[
  {
    "path": ".circleci/config.yml",
    "content": "version: 2.1\n\n# this allows you to use CircleCI's dynamic configuration feature\nsetup: true\n\n# the path-filtering orb is required to continue a pipeline based on\n# the path of an updated fileset\norbs:\n  path-filtering: circleci/path-filtering@0.1.2\n\nworkflows:\n  # the always-run workflow is always triggered, regardless of the pipeline parameters.\n  always-run:\n    jobs:\n      # the path-filtering/filter job determines which pipeline\n      # parameters to update.\n      - path-filtering/filter:\n          name: check-updated-files\n          # 3-column, whitespace-delimited mapping. One mapping per\n          # line:\n          # <regex path-to-test> <parameter-to-set> <value-of-pipeline-parameter>\n          mapping: |\n            mmpose/.* lint_only false\n            requirements/.* lint_only false\n            tests/.* lint_only false\n            tools/.* lint_only false\n            configs/.* lint_only false\n            .circleci/.* lint_only false\n          base-revision: dev-1.x\n          # this is the path of the configuration we should trigger once\n          # path filtering and pipeline parameter value updates are\n          # complete. In this case, we are using the parent dynamic\n          # configuration itself.\n          config-path: .circleci/test.yml\n"
  },
  {
    "path": ".circleci/docker/Dockerfile",
    "content": "ARG PYTORCH=\"1.7.1\"\nARG CUDA=\"11.0\"\nARG CUDNN=\"8\"\n\nFROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel\n\n# To fix GPG key error when running apt-get update\nRUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub\nRUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub\n\nRUN apt-get update && apt-get install -y ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 libgl1-mesa-glx\n"
  },
  {
    "path": ".circleci/scripts/get_mmcv_var.sh",
    "content": "#!/bin/bash\n\nTORCH=$1\nCUDA=$2\n\n# 10.2 -> cu102\nMMCV_CUDA=\"cu`echo ${CUDA} | tr -d '.'`\"\n\n# MMCV only provides pre-compiled packages for torch 1.x.0\n# which works for any subversions of torch 1.x.\n# We force the torch version to be 1.x.0 to ease package searching\n# and avoid unnecessary rebuild during MMCV's installation.\nTORCH_VER_ARR=(${TORCH//./ })\nTORCH_VER_ARR[2]=0\nprintf -v MMCV_TORCH \"%s.\" \"${TORCH_VER_ARR[@]}\"\nMMCV_TORCH=${MMCV_TORCH%?}  # Remove the last dot\n\necho \"export MMCV_CUDA=${MMCV_CUDA}\" >> $BASH_ENV\necho \"export MMCV_TORCH=${MMCV_TORCH}\" >> $BASH_ENV\n"
  },
  {
    "path": ".circleci/test.yml",
    "content": "version: 2.1\n\n# the default pipeline parameters, which will be updated according to\n# the results of the path-filtering orb\nparameters:\n  lint_only:\n    type: boolean\n    default: true\n\njobs:\n  lint:\n    docker:\n      - image: cimg/python:3.7.4\n    steps:\n      - checkout\n      - run:\n          name: Install pre-commit hook\n          command: |\n            pip install pre-commit\n            pre-commit install\n      - run:\n          name: Linting\n          command: pre-commit run --all-files\n      - run:\n          name: Check docstring coverage\n          command: |\n            pip install interrogate\n            interrogate -v --ignore-init-method --ignore-module --ignore-nested-functions --ignore-regex \"__repr__\" --fail-under 80 mmpose\n  build_cpu:\n    parameters:\n      # The python version must match available image tags in\n      # https://circleci.com/developer/images/image/cimg/python\n      python:\n        type: string\n      torch:\n        type: string\n      torchvision:\n        type: string\n    docker:\n      - image: cimg/python:<< parameters.python >>\n    resource_class: large\n    steps:\n      - checkout\n      - run:\n          name: Install Libraries\n          command: |\n            sudo apt-get update\n            sudo apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 libturbojpeg git\n      - run:\n          name: Configure Python & pip\n          command: |\n            pip install --upgrade pip\n            pip install wheel\n      - run:\n          name: Install PyTorch\n          command: |\n            python -V\n            pip install torch==<< parameters.torch >>+cpu torchvision==<< parameters.torchvision >>+cpu -f https://download.pytorch.org/whl/torch_stable.html\n      - run:\n          name: Install mmpose dependencies\n          command: |\n            pip install -U numpy\n            pip install git+https://github.com/open-mmlab/mmengine.git@main\n            pip install -U openmim\n            mim install 'mmcv >= 2.0.0'\n            pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n            pip install -r requirements/tests.txt\n            pip install -r requirements/albu.txt\n            pip install -r requirements/poseval.txt\n      - run:\n          name: Build and install\n          command: |\n            pip install -e .\n      - run:\n          name: Run unittests\n          command: |\n            coverage run --branch --source mmpose -m pytest tests/\n            coverage xml\n            coverage report -m\n  build_cuda:\n    parameters:\n      torch:\n        type: string\n      cuda:\n        type: enum\n        enum: [\"11.0\", \"11.7\"]\n      cudnn:\n        type: integer\n        default: 8\n    machine:\n      image: ubuntu-2004-cuda-11.4:202110-01\n      # docker_layer_caching: true\n    resource_class: gpu.nvidia.small\n    steps:\n      - checkout\n      - run:\n          # Cloning repos in VM since Docker doesn't have access to the private key\n          name: Clone Repos\n          command: |\n            git clone -b main --depth 1 https://github.com/open-mmlab/mmengine.git /home/circleci/mmengine\n            git clone -b dev-3.x --depth 1 https://github.com/open-mmlab/mmdetection.git /home/circleci/mmdetection\n      - run:\n          name: Build Docker image\n          command: |\n            docker build .circleci/docker -t mmpose:gpu --build-arg PYTORCH=<< parameters.torch >> --build-arg CUDA=<< parameters.cuda >> --build-arg CUDNN=<< parameters.cudnn >>\n            docker run --gpus all -t -d -v /home/circleci/project:/mmpose -v /home/circleci/mmengine:/mmengine -v /home/circleci/mmdetection:/mmdetection -w /mmpose --name mmpose mmpose:gpu\n      - run:\n          name: Install mmpose dependencies\n          command: |\n            docker exec mmpose apt install git -y\n            docker exec mmpose pip install -U numpy\n            docker exec mmpose pip install -e /mmengine\n            docker exec mmpose pip install -U openmim\n            docker exec mmpose mim install 'mmcv >= 2.0.0'\n            docker exec mmpose pip install -e /mmdetection\n            docker exec mmpose pip install -r requirements/tests.txt\n            docker exec mmpose pip install -r requirements/albu.txt\n            docker exec mmpose pip install -r requirements/poseval.txt\n      - run:\n          name: Build and install\n          command: |\n            docker exec mmpose pip install -e .\n      - run:\n          name: Run unittests\n          command: |\n            docker exec mmpose pytest tests/\n\nworkflows:\n  pr_stage_lint:\n    when: << pipeline.parameters.lint_only >>\n    jobs:\n      - lint:\n          name: lint\n          filters:\n            branches:\n              ignore:\n                - dev-1.x\n                - main\n  pr_stage_test:\n    when:\n      not:\n        << pipeline.parameters.lint_only >>\n    jobs:\n      - lint:\n          name: lint\n          filters:\n            branches:\n              ignore:\n                - dev-1.x\n                - main\n      - build_cpu:\n          name: minimum_version_cpu\n          torch: 1.7.1\n          torchvision: 0.8.2\n          python: 3.7.4\n          requires:\n            - lint\n      - build_cpu:\n          name: maximum_version_cpu\n          torch: 2.0.0\n          torchvision: 0.15.1\n          python: 3.9.0\n          requires:\n            - minimum_version_cpu\n      - hold:\n          type: approval\n          requires:\n            - maximum_version_cpu\n      - build_cuda:\n          name: mainstream_version_gpu\n          torch: 1.7.1\n          # Use double quotation mark to explicitly specify its type\n          # as string instead of number\n          cuda: \"11.0\"\n          requires:\n            - hold\n      - build_cuda:\n          name: maximum_version_gpu\n          torch: 2.0.0\n          cuda: \"11.7\"\n          cudnn: 8\n          requires:\n            - hold\n  merge_stage_test:\n    when:\n      not:\n        << pipeline.parameters.lint_only >>\n    jobs:\n      - build_cuda:\n          name: minimum_version_gpu\n          torch: 1.7.1\n          # Use double quotation mark to explicitly specify its type\n          # as string instead of number\n          cuda: \"11.0\"\n          filters:\n            branches:\n              only:\n                - dev-1.x\n                - main\n"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "content": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, we as\ncontributors and maintainers pledge to making participation in our project and\nour community a harassment-free experience for everyone, regardless of age, body\nsize, disability, ethnicity, sex characteristics, gender identity and expression,\nlevel of experience, education, socio-economic status, nationality, personal\nappearance, race, religion, or sexual identity and orientation.\n\n## Our Standards\n\nExamples of behavior that contributes to creating a positive environment\ninclude:\n\n- Using welcoming and inclusive language\n- Being respectful of differing viewpoints and experiences\n- Gracefully accepting constructive criticism\n- Focusing on what is best for the community\n- Showing empathy towards other community members\n\nExamples of unacceptable behavior by participants include:\n\n- The use of sexualized language or imagery and unwelcome sexual attention or\n  advances\n- Trolling, insulting/derogatory comments, and personal or political attacks\n- Public or private harassment\n- Publishing others' private information, such as a physical or electronic\n  address, without explicit permission\n- Other conduct which could reasonably be considered inappropriate in a\n  professional setting\n\n## Our Responsibilities\n\nProject maintainers are responsible for clarifying the standards of acceptable\nbehavior and are expected to take appropriate and fair corrective action in\nresponse to any instances of unacceptable behavior.\n\nProject maintainers have the right and responsibility to remove, edit, or\nreject comments, commits, code, wiki edits, issues, and other contributions\nthat are not aligned to this Code of Conduct, or to ban temporarily or\npermanently any contributor for other behaviors that they deem inappropriate,\nthreatening, offensive, or harmful.\n\n## Scope\n\nThis Code of Conduct applies both within project spaces and in public spaces\nwhen an individual is representing the project or its community. Examples of\nrepresenting a project or community include using an official project e-mail\naddress, posting via an official social media account, or acting as an appointed\nrepresentative at an online or offline event. Representation of a project may be\nfurther defined and clarified by project maintainers.\n\n## Enforcement\n\nInstances of abusive, harassing, or otherwise unacceptable behavior may be\nreported by contacting the project team at chenkaidev@gmail.com. All\ncomplaints will be reviewed and investigated and will result in a response that\nis deemed necessary and appropriate to the circumstances. The project team is\nobligated to maintain confidentiality with regard to the reporter of an incident.\nFurther details of specific enforcement policies may be posted separately.\n\nProject maintainers who do not follow or enforce the Code of Conduct in good\nfaith may face temporary or permanent repercussions as determined by other\nmembers of the project's leadership.\n\n## Attribution\n\nThis Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,\navailable at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n\nFor answers to common questions about this code of conduct, see\nhttps://www.contributor-covenant.org/faq\n\n[homepage]: https://www.contributor-covenant.org\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/1-bug-report.yml",
    "content": "name: \"🐞 Bug report\"\ndescription: \"Create a report to help us reproduce and fix the bug\"\nlabels: bug\ntitle: \"[Bug] \"\n\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ## Note\n        For general usage questions or idea discussions, please post it to our [**Forum**](https://github.com/open-mmlab/mmpose/discussions)\n        Please fill in as **much** of the following form as you're able to. **The clearer the description, the shorter it will take to solve it.**\n\n  - type: checkboxes\n    attributes:\n      label: Prerequisite\n      description: Please check the following items before creating a new issue.\n      options:\n      - label: I have searched [Issues](https://github.com/open-mmlab/mmpose/issues) and [Discussions](https://github.com/open-mmlab/mmpose/discussions) but cannot get the expected help.\n        required: true\n      - label: The bug has not been fixed in the latest version(https://github.com/open-mmlab/mmpose).\n        required: true\n\n  - type: textarea\n    attributes:\n      label: Environment\n      description: |\n        Please run following commands and and copy-paste it here:\n          - `python -c \"from mmpose.utils import collect_env; print(collect_env())\"` to collect necessary environment information.\n          - `pip list | grep mm` to collect repositories related to OpenMMLab.\n          - \\[Optional\\] Other environment variables that may be related (such as `$PATH`, `$LD_LIBRARY_PATH`, `$PYTHONPATH`, etc.)\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Reproduces the problem - code sample\n      description: |\n        Please provide a code sample that reproduces the problem you ran into. It can be a Colab link or just a code snippet.\n      placeholder: |\n        ```python\n        # Sample code to reproduce the problem\n        ```\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Reproduces the problem - command or script\n      description: |\n        What command or script did you run?\n      placeholder: |\n        ```shell\n        The command or script you run.\n        ```\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Reproduces the problem - error message\n      description: |\n        Please provide the error message or logs you got, with the full traceback.\n\n        Tip: You can attach screenshots or log files by dragging them into the text area..\n      placeholder: |\n        ```\n        The error message or logs you got, with the full traceback.\n        ```\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Additional information\n      description: |\n        Tell us anything else you think we should know.\n\n        Tip: You can attach screenshots or log files by dragging them into the text area.\n      placeholder: |\n        1. What's your expected result?\n        2. What dataset did you use?\n        3. What do you think might be the reason?\n\n  - type: markdown\n    attributes:\n      value: |\n        ## Acknowledgement\n        Thanks for taking the time to fill out this report.\n\n        If you have already identified the reason, we strongly appreciate you creating a new PR to fix it [**Here**](https://github.com/open-mmlab/mmpose/pulls)!\n        Please refer to [**Contribution Guide**](https://mmpose.readthedocs.io/en/latest/contribution_guide.html) for contributing.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/2-feature_request.yml",
    "content": "name: 🚀 Feature request\ndescription: Suggest an idea for this project\nlabels: feature-request\ntitle: \"[Feature] \"\n\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ## Note\n        For general usage questions or idea discussions, please post it to our [**Forum**](https://github.com/open-mmlab/mmpose/discussions)\n\n        Please fill in as **much** of the following form as you're able to. **The clearer the description, the shorter it will take to solve it.**\n\n  - type: textarea\n    attributes:\n      label: What is the feature?\n      description: Tell us more about the feature and how this feature can help.\n      placeholder: |\n        E.g., It is inconvenient when \\[....\\].\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Any other context?\n      description: |\n        Have you considered any alternative solutions or features? If so, what are they? Also, feel free to add any other context or screenshots about the feature request here.\n\n  - type: markdown\n    attributes:\n      value: |\n        ## Acknowledgement\n        Thanks for taking the time to fill out this report.\n\n        We strongly appreciate you creating a new PR to implement it [**Here**](https://github.com/open-mmlab/mmpose/pulls)!\n        Please refer to [**Contribution Guide**](https://mmpose.readthedocs.io/en/latest/contribution_guide.html) for contributing.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/3-documentation.yml",
    "content": "name: 📚 Documentation\ndescription: Report an issue related to the documentation.\nlabels: \"docs\"\ntitle: \"[Docs] \"\n\nbody:\n  - type: markdown\n    attributes:\n      value: |\n        ## Note\n        For general usage questions or idea discussions, please post it to our [**Forum**](https://github.com/open-mmlab/mmpose/discussions)\n        Please fill in as **much** of the following form as you're able to. **The clearer the description, the shorter it will take to solve it.**\n\n  - type: textarea\n    attributes:\n      label: 📚 The doc issue\n      description: >\n        A clear and concise description the issue.\n    validations:\n      required: true\n\n  - type: textarea\n    attributes:\n      label: Suggest a potential alternative/fix\n      description: >\n        Tell us how we could improve the documentation in this regard.\n\n  - type: markdown\n    attributes:\n      value: |\n        ## Acknowledgement\n        Thanks for taking the time to fill out this report.\n\n        If you have already identified the reason, we strongly appreciate you creating a new PR to fix it [**here**](https://github.com/open-mmlab/mmpose/pulls)!\n        Please refer to [**Contribution Guide**](https://mmpose.readthedocs.io/en/latest/contribution_guide.html) for contributing.\n"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/config.yml",
    "content": "blank_issues_enabled: false\n\ncontact_links:\n  - name: Common Issues\n    url: https://mmpose.readthedocs.io/en/latest/faq.html\n    about: Check if your issue already has solutions\n  - name: MMPose Documentation\n    url: https://mmpose.readthedocs.io/en/latest/\n    about: Check if your question is answered in docs\n"
  },
  {
    "path": ".github/pull_request_template.md",
    "content": "<!-- Thanks for your contribution and we appreciate it a lot. The following instructions would make your pull request more healthy and more easily get feedback. If you do not understand some items, don't worry, just make the pull request and seek help from maintainers. -->\n\n## Motivation\n\n<!-- Please describe the motivation of this PR and the goal you want to achieve through this PR. -->\n\n## Modification\n\n<!-- Please briefly describe what modification is made in this PR. -->\n\n## BC-breaking (Optional)\n\n<!-- Does the modification introduce changes that break the backward compatibility of the downstream repositories?\nIf so, please describe how it breaks the compatibility and how the downstream projects should modify their code to keep compatibility with this PR. -->\n\n## Use cases (Optional)\n\n<!-- If this PR introduces a new feature, it is better to list some use cases here and update the documentation. -->\n\n## Checklist\n\n**Before PR**:\n\n- [ ] I have read and followed the workflow indicated in the [CONTRIBUTING.md](https://github.com/open-mmlab/mmpose/blob/master/.github/CONTRIBUTING.md) to create this PR.\n- [ ] Pre-commit or linting tools indicated in [CONTRIBUTING.md](https://github.com/open-mmlab/mmpose/blob/master/.github/CONTRIBUTING.md) are used to fix the potential lint issues.\n- [ ] Bug fixes are covered by unit tests, the case that causes the bug should be added in the unit tests.\n- [ ] New functionalities are covered by complete unit tests. If not, please add more unit tests to ensure correctness.\n- [ ] The documentation has been modified accordingly, including docstring or example tutorials.\n\n**After PR**:\n\n- [ ] CLA has been signed and all committers have signed the CLA in this PR.\n"
  },
  {
    "path": ".github/workflows/deploy.yml",
    "content": "name: deploy\n\non: push\n\njobs:\n  build-n-publish:\n    runs-on: ubuntu-latest\n    if: startsWith(github.event.ref, 'refs/tags')\n    steps:\n      - uses: actions/checkout@v2\n      - name: Set up Python 3.7\n        uses: actions/setup-python@v2\n        with:\n          python-version: 3.7\n      - name: Build MMPose\n        run: |\n          pip install wheel\n          python setup.py sdist bdist_wheel\n      - name: Publish distribution to PyPI\n        run: |\n          pip install twine\n          twine upload dist/* -u __token__ -p ${{ secrets.pypi_password }}\n"
  },
  {
    "path": ".github/workflows/lint.yml",
    "content": "name: lint\n\non: [push, pull_request]\n\nconcurrency:\n  group: github.workflow−{{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  lint:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions/checkout@v2\n      - name: Set up Python 3.7\n        uses: actions/setup-python@v2\n        with:\n          python-version: 3.7\n      - name: Install pre-commit hook\n        run: |\n          pip install pre-commit\n          pre-commit install\n      - name: Linting\n        run: pre-commit run --all-files\n      - name: Check docstring coverage\n        run: |\n          pip install interrogate\n          interrogate -v --ignore-init-method --ignore-module --ignore-nested-functions --ignore-regex \"__repr__\" --fail-under 80 mmpose\n"
  },
  {
    "path": ".github/workflows/merge_stage_test.yml",
    "content": "name: merge_stage_test\n\non:\n  push:\n    paths-ignore:\n      - 'README.md'\n      - 'README_zh-CN.md'\n      - 'docs/**'\n      - 'demo/**'\n      - '.dev_scripts/**'\n      - '.circleci/**'\n    branches:\n      - dev-1.x\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  build_cpu_py:\n    runs-on: ubuntu-22.04\n    strategy:\n      matrix:\n        python-version: [3.8, 3.9]\n        torch: [1.8.1]\n        include:\n          - torch: 1.8.1\n            torchvision: 0.9.1\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: pip install pip --upgrade\n      - name: Install Numpy\n        run: pip install -U numpy\n      - name: Install PyTorch\n        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html\n      - name: Install MMEngine\n        run: pip install git+https://github.com/open-mmlab/mmengine.git@main\n      - name: Install MMCV\n        run: |\n          pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n      - name: Install MMDet\n        run: |\n          python -m pip install --upgrade pip setuptools wheel\n          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n      - name: Install other dependencies\n        run: |\n          pip install -r requirements/tests.txt\n          pip install -r requirements/runtime.txt\n          pip install -r requirements/albu.txt\n          pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: rm -rf .eggs && pip install -e .\n      - name: Run unittests and generate coverage report\n        run: |\n          coverage run --branch --source mmpose -m pytest tests/\n          coverage xml\n          coverage report -m\n\n  build_cpu_pt:\n    runs-on: ubuntu-22.04\n    strategy:\n      matrix:\n        python-version: [3.7]\n        torch: [1.8.0, 1.8.1, 1.9.1, 1.10.1, 1.11.0, 1.12.1, 1.13.0]\n        include:\n          - torch: 1.8.0\n            torchvision: 0.9.0\n          - torch: 1.8.1\n            torchvision: 0.9.1\n          - torch: 1.9.1\n            torchvision: 0.10.1\n          - torch: 1.10.1\n            torchvision: 0.11.2\n          - torch: 1.11.0\n            torchvision: 0.12.0\n          - torch: 1.12.1\n            torchvision: 0.13.1\n          - torch: 1.13.0\n            torchvision: 0.14.0\n          - torch: 2.0.0\n            torchvision: 0.15.1\n            python-version: 3.8\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: pip install pip --upgrade\n      - name: Install Numpy\n        run: pip install -U numpy\n      - name: Install PyTorch\n        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html\n      - name: Install MMEngine\n        run: pip install git+https://github.com/open-mmlab/mmengine.git@main\n      - name: Install MMCV\n        run: |\n          pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n      - name: Install MMDet\n        run: |\n          python -m pip install --upgrade pip setuptools wheel\n          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n      - name: Install other dependencies\n        run: |\n          pip install -r requirements/tests.txt\n          pip install -r requirements/runtime.txt\n          pip install -r requirements/albu.txt\n          pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: rm -rf .eggs && pip install -e .\n      - name: Run unittests and generate coverage report\n        run: |\n          coverage run --branch --source mmpose -m pytest tests/\n          coverage xml\n          coverage report -m\n      # Only upload coverage report for python3.7 && pytorch1.8.1 cpu\n      - name: Upload coverage to Codecov\n        if: ${{matrix.torch == '1.8.1' && matrix.python-version == '3.7'}}\n        uses: codecov/codecov-action@v1.0.14\n        with:\n          file: ./coverage.xml\n          flags: unittests\n          env_vars: OS,PYTHON\n          name: codecov-umbrella\n          fail_ci_if_error: false\n\n  build_cu102:\n    runs-on: ubuntu-22.04\n    container:\n      image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel\n    strategy:\n      matrix:\n        python-version: [3.7]\n        include:\n          - torch: 1.8.1\n            cuda: 10.2\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: pip install pip --upgrade\n      - name: Fetch GPG keys\n        run: |\n          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub\n          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub\n      - name: Install Python-dev\n        run: apt-get update && apt-get install -y python${{matrix.python-version}}-dev\n        if: ${{matrix.python-version != 3.9}}\n      - name: Install system dependencies\n        run: |\n          apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6\n      - name: Install mmpose dependencies\n        run: |\n          pip install -U numpy\n          pip install git+https://github.com/open-mmlab/mmengine.git@main\n          pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n          pip install -r requirements/tests.txt\n          pip install -r requirements/runtime.txt\n          pip install -r requirements/albu.txt\n          pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: rm -rf .eggs && pip install -e .\n      - name: Run unittests and generate coverage report\n        run: |\n          coverage run --branch --source mmpose -m pytest tests/\n          coverage xml\n          coverage report -m\n\n  build_windows:\n    runs-on: windows-2022\n    strategy:\n      matrix:\n        os: [windows-2022]\n        python: [3.7]\n        platform: [cpu, cu111]\n        torch: [1.8.1]\n        torchvision: [0.9.1]\n        include:\n          - python-version: 3.8\n            platform: cu117\n            torch: 2.0.0\n            torchvision: 0.15.1\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: python -m pip install pip --upgrade\n      - name: Install lmdb\n        run: python -m pip install lmdb\n      - name: Install PyTorch\n        run: python -m pip install torch==${{matrix.torch}}+${{matrix.platform}} torchvision==${{matrix.torchvision}}+${{matrix.platform}} -f https://download.pytorch.org/whl/${{matrix.platform}}/torch_stable.html\n      - name: Install mmpose dependencies\n        run: |\n          python -m pip install -U numpy\n          python -m pip install --upgrade pip setuptools wheel\n          python -m pip install git+https://github.com/open-mmlab/mmengine.git@main\n          python -m pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n          mim install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n          python -m pip install -r requirements/tests.txt\n          python -m pip install -r requirements/runtime.txt\n          python -m pip install -r requirements/albu.txt\n          python -m pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: |\n          python -m pip install -e . -v\n      - name: Run unittests and generate coverage report\n        run: |\n          pytest tests/\n"
  },
  {
    "path": ".github/workflows/pr_stage_test.yml",
    "content": "name: pr_stage_test\n\non:\n  pull_request:\n    paths-ignore:\n      - 'README.md'\n      - 'README_zh-CN.md'\n      - 'docs/**'\n      - 'demo/**'\n      - '.dev_scripts/**'\n      - '.circleci/**'\n\nconcurrency:\n  group: ${{ github.workflow }}-${{ github.ref }}\n  cancel-in-progress: true\n\njobs:\n  build_cpu:\n    runs-on: ubuntu-22.04\n    strategy:\n      matrix:\n        python-version: [3.7]\n        include:\n          - torch: 1.8.1\n            torchvision: 0.9.1\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: pip install pip --upgrade\n      - name: Install Numpy\n        run: pip install -U numpy\n      - name: Install PyTorch\n        run: pip install torch==${{matrix.torch}}+cpu torchvision==${{matrix.torchvision}}+cpu -f https://download.pytorch.org/whl/torch_stable.html\n      - name: Install mmpose dependencies\n        run: |\n          python -m pip install --upgrade pip setuptools wheel\n          pip install -U numpy\n          pip install git+https://github.com/open-mmlab/mmengine.git@main\n          pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n          pip install -r requirements/tests.txt\n          pip install -r requirements/runtime.txt\n          pip install -r requirements/albu.txt\n          pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: rm -rf .eggs && pip install -e .\n      - name: Run unittests and generate coverage report\n        run: |\n          coverage run --branch --source mmpose -m pytest tests/\n          coverage xml\n          coverage report -m\n      # Upload coverage report for python3.7 && pytorch1.8.1 cpu\n      - name: Upload coverage to Codecov\n        uses: codecov/codecov-action@v1.0.14\n        with:\n          file: ./coverage.xml\n          flags: unittests\n          env_vars: OS,PYTHON\n          name: codecov-umbrella\n          fail_ci_if_error: false\n\n  build_cu102:\n    runs-on: ubuntu-22.04\n    container:\n      image: pytorch/pytorch:1.8.1-cuda10.2-cudnn7-devel\n    strategy:\n      matrix:\n        python-version: [3.7]\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: pip install pip --upgrade\n      - name: Fetch GPG keys\n        run: |\n          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub\n          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub\n      - name: Install Python-dev\n        run: apt-get update && apt-get install -y python${{matrix.python-version}}-dev\n        if: ${{matrix.python-version != 3.9}}\n      - name: Install system dependencies\n        run: |\n          apt-get update\n          apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libxrender-dev\n      - name: Install mmpose dependencies\n        run: |\n          pip install -U numpy\n          pip install git+https://github.com/open-mmlab/mmengine.git@main\n          pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n          pip install -r requirements/tests.txt\n          pip install -r requirements/runtime.txt\n          pip install -r requirements/albu.txt\n          pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: rm -rf .eggs && pip install -e .\n      - name: Run unittests and generate coverage report\n        run: |\n          coverage run --branch --source mmpose -m pytest tests/\n          coverage xml\n          coverage report -m\n\n  build_cu117:\n    runs-on: ubuntu-22.04\n    container:\n      image: pytorch/pytorch:2.0.0-cuda11.7-cudnn8-devel\n    strategy:\n      matrix:\n        python-version: [3.9]\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: pip install pip --upgrade\n      - name: Fetch GPG keys\n        run: |\n          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub\n          apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub\n      - name: Install system dependencies\n        run: apt-get update && apt-get install -y ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libxrender-dev\n      - name: Install mmpose dependencies\n        run: |\n          pip install -U numpy\n          pip install git+https://github.com/open-mmlab/mmengine.git@main\n          pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n          pip install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n          pip install -r requirements/tests.txt\n          pip install -r requirements/runtime.txt\n          pip install -r requirements/albu.txt\n          pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: rm -rf .eggs && pip install -e .\n      - name: Run unittests and generate coverage report\n        run: |\n          coverage run --branch --source mmpose -m pytest tests/\n          coverage xml\n          coverage report -m\n\n  build_windows:\n    runs-on: windows-2022\n    strategy:\n      matrix:\n        os: [windows-2022]\n        python: [3.7]\n        platform: [cpu, cu111]\n        torch: [1.8.1]\n        torchvision: [0.9.1]\n        include:\n          - python-version: 3.8\n            platform: cu117\n            torch: 2.0.0\n            torchvision: 0.15.1\n    steps:\n      - uses: actions/checkout@v3\n      - name: Set up Python ${{ matrix.python-version }}\n        uses: actions/setup-python@v4\n        with:\n          python-version: ${{ matrix.python-version }}\n      - name: Upgrade pip\n        run: python -m pip install pip --upgrade\n      - name: Install lmdb\n        run: python -m pip install lmdb\n      - name: Install PyTorch\n        run: python -m pip install torch==${{matrix.torch}}+${{matrix.platform}} torchvision==${{matrix.torchvision}}+${{matrix.platform}} -f https://download.pytorch.org/whl/${{matrix.platform}}/torch_stable.html\n      - name: Install mmpose dependencies\n        run: |\n          python -m pip install -U numpy\n          python -m pip install --upgrade pip setuptools wheel\n          python -m pip install git+https://github.com/open-mmlab/mmengine.git@main\n          python -m pip install -U openmim\n          mim install 'mmcv >= 2.0.0'\n          mim install git+https://github.com/open-mmlab/mmdetection.git@dev-3.x\n          python -m pip install -r requirements/tests.txt\n          python -m pip install -r requirements/albu.txt\n          python -m pip install -r requirements/poseval.txt\n      - name: Build and install\n        run: |\n          python -m pip install -e . -v\n      - name: Run unittests and generate coverage report\n        run: |\n          pytest tests/\n"
  },
  {
    "path": ".github/workflows/scripts/get_mmcv_var.sh",
    "content": "#!/bin/bash\n\nTORCH=$1\nCUDA=$2\n\n# 10.2 -> cu102\nMMCV_CUDA=\"cu`echo ${CUDA} | tr -d '.'`\"\n\n# MMCV only provides pre-compiled packages for torch 1.x.0\n# which works for any subversions of torch 1.x.\n# We force the torch version to be 1.x.0 to ease package searching\n# and avoid unnecessary rebuild during MMCV's installation.\nTORCH_VER_ARR=(${TORCH//./ })\nTORCH_VER_ARR[2]=0\nprintf -v MMCV_TORCH \"%s.\" \"${TORCH_VER_ARR[@]}\"\nMMCV_TORCH=${MMCV_TORCH%?}  # Remove the last dot\n\necho \"MMCV_CUDA=${MMCV_CUDA}\" >> $GITHUB_ENV\necho \"MMCV_TORCH=${MMCV_TORCH}\" >> $GITHUB_ENV\n"
  },
  {
    "path": ".gitignore",
    "content": "# Byte-compiled / optimized / DLL files\n__pycache__/\n*.py[cod]\n*$py.class\n**/*.pyc\n\n# C extensions\n*.so\n\n# Distribution / packaging\n.Python\nbuild/\ndevelop-eggs/\ndist/\ndownloads/\neggs/\n.eggs/\nlib/\nlib64/\nparts/\nsdist/\nvar/\nwheels/\n*.egg-info/\n.installed.cfg\n*.egg\nMANIFEST\n\n# PyInstaller\n#  Usually these files are written by a python script from a template\n#  before PyInstaller builds the exe, so as to inject date/other infos into it.\n*.manifest\n*.spec\n\n# Installer logs\npip-log.txt\npip-delete-this-directory.txt\n\n# Unit test / coverage reports\nhtmlcov/\n.tox/\n.coverage\n.coverage.*\n.cache\nnosetests.xml\ncoverage.xml\n*.cover\n.hypothesis/\n.pytest_cache/\n\n# Translations\n*.mo\n*.pot\n\n# Django stuff:\n*.log\nlocal_settings.py\ndb.sqlite3\n\n# Flask stuff:\ninstance/\n.webassets-cache\n\n# Scrapy stuff:\n.scrapy\n\n# Sphinx documentation\ndocs/en/_build\ndocs/zh_cn/_build\n\n# PyBuilder\ntarget/\n\n# Jupyter Notebook\n.ipynb_checkpoints\n\n# pyenv\n.python-version\n\n# celery beat schedule file\ncelerybeat-schedule\n\n# SageMath parsed files\n*.sage.py\n\n# Environments\n.env\n.venv\nenv/\nvenv/\nENV/\nenv.bak/\nvenv.bak/\n\n# Spyder project settings\n.spyderproject\n.spyproject\n\n# Rope project settings\n.ropeproject\n\n# mkdocs documentation\n/site\n\n# mypy\n.mypy_cache/\n\n# custom\nmmpose/.mim\n/models\n/data\n.vscode\n.idea\n*.pkl\n*.pkl.json\n*.log.json\n*.npy\nwork_dirs/\ndocs/**/topics/\ndocs/**/papers/*.md\ndocs/**/datasets.md\ndocs/**/modelzoo.md\n\n!tests/data/**/*.pkl\n!tests/data/**/*.pkl.json\n!tests/data/**/*.log.json\n!tests/data/**/*.pth\n!tests/data/**/*.npy\n!tests/data/**/vis/\n\n# Pytorch\n*.pth\n\n*.DS_Store\n"
  },
  {
    "path": ".pre-commit-config.yaml",
    "content": "exclude: ^tests/data/\nrepos:\n  - repo: https://github.com/PyCQA/flake8\n    rev: 5.0.4\n    hooks:\n      - id: flake8\n  - repo: https://github.com/PyCQA/isort\n    rev: 5.11.5\n    hooks:\n      - id: isort\n  - repo: https://github.com/pre-commit/mirrors-yapf\n    rev: v0.32.0\n    hooks:\n      - id: yapf\n  - repo: https://github.com/pre-commit/pre-commit-hooks\n    rev: v4.3.0\n    hooks:\n      - id: trailing-whitespace\n      - id: check-yaml\n      - id: end-of-file-fixer\n      - id: requirements-txt-fixer\n      - id: double-quote-string-fixer\n      - id: check-merge-conflict\n      - id: fix-encoding-pragma\n        args: [\"--remove\"]\n      - id: mixed-line-ending\n        args: [\"--fix=lf\"]\n  - repo: https://github.com/myint/docformatter\n    rev: v1.3.1\n    hooks:\n      - id: docformatter\n        args: [\"--in-place\", \"--wrap-descriptions\", \"79\"]\n  - repo: https://github.com/codespell-project/codespell\n    rev: v2.1.0\n    hooks:\n      - id: codespell\n        args: [\"--skip\", \"*.ipynb\", \"-L\", \"mot\"]\n  - repo: https://github.com/executablebooks/mdformat\n    rev: 0.7.14\n    hooks:\n      - id: mdformat\n        args: [\"--number\", \"--table-width\", \"200\"]\n        additional_dependencies:\n          - mdformat-openmmlab\n          - mdformat_frontmatter\n          - linkify-it-py\n  - repo: https://github.com/open-mmlab/pre-commit-hooks\n    rev: v0.2.0\n    hooks:\n      - id: check-copyright\n        args: [\"mmpose\", \"tests\", \"demo\", \"tools\", \"--excludes\", \"demo/mmdetection_cfg\", \"demo/mmtracking_cfg\"]\n"
  },
  {
    "path": ".pylintrc",
    "content": "[MASTER]\n\n# A comma-separated list of package or module names from where C extensions may\n# be loaded. Extensions are loading into the active Python interpreter and may\n# run arbitrary code.\nextension-pkg-whitelist=\n\n# Specify a score threshold to be exceeded before program exits with error.\nfail-under=10.0\n\n# Add files or directories to the blacklist. They should be base names, not\n# paths.\nignore=CVS,configs\n\n# Add files or directories matching the regex patterns to the blacklist. The\n# regex matches against base names, not paths.\nignore-patterns=\n\n# Python code to execute, usually for sys.path manipulation such as\n# pygtk.require().\n#init-hook=\n\n# Use multiple processes to speed up Pylint. Specifying 0 will auto-detect the\n# number of processors available to use.\njobs=1\n\n# Control the amount of potential inferred values when inferring a single\n# object. This can help the performance when dealing with large functions or\n# complex, nested conditions.\nlimit-inference-results=100\n\n# List of plugins (as comma separated values of python module names) to load,\n# usually to register additional checkers.\nload-plugins=\n\n# Pickle collected data for later comparisons.\npersistent=yes\n\n# When enabled, pylint would attempt to guess common misconfiguration and emit\n# user-friendly hints instead of false-positive error messages.\nsuggestion-mode=yes\n\n# Allow loading of arbitrary C extensions. Extensions are imported into the\n# active Python interpreter and may run arbitrary code.\nunsafe-load-any-extension=no\n\n\n[MESSAGES CONTROL]\n\n# Only show warnings with the listed confidence levels. Leave empty to show\n# all. Valid levels: HIGH, INFERENCE, INFERENCE_FAILURE, UNDEFINED.\nconfidence=\n\n# Disable the message, report, category or checker with the given id(s). You\n# can either give multiple identifiers separated by comma (,) or put this\n# option multiple times (only on the command line, not in the configuration\n# file where it should appear only once). You can also use \"--disable=all\" to\n# disable everything first and then reenable specific checks. For example, if\n# you want to run only the similarities checker, you can use \"--disable=all\n# --enable=similarities\". If you want to run only the classes checker, but have\n# no Warning level messages displayed, use \"--disable=all --enable=classes\n# --disable=W\".\ndisable=print-statement,\n        parameter-unpacking,\n        unpacking-in-except,\n        old-raise-syntax,\n        backtick,\n        long-suffix,\n        old-ne-operator,\n        old-octal-literal,\n        import-star-module-level,\n        non-ascii-bytes-literal,\n        raw-checker-failed,\n        bad-inline-option,\n        locally-disabled,\n        file-ignored,\n        suppressed-message,\n        useless-suppression,\n        deprecated-pragma,\n        use-symbolic-message-instead,\n        apply-builtin,\n        basestring-builtin,\n        buffer-builtin,\n        cmp-builtin,\n        coerce-builtin,\n        execfile-builtin,\n        file-builtin,\n        long-builtin,\n        raw_input-builtin,\n        reduce-builtin,\n        standarderror-builtin,\n        unicode-builtin,\n        xrange-builtin,\n        coerce-method,\n        delslice-method,\n        getslice-method,\n        setslice-method,\n        no-absolute-import,\n        old-division,\n        dict-iter-method,\n        dict-view-method,\n        next-method-called,\n        metaclass-assignment,\n        indexing-exception,\n        raising-string,\n        reload-builtin,\n        oct-method,\n        hex-method,\n        nonzero-method,\n        cmp-method,\n        input-builtin,\n        round-builtin,\n        intern-builtin,\n        unichr-builtin,\n        map-builtin-not-iterating,\n        zip-builtin-not-iterating,\n        range-builtin-not-iterating,\n        filter-builtin-not-iterating,\n        using-cmp-argument,\n        eq-without-hash,\n        div-method,\n        idiv-method,\n        rdiv-method,\n        exception-message-attribute,\n        invalid-str-codec,\n        sys-max-int,\n        bad-python3-import,\n        deprecated-string-function,\n        deprecated-str-translate-call,\n        deprecated-itertools-function,\n        deprecated-types-field,\n        next-method-defined,\n        dict-items-not-iterating,\n        dict-keys-not-iterating,\n        dict-values-not-iterating,\n        deprecated-operator-function,\n        deprecated-urllib-function,\n        xreadlines-attribute,\n        deprecated-sys-function,\n        exception-escape,\n        comprehension-escape,\n        no-member,\n        invalid-name,\n        too-many-branches,\n        wrong-import-order,\n        too-many-arguments,\n        missing-function-docstring,\n        missing-module-docstring,\n        too-many-locals,\n        too-few-public-methods,\n        abstract-method,\n        broad-except,\n        too-many-nested-blocks,\n        too-many-instance-attributes,\n        missing-class-docstring,\n        duplicate-code,\n        not-callable,\n        protected-access,\n        dangerous-default-value,\n        no-name-in-module,\n        logging-fstring-interpolation,\n        super-init-not-called,\n        redefined-builtin,\n        attribute-defined-outside-init,\n        arguments-differ,\n        cyclic-import,\n        bad-super-call,\n        too-many-statements\n\n# Enable the message, report, category or checker with the given id(s). You can\n# either give multiple identifier separated by comma (,) or put this option\n# multiple time (only on the command line, not in the configuration file where\n# it should appear only once). See also the \"--disable\" option for examples.\nenable=c-extension-no-member\n\n\n[REPORTS]\n\n# Python expression which should return a score less than or equal to 10. You\n# have access to the variables 'error', 'warning', 'refactor', and 'convention'\n# which contain the number of messages in each category, as well as 'statement'\n# which is the total number of statements analyzed. This score is used by the\n# global evaluation report (RP0004).\nevaluation=10.0 - ((float(5 * error + warning + refactor + convention) / statement) * 10)\n\n# Template used to display messages. This is a python new-style format string\n# used to format the message information. See doc for all details.\n#msg-template=\n\n# Set the output format. Available formats are text, parseable, colorized, json\n# and msvs (visual studio). You can also give a reporter class, e.g.\n# mypackage.mymodule.MyReporterClass.\noutput-format=text\n\n# Tells whether to display a full report or only the messages.\nreports=no\n\n# Activate the evaluation score.\nscore=yes\n\n\n[REFACTORING]\n\n# Maximum number of nested blocks for function / method body\nmax-nested-blocks=5\n\n# Complete name of functions that never returns. When checking for\n# inconsistent-return-statements if a never returning function is called then\n# it will be considered as an explicit return statement and no message will be\n# printed.\nnever-returning-functions=sys.exit\n\n\n[TYPECHECK]\n\n# List of decorators that produce context managers, such as\n# contextlib.contextmanager. Add to this list to register other decorators that\n# produce valid context managers.\ncontextmanager-decorators=contextlib.contextmanager\n\n# List of members which are set dynamically and missed by pylint inference\n# system, and so shouldn't trigger E1101 when accessed. Python regular\n# expressions are accepted.\ngenerated-members=\n\n# Tells whether missing members accessed in mixin class should be ignored. A\n# mixin class is detected if its name ends with \"mixin\" (case insensitive).\nignore-mixin-members=yes\n\n# Tells whether to warn about missing members when the owner of the attribute\n# is inferred to be None.\nignore-none=yes\n\n# This flag controls whether pylint should warn about no-member and similar\n# checks whenever an opaque object is returned when inferring. The inference\n# can return multiple potential results while evaluating a Python object, but\n# some branches might not be evaluated, which results in partial inference. In\n# that case, it might be useful to still emit no-member and other checks for\n# the rest of the inferred objects.\nignore-on-opaque-inference=yes\n\n# List of class names for which member attributes should not be checked (useful\n# for classes with dynamically set attributes). This supports the use of\n# qualified names.\nignored-classes=optparse.Values,thread._local,_thread._local\n\n# List of module names for which member attributes should not be checked\n# (useful for modules/projects where namespaces are manipulated during runtime\n# and thus existing member attributes cannot be deduced by static analysis). It\n# supports qualified module names, as well as Unix pattern matching.\nignored-modules=\n\n# Show a hint with possible names when a member name was not found. The aspect\n# of finding the hint is based on edit distance.\nmissing-member-hint=yes\n\n# The minimum edit distance a name should have in order to be considered a\n# similar match for a missing member name.\nmissing-member-hint-distance=1\n\n# The total number of similar names that should be taken in consideration when\n# showing a hint for a missing member.\nmissing-member-max-choices=1\n\n# List of decorators that change the signature of a decorated function.\nsignature-mutators=\n\n\n[SPELLING]\n\n# Limits count of emitted suggestions for spelling mistakes.\nmax-spelling-suggestions=4\n\n# Spelling dictionary name. Available dictionaries: none. To make it work,\n# install the python-enchant package.\nspelling-dict=\n\n# List of comma separated words that should not be checked.\nspelling-ignore-words=\n\n# A path to a file that contains the private dictionary; one word per line.\nspelling-private-dict-file=\n\n# Tells whether to store unknown words to the private dictionary (see the\n# --spelling-private-dict-file option) instead of raising a message.\nspelling-store-unknown-words=no\n\n\n[LOGGING]\n\n# The type of string formatting that logging methods do. `old` means using %\n# formatting, `new` is for `{}` formatting.\nlogging-format-style=old\n\n# Logging modules to check that the string format arguments are in logging\n# function parameter format.\nlogging-modules=logging\n\n\n[VARIABLES]\n\n# List of additional names supposed to be defined in builtins. Remember that\n# you should avoid defining new builtins when possible.\nadditional-builtins=\n\n# Tells whether unused global variables should be treated as a violation.\nallow-global-unused-variables=yes\n\n# List of strings which can identify a callback function by name. A callback\n# name must start or end with one of those strings.\ncallbacks=cb_,\n          _cb\n\n# A regular expression matching the name of dummy variables (i.e. expected to\n# not be used).\ndummy-variables-rgx=_+$|(_[a-zA-Z0-9_]*[a-zA-Z0-9]+?$)|dummy|^ignored_|^unused_\n\n# Argument names that match this expression will be ignored. Default to name\n# with leading underscore.\nignored-argument-names=_.*|^ignored_|^unused_\n\n# Tells whether we should check for unused import in __init__ files.\ninit-import=no\n\n# List of qualified module names which can have objects that can redefine\n# builtins.\nredefining-builtins-modules=six.moves,past.builtins,future.builtins,builtins,io\n\n\n[FORMAT]\n\n# Expected format of line ending, e.g. empty (any line ending), LF or CRLF.\nexpected-line-ending-format=\n\n# Regexp for a line that is allowed to be longer than the limit.\nignore-long-lines=^\\s*(# )?<?https?://\\S+>?$\n\n# Number of spaces of indent required inside a hanging or continued line.\nindent-after-paren=4\n\n# String used as indentation unit. This is usually \"    \" (4 spaces) or \"\\t\" (1\n# tab).\nindent-string='    '\n\n# Maximum number of characters on a single line.\nmax-line-length=100\n\n# Maximum number of lines in a module.\nmax-module-lines=1000\n\n# Allow the body of a class to be on the same line as the declaration if body\n# contains single statement.\nsingle-line-class-stmt=no\n\n# Allow the body of an if to be on the same line as the test if there is no\n# else.\nsingle-line-if-stmt=no\n\n\n[STRING]\n\n# This flag controls whether inconsistent-quotes generates a warning when the\n# character used as a quote delimiter is used inconsistently within a module.\ncheck-quote-consistency=no\n\n# This flag controls whether the implicit-str-concat should generate a warning\n# on implicit string concatenation in sequences defined over several lines.\ncheck-str-concat-over-line-jumps=no\n\n\n[SIMILARITIES]\n\n# Ignore comments when computing similarities.\nignore-comments=yes\n\n# Ignore docstrings when computing similarities.\nignore-docstrings=yes\n\n# Ignore imports when computing similarities.\nignore-imports=no\n\n# Minimum lines number of a similarity.\nmin-similarity-lines=4\n\n\n[MISCELLANEOUS]\n\n# List of note tags to take in consideration, separated by a comma.\nnotes=FIXME,\n      XXX,\n      TODO\n\n# Regular expression of note tags to take in consideration.\n#notes-rgx=\n\n\n[BASIC]\n\n# Naming style matching correct argument names.\nargument-naming-style=snake_case\n\n# Regular expression matching correct argument names. Overrides argument-\n# naming-style.\n#argument-rgx=\n\n# Naming style matching correct attribute names.\nattr-naming-style=snake_case\n\n# Regular expression matching correct attribute names. Overrides attr-naming-\n# style.\n#attr-rgx=\n\n# Bad variable names which should always be refused, separated by a comma.\nbad-names=foo,\n          bar,\n          baz,\n          toto,\n          tutu,\n          tata\n\n# Bad variable names regexes, separated by a comma. If names match any regex,\n# they will always be refused\nbad-names-rgxs=\n\n# Naming style matching correct class attribute names.\nclass-attribute-naming-style=any\n\n# Regular expression matching correct class attribute names. Overrides class-\n# attribute-naming-style.\n#class-attribute-rgx=\n\n# Naming style matching correct class names.\nclass-naming-style=PascalCase\n\n# Regular expression matching correct class names. Overrides class-naming-\n# style.\n#class-rgx=\n\n# Naming style matching correct constant names.\nconst-naming-style=UPPER_CASE\n\n# Regular expression matching correct constant names. Overrides const-naming-\n# style.\n#const-rgx=\n\n# Minimum line length for functions/classes that require docstrings, shorter\n# ones are exempt.\ndocstring-min-length=-1\n\n# Naming style matching correct function names.\nfunction-naming-style=snake_case\n\n# Regular expression matching correct function names. Overrides function-\n# naming-style.\n#function-rgx=\n\n# Good variable names which should always be accepted, separated by a comma.\ngood-names=i,\n           j,\n           k,\n           ex,\n           Run,\n           _,\n           x,\n           y,\n           w,\n           h,\n           a,\n           b\n\n# Good variable names regexes, separated by a comma. If names match any regex,\n# they will always be accepted\ngood-names-rgxs=\n\n# Include a hint for the correct naming format with invalid-name.\ninclude-naming-hint=no\n\n# Naming style matching correct inline iteration names.\ninlinevar-naming-style=any\n\n# Regular expression matching correct inline iteration names. Overrides\n# inlinevar-naming-style.\n#inlinevar-rgx=\n\n# Naming style matching correct method names.\nmethod-naming-style=snake_case\n\n# Regular expression matching correct method names. Overrides method-naming-\n# style.\n#method-rgx=\n\n# Naming style matching correct module names.\nmodule-naming-style=snake_case\n\n# Regular expression matching correct module names. Overrides module-naming-\n# style.\n#module-rgx=\n\n# Colon-delimited sets of names that determine each other's naming style when\n# the name regexes allow several styles.\nname-group=\n\n# Regular expression which should only match function or class names that do\n# not require a docstring.\nno-docstring-rgx=^_\n\n# List of decorators that produce properties, such as abc.abstractproperty. Add\n# to this list to register other decorators that produce valid properties.\n# These decorators are taken in consideration only for invalid-name.\nproperty-classes=abc.abstractproperty\n\n# Naming style matching correct variable names.\nvariable-naming-style=snake_case\n\n# Regular expression matching correct variable names. Overrides variable-\n# naming-style.\n#variable-rgx=\n\n\n[DESIGN]\n\n# Maximum number of arguments for function / method.\nmax-args=5\n\n# Maximum number of attributes for a class (see R0902).\nmax-attributes=7\n\n# Maximum number of boolean expressions in an if statement (see R0916).\nmax-bool-expr=5\n\n# Maximum number of branch for function / method body.\nmax-branches=12\n\n# Maximum number of locals for function / method body.\nmax-locals=15\n\n# Maximum number of parents for a class (see R0901).\nmax-parents=7\n\n# Maximum number of public methods for a class (see R0904).\nmax-public-methods=20\n\n# Maximum number of return / yield for function / method body.\nmax-returns=6\n\n# Maximum number of statements in function / method body.\nmax-statements=50\n\n# Minimum number of public methods for a class (see R0903).\nmin-public-methods=2\n\n\n[IMPORTS]\n\n# List of modules that can be imported at any level, not just the top level\n# one.\nallow-any-import-level=\n\n# Allow wildcard imports from modules that define __all__.\nallow-wildcard-with-all=no\n\n# Analyse import fallback blocks. This can be used to support both Python 2 and\n# 3 compatible code, which means that the block might have code that exists\n# only in one or another interpreter, leading to false positives when analysed.\nanalyse-fallback-blocks=no\n\n# Deprecated modules which should not be used, separated by a comma.\ndeprecated-modules=optparse,tkinter.tix\n\n# Create a graph of external dependencies in the given file (report RP0402 must\n# not be disabled).\next-import-graph=\n\n# Create a graph of every (i.e. internal and external) dependencies in the\n# given file (report RP0402 must not be disabled).\nimport-graph=\n\n# Create a graph of internal dependencies in the given file (report RP0402 must\n# not be disabled).\nint-import-graph=\n\n# Force import order to recognize a module as part of the standard\n# compatibility libraries.\nknown-standard-library=\n\n# Force import order to recognize a module as part of a third party library.\nknown-third-party=enchant\n\n# Couples of modules and preferred modules, separated by a comma.\npreferred-modules=\n\n\n[CLASSES]\n\n# List of method names used to declare (i.e. assign) instance attributes.\ndefining-attr-methods=__init__,\n                      __new__,\n                      setUp,\n                      __post_init__\n\n# List of member names, which should be excluded from the protected access\n# warning.\nexclude-protected=_asdict,\n                  _fields,\n                  _replace,\n                  _source,\n                  _make\n\n# List of valid names for the first argument in a class method.\nvalid-classmethod-first-arg=cls\n\n# List of valid names for the first argument in a metaclass class method.\nvalid-metaclass-classmethod-first-arg=cls\n\n\n[EXCEPTIONS]\n\n# Exceptions that will emit a warning when being caught. Defaults to\n# \"BaseException, Exception\".\novergeneral-exceptions=BaseException,\n                       Exception\n"
  },
  {
    "path": "CITATION.cff",
    "content": "cff-version: 1.3.1\nmessage: \"If you use this software, please cite it as below.\"\nauthors:\n  - name: \"MMPose Contributors\"\ntitle: \"OpenMMLab Pose Estimation Toolbox and Benchmark\"\ndate-released: 2020-08-31\nurl: \"https://github.com/open-mmlab/mmpose\"\nlicense: Apache-2.0\n"
  },
  {
    "path": "LICENSE",
    "content": "Copyright 2018-2020 Open-MMLab. All rights reserved.\n\n                                 Apache License\n                           Version 2.0, January 2004\n                        http://www.apache.org/licenses/\n\n   TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION\n\n   1. Definitions.\n\n      \"License\" shall mean the terms and conditions for use, reproduction,\n      and distribution as defined by Sections 1 through 9 of this document.\n\n      \"Licensor\" shall mean the copyright owner or entity authorized by\n      the copyright owner that is granting the License.\n\n      \"Legal Entity\" shall mean the union of the acting entity and all\n      other entities that control, are controlled by, or are under common\n      control with that entity. For the purposes of this definition,\n      \"control\" means (i) the power, direct or indirect, to cause the\n      direction or management of such entity, whether by contract or\n      otherwise, or (ii) ownership of fifty percent (50%) or more of the\n      outstanding shares, or (iii) beneficial ownership of such entity.\n\n      \"You\" (or \"Your\") shall mean an individual or Legal Entity\n      exercising permissions granted by this License.\n\n      \"Source\" form shall mean the preferred form for making modifications,\n      including but not limited to software source code, documentation\n      source, and configuration files.\n\n      \"Object\" form shall mean any form resulting from mechanical\n      transformation or translation of a Source form, including but\n      not limited to compiled object code, generated documentation,\n      and conversions to other media types.\n\n      \"Work\" shall mean the work of authorship, whether in Source or\n      Object form, made available under the License, as indicated by a\n      copyright notice that is included in or attached to the work\n      (an example is provided in the Appendix below).\n\n      \"Derivative Works\" shall mean any work, whether in Source or Object\n      form, that is based on (or derived from) the Work and for which the\n      editorial revisions, annotations, elaborations, or other modifications\n      represent, as a whole, an original work of authorship. For the purposes\n      of this License, Derivative Works shall not include works that remain\n      separable from, or merely link (or bind by name) to the interfaces of,\n      the Work and Derivative Works thereof.\n\n      \"Contribution\" shall mean any work of authorship, including\n      the original version of the Work and any modifications or additions\n      to that Work or Derivative Works thereof, that is intentionally\n      submitted to Licensor for inclusion in the Work by the copyright owner\n      or by an individual or Legal Entity authorized to submit on behalf of\n      the copyright owner. For the purposes of this definition, \"submitted\"\n      means any form of electronic, verbal, or written communication sent\n      to the Licensor or its representatives, including but not limited to\n      communication on electronic mailing lists, source code control systems,\n      and issue tracking systems that are managed by, or on behalf of, the\n      Licensor for the purpose of discussing and improving the Work, but\n      excluding communication that is conspicuously marked or otherwise\n      designated in writing by the copyright owner as \"Not a Contribution.\"\n\n      \"Contributor\" shall mean Licensor and any individual or Legal Entity\n      on behalf of whom a Contribution has been received by Licensor and\n      subsequently incorporated within the Work.\n\n   2. Grant of Copyright License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      copyright license to reproduce, prepare Derivative Works of,\n      publicly display, publicly perform, sublicense, and distribute the\n      Work and such Derivative Works in Source or Object form.\n\n   3. Grant of Patent License. Subject to the terms and conditions of\n      this License, each Contributor hereby grants to You a perpetual,\n      worldwide, non-exclusive, no-charge, royalty-free, irrevocable\n      (except as stated in this section) patent license to make, have made,\n      use, offer to sell, sell, import, and otherwise transfer the Work,\n      where such license applies only to those patent claims licensable\n      by such Contributor that are necessarily infringed by their\n      Contribution(s) alone or by combination of their Contribution(s)\n      with the Work to which such Contribution(s) was submitted. If You\n      institute patent litigation against any entity (including a\n      cross-claim or counterclaim in a lawsuit) alleging that the Work\n      or a Contribution incorporated within the Work constitutes direct\n      or contributory patent infringement, then any patent licenses\n      granted to You under this License for that Work shall terminate\n      as of the date such litigation is filed.\n\n   4. Redistribution. You may reproduce and distribute copies of the\n      Work or Derivative Works thereof in any medium, with or without\n      modifications, and in Source or Object form, provided that You\n      meet the following conditions:\n\n      (a) You must give any other recipients of the Work or\n          Derivative Works a copy of this License; and\n\n      (b) You must cause any modified files to carry prominent notices\n          stating that You changed the files; and\n\n      (c) You must retain, in the Source form of any Derivative Works\n          that You distribute, all copyright, patent, trademark, and\n          attribution notices from the Source form of the Work,\n          excluding those notices that do not pertain to any part of\n          the Derivative Works; and\n\n      (d) If the Work includes a \"NOTICE\" text file as part of its\n          distribution, then any Derivative Works that You distribute must\n          include a readable copy of the attribution notices contained\n          within such NOTICE file, excluding those notices that do not\n          pertain to any part of the Derivative Works, in at least one\n          of the following places: within a NOTICE text file distributed\n          as part of the Derivative Works; within the Source form or\n          documentation, if provided along with the Derivative Works; or,\n          within a display generated by the Derivative Works, if and\n          wherever such third-party notices normally appear. The contents\n          of the NOTICE file are for informational purposes only and\n          do not modify the License. You may add Your own attribution\n          notices within Derivative Works that You distribute, alongside\n          or as an addendum to the NOTICE text from the Work, provided\n          that such additional attribution notices cannot be construed\n          as modifying the License.\n\n      You may add Your own copyright statement to Your modifications and\n      may provide additional or different license terms and conditions\n      for use, reproduction, or distribution of Your modifications, or\n      for any such Derivative Works as a whole, provided Your use,\n      reproduction, and distribution of the Work otherwise complies with\n      the conditions stated in this License.\n\n   5. Submission of Contributions. Unless You explicitly state otherwise,\n      any Contribution intentionally submitted for inclusion in the Work\n      by You to the Licensor shall be under the terms and conditions of\n      this License, without any additional terms or conditions.\n      Notwithstanding the above, nothing herein shall supersede or modify\n      the terms of any separate license agreement you may have executed\n      with Licensor regarding such Contributions.\n\n   6. Trademarks. This License does not grant permission to use the trade\n      names, trademarks, service marks, or product names of the Licensor,\n      except as required for reasonable and customary use in describing the\n      origin of the Work and reproducing the content of the NOTICE file.\n\n   7. Disclaimer of Warranty. Unless required by applicable law or\n      agreed to in writing, Licensor provides the Work (and each\n      Contributor provides its Contributions) on an \"AS IS\" BASIS,\n      WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or\n      implied, including, without limitation, any warranties or conditions\n      of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A\n      PARTICULAR PURPOSE. You are solely responsible for determining the\n      appropriateness of using or redistributing the Work and assume any\n      risks associated with Your exercise of permissions under this License.\n\n   8. Limitation of Liability. In no event and under no legal theory,\n      whether in tort (including negligence), contract, or otherwise,\n      unless required by applicable law (such as deliberate and grossly\n      negligent acts) or agreed to in writing, shall any Contributor be\n      liable to You for damages, including any direct, indirect, special,\n      incidental, or consequential damages of any character arising as a\n      result of this License or out of the use or inability to use the\n      Work (including but not limited to damages for loss of goodwill,\n      work stoppage, computer failure or malfunction, or any and all\n      other commercial damages or losses), even if such Contributor\n      has been advised of the possibility of such damages.\n\n   9. Accepting Warranty or Additional Liability. While redistributing\n      the Work or Derivative Works thereof, You may choose to offer,\n      and charge a fee for, acceptance of support, warranty, indemnity,\n      or other liability obligations and/or rights consistent with this\n      License. However, in accepting such obligations, You may act only\n      on Your own behalf and on Your sole responsibility, not on behalf\n      of any other Contributor, and only if You agree to indemnify,\n      defend, and hold each Contributor harmless for any liability\n      incurred by, or claims asserted against, such Contributor by reason\n      of your accepting any such warranty or additional liability.\n\n   END OF TERMS AND CONDITIONS\n\n   APPENDIX: How to apply the Apache License to your work.\n\n      To apply the Apache License to your work, attach the following\n      boilerplate notice, with the fields enclosed by brackets \"[]\"\n      replaced with your own identifying information. (Don't include\n      the brackets!)  The text should be enclosed in the appropriate\n      comment syntax for the file format. We also recommend that a\n      file or class name and description of purpose be included on the\n      same \"printed page\" as the copyright notice for easier\n      identification within third-party archives.\n\n   Copyright 2018-2020 Open-MMLab.\n\n   Licensed under the Apache License, Version 2.0 (the \"License\");\n   you may not use this file except in compliance with the License.\n   You may obtain a copy of the License at\n\n       http://www.apache.org/licenses/LICENSE-2.0\n\n   Unless required by applicable law or agreed to in writing, software\n   distributed under the License is distributed on an \"AS IS\" BASIS,\n   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.\n   See the License for the specific language governing permissions and\n   limitations under the License.\n"
  },
  {
    "path": "LICENSES.md",
    "content": "# Licenses for special algorithms\n\nIn this file, we list the algorithms with other licenses instead of Apache 2.0. Users should be careful about adopting these algorithms in any commercial matters.\n\n| Algorithm |                                                                            Files                                                                            |     License      |\n| :-------: | :---------------------------------------------------------------------------------------------------------------------------------------------------------: | :--------------: |\n|  EDPose   | [mmpose/models/heads/transformer_heads/edpose_head.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/transformer_heads/edpose_head.py) | IDEA License 1.0 |\n"
  },
  {
    "path": "MANIFEST.in",
    "content": "include requirements/*.txt\ninclude mmpose/.mim/model-index.yml\ninclude mmpose/.mim/dataset-index.yml\nrecursive-include mmpose/.mim/configs *.py *.yml\nrecursive-include mmpose/.mim/tools *.py *.sh\nrecursive-include mmpose/.mim/demo *.py\n"
  },
  {
    "path": "README.md",
    "content": "<div align=\"center\">\n  <img src=\"resources/mmpose-logo.png\" width=\"450\"/>\n  <div>&nbsp;</div>\n  <div align=\"center\">\n    <b>OpenMMLab website</b>\n    <sup>\n      <a href=\"https://openmmlab.com\">\n        <i>HOT</i>\n      </a>\n    </sup>\n    &nbsp;&nbsp;&nbsp;&nbsp;\n    <b>OpenMMLab platform</b>\n    <sup>\n      <a href=\"https://platform.openmmlab.com\">\n        <i>TRY IT OUT</i>\n      </a>\n    </sup>\n  </div>\n  <div>&nbsp;</div>\n\n[![Documentation](https://readthedocs.org/projects/mmpose/badge/?version=latest)](https://mmpose.readthedocs.io/en/latest/?badge=latest)\n[![actions](https://github.com/open-mmlab/mmpose/workflows/merge_stage_test/badge.svg)](https://github.com/open-mmlab/mmpose/actions)\n[![codecov](https://codecov.io/gh/open-mmlab/mmpose/branch/latest/graph/badge.svg)](https://codecov.io/gh/open-mmlab/mmpose)\n[![PyPI](https://img.shields.io/pypi/v/mmpose)](https://pypi.org/project/mmpose/)\n[![LICENSE](https://img.shields.io/github/license/open-mmlab/mmpose.svg)](https://github.com/open-mmlab/mmpose/blob/main/LICENSE)\n[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/open-mmlab/mmpose.svg)](https://github.com/open-mmlab/mmpose/issues)\n[![Percentage of issues still open](https://isitmaintained.com/badge/open/open-mmlab/mmpose.svg)](https://github.com/open-mmlab/mmpose/issues)\n[![Open in OpenXLab](https://cdn-static.openxlab.org.cn/app-center/openxlab_demo.svg)](https://openxlab.org.cn/apps?search=mmpose)\n\n[📘Documentation](https://mmpose.readthedocs.io/en/latest/) |\n[🛠️Installation](https://mmpose.readthedocs.io/en/latest/installation.html) |\n[👀Model Zoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html) |\n[📜Papers](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html) |\n[🆕Update News](https://mmpose.readthedocs.io/en/latest/notes/changelog.html) |\n[🤔Reporting Issues](https://github.com/open-mmlab/mmpose/issues/new/choose) |\n[🔥RTMPose](/projects/rtmpose/)\n\n</div>\n\n<div align=\"center\">\n  <a href=\"https://openmmlab.medium.com/\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/219255827-67c1a27f-f8c5-46a9-811d-5e57448c61d1.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://discord.com/channels/1037617289144569886/1072798105428299817\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/218347213-c080267f-cbb6-443e-8532-8e1ed9a58ea9.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://twitter.com/OpenMMLab\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/218346637-d30c8a0f-3eba-4699-8131-512fb06d46db.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://www.youtube.com/openmmlab\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/218346691-ceb2116a-465a-40af-8424-9f30d2348ca9.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://space.bilibili.com/1293512903\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/219026751-d7d14cce-a7c9-4e82-9942-8375fca65b99.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://www.zhihu.com/people/openmmlab\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/219026120-ba71e48b-6e94-4bd4-b4e9-b7d175b5e362.png\" width=\"3%\" alt=\"\" /></a>\n</div>\n\n## Introduction\n\nEnglish | [简体中文](README_CN.md)\n\nMMPose is an open-source toolbox for pose estimation based on PyTorch.\nIt is a part of the [OpenMMLab project](https://github.com/open-mmlab).\n\nThe main branch works with **PyTorch 1.8+**.\n\nhttps://user-images.githubusercontent.com/15977946/124654387-0fd3c500-ded1-11eb-84f6-24eeddbf4d91.mp4\n\n<br/>\n\n<details close>\n<summary><b>Major Features</b></summary>\n\n- **Support diverse tasks**\n\n  We support a wide spectrum of mainstream pose analysis tasks in current research community, including 2d multi-person human pose estimation, 2d hand pose estimation, 2d face landmark detection, 133 keypoint whole-body human pose estimation, 3d human mesh recovery, fashion landmark detection and animal pose estimation.\n  See [Demo](demo/docs/en) for more information.\n\n- **Higher efficiency and higher accuracy**\n\n  MMPose implements multiple state-of-the-art (SOTA) deep learning models, including both top-down & bottom-up approaches. We achieve faster training speed and higher accuracy than other popular codebases, such as [HRNet](https://github.com/leoxiaobin/deep-high-resolution-net.pytorch).\n  See [benchmark.md](docs/en/notes/benchmark.md) for more information.\n\n- **Support for various datasets**\n\n  The toolbox directly supports multiple popular and representative datasets, COCO, AIC, MPII, MPII-TRB, OCHuman etc.\n  See [dataset_zoo](docs/en/dataset_zoo) for more information.\n\n- **Well designed, tested and documented**\n\n  We decompose MMPose into different components and one can easily construct a customized\n  pose estimation framework by combining different modules.\n  We provide detailed documentation and API reference, as well as unittests.\n\n</details>\n\n## What's New\n\n- Release [RTMW3D](/projects/rtmpose3d), a real-time model for 3D wholebody pose estimation.\n\n- Release [RTMO](/projects/rtmo), a state-of-the-art real-time method for multi-person pose estimation.\n\n  ![rtmo](https://github.com/open-mmlab/mmpose/assets/26127467/54d5555a-23e5-4308-89d1-f0c82a6734c2)\n\n- Release [RTMW](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw_cocktail14.md) models in various sizes ranging from RTMW-m to RTMW-x. The input sizes include `256x192` and `384x288`. This provides flexibility to select the right model for different speed and accuracy requirements.\n\n- Support inference of [PoseAnything](/projects/pose_anything). Web demo is available [here](https://openxlab.org.cn/apps/detail/orhir/Pose-Anything).\n\n- Support for new datasets:\n\n  - (ICCV 2015) [300VW](/docs/en/dataset_zoo/2d_face_keypoint.md)\n\n- Welcome to use the [*MMPose project*](/projects/README.md). Here, you can discover the latest features and algorithms in MMPose and quickly share your ideas and code implementations with the community. Adding new features to MMPose has become smoother:\n\n  - Provides a simple and fast way to add new algorithms, features, and applications to MMPose.\n  - More flexible code structure and style, fewer restrictions, and a shorter code review process.\n  - Utilize the powerful capabilities of MMPose in the form of independent projects without being constrained by the code framework.\n  - Newly added projects include:\n    - [RTMPose](/projects/rtmpose/)\n    - [RTMO](/projects/rtmo/)\n    - [RTMPose3D](/projects/rtmpose3d/)\n    - [PoseAnything](/projects/pose_anything/)\n    - [YOLOX-Pose](/projects/yolox_pose/)\n    - [MMPose4AIGC](/projects/mmpose4aigc/)\n    - [Simple Keypoints](/projects/skps/)\n    - [Just Dance](/projects/just_dance/)\n    - [Uniformer](/projects/uniformer/)\n  - Start your journey as an MMPose contributor with a simple [example project](/projects/example_project/), and let's build a better MMPose together!\n\n<br/>\n\n- January 4, 2024: MMPose [v1.3.0](https://github.com/open-mmlab/mmpose/releases/tag/v1.3.0) has been officially released, with major updates including:\n\n  - Support for new datasets: ExLPose, H3WB\n  - Release of new RTMPose series models: RTMO, RTMW\n  - Support for new algorithm PoseAnything\n  - Enhanced Inferencer with optional progress bar and improved affinity for one-stage methods\n\n  Please check the complete [release notes](https://github.com/open-mmlab/mmpose/releases/tag/v1.3.0) for more details on the updates brought by MMPose v1.3.0!\n\n## 0.x / 1.x Migration\n\nMMPose v1.0.0 is a major update, including many API and config file changes. Currently, a part of the algorithms have been migrated to v1.0.0, and the remaining algorithms will be completed in subsequent versions. We will show the migration progress in this [Roadmap](https://github.com/open-mmlab/mmpose/issues/2258).\n\nIf your algorithm has not been migrated, you can continue to use the [0.x branch](https://github.com/open-mmlab/mmpose/tree/0.x) and [old documentation](https://mmpose.readthedocs.io/en/0.x/).\n\n## Installation\n\nPlease refer to [installation.md](https://mmpose.readthedocs.io/en/latest/installation.html) for more detailed installation and dataset preparation.\n\n## Getting Started\n\nWe provided a series of tutorials about the basic usage of MMPose for new users:\n\n1. For the basic usage of MMPose:\n\n   - [A 20-minute Tour to MMPose](https://mmpose.readthedocs.io/en/latest/guide_to_framework.html)\n   - [Demos](https://mmpose.readthedocs.io/en/latest/demos.html)\n   - [Inference](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html)\n   - [Configs](https://mmpose.readthedocs.io/en/latest/user_guides/configs.html)\n   - [Prepare Datasets](https://mmpose.readthedocs.io/en/latest/user_guides/prepare_datasets.html)\n   - [Train and Test](https://mmpose.readthedocs.io/en/latest/user_guides/train_and_test.html)\n   - [Deployment](https://mmpose.readthedocs.io/en/latest/user_guides/how_to_deploy.html)\n   - [Model Analysis](https://mmpose.readthedocs.io/en/latest/user_guides/model_analysis.html)\n   - [Dataset Annotation and Preprocessing](https://mmpose.readthedocs.io/en/latest/user_guides/dataset_tools.html)\n\n2. For developers who wish to develop based on MMPose:\n\n   - [Learn about Codecs](https://mmpose.readthedocs.io/en/latest/advanced_guides/codecs.html)\n   - [Dataflow in MMPose](https://mmpose.readthedocs.io/en/latest/advanced_guides/dataflow.html)\n   - [Implement New Models](https://mmpose.readthedocs.io/en/latest/advanced_guides/implement_new_models.html)\n   - [Customize Datasets](https://mmpose.readthedocs.io/en/latest/advanced_guides/customize_datasets.html)\n   - [Customize Data Transforms](https://mmpose.readthedocs.io/en/latest/advanced_guides/customize_transforms.html)\n   - [Customize Evaluation](https://mmpose.readthedocs.io/en/latest/advanced_guides/customize_evaluation.html)\n   - [Customize Optimizer](https://mmpose.readthedocs.io/en/latest/advanced_guides/customize_optimizer.html)\n   - [Customize Logging](https://mmpose.readthedocs.io/en/latest/advanced_guides/customize_logging.html)\n   - [How to Deploy](https://mmpose.readthedocs.io/en/latest/user_guides/how_to_deploy.html)\n   - [Model Analysis](https://mmpose.readthedocs.io/en/latest/user_guides/model_analysis.html)\n   - [Migration Guide](https://mmpose.readthedocs.io/en/latest/migration.html)\n\n3. For researchers and developers who are willing to contribute to MMPose:\n\n   - [Contribution Guide](https://mmpose.readthedocs.io/en/latest/contribution_guide.html)\n\n4. For some common issues, we provide a FAQ list:\n\n   - [FAQ](https://mmpose.readthedocs.io/en/latest/faq.html)\n\n## Model Zoo\n\nResults and models are available in the **README.md** of each method's config directory.\nA summary can be found in the [Model Zoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html) page.\n\n<details open>\n<summary><b>Supported algorithms:</b></summary>\n\n- [x] [DeepPose](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#deeppose-cvpr-2014) (CVPR'2014)\n- [x] [CPM](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#cpm-cvpr-2016) (CVPR'2016)\n- [x] [Hourglass](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#hourglass-eccv-2016) (ECCV'2016)\n- [x] [SimpleBaseline3D](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#simplebaseline3d-iccv-2017) (ICCV'2017)\n- [ ] [Associative Embedding](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#associative-embedding-nips-2017) (NeurIPS'2017)\n- [x] [SimpleBaseline2D](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#simplebaseline2d-eccv-2018) (ECCV'2018)\n- [x] [DSNT](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#dsnt-2018) (ArXiv'2021)\n- [x] [HRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#hrnet-cvpr-2019) (CVPR'2019)\n- [x] [IPR](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#ipr-eccv-2018) (ECCV'2018)\n- [x] [VideoPose3D](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#videopose3d-cvpr-2019) (CVPR'2019)\n- [x] [HRNetv2](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#hrnetv2-tpami-2019) (TPAMI'2019)\n- [x] [MSPN](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#mspn-arxiv-2019) (ArXiv'2019)\n- [x] [SCNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#scnet-cvpr-2020) (CVPR'2020)\n- [ ] [HigherHRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#higherhrnet-cvpr-2020) (CVPR'2020)\n- [x] [RSN](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#rsn-eccv-2020) (ECCV'2020)\n- [x] [InterNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#internet-eccv-2020) (ECCV'2020)\n- [ ] [VoxelPose](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#voxelpose-eccv-2020) (ECCV'2020)\n- [x] [LiteHRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#litehrnet-cvpr-2021) (CVPR'2021)\n- [x] [ViPNAS](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#vipnas-cvpr-2021) (CVPR'2021)\n- [x] [Debias-IPR](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#debias-ipr-iccv-2021) (ICCV'2021)\n- [x] [SimCC](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#simcc-eccv-2022) (ECCV'2022)\n\n</details>\n\n<details open>\n<summary><b>Supported techniques:</b></summary>\n\n- [x] [FPN](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#fpn-cvpr-2017) (CVPR'2017)\n- [x] [FP16](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#fp16-arxiv-2017) (ArXiv'2017)\n- [x] [Wingloss](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#wingloss-cvpr-2018) (CVPR'2018)\n- [x] [AdaptiveWingloss](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#adaptivewingloss-iccv-2019) (ICCV'2019)\n- [x] [DarkPose](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#darkpose-cvpr-2020) (CVPR'2020)\n- [x] [UDP](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#udp-cvpr-2020) (CVPR'2020)\n- [x] [Albumentations](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#albumentations-information-2020) (Information'2020)\n- [x] [SoftWingloss](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#softwingloss-tip-2021) (TIP'2021)\n- [x] [RLE](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#rle-iccv-2021) (ICCV'2021)\n\n</details>\n\n<details open>\n<summary><b>Supported datasets:</b></summary>\n\n- [x] [AFLW](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#aflw-iccvw-2011) \\[[homepage](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/)\\] (ICCVW'2011)\n- [x] [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#jhmdb-iccv-2013) \\[[homepage](http://jhmdb.is.tue.mpg.de/dataset)\\] (ICCV'2013)\n- [x] [COFW](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#cofw-iccv-2013) \\[[homepage](http://www.vision.caltech.edu/xpburgos/ICCV13/)\\] (ICCV'2013)\n- [x] [MPII](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#mpii-cvpr-2014) \\[[homepage](http://human-pose.mpi-inf.mpg.de/)\\] (CVPR'2014)\n- [x] [Human3.6M](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#human3-6m-tpami-2014) \\[[homepage](http://vision.imar.ro/human3.6m/description.php)\\] (TPAMI'2014)\n- [x] [COCO](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#coco-eccv-2014) \\[[homepage](http://cocodataset.org/)\\] (ECCV'2014)\n- [x] [CMU Panoptic](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#cmu-panoptic-iccv-2015) \\[[homepage](http://domedb.perception.cs.cmu.edu/)\\] (ICCV'2015)\n- [x] [300VW](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#300w-imavis-2016) \\[[homepage](https://ibug.doc.ic.ac.uk/resources/300-VW/)\\] (ICCV'2015)\n- [x] [DeepFashion](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#deepfashion-cvpr-2016) \\[[homepage](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html)\\] (CVPR'2016)\n- [x] [300W](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#300w-imavis-2016) \\[[homepage](https://ibug.doc.ic.ac.uk/resources/300-W/)\\] (IMAVIS'2016)\n- [x] [RHD](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#rhd-iccv-2017) \\[[homepage](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html)\\] (ICCV'2017)\n- [x] [CMU Panoptic HandDB](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#cmu-panoptic-handdb-cvpr-2017) \\[[homepage](http://domedb.perception.cs.cmu.edu/handdb.html)\\] (CVPR'2017)\n- [x] [AI Challenger](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#ai-challenger-arxiv-2017) \\[[homepage](https://github.com/AIChallenger/AI_Challenger_2017)\\] (ArXiv'2017)\n- [x] [MHP](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#mhp-acm-mm-2018) \\[[homepage](https://lv-mhp.github.io/dataset)\\] (ACM MM'2018)\n- [x] [WFLW](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#wflw-cvpr-2018) \\[[homepage](https://wywu.github.io/projects/LAB/WFLW.html)\\] (CVPR'2018)\n- [x] [PoseTrack18](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#posetrack18-cvpr-2018) \\[[homepage](https://posetrack.net/users/download.php)\\] (CVPR'2018)\n- [x] [OCHuman](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#ochuman-cvpr-2019) \\[[homepage](https://github.com/liruilong940607/OCHumanApi)\\] (CVPR'2019)\n- [x] [CrowdPose](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#crowdpose-cvpr-2019) \\[[homepage](https://github.com/Jeff-sjtu/CrowdPose)\\] (CVPR'2019)\n- [x] [MPII-TRB](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#mpii-trb-iccv-2019) \\[[homepage](https://github.com/kennymckormick/Triplet-Representation-of-human-Body)\\] (ICCV'2019)\n- [x] [FreiHand](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#freihand-iccv-2019) \\[[homepage](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\\] (ICCV'2019)\n- [x] [Animal-Pose](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#animal-pose-iccv-2019) \\[[homepage](https://sites.google.com/view/animal-pose/)\\] (ICCV'2019)\n- [x] [OneHand10K](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#onehand10k-tcsvt-2019) \\[[homepage](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\\] (TCSVT'2019)\n- [x] [Vinegar Fly](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#vinegar-fly-nature-methods-2019) \\[[homepage](https://github.com/jgraving/DeepPoseKit-Data)\\] (Nature Methods'2019)\n- [x] [Desert Locust](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#desert-locust-elife-2019) \\[[homepage](https://github.com/jgraving/DeepPoseKit-Data)\\] (Elife'2019)\n- [x] [Grévy’s Zebra](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#grevys-zebra-elife-2019) \\[[homepage](https://github.com/jgraving/DeepPoseKit-Data)\\] (Elife'2019)\n- [x] [ATRW](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#atrw-acm-mm-2020) \\[[homepage](https://cvwc2019.github.io/challenge.html)\\] (ACM MM'2020)\n- [x] [Halpe](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#halpe-cvpr-2020) \\[[homepage](https://github.com/Fang-Haoshu/Halpe-FullBody/)\\] (CVPR'2020)\n- [x] [COCO-WholeBody](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#coco-wholebody-eccv-2020) \\[[homepage](https://github.com/jin-s13/COCO-WholeBody/)\\] (ECCV'2020)\n- [x] [MacaquePose](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#macaquepose-biorxiv-2020) \\[[homepage](http://www.pri.kyoto-u.ac.jp/datasets/macaquepose/index.html)\\] (bioRxiv'2020)\n- [x] [InterHand2.6M](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#interhand2-6m-eccv-2020) \\[[homepage](https://mks0601.github.io/InterHand2.6M/)\\] (ECCV'2020)\n- [x] [AP-10K](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#ap-10k-neurips-2021) \\[[homepage](https://github.com/AlexTheBad/AP-10K)\\] (NeurIPS'2021)\n- [x] [Horse-10](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#horse-10-wacv-2021) \\[[homepage](http://www.mackenziemathislab.org/horse10)\\] (WACV'2021)\n- [x] [Human-Art](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#human-art-cvpr-2023) \\[[homepage](https://idea-research.github.io/HumanArt/)\\] (CVPR'2023)\n- [x] [LaPa](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#lapa-aaai-2020) \\[[homepage](https://github.com/JDAI-CV/lapa-dataset)\\] (AAAI'2020)\n- [x] [UBody](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#ubody-cvpr-2023) \\[[homepage](https://github.com/IDEA-Research/OSX)\\] (CVPR'2023)\n\n</details>\n\n<details open>\n<summary><b>Supported backbones:</b></summary>\n\n- [x] [AlexNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#alexnet-neurips-2012) (NeurIPS'2012)\n- [x] [VGG](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#vgg-iclr-2015) (ICLR'2015)\n- [x] [ResNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#resnet-cvpr-2016) (CVPR'2016)\n- [x] [ResNext](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#resnext-cvpr-2017) (CVPR'2017)\n- [x] [SEResNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#seresnet-cvpr-2018) (CVPR'2018)\n- [x] [ShufflenetV1](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#shufflenetv1-cvpr-2018) (CVPR'2018)\n- [x] [ShufflenetV2](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#shufflenetv2-eccv-2018) (ECCV'2018)\n- [x] [MobilenetV2](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#mobilenetv2-cvpr-2018) (CVPR'2018)\n- [x] [ResNetV1D](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#resnetv1d-cvpr-2019) (CVPR'2019)\n- [x] [ResNeSt](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#resnest-arxiv-2020) (ArXiv'2020)\n- [x] [Swin](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#swin-cvpr-2021) (CVPR'2021)\n- [x] [HRFormer](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#hrformer-nips-2021) (NIPS'2021)\n- [x] [PVT](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#pvt-iccv-2021) (ICCV'2021)\n- [x] [PVTV2](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#pvtv2-cvmj-2022) (CVMJ'2022)\n\n</details>\n\n### Model Request\n\nWe will keep up with the latest progress of the community, and support more popular algorithms and frameworks. If you have any feature requests, please feel free to leave a comment in [MMPose Roadmap](https://github.com/open-mmlab/mmpose/issues/2258).\n\n## Contributing\n\nWe appreciate all contributions to improve MMPose. Please refer to [CONTRIBUTING.md](https://mmpose.readthedocs.io/en/latest/contribution_guide.html) for the contributing guideline.\n\n## Acknowledgement\n\nMMPose is an open source project that is contributed by researchers and engineers from various colleges and companies.\nWe appreciate all the contributors who implement their methods or add new features, as well as users who give valuable feedbacks.\nWe wish that the toolbox and benchmark could serve the growing research community by providing a flexible toolkit to reimplement existing methods and develop their own new models.\n\n## Citation\n\nIf you find this project useful in your research, please consider cite:\n\n```bibtex\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n\n## License\n\nThis project is released under the [Apache 2.0 license](LICENSE).\n\n## Projects in OpenMMLab\n\n- [MMEngine](https://github.com/open-mmlab/mmengine): OpenMMLab foundational library for training deep learning models.\n- [MMCV](https://github.com/open-mmlab/mmcv): OpenMMLab foundational library for computer vision.\n- [MMPreTrain](https://github.com/open-mmlab/mmpretrain): OpenMMLab pre-training toolbox and benchmark.\n- [MMagic](https://github.com/open-mmlab/mmagic): Open**MM**Lab **A**dvanced, **G**enerative and **I**ntelligent **C**reation toolbox.\n- [MMDetection](https://github.com/open-mmlab/mmdetection): OpenMMLab detection toolbox and benchmark.\n- [MMDetection3D](https://github.com/open-mmlab/mmdetection3d): OpenMMLab's next-generation platform for general 3D object detection.\n- [MMRotate](https://github.com/open-mmlab/mmrotate): OpenMMLab rotated object detection toolbox and benchmark.\n- [MMTracking](https://github.com/open-mmlab/mmtracking): OpenMMLab video perception toolbox and benchmark.\n- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation): OpenMMLab semantic segmentation toolbox and benchmark.\n- [MMOCR](https://github.com/open-mmlab/mmocr): OpenMMLab text detection, recognition, and understanding toolbox.\n- [MMPose](https://github.com/open-mmlab/mmpose): OpenMMLab pose estimation toolbox and benchmark.\n- [MMHuman3D](https://github.com/open-mmlab/mmhuman3d): OpenMMLab 3D human parametric model toolbox and benchmark.\n- [MMFewShot](https://github.com/open-mmlab/mmfewshot): OpenMMLab fewshot learning toolbox and benchmark.\n- [MMAction2](https://github.com/open-mmlab/mmaction2): OpenMMLab's next-generation action understanding toolbox and benchmark.\n- [MMFlow](https://github.com/open-mmlab/mmflow): OpenMMLab optical flow toolbox and benchmark.\n- [MMDeploy](https://github.com/open-mmlab/mmdeploy): OpenMMLab Model Deployment Framework.\n- [MMRazor](https://github.com/open-mmlab/mmrazor): OpenMMLab model compression toolbox and benchmark.\n- [MIM](https://github.com/open-mmlab/mim): MIM installs OpenMMLab packages.\n- [Playground](https://github.com/open-mmlab/playground): A central hub for gathering and showcasing amazing projects built upon OpenMMLab.\n"
  },
  {
    "path": "README_CN.md",
    "content": "<div align=\"center\">\n  <img src=\"resources/mmpose-logo.png\" width=\"450\"/>\n  <div>&nbsp;</div>\n  <div align=\"center\">\n    <b><font size=\"5\">OpenMMLab 官网</font></b>\n    <sup>\n      <a href=\"https://openmmlab.com\">\n        <i><font size=\"4\">HOT</font></i>\n      </a>\n    </sup>\n    &nbsp;&nbsp;&nbsp;&nbsp;\n    <b><font size=\"5\">OpenMMLab 开放平台</font></b>\n    <sup>\n      <a href=\"https://platform.openmmlab.com\">\n        <i><font size=\"4\">TRY IT OUT</font></i>\n      </a>\n    </sup>\n  </div>\n  <div>&nbsp;</div>\n\n[![Documentation](https://readthedocs.org/projects/mmpose/badge/?version=latest)](https://mmpose.readthedocs.io/en/latest/?badge=latest)\n[![actions](https://github.com/open-mmlab/mmpose/workflows/merge_stage_test/badge.svg)](https://github.com/open-mmlab/mmpose/actions)\n[![codecov](https://codecov.io/gh/open-mmlab/mmpose/branch/latest/graph/badge.svg)](https://codecov.io/gh/open-mmlab/mmpose)\n[![PyPI](https://img.shields.io/pypi/v/mmpose)](https://pypi.org/project/mmpose/)\n[![LICENSE](https://img.shields.io/github/license/open-mmlab/mmpose.svg)](https://github.com/open-mmlab/mmpose/blob/main/LICENSE)\n[![Average time to resolve an issue](https://isitmaintained.com/badge/resolution/open-mmlab/mmpose.svg)](https://github.com/open-mmlab/mmpose/issues)\n[![Percentage of issues still open](https://isitmaintained.com/badge/open/open-mmlab/mmpose.svg)](https://github.com/open-mmlab/mmpose/issues)\n[![Open in OpenXLab](https://cdn-static.openxlab.org.cn/app-center/openxlab_demo.svg)](https://openxlab.org.cn/apps?search=mmpose)\n\n[📘文档](https://mmpose.readthedocs.io/zh_CN/latest/) |\n[🛠️安装](https://mmpose.readthedocs.io/zh_CN/latest/installation.html) |\n[👀模型库](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo.html) |\n[📜论文库](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html) |\n[🆕更新日志](https://mmpose.readthedocs.io/zh_CN/latest/notes/changelog.html) |\n[🤔报告问题](https://github.com/open-mmlab/mmpose/issues/new/choose) |\n[🔥RTMPose](/projects/rtmpose/)\n\n</div>\n\n<div align=\"center\">\n  <a href=\"https://openmmlab.medium.com/\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/219255827-67c1a27f-f8c5-46a9-811d-5e57448c61d1.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://discord.com/channels/1037617289144569886/1072798105428299817\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/218347213-c080267f-cbb6-443e-8532-8e1ed9a58ea9.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://twitter.com/OpenMMLab\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/218346637-d30c8a0f-3eba-4699-8131-512fb06d46db.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://www.youtube.com/openmmlab\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/218346691-ceb2116a-465a-40af-8424-9f30d2348ca9.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://space.bilibili.com/1293512903\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/219026751-d7d14cce-a7c9-4e82-9942-8375fca65b99.png\" width=\"3%\" alt=\"\" /></a>\n  <img src=\"https://user-images.githubusercontent.com/25839884/218346358-56cc8e2f-a2b8-487f-9088-32480cceabcf.png\" width=\"3%\" alt=\"\" />\n  <a href=\"https://www.zhihu.com/people/openmmlab\" style=\"text-decoration:none;\">\n    <img src=\"https://user-images.githubusercontent.com/25839884/219026120-ba71e48b-6e94-4bd4-b4e9-b7d175b5e362.png\" width=\"3%\" alt=\"\" /></a>\n</div>\n\n## Introduction\n\n[English](./README.md) | 简体中文\n\nMMPose 是一款基于 PyTorch 的姿态分析的开源工具箱，是 [OpenMMLab](https://github.com/open-mmlab) 项目的成员之一。\n\n主分支代码目前支持 **PyTorch 1.8 以上**的版本。\n\nhttps://user-images.githubusercontent.com/15977946/124654387-0fd3c500-ded1-11eb-84f6-24eeddbf4d91.mp4\n\n<details close>\n<summary><b>主要特性</b></summary>\n\n- **支持多种人体姿态分析相关任务**\n\n  MMPose 支持当前学界广泛关注的主流姿态分析任务：主要包括 2D多人姿态估计、2D手部姿态估计、2D人脸关键点检测、133关键点的全身人体姿态估计、3D人体形状恢复、服饰关键点检测、动物关键点检测等。\n  具体请参考 [功能演示](demo/docs/zh_cn/)。\n\n- **更高的精度和更快的速度**\n\n  MMPose 复现了多种学界最先进的人体姿态分析模型，包括“自顶向下”和“自底向上”两大类算法。MMPose 相比于其他主流的代码库，具有更高的模型精度和训练速度。\n  具体请参考 [基准测试](docs/en/notes/benchmark.md)（英文）。\n\n- **支持多样的数据集**\n\n  MMPose 支持了很多主流数据集的准备和构建，如 COCO、 MPII 等。 具体请参考 [数据集](docs/zh_cn/dataset_zoo)。\n\n- **模块化设计**\n\n  MMPose 将统一的人体姿态分析框架解耦成不同的模块组件，通过组合不同的模块组件，用户可以便捷地构建自定义的人体姿态分析模型。\n\n- **详尽的单元测试和文档**\n\n  MMPose 提供了详尽的说明文档，API 接口说明，全面的单元测试，以供社区参考。\n\n</details>\n\n## 最新进展\n\n- 发布了 [RTMW3D](/projects/rtmpose3d/), 一个 3D 全身姿态估计的实时模型。\n\n- 发布了单阶段实时多人姿态估计模型 [RTMO](/projects/rtmo)。相比 RTMPose 在多人场景下性能更优\n\n  ![rtmo](https://github.com/open-mmlab/mmpose/assets/26127467/54d5555a-23e5-4308-89d1-f0c82a6734c2)\n\n- 发布了不同尺寸的 [RTMW](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw_cocktail14.md) 模型，满足不同的使用场景。模型尺寸覆盖从 RTMW-m 到 RTMW-x 的模型，输入图像尺寸包含 256x192 和 384x288\n\n- 支持了 [PoseAnything](/projects/pose_anything) 的推理。[在线试玩](https://openxlab.org.cn/apps/detail/orhir/Pose-Anything)\n\n- 我们支持了新的数据集:\n\n  - (ICCV 2015) [300VW](/docs/en/dataset_zoo/2d_face_keypoint.md)\n\n- 欢迎使用 [*MMPose 项目*](/projects/README.md)。在这里，您可以发现 MMPose 中的最新功能和算法，并且可以通过最快的方式与社区分享自己的创意和代码实现。向 MMPose 中添加新功能从此变得简单丝滑：\n\n  - 提供了一种简单迅捷的方式，将新的算法、功能和应用添加到 MMPose 中\n  - 更灵活的代码结构和风格，更少的限制，更简短的代码审核流程\n  - 通过独立项目的形式，利用 MMPose 的强大功能，同时不被代码框架所束缚\n  - 最新添加的项目包括：\n    - [RTMPose](/projects/rtmpose/)\n    - [RTMO](/projects/rtmo/)\n    - [PoseAnything](/projects/pose_anything/)\n    - [YOLOX-Pose](/projects/yolox_pose/)\n    - [MMPose4AIGC](/projects/mmpose4aigc/)\n    - [Simple Keypoints](/projects/skps/)\n    - [Just Dance](/projects/just_dance/)\n    - [Uniformer](/projects/uniformer/)\n  - 从简单的 [示例项目](/projects/example_project/) 开启您的 MMPose 代码贡献者之旅吧，让我们共同打造更好用的 MMPose！\n\n<br/>\n\n- 2024-01-04：MMPose [v1.3.0](https://github.com/open-mmlab/mmpose/releases/tag/v1.3.0) 正式发布了，主要更新包括:\n\n  - 支持新数据集：ExLPose、H3WB\n  - 发布 RTMPose 系列新模型：RTMO、RTMW\n  - 支持新算法 PoseAnything\n  - 推理器 Inferencer 支持可选的进度条、提升与单阶段模型的适配性\n\n  请查看完整的 [版本说明](https://github.com/open-mmlab/mmpose/releases/tag/v1.3.0) 以了解更多 MMPose v1.3.0 带来的更新!\n\n## 0.x / 1.x 迁移\n\nMMPose v1.0.0 是一个重大更新，包括了大量的 API 和配置文件的变化。目前 v1.0.0 中已经完成了一部分算法的迁移工作，剩余的算法将在后续的版本中陆续完成，我们将在这个 [Issue 页面](https://github.com/open-mmlab/mmpose/issues/2258) 中展示迁移进度。\n\n如果您使用的算法还没有完成迁移，您也可以继续使用访问 [0.x 分支](https://github.com/open-mmlab/mmpose/tree/0.x) 和 [旧版文档](https://mmpose.readthedocs.io/zh_CN/0.x/)\n\n## 安装\n\n关于安装的详细说明请参考[安装文档](https://mmpose.readthedocs.io/zh_CN/latest/installation.html)。\n\n## 教程\n\n我们提供了一系列简明的教程，帮助 MMPose 的新用户轻松上手使用：\n\n1. MMPose 的基本使用方法：\n\n   - [20 分钟上手教程](https://mmpose.readthedocs.io/zh_CN/latest/guide_to_framework.html)\n   - [Demos](https://mmpose.readthedocs.io/zh_CN/latest/demos.html)\n   - [模型推理](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/inference.html)\n   - [配置文件](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/configs.html)\n   - [准备数据集](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/prepare_datasets.html)\n   - [训练与测试](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/train_and_test.html)\n   - [模型部署](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/how_to_deploy.html)\n   - [模型分析工具](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/model_analysis.html)\n   - [数据集标注与预处理脚本](https://mmpose.readthedocs.io/zh_CN/latest/user_guides/dataset_tools.html)\n\n2. 对于希望基于 MMPose 进行开发的研究者和开发者：\n\n   - [编解码器](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/codecs.html)\n   - [数据流](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/dataflow.html)\n   - [实现新模型](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/implement_new_models.html)\n   - [自定义数据集](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/customize_datasets.html)\n   - [自定义数据变换](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/customize_transforms.html)\n   - [自定义指标](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/customize_evaluation.html)\n   - [自定义优化器](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/customize_optimizer.html)\n   - [自定义日志](https://mmpose.readthedocs.io/zh_CN/latest/advanced_guides/customize_logging.html)\n   - [迁移指南](https://mmpose.readthedocs.io/zh_CN/latest/migration.html)\n\n3. 对于希望加入开源社区，向 MMPose 贡献代码的研究者和开发者：\n\n   - [参与贡献代码](https://mmpose.readthedocs.io/zh_CN/latest/contribution_guide.html)\n\n4. 对于使用过程中的常见问题：\n\n   - [FAQ](https://mmpose.readthedocs.io/zh_CN/latest/faq.html)\n\n## 模型库\n\n各个模型的结果和设置都可以在对应的 config（配置）目录下的 **README.md** 中查看。\n整体的概况也可也在 [模型库](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo.html) 页面中查看。\n\n<details open>\n<summary><b>支持的算法</b></summary>\n\n- [x] [DeepPose](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#deeppose-cvpr-2014) (CVPR'2014)\n- [x] [CPM](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#cpm-cvpr-2016) (CVPR'2016)\n- [x] [Hourglass](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#hourglass-eccv-2016) (ECCV'2016)\n- [x] [SimpleBaseline3D](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#simplebaseline3d-iccv-2017) (ICCV'2017)\n- [ ] [Associative Embedding](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#associative-embedding-nips-2017) (NeurIPS'2017)\n- [x] [SimpleBaseline2D](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#simplebaseline2d-eccv-2018) (ECCV'2018)\n- [x] [DSNT](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#dsnt-2018) (ArXiv'2021)\n- [x] [HRNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#hrnet-cvpr-2019) (CVPR'2019)\n- [x] [IPR](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#ipr-eccv-2018) (ECCV'2018)\n- [x] [VideoPose3D](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#videopose3d-cvpr-2019) (CVPR'2019)\n- [x] [HRNetv2](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#hrnetv2-tpami-2019) (TPAMI'2019)\n- [x] [MSPN](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#mspn-arxiv-2019) (ArXiv'2019)\n- [x] [SCNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#scnet-cvpr-2020) (CVPR'2020)\n- [ ] [HigherHRNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#higherhrnet-cvpr-2020) (CVPR'2020)\n- [x] [RSN](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#rsn-eccv-2020) (ECCV'2020)\n- [x] [InterNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#internet-eccv-2020) (ECCV'2020)\n- [ ] [VoxelPose](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#voxelpose-eccv-2020) (ECCV'2020)\n- [x] [LiteHRNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#litehrnet-cvpr-2021) (CVPR'2021)\n- [x] [ViPNAS](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#vipnas-cvpr-2021) (CVPR'2021)\n- [x] [Debias-IPR](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#debias-ipr-iccv-2021) (ICCV'2021)\n- [x] [SimCC](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/algorithms.html#simcc-eccv-2022) (ECCV'2022)\n\n</details>\n\n<details open>\n<summary><b>支持的技术</b></summary>\n\n- [x] [FPN](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#fpn-cvpr-2017) (CVPR'2017)\n- [x] [FP16](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#fp16-arxiv-2017) (ArXiv'2017)\n- [x] [Wingloss](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#wingloss-cvpr-2018) (CVPR'2018)\n- [x] [AdaptiveWingloss](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#adaptivewingloss-iccv-2019) (ICCV'2019)\n- [x] [DarkPose](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#darkpose-cvpr-2020) (CVPR'2020)\n- [x] [UDP](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#udp-cvpr-2020) (CVPR'2020)\n- [x] [Albumentations](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#albumentations-information-2020) (Information'2020)\n- [x] [SoftWingloss](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#softwingloss-tip-2021) (TIP'2021)\n- [x] [RLE](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/techniques.html#rle-iccv-2021) (ICCV'2021)\n\n</details>\n\n<details open>\n<summary><b>支持的数据集</b></summary>\n\n- [x] [AFLW](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#aflw-iccvw-2011) \\[[主页](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/)\\] (ICCVW'2011)\n- [x] [sub-JHMDB](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#jhmdb-iccv-2013) \\[[主页](http://jhmdb.is.tue.mpg.de/dataset)\\] (ICCV'2013)\n- [x] [COFW](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#cofw-iccv-2013) \\[[主页](http://www.vision.caltech.edu/xpburgos/ICCV13/)\\] (ICCV'2013)\n- [x] [MPII](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#mpii-cvpr-2014) \\[[主页](http://human-pose.mpi-inf.mpg.de/)\\] (CVPR'2014)\n- [x] [Human3.6M](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#human3-6m-tpami-2014) \\[[主页](http://vision.imar.ro/human3.6m/description.php)\\] (TPAMI'2014)\n- [x] [COCO](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#coco-eccv-2014) \\[[主页](http://cocodataset.org/)\\] (ECCV'2014)\n- [x] [CMU Panoptic](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#cmu-panoptic-iccv-2015) (ICCV'2015)\n- [x] [DeepFashion](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#deepfashion-cvpr-2016) \\[[主页](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html)\\] (CVPR'2016)\n- [x] [300W](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#300w-imavis-2016) \\[[主页](https://ibug.doc.ic.ac.uk/resources/300-W/)\\] (IMAVIS'2016)\n- [x] [RHD](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#rhd-iccv-2017) \\[[主页](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html)\\] (ICCV'2017)\n- [x] [CMU Panoptic](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#cmu-panoptic-iccv-2015) \\[[主页](http://domedb.perception.cs.cmu.edu/)\\] (ICCV'2015)\n- [x] [AI Challenger](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#ai-challenger-arxiv-2017) \\[[主页](https://github.com/AIChallenger/AI_Challenger_2017)\\] (ArXiv'2017)\n- [x] [MHP](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#mhp-acm-mm-2018) \\[[主页](https://lv-mhp.github.io/dataset)\\] (ACM MM'2018)\n- [x] [WFLW](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#wflw-cvpr-2018) \\[[主页](https://wywu.github.io/projects/LAB/WFLW.html)\\] (CVPR'2018)\n- [x] [PoseTrack18](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#posetrack18-cvpr-2018) \\[[主页](https://posetrack.net/users/download.php)\\] (CVPR'2018)\n- [x] [OCHuman](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#ochuman-cvpr-2019) \\[[主页](https://github.com/liruilong940607/OCHumanApi)\\] (CVPR'2019)\n- [x] [CrowdPose](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#crowdpose-cvpr-2019) \\[[主页](https://github.com/Jeff-sjtu/CrowdPose)\\] (CVPR'2019)\n- [x] [MPII-TRB](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#mpii-trb-iccv-2019) \\[[主页](https://github.com/kennymckormick/Triplet-Representation-of-human-Body)\\] (ICCV'2019)\n- [x] [FreiHand](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#freihand-iccv-2019) \\[[主页](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\\] (ICCV'2019)\n- [x] [Animal-Pose](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#animal-pose-iccv-2019) \\[[主页](https://sites.google.com/view/animal-pose/)\\] (ICCV'2019)\n- [x] [OneHand10K](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#onehand10k-tcsvt-2019) \\[[主页](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\\] (TCSVT'2019)\n- [x] [Vinegar Fly](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#vinegar-fly-nature-methods-2019) \\[[主页](https://github.com/jgraving/DeepPoseKit-Data)\\] (Nature Methods'2019)\n- [x] [Desert Locust](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#desert-locust-elife-2019) \\[[主页](https://github.com/jgraving/DeepPoseKit-Data)\\] (Elife'2019)\n- [x] [Grévy’s Zebra](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#grevys-zebra-elife-2019) \\[[主页](https://github.com/jgraving/DeepPoseKit-Data)\\] (Elife'2019)\n- [x] [ATRW](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#atrw-acm-mm-2020) \\[[主页](https://cvwc2019.github.io/challenge.html)\\] (ACM MM'2020)\n- [x] [Halpe](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#halpe-cvpr-2020) \\[[主页](https://github.com/Fang-Haoshu/Halpe-FullBody/)\\] (CVPR'2020)\n- [x] [COCO-WholeBody](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#coco-wholebody-eccv-2020) \\[[主页](https://github.com/jin-s13/COCO-WholeBody/)\\] (ECCV'2020)\n- [x] [MacaquePose](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#macaquepose-biorxiv-2020) \\[[主页](http://www.pri.kyoto-u.ac.jp/datasets/macaquepose/index.html)\\] (bioRxiv'2020)\n- [x] [InterHand2.6M](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#interhand2-6m-eccv-2020) \\[[主页](https://mks0601.github.io/InterHand2.6M/)\\] (ECCV'2020)\n- [x] [AP-10K](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/datasets.html#ap-10k-neurips-2021) \\[[主页](https://github.com/AlexTheBad/AP-10K)\\] (NeurIPS'2021)\n- [x] [Horse-10](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#horse-10-wacv-2021) \\[[主页](http://www.mackenziemathislab.org/horse10)\\] (WACV'2021)\n- [x] [Human-Art](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#human-art-cvpr-2023) \\[[主页](https://idea-research.github.io/HumanArt/)\\] (CVPR'2023)\n- [x] [LaPa](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#lapa-aaai-2020) \\[[主页](https://github.com/JDAI-CV/lapa-dataset)\\] (AAAI'2020)\n- [x] [UBody](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/datasets.html#ubody-cvpr-2023) \\[[主页](https://github.com/IDEA-Research/OSX)\\] (CVPR'2023)\n\n</details>\n\n<details open>\n<summary><b>支持的骨干网络</b></summary>\n\n- [x] [AlexNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#alexnet-neurips-2012) (NeurIPS'2012)\n- [x] [VGG](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#vgg-iclr-2015) (ICLR'2015)\n- [x] [ResNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#resnet-cvpr-2016) (CVPR'2016)\n- [x] [ResNext](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#resnext-cvpr-2017) (CVPR'2017)\n- [x] [SEResNet](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#seresnet-cvpr-2018) (CVPR'2018)\n- [x] [ShufflenetV1](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#shufflenetv1-cvpr-2018) (CVPR'2018)\n- [x] [ShufflenetV2](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#shufflenetv2-eccv-2018) (ECCV'2018)\n- [x] [MobilenetV2](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#mobilenetv2-cvpr-2018) (CVPR'2018)\n- [x] [ResNetV1D](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#resnetv1d-cvpr-2019) (CVPR'2019)\n- [x] [ResNeSt](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#resnest-arxiv-2020) (ArXiv'2020)\n- [x] [Swin](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#swin-cvpr-2021) (CVPR'2021)\n- [x] [HRFormer](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#hrformer-nips-2021) (NIPS'2021)\n- [x] [PVT](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#pvt-iccv-2021) (ICCV'2021)\n- [x] [PVTV2](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo_papers/backbones.html#pvtv2-cvmj-2022) (CVMJ'2022)\n\n</details>\n\n### 模型需求\n\n我们将跟进学界的最新进展，并支持更多算法和框架。如果您对 MMPose 有任何功能需求，请随时在 [MMPose Roadmap](https://github.com/open-mmlab/mmpose/issues/2258) 中留言。\n\n## 参与贡献\n\n我们非常欢迎用户对于 MMPose 做出的任何贡献，可以参考 [贡献指南](https://mmpose.readthedocs.io/zh_CN/latest/contribution_guide.html) 文件了解更多细节。\n\n## 致谢\n\nMMPose 是一款由不同学校和公司共同贡献的开源项目。我们感谢所有为项目提供算法复现和新功能支持的贡献者，以及提供宝贵反馈的用户。\n我们希望该工具箱和基准测试可以为社区提供灵活的代码工具，供用户复现现有算法并开发自己的新模型，从而不断为开源社区提供贡献。\n\n## 引用\n\n如果您觉得 MMPose 对您的研究有所帮助，请考虑引用它：\n\n```bibtex\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n\n## 许可证\n\n该项目采用 [Apache 2.0 license](LICENSE) 开源协议。\n\n## OpenMMLab的其他项目\n\n- [MMEngine](https://github.com/open-mmlab/mmengine): OpenMMLab 深度学习模型训练基础库\n- [MMCV](https://github.com/open-mmlab/mmcv): OpenMMLab 计算机视觉基础库\n- [MMPreTrain](https://github.com/open-mmlab/mmpretrain): OpenMMLab 深度学习预训练工具箱\n- [MMagic](https://github.com/open-mmlab/mmagic): OpenMMLab 新一代人工智能内容生成（AIGC）工具箱\n- [MMDetection](https://github.com/open-mmlab/mmdetection): OpenMMLab 目标检测工具箱\n- [MMDetection3D](https://github.com/open-mmlab/mmdetection3d): OpenMMLab 新一代通用 3D 目标检测平台\n- [MMRotate](https://github.com/open-mmlab/mmrotate): OpenMMLab 旋转框检测工具箱与测试基准\n- [MMTracking](https://github.com/open-mmlab/mmtracking): OpenMMLab 一体化视频目标感知平台\n- [MMSegmentation](https://github.com/open-mmlab/mmsegmentation): OpenMMLab 语义分割工具箱\n- [MMOCR](https://github.com/open-mmlab/mmocr): OpenMMLab 全流程文字检测识别理解工具包\n- [MMPose](https://github.com/open-mmlab/mmpose): OpenMMLab 姿态估计工具箱\n- [MMHuman3D](https://github.com/open-mmlab/mmhuman3d): OpenMMLab 人体参数化模型工具箱与测试基准\n- [MMFewShot](https://github.com/open-mmlab/mmfewshot): OpenMMLab 少样本学习工具箱与测试基准\n- [MMAction2](https://github.com/open-mmlab/mmaction2): OpenMMLab 新一代视频理解工具箱\n- [MMFlow](https://github.com/open-mmlab/mmflow): OpenMMLab 光流估计工具箱与测试基准\n- [MMDeploy](https://github.com/open-mmlab/mmdeploy): OpenMMLab 模型部署框架\n- [MMRazor](https://github.com/open-mmlab/mmrazor): OpenMMLab 模型压缩工具箱与测试基准\n- [MIM](https://github.com/open-mmlab/mim): OpenMMlab 项目、算法、模型的统一入口\n- [Playground](https://github.com/open-mmlab/playground): 收集和展示 OpenMMLab 相关的前沿、有趣的社区项目\n\n## 欢迎加入 OpenMMLab 社区\n\n扫描下方的二维码可关注 OpenMMLab 团队的 [知乎官方账号](https://www.zhihu.com/people/openmmlab)，扫描下方微信二维码添加喵喵好友，进入 MMPose 微信交流社群。【加好友申请格式：研究方向+地区+学校/公司+姓名】\n\n<div align=\"center\">\n<img src=\"https://user-images.githubusercontent.com/25839884/205870927-39f4946d-8751-4219-a4c0-740117558fd7.jpg\" height=\"400\"><img src=\"https://github.com/open-mmlab/mmpose/assets/62195058/256fe847-ad85-410a-a064-6314c5ce046d\" height=\"400\">\n</div>\n\n我们会在 OpenMMLab 社区为大家\n\n- 📢 分享 AI 框架的前沿核心技术\n- 💻 解读 PyTorch 常用模块源码\n- 📰 发布 OpenMMLab 的相关新闻\n- 🚀 介绍 OpenMMLab 开发的前沿算法\n- 🏃 获取更高效的问题答疑和意见反馈\n- 🔥 提供与各行各业开发者充分交流的平台\n\n干货满满 📘，等你来撩 💗，OpenMMLab 社区期待您的加入 👬\n"
  },
  {
    "path": "configs/_base_/datasets/300vw.py",
    "content": "dataset_info = dict(\n    dataset_name='300vw',\n    paper_info=dict(\n        author='Jie Shen, Stefanos Zafeiriou, Grigorios G. Chrysos, '\n        'Jean Kossaifi, Georgios Tzimiropoulos, Maja Pantic',\n        title='The First Facial Landmark Tracking in-the-Wild Challenge: '\n        'Benchmark and Results',\n        container='Proceedings of the IEEE '\n        'international conference on computer vision workshops',\n        year='2016',\n        homepage='https://ibug.doc.ic.ac.uk/resources/300-VW/',\n    ),\n    keypoint_info={\n        0: dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap='kpt-16'),\n        1: dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap='kpt-15'),\n        2: dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap='kpt-14'),\n        3: dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap='kpt-13'),\n        4: dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap='kpt-12'),\n        5: dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap='kpt-11'),\n        6: dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap='kpt-10'),\n        7: dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap='kpt-9'),\n        8: dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap=''),\n        9: dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap='kpt-7'),\n        10:\n        dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap='kpt-6'),\n        11:\n        dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap='kpt-5'),\n        12:\n        dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap='kpt-4'),\n        13:\n        dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap='kpt-3'),\n        14:\n        dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap='kpt-2'),\n        15:\n        dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap='kpt-1'),\n        16:\n        dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap='kpt-0'),\n        17:\n        dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap='kpt-26'),\n        18:\n        dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap='kpt-25'),\n        19:\n        dict(name='kpt-19', id=19, color=[255, 0, 0], type='', swap='kpt-24'),\n        20:\n        dict(name='kpt-20', id=20, color=[255, 0, 0], type='', swap='kpt-23'),\n        21:\n        dict(name='kpt-21', id=21, color=[255, 0, 0], type='', swap='kpt-22'),\n        22:\n        dict(name='kpt-22', id=22, color=[255, 0, 0], type='', swap='kpt-21'),\n        23:\n        dict(name='kpt-23', id=23, color=[255, 0, 0], type='', swap='kpt-20'),\n        24:\n        dict(name='kpt-24', id=24, color=[255, 0, 0], type='', swap='kpt-19'),\n        25:\n        dict(name='kpt-25', id=25, color=[255, 0, 0], type='', swap='kpt-18'),\n        26:\n        dict(name='kpt-26', id=26, color=[255, 0, 0], type='', swap='kpt-17'),\n        27: dict(name='kpt-27', id=27, color=[255, 0, 0], type='', swap=''),\n        28: dict(name='kpt-28', id=28, color=[255, 0, 0], type='', swap=''),\n        29: dict(name='kpt-29', id=29, color=[255, 0, 0], type='', swap=''),\n        30: dict(name='kpt-30', id=30, color=[255, 0, 0], type='', swap=''),\n        31:\n        dict(name='kpt-31', id=31, color=[255, 0, 0], type='', swap='kpt-35'),\n        32:\n        dict(name='kpt-32', id=32, color=[255, 0, 0], type='', swap='kpt-34'),\n        33: dict(name='kpt-33', id=33, color=[255, 0, 0], type='', swap=''),\n        34:\n        dict(name='kpt-34', id=34, color=[255, 0, 0], type='', swap='kpt-32'),\n        35:\n        dict(name='kpt-35', id=35, color=[255, 0, 0], type='', swap='kpt-31'),\n        36:\n        dict(name='kpt-36', id=36, color=[255, 0, 0], type='', swap='kpt-45'),\n        37:\n        dict(name='kpt-37', id=37, color=[255, 0, 0], type='', swap='kpt-44'),\n        38:\n        dict(name='kpt-38', id=38, color=[255, 0, 0], type='', swap='kpt-43'),\n        39:\n        dict(name='kpt-39', id=39, color=[255, 0, 0], type='', swap='kpt-42'),\n        40:\n        dict(name='kpt-40', id=40, color=[255, 0, 0], type='', swap='kpt-47'),\n        41: dict(\n            name='kpt-41', id=41, color=[255, 0, 0], type='', swap='kpt-46'),\n        42: dict(\n            name='kpt-42', id=42, color=[255, 0, 0], type='', swap='kpt-39'),\n        43: dict(\n            name='kpt-43', id=43, color=[255, 0, 0], type='', swap='kpt-38'),\n        44: dict(\n            name='kpt-44', id=44, color=[255, 0, 0], type='', swap='kpt-37'),\n        45: dict(\n            name='kpt-45', id=45, color=[255, 0, 0], type='', swap='kpt-36'),\n        46: dict(\n            name='kpt-46', id=46, color=[255, 0, 0], type='', swap='kpt-41'),\n        47: dict(\n            name='kpt-47', id=47, color=[255, 0, 0], type='', swap='kpt-40'),\n        48: dict(\n            name='kpt-48', id=48, color=[255, 0, 0], type='', swap='kpt-54'),\n        49: dict(\n            name='kpt-49', id=49, color=[255, 0, 0], type='', swap='kpt-53'),\n        50: dict(\n            name='kpt-50', id=50, color=[255, 0, 0], type='', swap='kpt-52'),\n        51: dict(name='kpt-51', id=51, color=[255, 0, 0], type='', swap=''),\n        52: dict(\n            name='kpt-52', id=52, color=[255, 0, 0], type='', swap='kpt-50'),\n        53: dict(\n            name='kpt-53', id=53, color=[255, 0, 0], type='', swap='kpt-49'),\n        54: dict(\n            name='kpt-54', id=54, color=[255, 0, 0], type='', swap='kpt-48'),\n        55: dict(\n            name='kpt-55', id=55, color=[255, 0, 0], type='', swap='kpt-59'),\n        56: dict(\n            name='kpt-56', id=56, color=[255, 0, 0], type='', swap='kpt-58'),\n        57: dict(name='kpt-57', id=57, color=[255, 0, 0], type='', swap=''),\n        58: dict(\n            name='kpt-58', id=58, color=[255, 0, 0], type='', swap='kpt-56'),\n        59: dict(\n            name='kpt-59', id=59, color=[255, 0, 0], type='', swap='kpt-55'),\n        60: dict(\n            name='kpt-60', id=60, color=[255, 0, 0], type='', swap='kpt-64'),\n        61: dict(\n            name='kpt-61', id=61, color=[255, 0, 0], type='', swap='kpt-63'),\n        62: dict(name='kpt-62', id=62, color=[255, 0, 0], type='', swap=''),\n        63: dict(\n            name='kpt-63', id=63, color=[255, 0, 0], type='', swap='kpt-61'),\n        64: dict(\n            name='kpt-64', id=64, color=[255, 0, 0], type='', swap='kpt-60'),\n        65: dict(\n            name='kpt-65', id=65, color=[255, 0, 0], type='', swap='kpt-67'),\n        66: dict(name='kpt-66', id=66, color=[255, 0, 0], type='', swap=''),\n        67: dict(\n            name='kpt-67', id=67, color=[255, 0, 0], type='', swap='kpt-65'),\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 68,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/300w.py",
    "content": "dataset_info = dict(\n    dataset_name='300w',\n    paper_info=dict(\n        author='Sagonas, Christos and Antonakos, Epameinondas '\n        'and Tzimiropoulos, Georgios and Zafeiriou, Stefanos '\n        'and Pantic, Maja',\n        title='300 faces in-the-wild challenge: '\n        'Database and results',\n        container='Image and vision computing',\n        year='2016',\n        homepage='https://ibug.doc.ic.ac.uk/resources/300-W/',\n    ),\n    keypoint_info={\n        0: dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap='kpt-16'),\n        1: dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap='kpt-15'),\n        2: dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap='kpt-14'),\n        3: dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap='kpt-13'),\n        4: dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap='kpt-12'),\n        5: dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap='kpt-11'),\n        6: dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap='kpt-10'),\n        7: dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap='kpt-9'),\n        8: dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap=''),\n        9: dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap='kpt-7'),\n        10:\n        dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap='kpt-6'),\n        11:\n        dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap='kpt-5'),\n        12:\n        dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap='kpt-4'),\n        13:\n        dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap='kpt-3'),\n        14:\n        dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap='kpt-2'),\n        15:\n        dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap='kpt-1'),\n        16:\n        dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap='kpt-0'),\n        17:\n        dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap='kpt-26'),\n        18:\n        dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap='kpt-25'),\n        19:\n        dict(name='kpt-19', id=19, color=[255, 0, 0], type='', swap='kpt-24'),\n        20:\n        dict(name='kpt-20', id=20, color=[255, 0, 0], type='', swap='kpt-23'),\n        21:\n        dict(name='kpt-21', id=21, color=[255, 0, 0], type='', swap='kpt-22'),\n        22:\n        dict(name='kpt-22', id=22, color=[255, 0, 0], type='', swap='kpt-21'),\n        23:\n        dict(name='kpt-23', id=23, color=[255, 0, 0], type='', swap='kpt-20'),\n        24:\n        dict(name='kpt-24', id=24, color=[255, 0, 0], type='', swap='kpt-19'),\n        25:\n        dict(name='kpt-25', id=25, color=[255, 0, 0], type='', swap='kpt-18'),\n        26:\n        dict(name='kpt-26', id=26, color=[255, 0, 0], type='', swap='kpt-17'),\n        27: dict(name='kpt-27', id=27, color=[255, 0, 0], type='', swap=''),\n        28: dict(name='kpt-28', id=28, color=[255, 0, 0], type='', swap=''),\n        29: dict(name='kpt-29', id=29, color=[255, 0, 0], type='', swap=''),\n        30: dict(name='kpt-30', id=30, color=[255, 0, 0], type='', swap=''),\n        31:\n        dict(name='kpt-31', id=31, color=[255, 0, 0], type='', swap='kpt-35'),\n        32:\n        dict(name='kpt-32', id=32, color=[255, 0, 0], type='', swap='kpt-34'),\n        33: dict(name='kpt-33', id=33, color=[255, 0, 0], type='', swap=''),\n        34:\n        dict(name='kpt-34', id=34, color=[255, 0, 0], type='', swap='kpt-32'),\n        35:\n        dict(name='kpt-35', id=35, color=[255, 0, 0], type='', swap='kpt-31'),\n        36:\n        dict(name='kpt-36', id=36, color=[255, 0, 0], type='', swap='kpt-45'),\n        37:\n        dict(name='kpt-37', id=37, color=[255, 0, 0], type='', swap='kpt-44'),\n        38:\n        dict(name='kpt-38', id=38, color=[255, 0, 0], type='', swap='kpt-43'),\n        39:\n        dict(name='kpt-39', id=39, color=[255, 0, 0], type='', swap='kpt-42'),\n        40:\n        dict(name='kpt-40', id=40, color=[255, 0, 0], type='', swap='kpt-47'),\n        41: dict(\n            name='kpt-41', id=41, color=[255, 0, 0], type='', swap='kpt-46'),\n        42: dict(\n            name='kpt-42', id=42, color=[255, 0, 0], type='', swap='kpt-39'),\n        43: dict(\n            name='kpt-43', id=43, color=[255, 0, 0], type='', swap='kpt-38'),\n        44: dict(\n            name='kpt-44', id=44, color=[255, 0, 0], type='', swap='kpt-37'),\n        45: dict(\n            name='kpt-45', id=45, color=[255, 0, 0], type='', swap='kpt-36'),\n        46: dict(\n            name='kpt-46', id=46, color=[255, 0, 0], type='', swap='kpt-41'),\n        47: dict(\n            name='kpt-47', id=47, color=[255, 0, 0], type='', swap='kpt-40'),\n        48: dict(\n            name='kpt-48', id=48, color=[255, 0, 0], type='', swap='kpt-54'),\n        49: dict(\n            name='kpt-49', id=49, color=[255, 0, 0], type='', swap='kpt-53'),\n        50: dict(\n            name='kpt-50', id=50, color=[255, 0, 0], type='', swap='kpt-52'),\n        51: dict(name='kpt-51', id=51, color=[255, 0, 0], type='', swap=''),\n        52: dict(\n            name='kpt-52', id=52, color=[255, 0, 0], type='', swap='kpt-50'),\n        53: dict(\n            name='kpt-53', id=53, color=[255, 0, 0], type='', swap='kpt-49'),\n        54: dict(\n            name='kpt-54', id=54, color=[255, 0, 0], type='', swap='kpt-48'),\n        55: dict(\n            name='kpt-55', id=55, color=[255, 0, 0], type='', swap='kpt-59'),\n        56: dict(\n            name='kpt-56', id=56, color=[255, 0, 0], type='', swap='kpt-58'),\n        57: dict(name='kpt-57', id=57, color=[255, 0, 0], type='', swap=''),\n        58: dict(\n            name='kpt-58', id=58, color=[255, 0, 0], type='', swap='kpt-56'),\n        59: dict(\n            name='kpt-59', id=59, color=[255, 0, 0], type='', swap='kpt-55'),\n        60: dict(\n            name='kpt-60', id=60, color=[255, 0, 0], type='', swap='kpt-64'),\n        61: dict(\n            name='kpt-61', id=61, color=[255, 0, 0], type='', swap='kpt-63'),\n        62: dict(name='kpt-62', id=62, color=[255, 0, 0], type='', swap=''),\n        63: dict(\n            name='kpt-63', id=63, color=[255, 0, 0], type='', swap='kpt-61'),\n        64: dict(\n            name='kpt-64', id=64, color=[255, 0, 0], type='', swap='kpt-60'),\n        65: dict(\n            name='kpt-65', id=65, color=[255, 0, 0], type='', swap='kpt-67'),\n        66: dict(name='kpt-66', id=66, color=[255, 0, 0], type='', swap=''),\n        67: dict(\n            name='kpt-67', id=67, color=[255, 0, 0], type='', swap='kpt-65'),\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 68,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/300wlp.py",
    "content": "dataset_info = dict(\n    dataset_name='300wlp',\n    paper_info=dict(\n        author='Xiangyu Zhu1, and Zhen Lei1 '\n        'and Xiaoming Liu2, and Hailin Shi1 '\n        'and Stan Z. Li1',\n        title='300 faces in-the-wild challenge: '\n        'Database and results',\n        container='Image and vision computing',\n        year='2016',\n        homepage='http://www.cbsr.ia.ac.cn/users/xiangyuzhu/'\n        'projects/3DDFA/main.htm',\n    ),\n    keypoint_info={\n        0: dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap=''),\n        1: dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap=''),\n        2: dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap=''),\n        3: dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap=''),\n        4: dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap=''),\n        5: dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap=''),\n        6: dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap=''),\n        7: dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap=''),\n        8: dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap=''),\n        9: dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap=''),\n        10: dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap=''),\n        11: dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap=''),\n        12: dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap=''),\n        13: dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap=''),\n        14: dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap=''),\n        15: dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap=''),\n        16: dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap=''),\n        17: dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap=''),\n        18: dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap=''),\n        19: dict(name='kpt-19', id=19, color=[255, 0, 0], type='', swap=''),\n        20: dict(name='kpt-20', id=20, color=[255, 0, 0], type='', swap=''),\n        21: dict(name='kpt-21', id=21, color=[255, 0, 0], type='', swap=''),\n        22: dict(name='kpt-22', id=22, color=[255, 0, 0], type='', swap=''),\n        23: dict(name='kpt-23', id=23, color=[255, 0, 0], type='', swap=''),\n        24: dict(name='kpt-24', id=24, color=[255, 0, 0], type='', swap=''),\n        25: dict(name='kpt-25', id=25, color=[255, 0, 0], type='', swap=''),\n        26: dict(name='kpt-26', id=26, color=[255, 0, 0], type='', swap=''),\n        27: dict(name='kpt-27', id=27, color=[255, 0, 0], type='', swap=''),\n        28: dict(name='kpt-28', id=28, color=[255, 0, 0], type='', swap=''),\n        29: dict(name='kpt-29', id=29, color=[255, 0, 0], type='', swap=''),\n        30: dict(name='kpt-30', id=30, color=[255, 0, 0], type='', swap=''),\n        31: dict(name='kpt-31', id=31, color=[255, 0, 0], type='', swap=''),\n        32: dict(name='kpt-32', id=32, color=[255, 0, 0], type='', swap=''),\n        33: dict(name='kpt-33', id=33, color=[255, 0, 0], type='', swap=''),\n        34: dict(name='kpt-34', id=34, color=[255, 0, 0], type='', swap=''),\n        35: dict(name='kpt-35', id=35, color=[255, 0, 0], type='', swap=''),\n        36: dict(name='kpt-36', id=36, color=[255, 0, 0], type='', swap=''),\n        37: dict(name='kpt-37', id=37, color=[255, 0, 0], type='', swap=''),\n        38: dict(name='kpt-38', id=38, color=[255, 0, 0], type='', swap=''),\n        39: dict(name='kpt-39', id=39, color=[255, 0, 0], type='', swap=''),\n        40: dict(name='kpt-40', id=40, color=[255, 0, 0], type='', swap=''),\n        41: dict(name='kpt-41', id=41, color=[255, 0, 0], type='', swap=''),\n        42: dict(name='kpt-42', id=42, color=[255, 0, 0], type='', swap=''),\n        43: dict(name='kpt-43', id=43, color=[255, 0, 0], type='', swap=''),\n        44: dict(name='kpt-44', id=44, color=[255, 0, 0], type='', swap=''),\n        45: dict(name='kpt-45', id=45, color=[255, 0, 0], type='', swap=''),\n        46: dict(name='kpt-46', id=46, color=[255, 0, 0], type='', swap=''),\n        47: dict(name='kpt-47', id=47, color=[255, 0, 0], type='', swap=''),\n        48: dict(name='kpt-48', id=48, color=[255, 0, 0], type='', swap=''),\n        49: dict(name='kpt-49', id=49, color=[255, 0, 0], type='', swap=''),\n        50: dict(name='kpt-50', id=50, color=[255, 0, 0], type='', swap=''),\n        51: dict(name='kpt-51', id=51, color=[255, 0, 0], type='', swap=''),\n        52: dict(name='kpt-52', id=52, color=[255, 0, 0], type='', swap=''),\n        53: dict(name='kpt-53', id=53, color=[255, 0, 0], type='', swap=''),\n        54: dict(name='kpt-54', id=54, color=[255, 0, 0], type='', swap=''),\n        55: dict(name='kpt-55', id=55, color=[255, 0, 0], type='', swap=''),\n        56: dict(name='kpt-56', id=56, color=[255, 0, 0], type='', swap=''),\n        57: dict(name='kpt-57', id=57, color=[255, 0, 0], type='', swap=''),\n        58: dict(name='kpt-58', id=58, color=[255, 0, 0], type='', swap=''),\n        59: dict(name='kpt-59', id=59, color=[255, 0, 0], type='', swap=''),\n        60: dict(name='kpt-60', id=60, color=[255, 0, 0], type='', swap=''),\n        61: dict(name='kpt-61', id=61, color=[255, 0, 0], type='', swap=''),\n        62: dict(name='kpt-62', id=62, color=[255, 0, 0], type='', swap=''),\n        63: dict(name='kpt-63', id=63, color=[255, 0, 0], type='', swap=''),\n        64: dict(name='kpt-64', id=64, color=[255, 0, 0], type='', swap=''),\n        65: dict(name='kpt-65', id=65, color=[255, 0, 0], type='', swap=''),\n        66: dict(name='kpt-66', id=66, color=[255, 0, 0], type='', swap=''),\n        67: dict(name='kpt-67', id=67, color=[255, 0, 0], type='', swap=''),\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 68,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/aflw.py",
    "content": "dataset_info = dict(\n    dataset_name='aflw',\n    paper_info=dict(\n        author='Koestinger, Martin and Wohlhart, Paul and '\n        'Roth, Peter M and Bischof, Horst',\n        title='Annotated facial landmarks in the wild: '\n        'A large-scale, real-world database for facial '\n        'landmark localization',\n        container='2011 IEEE international conference on computer '\n        'vision workshops (ICCV workshops)',\n        year='2011',\n        homepage='https://www.tugraz.at/institute/icg/research/'\n        'team-bischof/lrs/downloads/aflw/',\n    ),\n    keypoint_info={\n        0: dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap='kpt-5'),\n        1: dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap='kpt-4'),\n        2: dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap='kpt-3'),\n        3: dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap='kpt-2'),\n        4: dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap='kpt-1'),\n        5: dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap='kpt-0'),\n        6: dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap='kpt-11'),\n        7: dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap='kpt-10'),\n        8: dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap='kpt-9'),\n        9: dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap='kpt-8'),\n        10:\n        dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap='kpt-7'),\n        11:\n        dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap='kpt-6'),\n        12:\n        dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap='kpt-14'),\n        13: dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap=''),\n        14:\n        dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap='kpt-12'),\n        15:\n        dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap='kpt-17'),\n        16: dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap=''),\n        17:\n        dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap='kpt-15'),\n        18: dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap='')\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 19,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/aic.py",
    "content": "dataset_info = dict(\n    dataset_name='aic',\n    paper_info=dict(\n        author='Wu, Jiahong and Zheng, He and Zhao, Bo and '\n        'Li, Yixin and Yan, Baoming and Liang, Rui and '\n        'Wang, Wenjia and Zhou, Shipei and Lin, Guosen and '\n        'Fu, Yanwei and others',\n        title='Ai challenger: A large-scale dataset for going '\n        'deeper in image understanding',\n        container='arXiv',\n        year='2017',\n        homepage='https://github.com/AIChallenger/AI_Challenger_2017',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_shoulder',\n            id=0,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        1:\n        dict(\n            name='right_elbow',\n            id=1,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        2:\n        dict(\n            name='right_wrist',\n            id=2,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        3:\n        dict(\n            name='left_shoulder',\n            id=3,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        4:\n        dict(\n            name='left_elbow',\n            id=4,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        5:\n        dict(\n            name='left_wrist',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        6:\n        dict(\n            name='right_hip',\n            id=6,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        7:\n        dict(\n            name='right_knee',\n            id=7,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        8:\n        dict(\n            name='right_ankle',\n            id=8,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        9:\n        dict(\n            name='left_hip',\n            id=9,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        10:\n        dict(\n            name='left_knee',\n            id=10,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        11:\n        dict(\n            name='left_ankle',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        12:\n        dict(\n            name='head_top',\n            id=12,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        13:\n        dict(name='neck', id=13, color=[51, 153, 255], type='upper', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_wrist', 'right_elbow'), id=0, color=[255, 128, 0]),\n        1: dict(\n            link=('right_elbow', 'right_shoulder'), id=1, color=[255, 128, 0]),\n        2: dict(link=('right_shoulder', 'neck'), id=2, color=[51, 153, 255]),\n        3: dict(link=('neck', 'left_shoulder'), id=3, color=[51, 153, 255]),\n        4: dict(link=('left_shoulder', 'left_elbow'), id=4, color=[0, 255, 0]),\n        5: dict(link=('left_elbow', 'left_wrist'), id=5, color=[0, 255, 0]),\n        6: dict(link=('right_ankle', 'right_knee'), id=6, color=[255, 128, 0]),\n        7: dict(link=('right_knee', 'right_hip'), id=7, color=[255, 128, 0]),\n        8: dict(link=('right_hip', 'left_hip'), id=8, color=[51, 153, 255]),\n        9: dict(link=('left_hip', 'left_knee'), id=9, color=[0, 255, 0]),\n        10: dict(link=('left_knee', 'left_ankle'), id=10, color=[0, 255, 0]),\n        11: dict(link=('head_top', 'neck'), id=11, color=[51, 153, 255]),\n        12: dict(\n            link=('right_shoulder', 'right_hip'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('left_shoulder', 'left_hip'), id=13, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1.2, 1.5, 1., 1.2, 1.5, 1., 1.2, 1.5, 1., 1.2, 1.5, 1., 1.\n    ],\n\n    # 'https://github.com/AIChallenger/AI_Challenger_2017/blob/master/'\n    # 'Evaluation/keypoint_eval/keypoint_eval.py#L50'\n    # delta = 2 x sigma\n    sigmas=[\n        0.01388152, 0.01515228, 0.01057665, 0.01417709, 0.01497891, 0.01402144,\n        0.03909642, 0.03686941, 0.01981803, 0.03843971, 0.03412318, 0.02415081,\n        0.01291456, 0.01236173\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/ak.py",
    "content": "dataset_info = dict(\n    dataset_name='Animal Kingdom',\n    paper_info=dict(\n        author='Singapore University of Technology and Design, Singapore.'\n        ' Xun Long Ng, Kian Eng Ong, Qichen Zheng,'\n        ' Yun Ni, Si Yong Yeo, Jun Liu.',\n        title='Animal Kingdom: '\n        'A Large and Diverse Dataset for Animal Behavior Understanding',\n        container='Conference on Computer Vision '\n        'and Pattern Recognition (CVPR)',\n        year='2022',\n        homepage='https://sutdcv.github.io/Animal-Kingdom',\n        version='1.0 (2022-06)',\n        date_created='2022-06',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='Head_Mid_Top',\n            id=0,\n            color=(225, 0, 255),\n            type='upper',\n            swap=''),\n        1:\n        dict(\n            name='Eye_Left',\n            id=1,\n            color=[220, 20, 60],\n            type='upper',\n            swap='Eye_Right'),\n        2:\n        dict(\n            name='Eye_Right',\n            id=2,\n            color=[0, 255, 255],\n            type='upper',\n            swap='Eye_Left'),\n        3:\n        dict(\n            name='Mouth_Front_Top',\n            id=3,\n            color=(0, 255, 42),\n            type='upper',\n            swap=''),\n        4:\n        dict(\n            name='Mouth_Back_Left',\n            id=4,\n            color=[221, 160, 221],\n            type='upper',\n            swap='Mouth_Back_Right'),\n        5:\n        dict(\n            name='Mouth_Back_Right',\n            id=5,\n            color=[135, 206, 250],\n            type='upper',\n            swap='Mouth_Back_Left'),\n        6:\n        dict(\n            name='Mouth_Front_Bottom',\n            id=6,\n            color=[50, 205, 50],\n            type='upper',\n            swap=''),\n        7:\n        dict(\n            name='Shoulder_Left',\n            id=7,\n            color=[255, 182, 193],\n            type='upper',\n            swap='Shoulder_Right'),\n        8:\n        dict(\n            name='Shoulder_Right',\n            id=8,\n            color=[0, 191, 255],\n            type='upper',\n            swap='Shoulder_Left'),\n        9:\n        dict(\n            name='Elbow_Left',\n            id=9,\n            color=[255, 105, 180],\n            type='upper',\n            swap='Elbow_Right'),\n        10:\n        dict(\n            name='Elbow_Right',\n            id=10,\n            color=[30, 144, 255],\n            type='upper',\n            swap='Elbow_Left'),\n        11:\n        dict(\n            name='Wrist_Left',\n            id=11,\n            color=[255, 20, 147],\n            type='upper',\n            swap='Wrist_Right'),\n        12:\n        dict(\n            name='Wrist_Right',\n            id=12,\n            color=[0, 0, 255],\n            type='upper',\n            swap='Wrist_Left'),\n        13:\n        dict(\n            name='Torso_Mid_Back',\n            id=13,\n            color=(185, 3, 221),\n            type='upper',\n            swap=''),\n        14:\n        dict(\n            name='Hip_Left',\n            id=14,\n            color=[255, 215, 0],\n            type='lower',\n            swap='Hip_Right'),\n        15:\n        dict(\n            name='Hip_Right',\n            id=15,\n            color=[147, 112, 219],\n            type='lower',\n            swap='Hip_Left'),\n        16:\n        dict(\n            name='Knee_Left',\n            id=16,\n            color=[255, 165, 0],\n            type='lower',\n            swap='Knee_Right'),\n        17:\n        dict(\n            name='Knee_Right',\n            id=17,\n            color=[138, 43, 226],\n            type='lower',\n            swap='Knee_Left'),\n        18:\n        dict(\n            name='Ankle_Left',\n            id=18,\n            color=[255, 140, 0],\n            type='lower',\n            swap='Ankle_Right'),\n        19:\n        dict(\n            name='Ankle_Right',\n            id=19,\n            color=[128, 0, 128],\n            type='lower',\n            swap='Ankle_Left'),\n        20:\n        dict(\n            name='Tail_Top_Back',\n            id=20,\n            color=(0, 251, 255),\n            type='lower',\n            swap=''),\n        21:\n        dict(\n            name='Tail_Mid_Back',\n            id=21,\n            color=[32, 178, 170],\n            type='lower',\n            swap=''),\n        22:\n        dict(\n            name='Tail_End_Back',\n            id=22,\n            color=(0, 102, 102),\n            type='lower',\n            swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('Eye_Left', 'Head_Mid_Top'), id=0, color=[220, 20, 60]),\n        1:\n        dict(link=('Eye_Right', 'Head_Mid_Top'), id=1, color=[0, 255, 255]),\n        2:\n        dict(\n            link=('Mouth_Front_Top', 'Mouth_Back_Left'),\n            id=2,\n            color=[221, 160, 221]),\n        3:\n        dict(\n            link=('Mouth_Front_Top', 'Mouth_Back_Right'),\n            id=3,\n            color=[135, 206, 250]),\n        4:\n        dict(\n            link=('Mouth_Front_Bottom', 'Mouth_Back_Left'),\n            id=4,\n            color=[221, 160, 221]),\n        5:\n        dict(\n            link=('Mouth_Front_Bottom', 'Mouth_Back_Right'),\n            id=5,\n            color=[135, 206, 250]),\n        6:\n        dict(\n            link=('Head_Mid_Top', 'Torso_Mid_Back'), id=6,\n            color=(225, 0, 255)),\n        7:\n        dict(\n            link=('Torso_Mid_Back', 'Tail_Top_Back'),\n            id=7,\n            color=(185, 3, 221)),\n        8:\n        dict(\n            link=('Tail_Top_Back', 'Tail_Mid_Back'), id=8,\n            color=(0, 251, 255)),\n        9:\n        dict(\n            link=('Tail_Mid_Back', 'Tail_End_Back'),\n            id=9,\n            color=[32, 178, 170]),\n        10:\n        dict(\n            link=('Head_Mid_Top', 'Shoulder_Left'),\n            id=10,\n            color=[255, 182, 193]),\n        11:\n        dict(\n            link=('Head_Mid_Top', 'Shoulder_Right'),\n            id=11,\n            color=[0, 191, 255]),\n        12:\n        dict(\n            link=('Shoulder_Left', 'Elbow_Left'), id=12, color=[255, 105,\n                                                                180]),\n        13:\n        dict(\n            link=('Shoulder_Right', 'Elbow_Right'),\n            id=13,\n            color=[30, 144, 255]),\n        14:\n        dict(link=('Elbow_Left', 'Wrist_Left'), id=14, color=[255, 20, 147]),\n        15:\n        dict(link=('Elbow_Right', 'Wrist_Right'), id=15, color=[0, 0, 255]),\n        16:\n        dict(link=('Tail_Top_Back', 'Hip_Left'), id=16, color=[255, 215, 0]),\n        17:\n        dict(\n            link=('Tail_Top_Back', 'Hip_Right'), id=17, color=[147, 112, 219]),\n        18:\n        dict(link=('Hip_Left', 'Knee_Left'), id=18, color=[255, 165, 0]),\n        19:\n        dict(link=('Hip_Right', 'Knee_Right'), id=19, color=[138, 43, 226]),\n        20:\n        dict(link=('Knee_Left', 'Ankle_Left'), id=20, color=[255, 140, 0]),\n        21:\n        dict(link=('Knee_Right', 'Ankle_Right'), id=21, color=[128, 0, 128])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.,\n        1., 1., 1., 1., 1.\n    ],\n    sigmas=[\n        0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025,\n        0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025, 0.025,\n        0.025, 0.025, 0.025\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/animalpose.py",
    "content": "dataset_info = dict(\n    dataset_name='animalpose',\n    paper_info=dict(\n        author='Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and '\n        'Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing',\n        title='Cross-Domain Adaptation for Animal Pose Estimation',\n        container='The IEEE International Conference on '\n        'Computer Vision (ICCV)',\n        year='2019',\n        homepage='https://sites.google.com/view/animal-pose/',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='L_Eye', id=0, color=[0, 255, 0], type='upper', swap='R_Eye'),\n        1:\n        dict(\n            name='R_Eye',\n            id=1,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_Eye'),\n        2:\n        dict(\n            name='L_EarBase',\n            id=2,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_EarBase'),\n        3:\n        dict(\n            name='R_EarBase',\n            id=3,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_EarBase'),\n        4:\n        dict(name='Nose', id=4, color=[51, 153, 255], type='upper', swap=''),\n        5:\n        dict(name='Throat', id=5, color=[51, 153, 255], type='upper', swap=''),\n        6:\n        dict(\n            name='TailBase', id=6, color=[51, 153, 255], type='lower',\n            swap=''),\n        7:\n        dict(\n            name='Withers', id=7, color=[51, 153, 255], type='upper', swap=''),\n        8:\n        dict(\n            name='L_F_Elbow',\n            id=8,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_F_Elbow'),\n        9:\n        dict(\n            name='R_F_Elbow',\n            id=9,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_F_Elbow'),\n        10:\n        dict(\n            name='L_B_Elbow',\n            id=10,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_B_Elbow'),\n        11:\n        dict(\n            name='R_B_Elbow',\n            id=11,\n            color=[255, 128, 0],\n            type='lower',\n            swap='L_B_Elbow'),\n        12:\n        dict(\n            name='L_F_Knee',\n            id=12,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_F_Knee'),\n        13:\n        dict(\n            name='R_F_Knee',\n            id=13,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_F_Knee'),\n        14:\n        dict(\n            name='L_B_Knee',\n            id=14,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_B_Knee'),\n        15:\n        dict(\n            name='R_B_Knee',\n            id=15,\n            color=[255, 128, 0],\n            type='lower',\n            swap='L_B_Knee'),\n        16:\n        dict(\n            name='L_F_Paw',\n            id=16,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_F_Paw'),\n        17:\n        dict(\n            name='R_F_Paw',\n            id=17,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_F_Paw'),\n        18:\n        dict(\n            name='L_B_Paw',\n            id=18,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_B_Paw'),\n        19:\n        dict(\n            name='R_B_Paw',\n            id=19,\n            color=[255, 128, 0],\n            type='lower',\n            swap='L_B_Paw')\n    },\n    skeleton_info={\n        0: dict(link=('L_Eye', 'R_Eye'), id=0, color=[51, 153, 255]),\n        1: dict(link=('L_Eye', 'L_EarBase'), id=1, color=[0, 255, 0]),\n        2: dict(link=('R_Eye', 'R_EarBase'), id=2, color=[255, 128, 0]),\n        3: dict(link=('L_Eye', 'Nose'), id=3, color=[0, 255, 0]),\n        4: dict(link=('R_Eye', 'Nose'), id=4, color=[255, 128, 0]),\n        5: dict(link=('Nose', 'Throat'), id=5, color=[51, 153, 255]),\n        6: dict(link=('Throat', 'Withers'), id=6, color=[51, 153, 255]),\n        7: dict(link=('TailBase', 'Withers'), id=7, color=[51, 153, 255]),\n        8: dict(link=('Throat', 'L_F_Elbow'), id=8, color=[0, 255, 0]),\n        9: dict(link=('L_F_Elbow', 'L_F_Knee'), id=9, color=[0, 255, 0]),\n        10: dict(link=('L_F_Knee', 'L_F_Paw'), id=10, color=[0, 255, 0]),\n        11: dict(link=('Throat', 'R_F_Elbow'), id=11, color=[255, 128, 0]),\n        12: dict(link=('R_F_Elbow', 'R_F_Knee'), id=12, color=[255, 128, 0]),\n        13: dict(link=('R_F_Knee', 'R_F_Paw'), id=13, color=[255, 128, 0]),\n        14: dict(link=('TailBase', 'L_B_Elbow'), id=14, color=[0, 255, 0]),\n        15: dict(link=('L_B_Elbow', 'L_B_Knee'), id=15, color=[0, 255, 0]),\n        16: dict(link=('L_B_Knee', 'L_B_Paw'), id=16, color=[0, 255, 0]),\n        17: dict(link=('TailBase', 'R_B_Elbow'), id=17, color=[255, 128, 0]),\n        18: dict(link=('R_B_Elbow', 'R_B_Knee'), id=18, color=[255, 128, 0]),\n        19: dict(link=('R_B_Knee', 'R_B_Paw'), id=19, color=[255, 128, 0])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.2, 1.2,\n        1.5, 1.5, 1.5, 1.5\n    ],\n\n    # Note: The original paper did not provide enough information about\n    # the sigmas. We modified from 'https://github.com/cocodataset/'\n    # 'cocoapi/blob/master/PythonAPI/pycocotools/cocoeval.py#L523'\n    sigmas=[\n        0.025, 0.025, 0.026, 0.035, 0.035, 0.10, 0.10, 0.10, 0.107, 0.107,\n        0.107, 0.107, 0.087, 0.087, 0.087, 0.087, 0.089, 0.089, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/ap10k.py",
    "content": "dataset_info = dict(\n    dataset_name='ap10k',\n    paper_info=dict(\n        author='Yu, Hang and Xu, Yufei and Zhang, Jing and '\n        'Zhao, Wei and Guan, Ziyu and Tao, Dacheng',\n        title='AP-10K: A Benchmark for Animal Pose Estimation in the Wild',\n        container='35th Conference on Neural Information Processing Systems '\n        '(NeurIPS 2021) Track on Datasets and Bench-marks.',\n        year='2021',\n        homepage='https://github.com/AlexTheBad/AP-10K',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='L_Eye', id=0, color=[0, 255, 0], type='upper', swap='R_Eye'),\n        1:\n        dict(\n            name='R_Eye',\n            id=1,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_Eye'),\n        2:\n        dict(name='Nose', id=2, color=[51, 153, 255], type='upper', swap=''),\n        3:\n        dict(name='Neck', id=3, color=[51, 153, 255], type='upper', swap=''),\n        4:\n        dict(\n            name='Root of tail',\n            id=4,\n            color=[51, 153, 255],\n            type='lower',\n            swap=''),\n        5:\n        dict(\n            name='L_Shoulder',\n            id=5,\n            color=[51, 153, 255],\n            type='upper',\n            swap='R_Shoulder'),\n        6:\n        dict(\n            name='L_Elbow',\n            id=6,\n            color=[51, 153, 255],\n            type='upper',\n            swap='R_Elbow'),\n        7:\n        dict(\n            name='L_F_Paw',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_F_Paw'),\n        8:\n        dict(\n            name='R_Shoulder',\n            id=8,\n            color=[0, 255, 0],\n            type='upper',\n            swap='L_Shoulder'),\n        9:\n        dict(\n            name='R_Elbow',\n            id=9,\n            color=[255, 128, 0],\n            type='upper',\n            swap='L_Elbow'),\n        10:\n        dict(\n            name='R_F_Paw',\n            id=10,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_F_Paw'),\n        11:\n        dict(\n            name='L_Hip',\n            id=11,\n            color=[255, 128, 0],\n            type='lower',\n            swap='R_Hip'),\n        12:\n        dict(\n            name='L_Knee',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='R_Knee'),\n        13:\n        dict(\n            name='L_B_Paw',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_B_Paw'),\n        14:\n        dict(\n            name='R_Hip', id=14, color=[0, 255, 0], type='lower',\n            swap='L_Hip'),\n        15:\n        dict(\n            name='R_Knee',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_Knee'),\n        16:\n        dict(\n            name='R_B_Paw',\n            id=16,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_B_Paw'),\n    },\n    skeleton_info={\n        0: dict(link=('L_Eye', 'R_Eye'), id=0, color=[0, 0, 255]),\n        1: dict(link=('L_Eye', 'Nose'), id=1, color=[0, 0, 255]),\n        2: dict(link=('R_Eye', 'Nose'), id=2, color=[0, 0, 255]),\n        3: dict(link=('Nose', 'Neck'), id=3, color=[0, 255, 0]),\n        4: dict(link=('Neck', 'Root of tail'), id=4, color=[0, 255, 0]),\n        5: dict(link=('Neck', 'L_Shoulder'), id=5, color=[0, 255, 255]),\n        6: dict(link=('L_Shoulder', 'L_Elbow'), id=6, color=[0, 255, 255]),\n        7: dict(link=('L_Elbow', 'L_F_Paw'), id=6, color=[0, 255, 255]),\n        8: dict(link=('Neck', 'R_Shoulder'), id=7, color=[6, 156, 250]),\n        9: dict(link=('R_Shoulder', 'R_Elbow'), id=8, color=[6, 156, 250]),\n        10: dict(link=('R_Elbow', 'R_F_Paw'), id=9, color=[6, 156, 250]),\n        11: dict(link=('Root of tail', 'L_Hip'), id=10, color=[0, 255, 255]),\n        12: dict(link=('L_Hip', 'L_Knee'), id=11, color=[0, 255, 255]),\n        13: dict(link=('L_Knee', 'L_B_Paw'), id=12, color=[0, 255, 255]),\n        14: dict(link=('Root of tail', 'R_Hip'), id=13, color=[6, 156, 250]),\n        15: dict(link=('R_Hip', 'R_Knee'), id=14, color=[6, 156, 250]),\n        16: dict(link=('R_Knee', 'R_B_Paw'), id=15, color=[6, 156, 250]),\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.025, 0.025, 0.026, 0.035, 0.035, 0.079, 0.072, 0.062, 0.079, 0.072,\n        0.062, 0.107, 0.087, 0.089, 0.107, 0.087, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/atrw.py",
    "content": "dataset_info = dict(\n    dataset_name='atrw',\n    paper_info=dict(\n        author='Li, Shuyuan and Li, Jianguo and Tang, Hanlin '\n        'and Qian, Rui and Lin, Weiyao',\n        title='ATRW: A Benchmark for Amur Tiger '\n        'Re-identification in the Wild',\n        container='Proceedings of the 28th ACM '\n        'International Conference on Multimedia',\n        year='2020',\n        homepage='https://cvwc2019.github.io/challenge.html',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left_ear',\n            id=0,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        1:\n        dict(\n            name='right_ear',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        2:\n        dict(name='nose', id=2, color=[51, 153, 255], type='upper', swap=''),\n        3:\n        dict(\n            name='right_shoulder',\n            id=3,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        4:\n        dict(\n            name='right_front_paw',\n            id=4,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_front_paw'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='left_front_paw',\n            id=6,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_front_paw'),\n        7:\n        dict(\n            name='right_hip',\n            id=7,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        8:\n        dict(\n            name='right_knee',\n            id=8,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        9:\n        dict(\n            name='right_back_paw',\n            id=9,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_back_paw'),\n        10:\n        dict(\n            name='left_hip',\n            id=10,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        11:\n        dict(\n            name='left_knee',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        12:\n        dict(\n            name='left_back_paw',\n            id=12,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_back_paw'),\n        13:\n        dict(name='tail', id=13, color=[51, 153, 255], type='lower', swap=''),\n        14:\n        dict(\n            name='center', id=14, color=[51, 153, 255], type='lower', swap=''),\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ear', 'nose'), id=0, color=[51, 153, 255]),\n        1:\n        dict(link=('right_ear', 'nose'), id=1, color=[51, 153, 255]),\n        2:\n        dict(link=('nose', 'center'), id=2, color=[51, 153, 255]),\n        3:\n        dict(\n            link=('left_shoulder', 'left_front_paw'), id=3, color=[0, 255, 0]),\n        4:\n        dict(link=('left_shoulder', 'center'), id=4, color=[0, 255, 0]),\n        5:\n        dict(\n            link=('right_shoulder', 'right_front_paw'),\n            id=5,\n            color=[255, 128, 0]),\n        6:\n        dict(link=('right_shoulder', 'center'), id=6, color=[255, 128, 0]),\n        7:\n        dict(link=('tail', 'center'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('right_back_paw', 'right_knee'), id=8, color=[255, 128, 0]),\n        9:\n        dict(link=('right_knee', 'right_hip'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('right_hip', 'tail'), id=10, color=[255, 128, 0]),\n        11:\n        dict(link=('left_back_paw', 'left_knee'), id=11, color=[0, 255, 0]),\n        12:\n        dict(link=('left_knee', 'left_hip'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('left_hip', 'tail'), id=13, color=[0, 255, 0]),\n    },\n    joint_weights=[1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1., 1.],\n    sigmas=[\n        0.0277, 0.0823, 0.0831, 0.0202, 0.0716, 0.0263, 0.0646, 0.0302, 0.0440,\n        0.0316, 0.0333, 0.0547, 0.0263, 0.0683, 0.0539\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/campus.py",
    "content": "dataset_info = dict(\n    dataset_name='campus',\n    paper_info=dict(\n        author='Belagiannis, Vasileios and Amin, Sikandar and Andriluka, '\n        'Mykhaylo and Schiele, Bernt and Navab, Nassir and Ilic, Slobodan',\n        title='3D Pictorial Structures for Multiple Human Pose Estimation',\n        container='IEEE Computer Society Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2014',\n        homepage='http://campar.in.tum.de/Chair/MultiHumanPose',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_ankle',\n            id=0,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        1:\n        dict(\n            name='right_knee',\n            id=1,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        2:\n        dict(\n            name='right_hip',\n            id=2,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        3:\n        dict(\n            name='left_hip',\n            id=3,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        4:\n        dict(\n            name='left_knee',\n            id=4,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        5:\n        dict(\n            name='left_ankle',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        6:\n        dict(\n            name='right_wrist',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        7:\n        dict(\n            name='right_elbow',\n            id=7,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        8:\n        dict(\n            name='right_shoulder',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        9:\n        dict(\n            name='left_shoulder',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        10:\n        dict(\n            name='left_elbow',\n            id=10,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        11:\n        dict(\n            name='left_wrist',\n            id=11,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        12:\n        dict(\n            name='bottom_head',\n            id=12,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        13:\n        dict(\n            name='top_head',\n            id=13,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('right_knee', 'right_hip'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('left_hip', 'left_knee'), id=2, color=[0, 255, 0]),\n        3:\n        dict(link=('left_knee', 'left_ankle'), id=3, color=[0, 255, 0]),\n        4:\n        dict(link=('right_hip', 'left_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('right_wrist', 'right_elbow'), id=5, color=[255, 128, 0]),\n        6:\n        dict(\n            link=('right_elbow', 'right_shoulder'), id=6, color=[255, 128, 0]),\n        7:\n        dict(link=('left_shoulder', 'left_elbow'), id=7, color=[0, 255, 0]),\n        8:\n        dict(link=('left_elbow', 'left_wrist'), id=8, color=[0, 255, 0]),\n        9:\n        dict(link=('right_hip', 'right_shoulder'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_hip', 'left_shoulder'), id=10, color=[0, 255, 0]),\n        11:\n        dict(\n            link=('right_shoulder', 'bottom_head'), id=11, color=[255, 128,\n                                                                  0]),\n        12:\n        dict(link=('left_shoulder', 'bottom_head'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('bottom_head', 'top_head'), id=13, color=[51, 153, 255]),\n    },\n    joint_weights=[\n        1.5, 1.2, 1.0, 1.0, 1.2, 1.5, 1.5, 1.2, 1.0, 1.0, 1.2, 1.5, 1.0, 1.0\n    ],\n    sigmas=[\n        0.089, 0.087, 0.107, 0.107, 0.087, 0.089, 0.062, 0.072, 0.079, 0.079,\n        0.072, 0.062, 0.026, 0.026\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco.py",
    "content": "dataset_info = dict(\n    dataset_name='coco',\n    paper_info=dict(\n        author='Lin, Tsung-Yi and Maire, Michael and '\n        'Belongie, Serge and Hays, James and '\n        'Perona, Pietro and Ramanan, Deva and '\n        r'Doll{\\'a}r, Piotr and Zitnick, C Lawrence',\n        title='Microsoft coco: Common objects in context',\n        container='European conference on computer vision',\n        year='2014',\n        homepage='http://cocodataset.org/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco_aic.py",
    "content": "dataset_info = dict(\n    dataset_name='coco',\n    paper_info=[\n        dict(\n            author='Lin, Tsung-Yi and Maire, Michael and '\n            'Belongie, Serge and Hays, James and '\n            'Perona, Pietro and Ramanan, Deva and '\n            r'Doll{\\'a}r, Piotr and Zitnick, C Lawrence',\n            title='Microsoft coco: Common objects in context',\n            container='European conference on computer vision',\n            year='2014',\n            homepage='http://cocodataset.org/',\n        ),\n        dict(\n            author='Wu, Jiahong and Zheng, He and Zhao, Bo and '\n            'Li, Yixin and Yan, Baoming and Liang, Rui and '\n            'Wang, Wenjia and Zhou, Shipei and Lin, Guosen and '\n            'Fu, Yanwei and others',\n            title='Ai challenger: A large-scale dataset for going '\n            'deeper in image understanding',\n            container='arXiv',\n            year='2017',\n            homepage='https://github.com/AIChallenger/AI_Challenger_2017',\n        ),\n    ],\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(\n            name='head_top',\n            id=17,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        18:\n        dict(name='neck', id=18, color=[51, 153, 255], type='upper', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('head_top', 'neck'), id=11, color=[51, 153, 255]),\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5, 1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.026, 0.026\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco_openpose.py",
    "content": "dataset_info = dict(\n    dataset_name='coco_openpose',\n    paper_info=dict(\n        author='Zhe, Cao and Tomas, Simon and '\n        'Shih-En, Wei and Yaser, Sheikh',\n        title='OpenPose: Realtime Multi-Person 2D Pose '\n        'Estimation using Part Affinity Fields',\n        container='IEEE Transactions on Pattern Analysis '\n        'and Machine Intelligence',\n        year='2019',\n        homepage='https://github.com/CMU-Perceptual-Computing-Lab/openpose/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[255, 0, 0], type='upper', swap=''),\n        1:\n        dict(name='neck', id=1, color=[255, 85, 0], type='upper', swap=''),\n        2:\n        dict(\n            name='right_shoulder',\n            id=2,\n            color=[255, 170, 0],\n            type='upper',\n            swap='left_shoulder'),\n        3:\n        dict(\n            name='right_elbow',\n            id=3,\n            color=[255, 255, 0],\n            type='upper',\n            swap='left_elbow'),\n        4:\n        dict(\n            name='right_wrist',\n            id=4,\n            color=[170, 255, 0],\n            type='upper',\n            swap='left_wrist'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[85, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='left_elbow',\n            id=6,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        7:\n        dict(\n            name='left_wrist',\n            id=7,\n            color=[0, 255, 85],\n            type='upper',\n            swap='right_wrist'),\n        8:\n        dict(\n            name='right_hip',\n            id=8,\n            color=[0, 255, 170],\n            type='lower',\n            swap='left_hip'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[0, 255, 255],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='right_ankle',\n            id=10,\n            color=[0, 170, 255],\n            type='lower',\n            swap='left_ankle'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 85, 255],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='left_knee',\n            id=12,\n            color=[0, 0, 255],\n            type='lower',\n            swap='right_knee'),\n        13:\n        dict(\n            name='left_ankle',\n            id=13,\n            color=[85, 0, 255],\n            type='lower',\n            swap='right_ankle'),\n        14:\n        dict(\n            name='right_eye',\n            id=14,\n            color=[170, 0, 255],\n            type='upper',\n            swap='left_eye'),\n        15:\n        dict(\n            name='left_eye',\n            id=15,\n            color=[255, 0, 255],\n            type='upper',\n            swap='right_eye'),\n        16:\n        dict(\n            name='right_ear',\n            id=16,\n            color=[255, 0, 170],\n            type='upper',\n            swap='left_ear'),\n        17:\n        dict(\n            name='left_ear',\n            id=17,\n            color=[255, 0, 85],\n            type='upper',\n            swap='right_ear'),\n    },\n    skeleton_info={\n        0: dict(link=('neck', 'right_shoulder'), id=0, color=[255, 0, 0]),\n        1: dict(link=('neck', 'left_shoulder'), id=1, color=[255, 85, 0]),\n        2: dict(\n            link=('right_shoulder', 'right_elbow'), id=2, color=[255, 170, 0]),\n        3:\n        dict(link=('right_elbow', 'right_wrist'), id=3, color=[255, 255, 0]),\n        4:\n        dict(link=('left_shoulder', 'left_elbow'), id=4, color=[170, 255, 0]),\n        5: dict(link=('left_elbow', 'left_wrist'), id=5, color=[85, 255, 0]),\n        6: dict(link=('neck', 'right_hip'), id=6, color=[0, 255, 0]),\n        7: dict(link=('right_hip', 'right_knee'), id=7, color=[0, 255, 85]),\n        8: dict(link=('right_knee', 'right_ankle'), id=8, color=[0, 255, 170]),\n        9: dict(link=('neck', 'left_hip'), id=9, color=[0, 255, 225]),\n        10: dict(link=('left_hip', 'left_knee'), id=10, color=[0, 170, 255]),\n        11: dict(link=('left_knee', 'left_ankle'), id=11, color=[0, 85, 255]),\n        12: dict(link=('neck', 'nose'), id=12, color=[0, 0, 255]),\n        13: dict(link=('nose', 'right_eye'), id=13, color=[255, 0, 170]),\n        14: dict(link=('right_eye', 'right_ear'), id=14, color=[170, 0, 255]),\n        15: dict(link=('nose', 'left_eye'), id=15, color=[255, 0, 255]),\n        16: dict(link=('left_eye', 'left_ear'), id=16, color=[255, 0, 170]),\n    },\n    joint_weights=[1.] * 18,\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.082\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco_wholebody.py",
    "content": "dataset_info = dict(\n    dataset_name='coco_wholebody',\n    paper_info=dict(\n        author='Jin, Sheng and Xu, Lumin and Xu, Jin and '\n        'Wang, Can and Liu, Wentao and '\n        'Qian, Chen and Ouyang, Wanli and Luo, Ping',\n        title='Whole-Body Human Pose Estimation in the Wild',\n        container='Proceedings of the European '\n        'Conference on Computer Vision (ECCV)',\n        year='2020',\n        homepage='https://github.com/jin-s13/COCO-WholeBody/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(\n            name='left_big_toe',\n            id=17,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_big_toe'),\n        18:\n        dict(\n            name='left_small_toe',\n            id=18,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_small_toe'),\n        19:\n        dict(\n            name='left_heel',\n            id=19,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_heel'),\n        20:\n        dict(\n            name='right_big_toe',\n            id=20,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_big_toe'),\n        21:\n        dict(\n            name='right_small_toe',\n            id=21,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_small_toe'),\n        22:\n        dict(\n            name='right_heel',\n            id=22,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_heel'),\n        23:\n        dict(\n            name='face-0',\n            id=23,\n            color=[255, 255, 255],\n            type='',\n            swap='face-16'),\n        24:\n        dict(\n            name='face-1',\n            id=24,\n            color=[255, 255, 255],\n            type='',\n            swap='face-15'),\n        25:\n        dict(\n            name='face-2',\n            id=25,\n            color=[255, 255, 255],\n            type='',\n            swap='face-14'),\n        26:\n        dict(\n            name='face-3',\n            id=26,\n            color=[255, 255, 255],\n            type='',\n            swap='face-13'),\n        27:\n        dict(\n            name='face-4',\n            id=27,\n            color=[255, 255, 255],\n            type='',\n            swap='face-12'),\n        28:\n        dict(\n            name='face-5',\n            id=28,\n            color=[255, 255, 255],\n            type='',\n            swap='face-11'),\n        29:\n        dict(\n            name='face-6',\n            id=29,\n            color=[255, 255, 255],\n            type='',\n            swap='face-10'),\n        30:\n        dict(\n            name='face-7',\n            id=30,\n            color=[255, 255, 255],\n            type='',\n            swap='face-9'),\n        31:\n        dict(name='face-8', id=31, color=[255, 255, 255], type='', swap=''),\n        32:\n        dict(\n            name='face-9',\n            id=32,\n            color=[255, 255, 255],\n            type='',\n            swap='face-7'),\n        33:\n        dict(\n            name='face-10',\n            id=33,\n            color=[255, 255, 255],\n            type='',\n            swap='face-6'),\n        34:\n        dict(\n            name='face-11',\n            id=34,\n            color=[255, 255, 255],\n            type='',\n            swap='face-5'),\n        35:\n        dict(\n            name='face-12',\n            id=35,\n            color=[255, 255, 255],\n            type='',\n            swap='face-4'),\n        36:\n        dict(\n            name='face-13',\n            id=36,\n            color=[255, 255, 255],\n            type='',\n            swap='face-3'),\n        37:\n        dict(\n            name='face-14',\n            id=37,\n            color=[255, 255, 255],\n            type='',\n            swap='face-2'),\n        38:\n        dict(\n            name='face-15',\n            id=38,\n            color=[255, 255, 255],\n            type='',\n            swap='face-1'),\n        39:\n        dict(\n            name='face-16',\n            id=39,\n            color=[255, 255, 255],\n            type='',\n            swap='face-0'),\n        40:\n        dict(\n            name='face-17',\n            id=40,\n            color=[255, 255, 255],\n            type='',\n            swap='face-26'),\n        41:\n        dict(\n            name='face-18',\n            id=41,\n            color=[255, 255, 255],\n            type='',\n            swap='face-25'),\n        42:\n        dict(\n            name='face-19',\n            id=42,\n            color=[255, 255, 255],\n            type='',\n            swap='face-24'),\n        43:\n        dict(\n            name='face-20',\n            id=43,\n            color=[255, 255, 255],\n            type='',\n            swap='face-23'),\n        44:\n        dict(\n            name='face-21',\n            id=44,\n            color=[255, 255, 255],\n            type='',\n            swap='face-22'),\n        45:\n        dict(\n            name='face-22',\n            id=45,\n            color=[255, 255, 255],\n            type='',\n            swap='face-21'),\n        46:\n        dict(\n            name='face-23',\n            id=46,\n            color=[255, 255, 255],\n            type='',\n            swap='face-20'),\n        47:\n        dict(\n            name='face-24',\n            id=47,\n            color=[255, 255, 255],\n            type='',\n            swap='face-19'),\n        48:\n        dict(\n            name='face-25',\n            id=48,\n            color=[255, 255, 255],\n            type='',\n            swap='face-18'),\n        49:\n        dict(\n            name='face-26',\n            id=49,\n            color=[255, 255, 255],\n            type='',\n            swap='face-17'),\n        50:\n        dict(name='face-27', id=50, color=[255, 255, 255], type='', swap=''),\n        51:\n        dict(name='face-28', id=51, color=[255, 255, 255], type='', swap=''),\n        52:\n        dict(name='face-29', id=52, color=[255, 255, 255], type='', swap=''),\n        53:\n        dict(name='face-30', id=53, color=[255, 255, 255], type='', swap=''),\n        54:\n        dict(\n            name='face-31',\n            id=54,\n            color=[255, 255, 255],\n            type='',\n            swap='face-35'),\n        55:\n        dict(\n            name='face-32',\n            id=55,\n            color=[255, 255, 255],\n            type='',\n            swap='face-34'),\n        56:\n        dict(name='face-33', id=56, color=[255, 255, 255], type='', swap=''),\n        57:\n        dict(\n            name='face-34',\n            id=57,\n            color=[255, 255, 255],\n            type='',\n            swap='face-32'),\n        58:\n        dict(\n            name='face-35',\n            id=58,\n            color=[255, 255, 255],\n            type='',\n            swap='face-31'),\n        59:\n        dict(\n            name='face-36',\n            id=59,\n            color=[255, 255, 255],\n            type='',\n            swap='face-45'),\n        60:\n        dict(\n            name='face-37',\n            id=60,\n            color=[255, 255, 255],\n            type='',\n            swap='face-44'),\n        61:\n        dict(\n            name='face-38',\n            id=61,\n            color=[255, 255, 255],\n            type='',\n            swap='face-43'),\n        62:\n        dict(\n            name='face-39',\n            id=62,\n            color=[255, 255, 255],\n            type='',\n            swap='face-42'),\n        63:\n        dict(\n            name='face-40',\n            id=63,\n            color=[255, 255, 255],\n            type='',\n            swap='face-47'),\n        64:\n        dict(\n            name='face-41',\n            id=64,\n            color=[255, 255, 255],\n            type='',\n            swap='face-46'),\n        65:\n        dict(\n            name='face-42',\n            id=65,\n            color=[255, 255, 255],\n            type='',\n            swap='face-39'),\n        66:\n        dict(\n            name='face-43',\n            id=66,\n            color=[255, 255, 255],\n            type='',\n            swap='face-38'),\n        67:\n        dict(\n            name='face-44',\n            id=67,\n            color=[255, 255, 255],\n            type='',\n            swap='face-37'),\n        68:\n        dict(\n            name='face-45',\n            id=68,\n            color=[255, 255, 255],\n            type='',\n            swap='face-36'),\n        69:\n        dict(\n            name='face-46',\n            id=69,\n            color=[255, 255, 255],\n            type='',\n            swap='face-41'),\n        70:\n        dict(\n            name='face-47',\n            id=70,\n            color=[255, 255, 255],\n            type='',\n            swap='face-40'),\n        71:\n        dict(\n            name='face-48',\n            id=71,\n            color=[255, 255, 255],\n            type='',\n            swap='face-54'),\n        72:\n        dict(\n            name='face-49',\n            id=72,\n            color=[255, 255, 255],\n            type='',\n            swap='face-53'),\n        73:\n        dict(\n            name='face-50',\n            id=73,\n            color=[255, 255, 255],\n            type='',\n            swap='face-52'),\n        74:\n        dict(name='face-51', id=74, color=[255, 255, 255], type='', swap=''),\n        75:\n        dict(\n            name='face-52',\n            id=75,\n            color=[255, 255, 255],\n            type='',\n            swap='face-50'),\n        76:\n        dict(\n            name='face-53',\n            id=76,\n            color=[255, 255, 255],\n            type='',\n            swap='face-49'),\n        77:\n        dict(\n            name='face-54',\n            id=77,\n            color=[255, 255, 255],\n            type='',\n            swap='face-48'),\n        78:\n        dict(\n            name='face-55',\n            id=78,\n            color=[255, 255, 255],\n            type='',\n            swap='face-59'),\n        79:\n        dict(\n            name='face-56',\n            id=79,\n            color=[255, 255, 255],\n            type='',\n            swap='face-58'),\n        80:\n        dict(name='face-57', id=80, color=[255, 255, 255], type='', swap=''),\n        81:\n        dict(\n            name='face-58',\n            id=81,\n            color=[255, 255, 255],\n            type='',\n            swap='face-56'),\n        82:\n        dict(\n            name='face-59',\n            id=82,\n            color=[255, 255, 255],\n            type='',\n            swap='face-55'),\n        83:\n        dict(\n            name='face-60',\n            id=83,\n            color=[255, 255, 255],\n            type='',\n            swap='face-64'),\n        84:\n        dict(\n            name='face-61',\n            id=84,\n            color=[255, 255, 255],\n            type='',\n            swap='face-63'),\n        85:\n        dict(name='face-62', id=85, color=[255, 255, 255], type='', swap=''),\n        86:\n        dict(\n            name='face-63',\n            id=86,\n            color=[255, 255, 255],\n            type='',\n            swap='face-61'),\n        87:\n        dict(\n            name='face-64',\n            id=87,\n            color=[255, 255, 255],\n            type='',\n            swap='face-60'),\n        88:\n        dict(\n            name='face-65',\n            id=88,\n            color=[255, 255, 255],\n            type='',\n            swap='face-67'),\n        89:\n        dict(name='face-66', id=89, color=[255, 255, 255], type='', swap=''),\n        90:\n        dict(\n            name='face-67',\n            id=90,\n            color=[255, 255, 255],\n            type='',\n            swap='face-65'),\n        91:\n        dict(\n            name='left_hand_root',\n            id=91,\n            color=[255, 255, 255],\n            type='',\n            swap='right_hand_root'),\n        92:\n        dict(\n            name='left_thumb1',\n            id=92,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb1'),\n        93:\n        dict(\n            name='left_thumb2',\n            id=93,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb2'),\n        94:\n        dict(\n            name='left_thumb3',\n            id=94,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb3'),\n        95:\n        dict(\n            name='left_thumb4',\n            id=95,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb4'),\n        96:\n        dict(\n            name='left_forefinger1',\n            id=96,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger1'),\n        97:\n        dict(\n            name='left_forefinger2',\n            id=97,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger2'),\n        98:\n        dict(\n            name='left_forefinger3',\n            id=98,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger3'),\n        99:\n        dict(\n            name='left_forefinger4',\n            id=99,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger4'),\n        100:\n        dict(\n            name='left_middle_finger1',\n            id=100,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger1'),\n        101:\n        dict(\n            name='left_middle_finger2',\n            id=101,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger2'),\n        102:\n        dict(\n            name='left_middle_finger3',\n            id=102,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger3'),\n        103:\n        dict(\n            name='left_middle_finger4',\n            id=103,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger4'),\n        104:\n        dict(\n            name='left_ring_finger1',\n            id=104,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger1'),\n        105:\n        dict(\n            name='left_ring_finger2',\n            id=105,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger2'),\n        106:\n        dict(\n            name='left_ring_finger3',\n            id=106,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger3'),\n        107:\n        dict(\n            name='left_ring_finger4',\n            id=107,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger4'),\n        108:\n        dict(\n            name='left_pinky_finger1',\n            id=108,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger1'),\n        109:\n        dict(\n            name='left_pinky_finger2',\n            id=109,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger2'),\n        110:\n        dict(\n            name='left_pinky_finger3',\n            id=110,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger3'),\n        111:\n        dict(\n            name='left_pinky_finger4',\n            id=111,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger4'),\n        112:\n        dict(\n            name='right_hand_root',\n            id=112,\n            color=[255, 255, 255],\n            type='',\n            swap='left_hand_root'),\n        113:\n        dict(\n            name='right_thumb1',\n            id=113,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb1'),\n        114:\n        dict(\n            name='right_thumb2',\n            id=114,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb2'),\n        115:\n        dict(\n            name='right_thumb3',\n            id=115,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb3'),\n        116:\n        dict(\n            name='right_thumb4',\n            id=116,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb4'),\n        117:\n        dict(\n            name='right_forefinger1',\n            id=117,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger1'),\n        118:\n        dict(\n            name='right_forefinger2',\n            id=118,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger2'),\n        119:\n        dict(\n            name='right_forefinger3',\n            id=119,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger3'),\n        120:\n        dict(\n            name='right_forefinger4',\n            id=120,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger4'),\n        121:\n        dict(\n            name='right_middle_finger1',\n            id=121,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger1'),\n        122:\n        dict(\n            name='right_middle_finger2',\n            id=122,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger2'),\n        123:\n        dict(\n            name='right_middle_finger3',\n            id=123,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger3'),\n        124:\n        dict(\n            name='right_middle_finger4',\n            id=124,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger4'),\n        125:\n        dict(\n            name='right_ring_finger1',\n            id=125,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger1'),\n        126:\n        dict(\n            name='right_ring_finger2',\n            id=126,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger2'),\n        127:\n        dict(\n            name='right_ring_finger3',\n            id=127,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger3'),\n        128:\n        dict(\n            name='right_ring_finger4',\n            id=128,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger4'),\n        129:\n        dict(\n            name='right_pinky_finger1',\n            id=129,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger1'),\n        130:\n        dict(\n            name='right_pinky_finger2',\n            id=130,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger2'),\n        131:\n        dict(\n            name='right_pinky_finger3',\n            id=131,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger3'),\n        132:\n        dict(\n            name='right_pinky_finger4',\n            id=132,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger4')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('left_ankle', 'left_big_toe'), id=19, color=[0, 255, 0]),\n        20:\n        dict(link=('left_ankle', 'left_small_toe'), id=20, color=[0, 255, 0]),\n        21:\n        dict(link=('left_ankle', 'left_heel'), id=21, color=[0, 255, 0]),\n        22:\n        dict(\n            link=('right_ankle', 'right_big_toe'), id=22, color=[255, 128, 0]),\n        23:\n        dict(\n            link=('right_ankle', 'right_small_toe'),\n            id=23,\n            color=[255, 128, 0]),\n        24:\n        dict(link=('right_ankle', 'right_heel'), id=24, color=[255, 128, 0]),\n        25:\n        dict(\n            link=('left_hand_root', 'left_thumb1'), id=25, color=[255, 128,\n                                                                  0]),\n        26:\n        dict(link=('left_thumb1', 'left_thumb2'), id=26, color=[255, 128, 0]),\n        27:\n        dict(link=('left_thumb2', 'left_thumb3'), id=27, color=[255, 128, 0]),\n        28:\n        dict(link=('left_thumb3', 'left_thumb4'), id=28, color=[255, 128, 0]),\n        29:\n        dict(\n            link=('left_hand_root', 'left_forefinger1'),\n            id=29,\n            color=[255, 153, 255]),\n        30:\n        dict(\n            link=('left_forefinger1', 'left_forefinger2'),\n            id=30,\n            color=[255, 153, 255]),\n        31:\n        dict(\n            link=('left_forefinger2', 'left_forefinger3'),\n            id=31,\n            color=[255, 153, 255]),\n        32:\n        dict(\n            link=('left_forefinger3', 'left_forefinger4'),\n            id=32,\n            color=[255, 153, 255]),\n        33:\n        dict(\n            link=('left_hand_root', 'left_middle_finger1'),\n            id=33,\n            color=[102, 178, 255]),\n        34:\n        dict(\n            link=('left_middle_finger1', 'left_middle_finger2'),\n            id=34,\n            color=[102, 178, 255]),\n        35:\n        dict(\n            link=('left_middle_finger2', 'left_middle_finger3'),\n            id=35,\n            color=[102, 178, 255]),\n        36:\n        dict(\n            link=('left_middle_finger3', 'left_middle_finger4'),\n            id=36,\n            color=[102, 178, 255]),\n        37:\n        dict(\n            link=('left_hand_root', 'left_ring_finger1'),\n            id=37,\n            color=[255, 51, 51]),\n        38:\n        dict(\n            link=('left_ring_finger1', 'left_ring_finger2'),\n            id=38,\n            color=[255, 51, 51]),\n        39:\n        dict(\n            link=('left_ring_finger2', 'left_ring_finger3'),\n            id=39,\n            color=[255, 51, 51]),\n        40:\n        dict(\n            link=('left_ring_finger3', 'left_ring_finger4'),\n            id=40,\n            color=[255, 51, 51]),\n        41:\n        dict(\n            link=('left_hand_root', 'left_pinky_finger1'),\n            id=41,\n            color=[0, 255, 0]),\n        42:\n        dict(\n            link=('left_pinky_finger1', 'left_pinky_finger2'),\n            id=42,\n            color=[0, 255, 0]),\n        43:\n        dict(\n            link=('left_pinky_finger2', 'left_pinky_finger3'),\n            id=43,\n            color=[0, 255, 0]),\n        44:\n        dict(\n            link=('left_pinky_finger3', 'left_pinky_finger4'),\n            id=44,\n            color=[0, 255, 0]),\n        45:\n        dict(\n            link=('right_hand_root', 'right_thumb1'),\n            id=45,\n            color=[255, 128, 0]),\n        46:\n        dict(\n            link=('right_thumb1', 'right_thumb2'), id=46, color=[255, 128, 0]),\n        47:\n        dict(\n            link=('right_thumb2', 'right_thumb3'), id=47, color=[255, 128, 0]),\n        48:\n        dict(\n            link=('right_thumb3', 'right_thumb4'), id=48, color=[255, 128, 0]),\n        49:\n        dict(\n            link=('right_hand_root', 'right_forefinger1'),\n            id=49,\n            color=[255, 153, 255]),\n        50:\n        dict(\n            link=('right_forefinger1', 'right_forefinger2'),\n            id=50,\n            color=[255, 153, 255]),\n        51:\n        dict(\n            link=('right_forefinger2', 'right_forefinger3'),\n            id=51,\n            color=[255, 153, 255]),\n        52:\n        dict(\n            link=('right_forefinger3', 'right_forefinger4'),\n            id=52,\n            color=[255, 153, 255]),\n        53:\n        dict(\n            link=('right_hand_root', 'right_middle_finger1'),\n            id=53,\n            color=[102, 178, 255]),\n        54:\n        dict(\n            link=('right_middle_finger1', 'right_middle_finger2'),\n            id=54,\n            color=[102, 178, 255]),\n        55:\n        dict(\n            link=('right_middle_finger2', 'right_middle_finger3'),\n            id=55,\n            color=[102, 178, 255]),\n        56:\n        dict(\n            link=('right_middle_finger3', 'right_middle_finger4'),\n            id=56,\n            color=[102, 178, 255]),\n        57:\n        dict(\n            link=('right_hand_root', 'right_ring_finger1'),\n            id=57,\n            color=[255, 51, 51]),\n        58:\n        dict(\n            link=('right_ring_finger1', 'right_ring_finger2'),\n            id=58,\n            color=[255, 51, 51]),\n        59:\n        dict(\n            link=('right_ring_finger2', 'right_ring_finger3'),\n            id=59,\n            color=[255, 51, 51]),\n        60:\n        dict(\n            link=('right_ring_finger3', 'right_ring_finger4'),\n            id=60,\n            color=[255, 51, 51]),\n        61:\n        dict(\n            link=('right_hand_root', 'right_pinky_finger1'),\n            id=61,\n            color=[0, 255, 0]),\n        62:\n        dict(\n            link=('right_pinky_finger1', 'right_pinky_finger2'),\n            id=62,\n            color=[0, 255, 0]),\n        63:\n        dict(\n            link=('right_pinky_finger2', 'right_pinky_finger3'),\n            id=63,\n            color=[0, 255, 0]),\n        64:\n        dict(\n            link=('right_pinky_finger3', 'right_pinky_finger4'),\n            id=64,\n            color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 133,\n    # 'https://github.com/jin-s13/COCO-WholeBody/blob/master/'\n    # 'evaluation/myeval_wholebody.py#L175'\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.068, 0.066, 0.066,\n        0.092, 0.094, 0.094, 0.042, 0.043, 0.044, 0.043, 0.040, 0.035, 0.031,\n        0.025, 0.020, 0.023, 0.029, 0.032, 0.037, 0.038, 0.043, 0.041, 0.045,\n        0.013, 0.012, 0.011, 0.011, 0.012, 0.012, 0.011, 0.011, 0.013, 0.015,\n        0.009, 0.007, 0.007, 0.007, 0.012, 0.009, 0.008, 0.016, 0.010, 0.017,\n        0.011, 0.009, 0.011, 0.009, 0.007, 0.013, 0.008, 0.011, 0.012, 0.010,\n        0.034, 0.008, 0.008, 0.009, 0.008, 0.008, 0.007, 0.010, 0.008, 0.009,\n        0.009, 0.009, 0.007, 0.007, 0.008, 0.011, 0.008, 0.008, 0.008, 0.01,\n        0.008, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024, 0.035,\n        0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02, 0.019,\n        0.022, 0.031, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024,\n        0.035, 0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02,\n        0.019, 0.022, 0.031\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco_wholebody_face.py",
    "content": "dataset_info = dict(\n    dataset_name='coco_wholebody_face',\n    paper_info=dict(\n        author='Jin, Sheng and Xu, Lumin and Xu, Jin and '\n        'Wang, Can and Liu, Wentao and '\n        'Qian, Chen and Ouyang, Wanli and Luo, Ping',\n        title='Whole-Body Human Pose Estimation in the Wild',\n        container='Proceedings of the European '\n        'Conference on Computer Vision (ECCV)',\n        year='2020',\n        homepage='https://github.com/jin-s13/COCO-WholeBody/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='face-0', id=0, color=[255, 0, 0], type='', swap='face-16'),\n        1:\n        dict(name='face-1', id=1, color=[255, 0, 0], type='', swap='face-15'),\n        2:\n        dict(name='face-2', id=2, color=[255, 0, 0], type='', swap='face-14'),\n        3:\n        dict(name='face-3', id=3, color=[255, 0, 0], type='', swap='face-13'),\n        4:\n        dict(name='face-4', id=4, color=[255, 0, 0], type='', swap='face-12'),\n        5:\n        dict(name='face-5', id=5, color=[255, 0, 0], type='', swap='face-11'),\n        6:\n        dict(name='face-6', id=6, color=[255, 0, 0], type='', swap='face-10'),\n        7:\n        dict(name='face-7', id=7, color=[255, 0, 0], type='', swap='face-9'),\n        8: dict(name='face-8', id=8, color=[255, 0, 0], type='', swap=''),\n        9:\n        dict(name='face-9', id=9, color=[255, 0, 0], type='', swap='face-7'),\n        10:\n        dict(name='face-10', id=10, color=[255, 0, 0], type='', swap='face-6'),\n        11:\n        dict(name='face-11', id=11, color=[255, 0, 0], type='', swap='face-5'),\n        12:\n        dict(name='face-12', id=12, color=[255, 0, 0], type='', swap='face-4'),\n        13:\n        dict(name='face-13', id=13, color=[255, 0, 0], type='', swap='face-3'),\n        14:\n        dict(name='face-14', id=14, color=[255, 0, 0], type='', swap='face-2'),\n        15:\n        dict(name='face-15', id=15, color=[255, 0, 0], type='', swap='face-1'),\n        16:\n        dict(name='face-16', id=16, color=[255, 0, 0], type='', swap='face-0'),\n        17: dict(\n            name='face-17', id=17, color=[255, 0, 0], type='', swap='face-26'),\n        18: dict(\n            name='face-18', id=18, color=[255, 0, 0], type='', swap='face-25'),\n        19: dict(\n            name='face-19', id=19, color=[255, 0, 0], type='', swap='face-24'),\n        20: dict(\n            name='face-20', id=20, color=[255, 0, 0], type='', swap='face-23'),\n        21: dict(\n            name='face-21', id=21, color=[255, 0, 0], type='', swap='face-22'),\n        22: dict(\n            name='face-22', id=22, color=[255, 0, 0], type='', swap='face-21'),\n        23: dict(\n            name='face-23', id=23, color=[255, 0, 0], type='', swap='face-20'),\n        24: dict(\n            name='face-24', id=24, color=[255, 0, 0], type='', swap='face-19'),\n        25: dict(\n            name='face-25', id=25, color=[255, 0, 0], type='', swap='face-18'),\n        26: dict(\n            name='face-26', id=26, color=[255, 0, 0], type='', swap='face-17'),\n        27: dict(name='face-27', id=27, color=[255, 0, 0], type='', swap=''),\n        28: dict(name='face-28', id=28, color=[255, 0, 0], type='', swap=''),\n        29: dict(name='face-29', id=29, color=[255, 0, 0], type='', swap=''),\n        30: dict(name='face-30', id=30, color=[255, 0, 0], type='', swap=''),\n        31: dict(\n            name='face-31', id=31, color=[255, 0, 0], type='', swap='face-35'),\n        32: dict(\n            name='face-32', id=32, color=[255, 0, 0], type='', swap='face-34'),\n        33: dict(name='face-33', id=33, color=[255, 0, 0], type='', swap=''),\n        34: dict(\n            name='face-34', id=34, color=[255, 0, 0], type='', swap='face-32'),\n        35: dict(\n            name='face-35', id=35, color=[255, 0, 0], type='', swap='face-31'),\n        36: dict(\n            name='face-36', id=36, color=[255, 0, 0], type='', swap='face-45'),\n        37: dict(\n            name='face-37', id=37, color=[255, 0, 0], type='', swap='face-44'),\n        38: dict(\n            name='face-38', id=38, color=[255, 0, 0], type='', swap='face-43'),\n        39: dict(\n            name='face-39', id=39, color=[255, 0, 0], type='', swap='face-42'),\n        40: dict(\n            name='face-40', id=40, color=[255, 0, 0], type='', swap='face-47'),\n        41: dict(\n            name='face-41', id=41, color=[255, 0, 0], type='', swap='face-46'),\n        42: dict(\n            name='face-42', id=42, color=[255, 0, 0], type='', swap='face-39'),\n        43: dict(\n            name='face-43', id=43, color=[255, 0, 0], type='', swap='face-38'),\n        44: dict(\n            name='face-44', id=44, color=[255, 0, 0], type='', swap='face-37'),\n        45: dict(\n            name='face-45', id=45, color=[255, 0, 0], type='', swap='face-36'),\n        46: dict(\n            name='face-46', id=46, color=[255, 0, 0], type='', swap='face-41'),\n        47: dict(\n            name='face-47', id=47, color=[255, 0, 0], type='', swap='face-40'),\n        48: dict(\n            name='face-48', id=48, color=[255, 0, 0], type='', swap='face-54'),\n        49: dict(\n            name='face-49', id=49, color=[255, 0, 0], type='', swap='face-53'),\n        50: dict(\n            name='face-50', id=50, color=[255, 0, 0], type='', swap='face-52'),\n        51: dict(name='face-51', id=52, color=[255, 0, 0], type='', swap=''),\n        52: dict(\n            name='face-52', id=52, color=[255, 0, 0], type='', swap='face-50'),\n        53: dict(\n            name='face-53', id=53, color=[255, 0, 0], type='', swap='face-49'),\n        54: dict(\n            name='face-54', id=54, color=[255, 0, 0], type='', swap='face-48'),\n        55: dict(\n            name='face-55', id=55, color=[255, 0, 0], type='', swap='face-59'),\n        56: dict(\n            name='face-56', id=56, color=[255, 0, 0], type='', swap='face-58'),\n        57: dict(name='face-57', id=57, color=[255, 0, 0], type='', swap=''),\n        58: dict(\n            name='face-58', id=58, color=[255, 0, 0], type='', swap='face-56'),\n        59: dict(\n            name='face-59', id=59, color=[255, 0, 0], type='', swap='face-55'),\n        60: dict(\n            name='face-60', id=60, color=[255, 0, 0], type='', swap='face-64'),\n        61: dict(\n            name='face-61', id=61, color=[255, 0, 0], type='', swap='face-63'),\n        62: dict(name='face-62', id=62, color=[255, 0, 0], type='', swap=''),\n        63: dict(\n            name='face-63', id=63, color=[255, 0, 0], type='', swap='face-61'),\n        64: dict(\n            name='face-64', id=64, color=[255, 0, 0], type='', swap='face-60'),\n        65: dict(\n            name='face-65', id=65, color=[255, 0, 0], type='', swap='face-67'),\n        66: dict(name='face-66', id=66, color=[255, 0, 0], type='', swap=''),\n        67: dict(\n            name='face-67', id=67, color=[255, 0, 0], type='', swap='face-65')\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 68,\n\n    # 'https://github.com/jin-s13/COCO-WholeBody/blob/master/'\n    # 'evaluation/myeval_wholebody.py#L177'\n    sigmas=[\n        0.042, 0.043, 0.044, 0.043, 0.040, 0.035, 0.031, 0.025, 0.020, 0.023,\n        0.029, 0.032, 0.037, 0.038, 0.043, 0.041, 0.045, 0.013, 0.012, 0.011,\n        0.011, 0.012, 0.012, 0.011, 0.011, 0.013, 0.015, 0.009, 0.007, 0.007,\n        0.007, 0.012, 0.009, 0.008, 0.016, 0.010, 0.017, 0.011, 0.009, 0.011,\n        0.009, 0.007, 0.013, 0.008, 0.011, 0.012, 0.010, 0.034, 0.008, 0.008,\n        0.009, 0.008, 0.008, 0.007, 0.010, 0.008, 0.009, 0.009, 0.009, 0.007,\n        0.007, 0.008, 0.011, 0.008, 0.008, 0.008, 0.01, 0.008\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco_wholebody_hand.py",
    "content": "dataset_info = dict(\n    dataset_name='coco_wholebody_hand',\n    paper_info=dict(\n        author='Jin, Sheng and Xu, Lumin and Xu, Jin and '\n        'Wang, Can and Liu, Wentao and '\n        'Qian, Chen and Ouyang, Wanli and Luo, Ping',\n        title='Whole-Body Human Pose Estimation in the Wild',\n        container='Proceedings of the European '\n        'Conference on Computer Vision (ECCV)',\n        year='2020',\n        homepage='https://github.com/jin-s13/COCO-WholeBody/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='wrist', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='thumb1', id=1, color=[255, 128, 0], type='', swap=''),\n        2:\n        dict(name='thumb2', id=2, color=[255, 128, 0], type='', swap=''),\n        3:\n        dict(name='thumb3', id=3, color=[255, 128, 0], type='', swap=''),\n        4:\n        dict(name='thumb4', id=4, color=[255, 128, 0], type='', swap=''),\n        5:\n        dict(\n            name='forefinger1', id=5, color=[255, 153, 255], type='', swap=''),\n        6:\n        dict(\n            name='forefinger2', id=6, color=[255, 153, 255], type='', swap=''),\n        7:\n        dict(\n            name='forefinger3', id=7, color=[255, 153, 255], type='', swap=''),\n        8:\n        dict(\n            name='forefinger4', id=8, color=[255, 153, 255], type='', swap=''),\n        9:\n        dict(\n            name='middle_finger1',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        10:\n        dict(\n            name='middle_finger2',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        11:\n        dict(\n            name='middle_finger3',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        12:\n        dict(\n            name='middle_finger4',\n            id=12,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        13:\n        dict(\n            name='ring_finger1', id=13, color=[255, 51, 51], type='', swap=''),\n        14:\n        dict(\n            name='ring_finger2', id=14, color=[255, 51, 51], type='', swap=''),\n        15:\n        dict(\n            name='ring_finger3', id=15, color=[255, 51, 51], type='', swap=''),\n        16:\n        dict(\n            name='ring_finger4', id=16, color=[255, 51, 51], type='', swap=''),\n        17:\n        dict(name='pinky_finger1', id=17, color=[0, 255, 0], type='', swap=''),\n        18:\n        dict(name='pinky_finger2', id=18, color=[0, 255, 0], type='', swap=''),\n        19:\n        dict(name='pinky_finger3', id=19, color=[0, 255, 0], type='', swap=''),\n        20:\n        dict(name='pinky_finger4', id=20, color=[0, 255, 0], type='', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('wrist', 'thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('thumb1', 'thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('thumb2', 'thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('thumb3', 'thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('wrist', 'forefinger1'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('forefinger1', 'forefinger2'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('forefinger2', 'forefinger3'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('forefinger3', 'forefinger4'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('wrist', 'middle_finger1'), id=8, color=[102, 178, 255]),\n        9:\n        dict(\n            link=('middle_finger1', 'middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('middle_finger2', 'middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('middle_finger3', 'middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(link=('wrist', 'ring_finger1'), id=12, color=[255, 51, 51]),\n        13:\n        dict(\n            link=('ring_finger1', 'ring_finger2'), id=13, color=[255, 51, 51]),\n        14:\n        dict(\n            link=('ring_finger2', 'ring_finger3'), id=14, color=[255, 51, 51]),\n        15:\n        dict(\n            link=('ring_finger3', 'ring_finger4'), id=15, color=[255, 51, 51]),\n        16:\n        dict(link=('wrist', 'pinky_finger1'), id=16, color=[0, 255, 0]),\n        17:\n        dict(\n            link=('pinky_finger1', 'pinky_finger2'), id=17, color=[0, 255, 0]),\n        18:\n        dict(\n            link=('pinky_finger2', 'pinky_finger3'), id=18, color=[0, 255, 0]),\n        19:\n        dict(\n            link=('pinky_finger3', 'pinky_finger4'), id=19, color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 21,\n    sigmas=[\n        0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024, 0.035, 0.018,\n        0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02, 0.019, 0.022,\n        0.031\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/coco_wholebody_openpose.py",
    "content": "dataset_info = dict(\n    dataset_name='coco_wholebody_openpose',\n    paper_info=dict(\n        author='Jin, Sheng and Xu, Lumin and Xu, Jin and '\n        'Wang, Can and Liu, Wentao and '\n        'Qian, Chen and Ouyang, Wanli and Luo, Ping',\n        title='Whole-Body Human Pose Estimation in the Wild',\n        container='Proceedings of the European '\n        'Conference on Computer Vision (ECCV)',\n        year='2020',\n        homepage='https://github.com/jin-s13/COCO-WholeBody/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[255, 0, 0], type='upper', swap=''),\n        1:\n        dict(name='neck', id=1, color=[255, 85, 0], type='upper', swap=''),\n        2:\n        dict(\n            name='right_shoulder',\n            id=2,\n            color=[255, 170, 0],\n            type='upper',\n            swap='left_shoulder'),\n        3:\n        dict(\n            name='right_elbow',\n            id=3,\n            color=[255, 255, 0],\n            type='upper',\n            swap='left_elbow'),\n        4:\n        dict(\n            name='right_wrist',\n            id=4,\n            color=[170, 255, 0],\n            type='upper',\n            swap='left_wrist'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[85, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='left_elbow',\n            id=6,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        7:\n        dict(\n            name='left_wrist',\n            id=7,\n            color=[0, 255, 85],\n            type='upper',\n            swap='right_wrist'),\n        8:\n        dict(\n            name='right_hip',\n            id=8,\n            color=[0, 255, 170],\n            type='lower',\n            swap='left_hip'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[0, 255, 255],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='right_ankle',\n            id=10,\n            color=[0, 170, 255],\n            type='lower',\n            swap='left_ankle'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 85, 255],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='left_knee',\n            id=12,\n            color=[0, 0, 255],\n            type='lower',\n            swap='right_knee'),\n        13:\n        dict(\n            name='left_ankle',\n            id=13,\n            color=[85, 0, 255],\n            type='lower',\n            swap='right_ankle'),\n        14:\n        dict(\n            name='right_eye',\n            id=14,\n            color=[170, 0, 255],\n            type='upper',\n            swap='left_eye'),\n        15:\n        dict(\n            name='left_eye',\n            id=15,\n            color=[255, 0, 255],\n            type='upper',\n            swap='right_eye'),\n        16:\n        dict(\n            name='right_ear',\n            id=16,\n            color=[255, 0, 170],\n            type='upper',\n            swap='left_ear'),\n        17:\n        dict(\n            name='left_ear',\n            id=17,\n            color=[255, 0, 85],\n            type='upper',\n            swap='right_ear'),\n        18:\n        dict(\n            name='left_big_toe',\n            id=17,\n            color=[0, 0, 0],\n            type='lower',\n            swap='right_big_toe'),\n        19:\n        dict(\n            name='left_small_toe',\n            id=18,\n            color=[0, 0, 0],\n            type='lower',\n            swap='right_small_toe'),\n        20:\n        dict(\n            name='left_heel',\n            id=19,\n            color=[0, 0, 0],\n            type='lower',\n            swap='right_heel'),\n        21:\n        dict(\n            name='right_big_toe',\n            id=20,\n            color=[0, 0, 0],\n            type='lower',\n            swap='left_big_toe'),\n        22:\n        dict(\n            name='right_small_toe',\n            id=21,\n            color=[0, 0, 0],\n            type='lower',\n            swap='left_small_toe'),\n        23:\n        dict(\n            name='right_heel',\n            id=22,\n            color=[0, 0, 0],\n            type='lower',\n            swap='left_heel'),\n        24:\n        dict(\n            name='face-0',\n            id=23,\n            color=[255, 255, 255],\n            type='',\n            swap='face-16'),\n        25:\n        dict(\n            name='face-1',\n            id=24,\n            color=[255, 255, 255],\n            type='',\n            swap='face-15'),\n        26:\n        dict(\n            name='face-2',\n            id=25,\n            color=[255, 255, 255],\n            type='',\n            swap='face-14'),\n        27:\n        dict(\n            name='face-3',\n            id=26,\n            color=[255, 255, 255],\n            type='',\n            swap='face-13'),\n        28:\n        dict(\n            name='face-4',\n            id=27,\n            color=[255, 255, 255],\n            type='',\n            swap='face-12'),\n        29:\n        dict(\n            name='face-5',\n            id=28,\n            color=[255, 255, 255],\n            type='',\n            swap='face-11'),\n        30:\n        dict(\n            name='face-6',\n            id=29,\n            color=[255, 255, 255],\n            type='',\n            swap='face-10'),\n        31:\n        dict(\n            name='face-7',\n            id=30,\n            color=[255, 255, 255],\n            type='',\n            swap='face-9'),\n        32:\n        dict(name='face-8', id=31, color=[255, 255, 255], type='', swap=''),\n        33:\n        dict(\n            name='face-9',\n            id=32,\n            color=[255, 255, 255],\n            type='',\n            swap='face-7'),\n        34:\n        dict(\n            name='face-10',\n            id=33,\n            color=[255, 255, 255],\n            type='',\n            swap='face-6'),\n        35:\n        dict(\n            name='face-11',\n            id=34,\n            color=[255, 255, 255],\n            type='',\n            swap='face-5'),\n        36:\n        dict(\n            name='face-12',\n            id=35,\n            color=[255, 255, 255],\n            type='',\n            swap='face-4'),\n        37:\n        dict(\n            name='face-13',\n            id=36,\n            color=[255, 255, 255],\n            type='',\n            swap='face-3'),\n        38:\n        dict(\n            name='face-14',\n            id=37,\n            color=[255, 255, 255],\n            type='',\n            swap='face-2'),\n        39:\n        dict(\n            name='face-15',\n            id=38,\n            color=[255, 255, 255],\n            type='',\n            swap='face-1'),\n        40:\n        dict(\n            name='face-16',\n            id=39,\n            color=[255, 255, 255],\n            type='',\n            swap='face-0'),\n        41:\n        dict(\n            name='face-17',\n            id=40,\n            color=[255, 255, 255],\n            type='',\n            swap='face-26'),\n        42:\n        dict(\n            name='face-18',\n            id=41,\n            color=[255, 255, 255],\n            type='',\n            swap='face-25'),\n        43:\n        dict(\n            name='face-19',\n            id=42,\n            color=[255, 255, 255],\n            type='',\n            swap='face-24'),\n        44:\n        dict(\n            name='face-20',\n            id=43,\n            color=[255, 255, 255],\n            type='',\n            swap='face-23'),\n        45:\n        dict(\n            name='face-21',\n            id=44,\n            color=[255, 255, 255],\n            type='',\n            swap='face-22'),\n        46:\n        dict(\n            name='face-22',\n            id=45,\n            color=[255, 255, 255],\n            type='',\n            swap='face-21'),\n        47:\n        dict(\n            name='face-23',\n            id=46,\n            color=[255, 255, 255],\n            type='',\n            swap='face-20'),\n        48:\n        dict(\n            name='face-24',\n            id=47,\n            color=[255, 255, 255],\n            type='',\n            swap='face-19'),\n        49:\n        dict(\n            name='face-25',\n            id=48,\n            color=[255, 255, 255],\n            type='',\n            swap='face-18'),\n        50:\n        dict(\n            name='face-26',\n            id=49,\n            color=[255, 255, 255],\n            type='',\n            swap='face-17'),\n        51:\n        dict(name='face-27', id=50, color=[255, 255, 255], type='', swap=''),\n        52:\n        dict(name='face-28', id=51, color=[255, 255, 255], type='', swap=''),\n        53:\n        dict(name='face-29', id=52, color=[255, 255, 255], type='', swap=''),\n        54:\n        dict(name='face-30', id=53, color=[255, 255, 255], type='', swap=''),\n        55:\n        dict(\n            name='face-31',\n            id=54,\n            color=[255, 255, 255],\n            type='',\n            swap='face-35'),\n        56:\n        dict(\n            name='face-32',\n            id=55,\n            color=[255, 255, 255],\n            type='',\n            swap='face-34'),\n        57:\n        dict(name='face-33', id=56, color=[255, 255, 255], type='', swap=''),\n        58:\n        dict(\n            name='face-34',\n            id=57,\n            color=[255, 255, 255],\n            type='',\n            swap='face-32'),\n        59:\n        dict(\n            name='face-35',\n            id=58,\n            color=[255, 255, 255],\n            type='',\n            swap='face-31'),\n        60:\n        dict(\n            name='face-36',\n            id=59,\n            color=[255, 255, 255],\n            type='',\n            swap='face-45'),\n        61:\n        dict(\n            name='face-37',\n            id=60,\n            color=[255, 255, 255],\n            type='',\n            swap='face-44'),\n        62:\n        dict(\n            name='face-38',\n            id=61,\n            color=[255, 255, 255],\n            type='',\n            swap='face-43'),\n        63:\n        dict(\n            name='face-39',\n            id=62,\n            color=[255, 255, 255],\n            type='',\n            swap='face-42'),\n        64:\n        dict(\n            name='face-40',\n            id=63,\n            color=[255, 255, 255],\n            type='',\n            swap='face-47'),\n        65:\n        dict(\n            name='face-41',\n            id=64,\n            color=[255, 255, 255],\n            type='',\n            swap='face-46'),\n        66:\n        dict(\n            name='face-42',\n            id=65,\n            color=[255, 255, 255],\n            type='',\n            swap='face-39'),\n        67:\n        dict(\n            name='face-43',\n            id=66,\n            color=[255, 255, 255],\n            type='',\n            swap='face-38'),\n        68:\n        dict(\n            name='face-44',\n            id=67,\n            color=[255, 255, 255],\n            type='',\n            swap='face-37'),\n        69:\n        dict(\n            name='face-45',\n            id=68,\n            color=[255, 255, 255],\n            type='',\n            swap='face-36'),\n        70:\n        dict(\n            name='face-46',\n            id=69,\n            color=[255, 255, 255],\n            type='',\n            swap='face-41'),\n        71:\n        dict(\n            name='face-47',\n            id=70,\n            color=[255, 255, 255],\n            type='',\n            swap='face-40'),\n        72:\n        dict(\n            name='face-48',\n            id=71,\n            color=[255, 255, 255],\n            type='',\n            swap='face-54'),\n        73:\n        dict(\n            name='face-49',\n            id=72,\n            color=[255, 255, 255],\n            type='',\n            swap='face-53'),\n        74:\n        dict(\n            name='face-50',\n            id=73,\n            color=[255, 255, 255],\n            type='',\n            swap='face-52'),\n        75:\n        dict(name='face-51', id=74, color=[255, 255, 255], type='', swap=''),\n        76:\n        dict(\n            name='face-52',\n            id=75,\n            color=[255, 255, 255],\n            type='',\n            swap='face-50'),\n        77:\n        dict(\n            name='face-53',\n            id=76,\n            color=[255, 255, 255],\n            type='',\n            swap='face-49'),\n        78:\n        dict(\n            name='face-54',\n            id=77,\n            color=[255, 255, 255],\n            type='',\n            swap='face-48'),\n        79:\n        dict(\n            name='face-55',\n            id=78,\n            color=[255, 255, 255],\n            type='',\n            swap='face-59'),\n        80:\n        dict(\n            name='face-56',\n            id=79,\n            color=[255, 255, 255],\n            type='',\n            swap='face-58'),\n        81:\n        dict(name='face-57', id=80, color=[255, 255, 255], type='', swap=''),\n        82:\n        dict(\n            name='face-58',\n            id=81,\n            color=[255, 255, 255],\n            type='',\n            swap='face-56'),\n        83:\n        dict(\n            name='face-59',\n            id=82,\n            color=[255, 255, 255],\n            type='',\n            swap='face-55'),\n        84:\n        dict(\n            name='face-60',\n            id=83,\n            color=[255, 255, 255],\n            type='',\n            swap='face-64'),\n        85:\n        dict(\n            name='face-61',\n            id=84,\n            color=[255, 255, 255],\n            type='',\n            swap='face-63'),\n        86:\n        dict(name='face-62', id=85, color=[255, 255, 255], type='', swap=''),\n        87:\n        dict(\n            name='face-63',\n            id=86,\n            color=[255, 255, 255],\n            type='',\n            swap='face-61'),\n        88:\n        dict(\n            name='face-64',\n            id=87,\n            color=[255, 255, 255],\n            type='',\n            swap='face-60'),\n        89:\n        dict(\n            name='face-65',\n            id=88,\n            color=[255, 255, 255],\n            type='',\n            swap='face-67'),\n        90:\n        dict(name='face-66', id=89, color=[255, 255, 255], type='', swap=''),\n        91:\n        dict(\n            name='face-67',\n            id=90,\n            color=[255, 255, 255],\n            type='',\n            swap='face-65'),\n        92:\n        dict(\n            name='left_hand_root',\n            id=92,\n            color=[0, 0, 255],\n            type='',\n            swap='right_hand_root'),\n        93:\n        dict(\n            name='left_thumb1',\n            id=93,\n            color=[0, 0, 255],\n            type='',\n            swap='right_thumb1'),\n        94:\n        dict(\n            name='left_thumb2',\n            id=94,\n            color=[0, 0, 255],\n            type='',\n            swap='right_thumb2'),\n        95:\n        dict(\n            name='left_thumb3',\n            id=95,\n            color=[0, 0, 255],\n            type='',\n            swap='right_thumb3'),\n        96:\n        dict(\n            name='left_thumb4',\n            id=96,\n            color=[0, 0, 255],\n            type='',\n            swap='right_thumb4'),\n        97:\n        dict(\n            name='left_forefinger1',\n            id=97,\n            color=[0, 0, 255],\n            type='',\n            swap='right_forefinger1'),\n        98:\n        dict(\n            name='left_forefinger2',\n            id=98,\n            color=[0, 0, 255],\n            type='',\n            swap='right_forefinger2'),\n        99:\n        dict(\n            name='left_forefinger3',\n            id=99,\n            color=[0, 0, 255],\n            type='',\n            swap='right_forefinger3'),\n        100:\n        dict(\n            name='left_forefinger4',\n            id=100,\n            color=[0, 0, 255],\n            type='',\n            swap='right_forefinger4'),\n        101:\n        dict(\n            name='left_middle_finger1',\n            id=101,\n            color=[0, 0, 255],\n            type='',\n            swap='right_middle_finger1'),\n        102:\n        dict(\n            name='left_middle_finger2',\n            id=102,\n            color=[0, 0, 255],\n            type='',\n            swap='right_middle_finger2'),\n        103:\n        dict(\n            name='left_middle_finger3',\n            id=103,\n            color=[0, 0, 255],\n            type='',\n            swap='right_middle_finger3'),\n        104:\n        dict(\n            name='left_middle_finger4',\n            id=104,\n            color=[0, 0, 255],\n            type='',\n            swap='right_middle_finger4'),\n        105:\n        dict(\n            name='left_ring_finger1',\n            id=105,\n            color=[0, 0, 255],\n            type='',\n            swap='right_ring_finger1'),\n        106:\n        dict(\n            name='left_ring_finger2',\n            id=106,\n            color=[0, 0, 255],\n            type='',\n            swap='right_ring_finger2'),\n        107:\n        dict(\n            name='left_ring_finger3',\n            id=107,\n            color=[0, 0, 255],\n            type='',\n            swap='right_ring_finger3'),\n        108:\n        dict(\n            name='left_ring_finger4',\n            id=108,\n            color=[0, 0, 255],\n            type='',\n            swap='right_ring_finger4'),\n        109:\n        dict(\n            name='left_pinky_finger1',\n            id=109,\n            color=[0, 0, 255],\n            type='',\n            swap='right_pinky_finger1'),\n        110:\n        dict(\n            name='left_pinky_finger2',\n            id=110,\n            color=[0, 0, 255],\n            type='',\n            swap='right_pinky_finger2'),\n        111:\n        dict(\n            name='left_pinky_finger3',\n            id=111,\n            color=[0, 0, 255],\n            type='',\n            swap='right_pinky_finger3'),\n        112:\n        dict(\n            name='left_pinky_finger4',\n            id=112,\n            color=[0, 0, 255],\n            type='',\n            swap='right_pinky_finger4'),\n        113:\n        dict(\n            name='right_hand_root',\n            id=113,\n            color=[0, 0, 255],\n            type='',\n            swap='left_hand_root'),\n        114:\n        dict(\n            name='right_thumb1',\n            id=114,\n            color=[0, 0, 255],\n            type='',\n            swap='left_thumb1'),\n        115:\n        dict(\n            name='right_thumb2',\n            id=115,\n            color=[0, 0, 255],\n            type='',\n            swap='left_thumb2'),\n        116:\n        dict(\n            name='right_thumb3',\n            id=116,\n            color=[0, 0, 255],\n            type='',\n            swap='left_thumb3'),\n        117:\n        dict(\n            name='right_thumb4',\n            id=117,\n            color=[0, 0, 255],\n            type='',\n            swap='left_thumb4'),\n        118:\n        dict(\n            name='right_forefinger1',\n            id=118,\n            color=[0, 0, 255],\n            type='',\n            swap='left_forefinger1'),\n        119:\n        dict(\n            name='right_forefinger2',\n            id=119,\n            color=[0, 0, 255],\n            type='',\n            swap='left_forefinger2'),\n        120:\n        dict(\n            name='right_forefinger3',\n            id=120,\n            color=[0, 0, 255],\n            type='',\n            swap='left_forefinger3'),\n        121:\n        dict(\n            name='right_forefinger4',\n            id=121,\n            color=[0, 0, 255],\n            type='',\n            swap='left_forefinger4'),\n        122:\n        dict(\n            name='right_middle_finger1',\n            id=122,\n            color=[0, 0, 255],\n            type='',\n            swap='left_middle_finger1'),\n        123:\n        dict(\n            name='right_middle_finger2',\n            id=123,\n            color=[0, 0, 255],\n            type='',\n            swap='left_middle_finger2'),\n        124:\n        dict(\n            name='right_middle_finger3',\n            id=124,\n            color=[0, 0, 255],\n            type='',\n            swap='left_middle_finger3'),\n        125:\n        dict(\n            name='right_middle_finger4',\n            id=125,\n            color=[0, 0, 255],\n            type='',\n            swap='left_middle_finger4'),\n        126:\n        dict(\n            name='right_ring_finger1',\n            id=126,\n            color=[0, 0, 255],\n            type='',\n            swap='left_ring_finger1'),\n        127:\n        dict(\n            name='right_ring_finger2',\n            id=127,\n            color=[0, 0, 255],\n            type='',\n            swap='left_ring_finger2'),\n        128:\n        dict(\n            name='right_ring_finger3',\n            id=128,\n            color=[0, 0, 255],\n            type='',\n            swap='left_ring_finger3'),\n        129:\n        dict(\n            name='right_ring_finger4',\n            id=129,\n            color=[0, 0, 255],\n            type='',\n            swap='left_ring_finger4'),\n        130:\n        dict(\n            name='right_pinky_finger1',\n            id=130,\n            color=[0, 0, 255],\n            type='',\n            swap='left_pinky_finger1'),\n        131:\n        dict(\n            name='right_pinky_finger2',\n            id=131,\n            color=[0, 0, 255],\n            type='',\n            swap='left_pinky_finger2'),\n        132:\n        dict(\n            name='right_pinky_finger3',\n            id=132,\n            color=[0, 0, 255],\n            type='',\n            swap='left_pinky_finger3'),\n        133:\n        dict(\n            name='right_pinky_finger4',\n            id=133,\n            color=[0, 0, 255],\n            type='',\n            swap='left_pinky_finger4')\n    },\n    skeleton_info={\n        0:\n        dict(link=('neck', 'right_shoulder'), id=0, color=[255, 0, 0]),\n        1:\n        dict(link=('neck', 'left_shoulder'), id=1, color=[255, 85, 0]),\n        2:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=2, color=[255, 170, 0]),\n        3:\n        dict(link=('right_elbow', 'right_wrist'), id=3, color=[255, 255, 0]),\n        4:\n        dict(link=('left_shoulder', 'left_elbow'), id=4, color=[170, 255, 0]),\n        5:\n        dict(link=('left_elbow', 'left_wrist'), id=5, color=[85, 255, 0]),\n        6:\n        dict(link=('neck', 'right_hip'), id=6, color=[0, 255, 0]),\n        7:\n        dict(link=('right_hip', 'right_knee'), id=7, color=[0, 255, 85]),\n        8:\n        dict(link=('right_knee', 'right_ankle'), id=8, color=[0, 255, 170]),\n        9:\n        dict(link=('neck', 'left_hip'), id=9, color=[0, 255, 225]),\n        10:\n        dict(link=('left_hip', 'left_knee'), id=10, color=[0, 170, 255]),\n        11:\n        dict(link=('left_knee', 'left_ankle'), id=11, color=[0, 85, 255]),\n        12:\n        dict(link=('neck', 'nose'), id=12, color=[0, 0, 255]),\n        13:\n        dict(link=('nose', 'right_eye'), id=13, color=[255, 0, 170]),\n        14:\n        dict(link=('right_eye', 'right_ear'), id=14, color=[170, 0, 255]),\n        15:\n        dict(link=('nose', 'left_eye'), id=15, color=[255, 0, 255]),\n        16:\n        dict(link=('left_eye', 'left_ear'), id=16, color=[255, 0, 170]),\n        17:\n        dict(link=('left_hand_root', 'left_thumb1'), id=17, color=[255, 0, 0]),\n        18:\n        dict(link=('left_thumb1', 'left_thumb2'), id=18, color=[255, 76, 0]),\n        19:\n        dict(link=('left_thumb2', 'left_thumb3'), id=19, color=[255, 153, 0]),\n        20:\n        dict(link=('left_thumb3', 'left_thumb4'), id=20, color=[255, 230, 0]),\n        21:\n        dict(\n            link=('left_hand_root', 'left_forefinger1'),\n            id=21,\n            color=[204, 255, 0]),\n        22:\n        dict(\n            link=('left_forefinger1', 'left_forefinger2'),\n            id=22,\n            color=[128, 255, 0]),\n        23:\n        dict(\n            link=('left_forefinger2', 'left_forefinger3'),\n            id=23,\n            color=[51, 255, 0]),\n        24:\n        dict(\n            link=('left_forefinger3', 'left_forefinger4'),\n            id=24,\n            color=[0, 255, 26]),\n        25:\n        dict(\n            link=('left_hand_root', 'left_middle_finger1'),\n            id=25,\n            color=[0, 255, 102]),\n        26:\n        dict(\n            link=('left_middle_finger1', 'left_middle_finger2'),\n            id=26,\n            color=[0, 255, 178]),\n        27:\n        dict(\n            link=('left_middle_finger2', 'left_middle_finger3'),\n            id=27,\n            color=[0, 255, 255]),\n        28:\n        dict(\n            link=('left_middle_finger3', 'left_middle_finger4'),\n            id=28,\n            color=[0, 178, 255]),\n        29:\n        dict(\n            link=('left_hand_root', 'left_ring_finger1'),\n            id=29,\n            color=[0, 102, 255]),\n        30:\n        dict(\n            link=('left_ring_finger1', 'left_ring_finger2'),\n            id=30,\n            color=[0, 26, 255]),\n        31:\n        dict(\n            link=('left_ring_finger2', 'left_ring_finger3'),\n            id=31,\n            color=[51, 0, 255]),\n        32:\n        dict(\n            link=('left_ring_finger3', 'left_ring_finger4'),\n            id=32,\n            color=[128, 0, 255]),\n        33:\n        dict(\n            link=('left_hand_root', 'left_pinky_finger1'),\n            id=33,\n            color=[204, 0, 255]),\n        34:\n        dict(\n            link=('left_pinky_finger1', 'left_pinky_finger2'),\n            id=34,\n            color=[255, 0, 230]),\n        35:\n        dict(\n            link=('left_pinky_finger2', 'left_pinky_finger3'),\n            id=35,\n            color=[255, 0, 153]),\n        36:\n        dict(\n            link=('left_pinky_finger3', 'left_pinky_finger4'),\n            id=36,\n            color=[255, 0, 76]),\n        37:\n        dict(\n            link=('right_hand_root', 'right_thumb1'), id=37, color=[255, 0,\n                                                                    0]),\n        38:\n        dict(link=('right_thumb1', 'right_thumb2'), id=38, color=[255, 76, 0]),\n        39:\n        dict(\n            link=('right_thumb2', 'right_thumb3'), id=39, color=[255, 153, 0]),\n        40:\n        dict(\n            link=('right_thumb3', 'right_thumb4'), id=40, color=[255, 230, 0]),\n        41:\n        dict(\n            link=('right_hand_root', 'right_forefinger1'),\n            id=41,\n            color=[204, 255, 0]),\n        42:\n        dict(\n            link=('right_forefinger1', 'right_forefinger2'),\n            id=42,\n            color=[128, 255, 0]),\n        43:\n        dict(\n            link=('right_forefinger2', 'right_forefinger3'),\n            id=43,\n            color=[51, 255, 0]),\n        44:\n        dict(\n            link=('right_forefinger3', 'right_forefinger4'),\n            id=44,\n            color=[0, 255, 26]),\n        45:\n        dict(\n            link=('right_hand_root', 'right_middle_finger1'),\n            id=45,\n            color=[0, 255, 102]),\n        46:\n        dict(\n            link=('right_middle_finger1', 'right_middle_finger2'),\n            id=46,\n            color=[0, 255, 178]),\n        47:\n        dict(\n            link=('right_middle_finger2', 'right_middle_finger3'),\n            id=47,\n            color=[255, 255, 255]),\n        48:\n        dict(\n            link=('right_middle_finger3', 'right_middle_finger4'),\n            id=48,\n            color=[0, 178, 255]),\n        49:\n        dict(\n            link=('right_hand_root', 'right_ring_finger1'),\n            id=49,\n            color=[0, 102, 255]),\n        50:\n        dict(\n            link=('right_ring_finger1', 'right_ring_finger2'),\n            id=50,\n            color=[0, 26, 255]),\n        51:\n        dict(\n            link=('right_ring_finger2', 'right_ring_finger3'),\n            id=51,\n            color=[51, 0, 255]),\n        52:\n        dict(\n            link=('right_ring_finger3', 'right_ring_finger4'),\n            id=52,\n            color=[128, 0, 255]),\n        53:\n        dict(\n            link=('right_hand_root', 'right_pinky_finger1'),\n            id=53,\n            color=[204, 0, 255]),\n        54:\n        dict(\n            link=('right_pinky_finger1', 'right_pinky_finger2'),\n            id=54,\n            color=[255, 0, 230]),\n        55:\n        dict(\n            link=('right_pinky_finger2', 'right_pinky_finger3'),\n            id=55,\n            color=[255, 0, 153]),\n        56:\n        dict(\n            link=('right_pinky_finger3', 'right_pinky_finger4'),\n            id=56,\n            color=[255, 0, 76])\n    },\n    joint_weights=[1.] * 134,\n    # 'https://github.com/jin-s13/COCO-WholeBody/blob/master/'\n    # 'evaluation/myeval_wholebody.py#L175'\n    sigmas=[\n        0.026, 0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072,\n        0.062, 0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.068, 0.066,\n        0.066, 0.092, 0.094, 0.094, 0.042, 0.043, 0.044, 0.043, 0.040, 0.035,\n        0.031, 0.025, 0.020, 0.023, 0.029, 0.032, 0.037, 0.038, 0.043, 0.041,\n        0.045, 0.013, 0.012, 0.011, 0.011, 0.012, 0.012, 0.011, 0.011, 0.013,\n        0.015, 0.009, 0.007, 0.007, 0.007, 0.012, 0.009, 0.008, 0.016, 0.010,\n        0.017, 0.011, 0.009, 0.011, 0.009, 0.007, 0.013, 0.008, 0.011, 0.012,\n        0.010, 0.034, 0.008, 0.008, 0.009, 0.008, 0.008, 0.007, 0.010, 0.008,\n        0.009, 0.009, 0.009, 0.007, 0.007, 0.008, 0.011, 0.008, 0.008, 0.008,\n        0.01, 0.008, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024,\n        0.035, 0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02,\n        0.019, 0.022, 0.031, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025,\n        0.024, 0.035, 0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032,\n        0.02, 0.019, 0.022, 0.031\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/cofw.py",
    "content": "dataset_info = dict(\n    dataset_name='cofw',\n    paper_info=dict(\n        author='Burgos-Artizzu, Xavier P and Perona, '\n        r'Pietro and Doll{\\'a}r, Piotr',\n        title='Robust face landmark estimation under occlusion',\n        container='Proceedings of the IEEE international '\n        'conference on computer vision',\n        year='2013',\n        homepage='http://www.vision.caltech.edu/xpburgos/ICCV13/',\n    ),\n    keypoint_info={\n        0: dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap='kpt-1'),\n        1: dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap='kpt-0'),\n        2: dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap='kpt-3'),\n        3: dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap='kpt-2'),\n        4: dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap='kpt-6'),\n        5: dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap='kpt-7'),\n        6: dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap='kpt-4'),\n        7: dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap='kpt-5'),\n        8: dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap='kpt-9'),\n        9: dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap='kpt-8'),\n        10:\n        dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap='kpt-11'),\n        11:\n        dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap='kpt-10'),\n        12:\n        dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap='kpt-14'),\n        13:\n        dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap='kpt-15'),\n        14:\n        dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap='kpt-12'),\n        15:\n        dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap='kpt-13'),\n        16:\n        dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap='kpt-17'),\n        17:\n        dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap='kpt-16'),\n        18:\n        dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap='kpt-19'),\n        19:\n        dict(name='kpt-19', id=19, color=[255, 0, 0], type='', swap='kpt-18'),\n        20: dict(name='kpt-20', id=20, color=[255, 0, 0], type='', swap=''),\n        21: dict(name='kpt-21', id=21, color=[255, 0, 0], type='', swap=''),\n        22:\n        dict(name='kpt-22', id=22, color=[255, 0, 0], type='', swap='kpt-23'),\n        23:\n        dict(name='kpt-23', id=23, color=[255, 0, 0], type='', swap='kpt-22'),\n        24: dict(name='kpt-24', id=24, color=[255, 0, 0], type='', swap=''),\n        25: dict(name='kpt-25', id=25, color=[255, 0, 0], type='', swap=''),\n        26: dict(name='kpt-26', id=26, color=[255, 0, 0], type='', swap=''),\n        27: dict(name='kpt-27', id=27, color=[255, 0, 0], type='', swap=''),\n        28: dict(name='kpt-28', id=28, color=[255, 0, 0], type='', swap='')\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 29,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/crowdpose.py",
    "content": "dataset_info = dict(\n    dataset_name='crowdpose',\n    paper_info=dict(\n        author='Li, Jiefeng and Wang, Can and Zhu, Hao and '\n        'Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu',\n        title='CrowdPose: Efficient Crowded Scenes Pose Estimation '\n        'and A New Benchmark',\n        container='Proceedings of IEEE Conference on Computer '\n        'Vision and Pattern Recognition (CVPR)',\n        year='2019',\n        homepage='https://github.com/Jeff-sjtu/CrowdPose',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left_shoulder',\n            id=0,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_shoulder'),\n        1:\n        dict(\n            name='right_shoulder',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_shoulder'),\n        2:\n        dict(\n            name='left_elbow',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_elbow'),\n        3:\n        dict(\n            name='right_elbow',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_elbow'),\n        4:\n        dict(\n            name='left_wrist',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_wrist'),\n        5:\n        dict(\n            name='right_wrist',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='left_wrist'),\n        6:\n        dict(\n            name='left_hip',\n            id=6,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_hip'),\n        7:\n        dict(\n            name='right_hip',\n            id=7,\n            color=[0, 255, 0],\n            type='lower',\n            swap='left_hip'),\n        8:\n        dict(\n            name='left_knee',\n            id=8,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_knee'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[0, 255, 0],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='left_ankle',\n            id=10,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_ankle'),\n        11:\n        dict(\n            name='right_ankle',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='left_ankle'),\n        12:\n        dict(\n            name='top_head', id=12, color=[255, 128, 0], type='upper',\n            swap=''),\n        13:\n        dict(name='neck', id=13, color=[0, 255, 0], type='upper', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('top_head', 'neck'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('right_shoulder', 'neck'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('left_shoulder', 'neck'), id=14, color=[51, 153, 255])\n    },\n    joint_weights=[\n        0.2, 0.2, 0.2, 1.3, 1.5, 0.2, 1.3, 1.5, 0.2, 0.2, 0.5, 0.2, 0.2, 0.5\n    ],\n    sigmas=[\n        0.079, 0.079, 0.072, 0.072, 0.062, 0.062, 0.107, 0.107, 0.087, 0.087,\n        0.089, 0.089, 0.079, 0.079\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/deepfashion2.py",
    "content": "colors = dict(\n    sss=[255, 128, 0],  # short_sleeve_shirt\n    lss=[255, 0, 128],  # long_sleeved_shirt\n    sso=[128, 0, 255],  # short_sleeved_outwear\n    lso=[0, 128, 255],  # long_sleeved_outwear\n    vest=[0, 128, 128],  # vest\n    sling=[0, 0, 128],  # sling\n    shorts=[128, 128, 128],  # shorts\n    trousers=[128, 0, 128],  # trousers\n    skirt=[64, 128, 128],  # skirt\n    ssd=[64, 64, 128],  # short_sleeved_dress\n    lsd=[128, 64, 0],  # long_sleeved_dress\n    vd=[128, 64, 255],  # vest_dress\n    sd=[128, 64, 0],  # sling_dress\n)\ndataset_info = dict(\n    dataset_name='deepfashion2',\n    paper_info=dict(\n        author='Yuying Ge and Ruimao Zhang and Lingyun Wu '\n        'and Xiaogang Wang and Xiaoou Tang and Ping Luo',\n        title='DeepFashion2: A Versatile Benchmark for '\n        'Detection, Pose Estimation, Segmentation and '\n        'Re-Identification of Clothing Images',\n        container='Proceedings of IEEE Conference on Computer '\n        'Vision and Pattern Recognition (CVPR)',\n        year='2019',\n        homepage='https://github.com/switchablenorms/DeepFashion2',\n    ),\n    keypoint_info={\n        # short_sleeved_shirt\n        0:\n        dict(name='sss_kpt1', id=0, color=colors['sss'], type='', swap=''),\n        1:\n        dict(\n            name='sss_kpt2',\n            id=1,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt6'),\n        2:\n        dict(\n            name='sss_kpt3',\n            id=2,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt5'),\n        3:\n        dict(name='sss_kpt4', id=3, color=colors['sss'], type='', swap=''),\n        4:\n        dict(\n            name='sss_kpt5',\n            id=4,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt3'),\n        5:\n        dict(\n            name='sss_kpt6',\n            id=5,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt2'),\n        6:\n        dict(\n            name='sss_kpt7',\n            id=6,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt25'),\n        7:\n        dict(\n            name='sss_kpt8',\n            id=7,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt24'),\n        8:\n        dict(\n            name='sss_kpt9',\n            id=8,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt23'),\n        9:\n        dict(\n            name='sss_kpt10',\n            id=9,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt22'),\n        10:\n        dict(\n            name='sss_kpt11',\n            id=10,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt21'),\n        11:\n        dict(\n            name='sss_kpt12',\n            id=11,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt20'),\n        12:\n        dict(\n            name='sss_kpt13',\n            id=12,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt19'),\n        13:\n        dict(\n            name='sss_kpt14',\n            id=13,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt18'),\n        14:\n        dict(\n            name='sss_kpt15',\n            id=14,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt17'),\n        15:\n        dict(name='sss_kpt16', id=15, color=colors['sss'], type='', swap=''),\n        16:\n        dict(\n            name='sss_kpt17',\n            id=16,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt15'),\n        17:\n        dict(\n            name='sss_kpt18',\n            id=17,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt14'),\n        18:\n        dict(\n            name='sss_kpt19',\n            id=18,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt13'),\n        19:\n        dict(\n            name='sss_kpt20',\n            id=19,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt12'),\n        20:\n        dict(\n            name='sss_kpt21',\n            id=20,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt11'),\n        21:\n        dict(\n            name='sss_kpt22',\n            id=21,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt10'),\n        22:\n        dict(\n            name='sss_kpt23',\n            id=22,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt9'),\n        23:\n        dict(\n            name='sss_kpt24',\n            id=23,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt8'),\n        24:\n        dict(\n            name='sss_kpt25',\n            id=24,\n            color=colors['sss'],\n            type='',\n            swap='sss_kpt7'),\n        # long_sleeved_shirt\n        25:\n        dict(name='lss_kpt1', id=25, color=colors['lss'], type='', swap=''),\n        26:\n        dict(\n            name='lss_kpt2',\n            id=26,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt6'),\n        27:\n        dict(\n            name='lss_kpt3',\n            id=27,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt5'),\n        28:\n        dict(name='lss_kpt4', id=28, color=colors['lss'], type='', swap=''),\n        29:\n        dict(\n            name='lss_kpt5',\n            id=29,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt3'),\n        30:\n        dict(\n            name='lss_kpt6',\n            id=30,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt2'),\n        31:\n        dict(\n            name='lss_kpt7',\n            id=31,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt33'),\n        32:\n        dict(\n            name='lss_kpt8',\n            id=32,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt32'),\n        33:\n        dict(\n            name='lss_kpt9',\n            id=33,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt31'),\n        34:\n        dict(\n            name='lss_kpt10',\n            id=34,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt30'),\n        35:\n        dict(\n            name='lss_kpt11',\n            id=35,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt29'),\n        36:\n        dict(\n            name='lss_kpt12',\n            id=36,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt28'),\n        37:\n        dict(\n            name='lss_kpt13',\n            id=37,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt27'),\n        38:\n        dict(\n            name='lss_kpt14',\n            id=38,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt26'),\n        39:\n        dict(\n            name='lss_kpt15',\n            id=39,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt25'),\n        40:\n        dict(\n            name='lss_kpt16',\n            id=40,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt24'),\n        41:\n        dict(\n            name='lss_kpt17',\n            id=41,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt23'),\n        42:\n        dict(\n            name='lss_kpt18',\n            id=42,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt22'),\n        43:\n        dict(\n            name='lss_kpt19',\n            id=43,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt21'),\n        44:\n        dict(name='lss_kpt20', id=44, color=colors['lss'], type='', swap=''),\n        45:\n        dict(\n            name='lss_kpt21',\n            id=45,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt19'),\n        46:\n        dict(\n            name='lss_kpt22',\n            id=46,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt18'),\n        47:\n        dict(\n            name='lss_kpt23',\n            id=47,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt17'),\n        48:\n        dict(\n            name='lss_kpt24',\n            id=48,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt16'),\n        49:\n        dict(\n            name='lss_kpt25',\n            id=49,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt15'),\n        50:\n        dict(\n            name='lss_kpt26',\n            id=50,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt14'),\n        51:\n        dict(\n            name='lss_kpt27',\n            id=51,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt13'),\n        52:\n        dict(\n            name='lss_kpt28',\n            id=52,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt12'),\n        53:\n        dict(\n            name='lss_kpt29',\n            id=53,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt11'),\n        54:\n        dict(\n            name='lss_kpt30',\n            id=54,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt10'),\n        55:\n        dict(\n            name='lss_kpt31',\n            id=55,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt9'),\n        56:\n        dict(\n            name='lss_kpt32',\n            id=56,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt8'),\n        57:\n        dict(\n            name='lss_kpt33',\n            id=57,\n            color=colors['lss'],\n            type='',\n            swap='lss_kpt7'),\n        # short_sleeved_outwear\n        58:\n        dict(name='sso_kpt1', id=58, color=colors['sso'], type='', swap=''),\n        59:\n        dict(\n            name='sso_kpt2',\n            id=59,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt26'),\n        60:\n        dict(\n            name='sso_kpt3',\n            id=60,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt5'),\n        61:\n        dict(\n            name='sso_kpt4',\n            id=61,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt6'),\n        62:\n        dict(\n            name='sso_kpt5',\n            id=62,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt3'),\n        63:\n        dict(\n            name='sso_kpt6',\n            id=63,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt4'),\n        64:\n        dict(\n            name='sso_kpt7',\n            id=64,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt25'),\n        65:\n        dict(\n            name='sso_kpt8',\n            id=65,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt24'),\n        66:\n        dict(\n            name='sso_kpt9',\n            id=66,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt23'),\n        67:\n        dict(\n            name='sso_kpt10',\n            id=67,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt22'),\n        68:\n        dict(\n            name='sso_kpt11',\n            id=68,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt21'),\n        69:\n        dict(\n            name='sso_kpt12',\n            id=69,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt20'),\n        70:\n        dict(\n            name='sso_kpt13',\n            id=70,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt19'),\n        71:\n        dict(\n            name='sso_kpt14',\n            id=71,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt18'),\n        72:\n        dict(\n            name='sso_kpt15',\n            id=72,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt17'),\n        73:\n        dict(\n            name='sso_kpt16',\n            id=73,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt29'),\n        74:\n        dict(\n            name='sso_kpt17',\n            id=74,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt15'),\n        75:\n        dict(\n            name='sso_kpt18',\n            id=75,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt14'),\n        76:\n        dict(\n            name='sso_kpt19',\n            id=76,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt13'),\n        77:\n        dict(\n            name='sso_kpt20',\n            id=77,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt12'),\n        78:\n        dict(\n            name='sso_kpt21',\n            id=78,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt11'),\n        79:\n        dict(\n            name='sso_kpt22',\n            id=79,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt10'),\n        80:\n        dict(\n            name='sso_kpt23',\n            id=80,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt9'),\n        81:\n        dict(\n            name='sso_kpt24',\n            id=81,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt8'),\n        82:\n        dict(\n            name='sso_kpt25',\n            id=82,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt7'),\n        83:\n        dict(\n            name='sso_kpt26',\n            id=83,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt2'),\n        84:\n        dict(\n            name='sso_kpt27',\n            id=84,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt30'),\n        85:\n        dict(\n            name='sso_kpt28',\n            id=85,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt31'),\n        86:\n        dict(\n            name='sso_kpt29',\n            id=86,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt16'),\n        87:\n        dict(\n            name='sso_kpt30',\n            id=87,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt27'),\n        88:\n        dict(\n            name='sso_kpt31',\n            id=88,\n            color=colors['sso'],\n            type='',\n            swap='sso_kpt28'),\n        # long_sleeved_outwear\n        89:\n        dict(name='lso_kpt1', id=89, color=colors['lso'], type='', swap=''),\n        90:\n        dict(\n            name='lso_kpt2',\n            id=90,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt6'),\n        91:\n        dict(\n            name='lso_kpt3',\n            id=91,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt5'),\n        92:\n        dict(\n            name='lso_kpt4',\n            id=92,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt34'),\n        93:\n        dict(\n            name='lso_kpt5',\n            id=93,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt3'),\n        94:\n        dict(\n            name='lso_kpt6',\n            id=94,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt2'),\n        95:\n        dict(\n            name='lso_kpt7',\n            id=95,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt33'),\n        96:\n        dict(\n            name='lso_kpt8',\n            id=96,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt32'),\n        97:\n        dict(\n            name='lso_kpt9',\n            id=97,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt31'),\n        98:\n        dict(\n            name='lso_kpt10',\n            id=98,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt30'),\n        99:\n        dict(\n            name='lso_kpt11',\n            id=99,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt29'),\n        100:\n        dict(\n            name='lso_kpt12',\n            id=100,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt28'),\n        101:\n        dict(\n            name='lso_kpt13',\n            id=101,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt27'),\n        102:\n        dict(\n            name='lso_kpt14',\n            id=102,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt26'),\n        103:\n        dict(\n            name='lso_kpt15',\n            id=103,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt25'),\n        104:\n        dict(\n            name='lso_kpt16',\n            id=104,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt24'),\n        105:\n        dict(\n            name='lso_kpt17',\n            id=105,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt23'),\n        106:\n        dict(\n            name='lso_kpt18',\n            id=106,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt22'),\n        107:\n        dict(\n            name='lso_kpt19',\n            id=107,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt21'),\n        108:\n        dict(\n            name='lso_kpt20',\n            id=108,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt37'),\n        109:\n        dict(\n            name='lso_kpt21',\n            id=109,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt19'),\n        110:\n        dict(\n            name='lso_kpt22',\n            id=110,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt18'),\n        111:\n        dict(\n            name='lso_kpt23',\n            id=111,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt17'),\n        112:\n        dict(\n            name='lso_kpt24',\n            id=112,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt16'),\n        113:\n        dict(\n            name='lso_kpt25',\n            id=113,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt15'),\n        114:\n        dict(\n            name='lso_kpt26',\n            id=114,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt14'),\n        115:\n        dict(\n            name='lso_kpt27',\n            id=115,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt13'),\n        116:\n        dict(\n            name='lso_kpt28',\n            id=116,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt12'),\n        117:\n        dict(\n            name='lso_kpt29',\n            id=117,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt11'),\n        118:\n        dict(\n            name='lso_kpt30',\n            id=118,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt10'),\n        119:\n        dict(\n            name='lso_kpt31',\n            id=119,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt9'),\n        120:\n        dict(\n            name='lso_kpt32',\n            id=120,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt8'),\n        121:\n        dict(\n            name='lso_kpt33',\n            id=121,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt7'),\n        122:\n        dict(\n            name='lso_kpt34',\n            id=122,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt4'),\n        123:\n        dict(\n            name='lso_kpt35',\n            id=123,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt38'),\n        124:\n        dict(\n            name='lso_kpt36',\n            id=124,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt39'),\n        125:\n        dict(\n            name='lso_kpt37',\n            id=125,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt20'),\n        126:\n        dict(\n            name='lso_kpt38',\n            id=126,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt35'),\n        127:\n        dict(\n            name='lso_kpt39',\n            id=127,\n            color=colors['lso'],\n            type='',\n            swap='lso_kpt36'),\n        # vest\n        128:\n        dict(name='vest_kpt1', id=128, color=colors['vest'], type='', swap=''),\n        129:\n        dict(\n            name='vest_kpt2',\n            id=129,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt6'),\n        130:\n        dict(\n            name='vest_kpt3',\n            id=130,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt5'),\n        131:\n        dict(name='vest_kpt4', id=131, color=colors['vest'], type='', swap=''),\n        132:\n        dict(\n            name='vest_kpt5',\n            id=132,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt3'),\n        133:\n        dict(\n            name='vest_kpt6',\n            id=133,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt2'),\n        134:\n        dict(\n            name='vest_kpt7',\n            id=134,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt15'),\n        135:\n        dict(\n            name='vest_kpt8',\n            id=135,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt14'),\n        136:\n        dict(\n            name='vest_kpt9',\n            id=136,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt13'),\n        137:\n        dict(\n            name='vest_kpt10',\n            id=137,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt12'),\n        138:\n        dict(\n            name='vest_kpt11', id=138, color=colors['vest'], type='', swap=''),\n        139:\n        dict(\n            name='vest_kpt12',\n            id=139,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt10'),\n        140:\n        dict(\n            name='vest_kpt13', id=140, color=colors['vest'], type='', swap=''),\n        141:\n        dict(\n            name='vest_kpt14',\n            id=141,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt8'),\n        142:\n        dict(\n            name='vest_kpt15',\n            id=142,\n            color=colors['vest'],\n            type='',\n            swap='vest_kpt7'),\n        # sling\n        143:\n        dict(\n            name='sling_kpt1', id=143, color=colors['sling'], type='',\n            swap=''),\n        144:\n        dict(\n            name='sling_kpt2',\n            id=144,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt6'),\n        145:\n        dict(\n            name='sling_kpt3',\n            id=145,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt5'),\n        146:\n        dict(\n            name='sling_kpt4', id=146, color=colors['sling'], type='',\n            swap=''),\n        147:\n        dict(\n            name='sling_kpt5',\n            id=147,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt3'),\n        148:\n        dict(\n            name='sling_kpt6',\n            id=148,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt2'),\n        149:\n        dict(\n            name='sling_kpt7',\n            id=149,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt15'),\n        150:\n        dict(\n            name='sling_kpt8',\n            id=150,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt14'),\n        151:\n        dict(\n            name='sling_kpt9',\n            id=151,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt13'),\n        152:\n        dict(\n            name='sling_kpt10',\n            id=152,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt12'),\n        153:\n        dict(\n            name='sling_kpt11',\n            id=153,\n            color=colors['sling'],\n            type='',\n            swap=''),\n        154:\n        dict(\n            name='sling_kpt12',\n            id=154,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt10'),\n        155:\n        dict(\n            name='sling_kpt13',\n            id=155,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt9'),\n        156:\n        dict(\n            name='sling_kpt14',\n            id=156,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt8'),\n        157:\n        dict(\n            name='sling_kpt15',\n            id=157,\n            color=colors['sling'],\n            type='',\n            swap='sling_kpt7'),\n        # shorts\n        158:\n        dict(\n            name='shorts_kpt1',\n            id=158,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt3'),\n        159:\n        dict(\n            name='shorts_kpt2',\n            id=159,\n            color=colors['shorts'],\n            type='',\n            swap=''),\n        160:\n        dict(\n            name='shorts_kpt3',\n            id=160,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt1'),\n        161:\n        dict(\n            name='shorts_kpt4',\n            id=161,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt10'),\n        162:\n        dict(\n            name='shorts_kpt5',\n            id=162,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt9'),\n        163:\n        dict(\n            name='shorts_kpt6',\n            id=163,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt8'),\n        164:\n        dict(\n            name='shorts_kpt7',\n            id=164,\n            color=colors['shorts'],\n            type='',\n            swap=''),\n        165:\n        dict(\n            name='shorts_kpt8',\n            id=165,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt6'),\n        166:\n        dict(\n            name='shorts_kpt9',\n            id=166,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt5'),\n        167:\n        dict(\n            name='shorts_kpt10',\n            id=167,\n            color=colors['shorts'],\n            type='',\n            swap='shorts_kpt4'),\n        # trousers\n        168:\n        dict(\n            name='trousers_kpt1',\n            id=168,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt3'),\n        169:\n        dict(\n            name='trousers_kpt2',\n            id=169,\n            color=colors['trousers'],\n            type='',\n            swap=''),\n        170:\n        dict(\n            name='trousers_kpt3',\n            id=170,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt1'),\n        171:\n        dict(\n            name='trousers_kpt4',\n            id=171,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt14'),\n        172:\n        dict(\n            name='trousers_kpt5',\n            id=172,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt13'),\n        173:\n        dict(\n            name='trousers_kpt6',\n            id=173,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt12'),\n        174:\n        dict(\n            name='trousers_kpt7',\n            id=174,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt11'),\n        175:\n        dict(\n            name='trousers_kpt8',\n            id=175,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt10'),\n        176:\n        dict(\n            name='trousers_kpt9',\n            id=176,\n            color=colors['trousers'],\n            type='',\n            swap=''),\n        177:\n        dict(\n            name='trousers_kpt10',\n            id=177,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt8'),\n        178:\n        dict(\n            name='trousers_kpt11',\n            id=178,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt7'),\n        179:\n        dict(\n            name='trousers_kpt12',\n            id=179,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt6'),\n        180:\n        dict(\n            name='trousers_kpt13',\n            id=180,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt5'),\n        181:\n        dict(\n            name='trousers_kpt14',\n            id=181,\n            color=colors['trousers'],\n            type='',\n            swap='trousers_kpt4'),\n        # skirt\n        182:\n        dict(\n            name='skirt_kpt1',\n            id=182,\n            color=colors['skirt'],\n            type='',\n            swap='skirt_kpt3'),\n        183:\n        dict(\n            name='skirt_kpt2', id=183, color=colors['skirt'], type='',\n            swap=''),\n        184:\n        dict(\n            name='skirt_kpt3',\n            id=184,\n            color=colors['skirt'],\n            type='',\n            swap='skirt_kpt1'),\n        185:\n        dict(\n            name='skirt_kpt4',\n            id=185,\n            color=colors['skirt'],\n            type='',\n            swap='skirt_kpt8'),\n        186:\n        dict(\n            name='skirt_kpt5',\n            id=186,\n            color=colors['skirt'],\n            type='',\n            swap='skirt_kpt7'),\n        187:\n        dict(\n            name='skirt_kpt6', id=187, color=colors['skirt'], type='',\n            swap=''),\n        188:\n        dict(\n            name='skirt_kpt7',\n            id=188,\n            color=colors['skirt'],\n            type='',\n            swap='skirt_kpt5'),\n        189:\n        dict(\n            name='skirt_kpt8',\n            id=189,\n            color=colors['skirt'],\n            type='',\n            swap='skirt_kpt4'),\n        # short_sleeved_dress\n        190:\n        dict(name='ssd_kpt1', id=190, color=colors['ssd'], type='', swap=''),\n        191:\n        dict(\n            name='ssd_kpt2',\n            id=191,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt6'),\n        192:\n        dict(\n            name='ssd_kpt3',\n            id=192,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt5'),\n        193:\n        dict(name='ssd_kpt4', id=193, color=colors['ssd'], type='', swap=''),\n        194:\n        dict(\n            name='ssd_kpt5',\n            id=194,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt3'),\n        195:\n        dict(\n            name='ssd_kpt6',\n            id=195,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt2'),\n        196:\n        dict(\n            name='ssd_kpt7',\n            id=196,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt29'),\n        197:\n        dict(\n            name='ssd_kpt8',\n            id=197,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt28'),\n        198:\n        dict(\n            name='ssd_kpt9',\n            id=198,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt27'),\n        199:\n        dict(\n            name='ssd_kpt10',\n            id=199,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt26'),\n        200:\n        dict(\n            name='ssd_kpt11',\n            id=200,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt25'),\n        201:\n        dict(\n            name='ssd_kpt12',\n            id=201,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt24'),\n        202:\n        dict(\n            name='ssd_kpt13',\n            id=202,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt23'),\n        203:\n        dict(\n            name='ssd_kpt14',\n            id=203,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt22'),\n        204:\n        dict(\n            name='ssd_kpt15',\n            id=204,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt21'),\n        205:\n        dict(\n            name='ssd_kpt16',\n            id=205,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt20'),\n        206:\n        dict(\n            name='ssd_kpt17',\n            id=206,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt19'),\n        207:\n        dict(name='ssd_kpt18', id=207, color=colors['ssd'], type='', swap=''),\n        208:\n        dict(\n            name='ssd_kpt19',\n            id=208,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt17'),\n        209:\n        dict(\n            name='ssd_kpt20',\n            id=209,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt16'),\n        210:\n        dict(\n            name='ssd_kpt21',\n            id=210,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt15'),\n        211:\n        dict(\n            name='ssd_kpt22',\n            id=211,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt14'),\n        212:\n        dict(\n            name='ssd_kpt23',\n            id=212,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt13'),\n        213:\n        dict(\n            name='ssd_kpt24',\n            id=213,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt12'),\n        214:\n        dict(\n            name='ssd_kpt25',\n            id=214,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt11'),\n        215:\n        dict(\n            name='ssd_kpt26',\n            id=215,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt10'),\n        216:\n        dict(\n            name='ssd_kpt27',\n            id=216,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt9'),\n        217:\n        dict(\n            name='ssd_kpt28',\n            id=217,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt8'),\n        218:\n        dict(\n            name='ssd_kpt29',\n            id=218,\n            color=colors['ssd'],\n            type='',\n            swap='ssd_kpt7'),\n        # long_sleeved_dress\n        219:\n        dict(name='lsd_kpt1', id=219, color=colors['lsd'], type='', swap=''),\n        220:\n        dict(\n            name='lsd_kpt2',\n            id=220,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt6'),\n        221:\n        dict(\n            name='lsd_kpt3',\n            id=221,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt5'),\n        222:\n        dict(name='lsd_kpt4', id=222, color=colors['lsd'], type='', swap=''),\n        223:\n        dict(\n            name='lsd_kpt5',\n            id=223,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt3'),\n        224:\n        dict(\n            name='lsd_kpt6',\n            id=224,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt2'),\n        225:\n        dict(\n            name='lsd_kpt7',\n            id=225,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt37'),\n        226:\n        dict(\n            name='lsd_kpt8',\n            id=226,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt36'),\n        227:\n        dict(\n            name='lsd_kpt9',\n            id=227,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt35'),\n        228:\n        dict(\n            name='lsd_kpt10',\n            id=228,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt34'),\n        229:\n        dict(\n            name='lsd_kpt11',\n            id=229,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt33'),\n        230:\n        dict(\n            name='lsd_kpt12',\n            id=230,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt32'),\n        231:\n        dict(\n            name='lsd_kpt13',\n            id=231,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt31'),\n        232:\n        dict(\n            name='lsd_kpt14',\n            id=232,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt30'),\n        233:\n        dict(\n            name='lsd_kpt15',\n            id=233,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt29'),\n        234:\n        dict(\n            name='lsd_kpt16',\n            id=234,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt28'),\n        235:\n        dict(\n            name='lsd_kpt17',\n            id=235,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt27'),\n        236:\n        dict(\n            name='lsd_kpt18',\n            id=236,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt26'),\n        237:\n        dict(\n            name='lsd_kpt19',\n            id=237,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt25'),\n        238:\n        dict(\n            name='lsd_kpt20',\n            id=238,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt24'),\n        239:\n        dict(\n            name='lsd_kpt21',\n            id=239,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt23'),\n        240:\n        dict(name='lsd_kpt22', id=240, color=colors['lsd'], type='', swap=''),\n        241:\n        dict(\n            name='lsd_kpt23',\n            id=241,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt21'),\n        242:\n        dict(\n            name='lsd_kpt24',\n            id=242,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt20'),\n        243:\n        dict(\n            name='lsd_kpt25',\n            id=243,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt19'),\n        244:\n        dict(\n            name='lsd_kpt26',\n            id=244,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt18'),\n        245:\n        dict(\n            name='lsd_kpt27',\n            id=245,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt17'),\n        246:\n        dict(\n            name='lsd_kpt28',\n            id=246,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt16'),\n        247:\n        dict(\n            name='lsd_kpt29',\n            id=247,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt15'),\n        248:\n        dict(\n            name='lsd_kpt30',\n            id=248,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt14'),\n        249:\n        dict(\n            name='lsd_kpt31',\n            id=249,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt13'),\n        250:\n        dict(\n            name='lsd_kpt32',\n            id=250,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt12'),\n        251:\n        dict(\n            name='lsd_kpt33',\n            id=251,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt11'),\n        252:\n        dict(\n            name='lsd_kpt34',\n            id=252,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt10'),\n        253:\n        dict(\n            name='lsd_kpt35',\n            id=253,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt9'),\n        254:\n        dict(\n            name='lsd_kpt36',\n            id=254,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt8'),\n        255:\n        dict(\n            name='lsd_kpt37',\n            id=255,\n            color=colors['lsd'],\n            type='',\n            swap='lsd_kpt7'),\n        # vest_dress\n        256:\n        dict(name='vd_kpt1', id=256, color=colors['vd'], type='', swap=''),\n        257:\n        dict(\n            name='vd_kpt2',\n            id=257,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt6'),\n        258:\n        dict(\n            name='vd_kpt3',\n            id=258,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt5'),\n        259:\n        dict(name='vd_kpt4', id=259, color=colors['vd'], type='', swap=''),\n        260:\n        dict(\n            name='vd_kpt5',\n            id=260,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt3'),\n        261:\n        dict(\n            name='vd_kpt6',\n            id=261,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt2'),\n        262:\n        dict(\n            name='vd_kpt7',\n            id=262,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt19'),\n        263:\n        dict(\n            name='vd_kpt8',\n            id=263,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt18'),\n        264:\n        dict(\n            name='vd_kpt9',\n            id=264,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt17'),\n        265:\n        dict(\n            name='vd_kpt10',\n            id=265,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt16'),\n        266:\n        dict(\n            name='vd_kpt11',\n            id=266,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt15'),\n        267:\n        dict(\n            name='vd_kpt12',\n            id=267,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt14'),\n        268:\n        dict(name='vd_kpt13', id=268, color=colors['vd'], type='', swap=''),\n        269:\n        dict(\n            name='vd_kpt14',\n            id=269,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt12'),\n        270:\n        dict(\n            name='vd_kpt15',\n            id=270,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt11'),\n        271:\n        dict(\n            name='vd_kpt16',\n            id=271,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt10'),\n        272:\n        dict(\n            name='vd_kpt17',\n            id=272,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt9'),\n        273:\n        dict(\n            name='vd_kpt18',\n            id=273,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt8'),\n        274:\n        dict(\n            name='vd_kpt19',\n            id=274,\n            color=colors['vd'],\n            type='',\n            swap='vd_kpt7'),\n        # sling_dress\n        275:\n        dict(name='sd_kpt1', id=275, color=colors['sd'], type='', swap=''),\n        276:\n        dict(\n            name='sd_kpt2',\n            id=276,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt6'),\n        277:\n        dict(\n            name='sd_kpt3',\n            id=277,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt5'),\n        278:\n        dict(name='sd_kpt4', id=278, color=colors['sd'], type='', swap=''),\n        279:\n        dict(\n            name='sd_kpt5',\n            id=279,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt3'),\n        280:\n        dict(\n            name='sd_kpt6',\n            id=280,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt2'),\n        281:\n        dict(\n            name='sd_kpt7',\n            id=281,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt19'),\n        282:\n        dict(\n            name='sd_kpt8',\n            id=282,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt18'),\n        283:\n        dict(\n            name='sd_kpt9',\n            id=283,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt17'),\n        284:\n        dict(\n            name='sd_kpt10',\n            id=284,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt16'),\n        285:\n        dict(\n            name='sd_kpt11',\n            id=285,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt15'),\n        286:\n        dict(\n            name='sd_kpt12',\n            id=286,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt14'),\n        287:\n        dict(name='sd_kpt13', id=287, color=colors['sd'], type='', swap=''),\n        288:\n        dict(\n            name='sd_kpt14',\n            id=288,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt12'),\n        289:\n        dict(\n            name='sd_kpt15',\n            id=289,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt11'),\n        290:\n        dict(\n            name='sd_kpt16',\n            id=290,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt10'),\n        291:\n        dict(\n            name='sd_kpt17',\n            id=291,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt9'),\n        292:\n        dict(\n            name='sd_kpt18',\n            id=292,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt8'),\n        293:\n        dict(\n            name='sd_kpt19',\n            id=293,\n            color=colors['sd'],\n            type='',\n            swap='sd_kpt7'),\n    },\n    skeleton_info={\n        # short_sleeved_shirt\n        0:\n        dict(link=('sss_kpt1', 'sss_kpt2'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('sss_kpt2', 'sss_kpt7'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('sss_kpt7', 'sss_kpt8'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('sss_kpt8', 'sss_kpt9'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('sss_kpt9', 'sss_kpt10'), id=4, color=[255, 128, 0]),\n        5:\n        dict(link=('sss_kpt10', 'sss_kpt11'), id=5, color=[255, 128, 0]),\n        6:\n        dict(link=('sss_kpt11', 'sss_kpt12'), id=6, color=[255, 128, 0]),\n        7:\n        dict(link=('sss_kpt12', 'sss_kpt13'), id=7, color=[255, 128, 0]),\n        8:\n        dict(link=('sss_kpt13', 'sss_kpt14'), id=8, color=[255, 128, 0]),\n        9:\n        dict(link=('sss_kpt14', 'sss_kpt15'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('sss_kpt15', 'sss_kpt16'), id=10, color=[255, 128, 0]),\n        11:\n        dict(link=('sss_kpt16', 'sss_kpt17'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('sss_kpt17', 'sss_kpt18'), id=12, color=[255, 128, 0]),\n        13:\n        dict(link=('sss_kpt18', 'sss_kpt19'), id=13, color=[255, 128, 0]),\n        14:\n        dict(link=('sss_kpt19', 'sss_kpt20'), id=14, color=[255, 128, 0]),\n        15:\n        dict(link=('sss_kpt20', 'sss_kpt21'), id=15, color=[255, 128, 0]),\n        16:\n        dict(link=('sss_kpt21', 'sss_kpt22'), id=16, color=[255, 128, 0]),\n        17:\n        dict(link=('sss_kpt22', 'sss_kpt23'), id=17, color=[255, 128, 0]),\n        18:\n        dict(link=('sss_kpt23', 'sss_kpt24'), id=18, color=[255, 128, 0]),\n        19:\n        dict(link=('sss_kpt24', 'sss_kpt25'), id=19, color=[255, 128, 0]),\n        20:\n        dict(link=('sss_kpt25', 'sss_kpt6'), id=20, color=[255, 128, 0]),\n        21:\n        dict(link=('sss_kpt6', 'sss_kpt1'), id=21, color=[255, 128, 0]),\n        22:\n        dict(link=('sss_kpt2', 'sss_kpt3'), id=22, color=[255, 128, 0]),\n        23:\n        dict(link=('sss_kpt3', 'sss_kpt4'), id=23, color=[255, 128, 0]),\n        24:\n        dict(link=('sss_kpt4', 'sss_kpt5'), id=24, color=[255, 128, 0]),\n        25:\n        dict(link=('sss_kpt5', 'sss_kpt6'), id=25, color=[255, 128, 0]),\n        # long_sleeve_shirt\n        26:\n        dict(link=('lss_kpt1', 'lss_kpt2'), id=26, color=[255, 0, 128]),\n        27:\n        dict(link=('lss_kpt2', 'lss_kpt7'), id=27, color=[255, 0, 128]),\n        28:\n        dict(link=('lss_kpt7', 'lss_kpt8'), id=28, color=[255, 0, 128]),\n        29:\n        dict(link=('lss_kpt8', 'lss_kpt9'), id=29, color=[255, 0, 128]),\n        30:\n        dict(link=('lss_kpt9', 'lss_kpt10'), id=30, color=[255, 0, 128]),\n        31:\n        dict(link=('lss_kpt10', 'lss_kpt11'), id=31, color=[255, 0, 128]),\n        32:\n        dict(link=('lss_kpt11', 'lss_kpt12'), id=32, color=[255, 0, 128]),\n        33:\n        dict(link=('lss_kpt12', 'lss_kpt13'), id=33, color=[255, 0, 128]),\n        34:\n        dict(link=('lss_kpt13', 'lss_kpt14'), id=34, color=[255, 0, 128]),\n        35:\n        dict(link=('lss_kpt14', 'lss_kpt15'), id=35, color=[255, 0, 128]),\n        36:\n        dict(link=('lss_kpt15', 'lss_kpt16'), id=36, color=[255, 0, 128]),\n        37:\n        dict(link=('lss_kpt16', 'lss_kpt17'), id=37, color=[255, 0, 128]),\n        38:\n        dict(link=('lss_kpt17', 'lss_kpt18'), id=38, color=[255, 0, 128]),\n        39:\n        dict(link=('lss_kpt18', 'lss_kpt19'), id=39, color=[255, 0, 128]),\n        40:\n        dict(link=('lss_kpt19', 'lss_kpt20'), id=40, color=[255, 0, 128]),\n        41:\n        dict(link=('lss_kpt20', 'lss_kpt21'), id=41, color=[255, 0, 128]),\n        42:\n        dict(link=('lss_kpt21', 'lss_kpt22'), id=42, color=[255, 0, 128]),\n        43:\n        dict(link=('lss_kpt22', 'lss_kpt23'), id=43, color=[255, 0, 128]),\n        44:\n        dict(link=('lss_kpt23', 'lss_kpt24'), id=44, color=[255, 0, 128]),\n        45:\n        dict(link=('lss_kpt24', 'lss_kpt25'), id=45, color=[255, 0, 128]),\n        46:\n        dict(link=('lss_kpt25', 'lss_kpt26'), id=46, color=[255, 0, 128]),\n        47:\n        dict(link=('lss_kpt26', 'lss_kpt27'), id=47, color=[255, 0, 128]),\n        48:\n        dict(link=('lss_kpt27', 'lss_kpt28'), id=48, color=[255, 0, 128]),\n        49:\n        dict(link=('lss_kpt28', 'lss_kpt29'), id=49, color=[255, 0, 128]),\n        50:\n        dict(link=('lss_kpt29', 'lss_kpt30'), id=50, color=[255, 0, 128]),\n        51:\n        dict(link=('lss_kpt30', 'lss_kpt31'), id=51, color=[255, 0, 128]),\n        52:\n        dict(link=('lss_kpt31', 'lss_kpt32'), id=52, color=[255, 0, 128]),\n        53:\n        dict(link=('lss_kpt32', 'lss_kpt33'), id=53, color=[255, 0, 128]),\n        54:\n        dict(link=('lss_kpt33', 'lss_kpt6'), id=54, color=[255, 0, 128]),\n        55:\n        dict(link=('lss_kpt6', 'lss_kpt5'), id=55, color=[255, 0, 128]),\n        56:\n        dict(link=('lss_kpt5', 'lss_kpt4'), id=56, color=[255, 0, 128]),\n        57:\n        dict(link=('lss_kpt4', 'lss_kpt3'), id=57, color=[255, 0, 128]),\n        58:\n        dict(link=('lss_kpt3', 'lss_kpt2'), id=58, color=[255, 0, 128]),\n        59:\n        dict(link=('lss_kpt6', 'lss_kpt1'), id=59, color=[255, 0, 128]),\n        # short_sleeved_outwear\n        60:\n        dict(link=('sso_kpt1', 'sso_kpt4'), id=60, color=[128, 0, 255]),\n        61:\n        dict(link=('sso_kpt4', 'sso_kpt7'), id=61, color=[128, 0, 255]),\n        62:\n        dict(link=('sso_kpt7', 'sso_kpt8'), id=62, color=[128, 0, 255]),\n        63:\n        dict(link=('sso_kpt8', 'sso_kpt9'), id=63, color=[128, 0, 255]),\n        64:\n        dict(link=('sso_kpt9', 'sso_kpt10'), id=64, color=[128, 0, 255]),\n        65:\n        dict(link=('sso_kpt10', 'sso_kpt11'), id=65, color=[128, 0, 255]),\n        66:\n        dict(link=('sso_kpt11', 'sso_kpt12'), id=66, color=[128, 0, 255]),\n        67:\n        dict(link=('sso_kpt12', 'sso_kpt13'), id=67, color=[128, 0, 255]),\n        68:\n        dict(link=('sso_kpt13', 'sso_kpt14'), id=68, color=[128, 0, 255]),\n        69:\n        dict(link=('sso_kpt14', 'sso_kpt15'), id=69, color=[128, 0, 255]),\n        70:\n        dict(link=('sso_kpt15', 'sso_kpt16'), id=70, color=[128, 0, 255]),\n        71:\n        dict(link=('sso_kpt16', 'sso_kpt31'), id=71, color=[128, 0, 255]),\n        72:\n        dict(link=('sso_kpt31', 'sso_kpt30'), id=72, color=[128, 0, 255]),\n        73:\n        dict(link=('sso_kpt30', 'sso_kpt2'), id=73, color=[128, 0, 255]),\n        74:\n        dict(link=('sso_kpt2', 'sso_kpt3'), id=74, color=[128, 0, 255]),\n        75:\n        dict(link=('sso_kpt3', 'sso_kpt4'), id=75, color=[128, 0, 255]),\n        76:\n        dict(link=('sso_kpt1', 'sso_kpt6'), id=76, color=[128, 0, 255]),\n        77:\n        dict(link=('sso_kpt6', 'sso_kpt25'), id=77, color=[128, 0, 255]),\n        78:\n        dict(link=('sso_kpt25', 'sso_kpt24'), id=78, color=[128, 0, 255]),\n        79:\n        dict(link=('sso_kpt24', 'sso_kpt23'), id=79, color=[128, 0, 255]),\n        80:\n        dict(link=('sso_kpt23', 'sso_kpt22'), id=80, color=[128, 0, 255]),\n        81:\n        dict(link=('sso_kpt22', 'sso_kpt21'), id=81, color=[128, 0, 255]),\n        82:\n        dict(link=('sso_kpt21', 'sso_kpt20'), id=82, color=[128, 0, 255]),\n        83:\n        dict(link=('sso_kpt20', 'sso_kpt19'), id=83, color=[128, 0, 255]),\n        84:\n        dict(link=('sso_kpt19', 'sso_kpt18'), id=84, color=[128, 0, 255]),\n        85:\n        dict(link=('sso_kpt18', 'sso_kpt17'), id=85, color=[128, 0, 255]),\n        86:\n        dict(link=('sso_kpt17', 'sso_kpt29'), id=86, color=[128, 0, 255]),\n        87:\n        dict(link=('sso_kpt29', 'sso_kpt28'), id=87, color=[128, 0, 255]),\n        88:\n        dict(link=('sso_kpt28', 'sso_kpt27'), id=88, color=[128, 0, 255]),\n        89:\n        dict(link=('sso_kpt27', 'sso_kpt26'), id=89, color=[128, 0, 255]),\n        90:\n        dict(link=('sso_kpt26', 'sso_kpt5'), id=90, color=[128, 0, 255]),\n        91:\n        dict(link=('sso_kpt5', 'sso_kpt6'), id=91, color=[128, 0, 255]),\n        # long_sleeved_outwear\n        92:\n        dict(link=('lso_kpt1', 'lso_kpt2'), id=92, color=[0, 128, 255]),\n        93:\n        dict(link=('lso_kpt2', 'lso_kpt7'), id=93, color=[0, 128, 255]),\n        94:\n        dict(link=('lso_kpt7', 'lso_kpt8'), id=94, color=[0, 128, 255]),\n        95:\n        dict(link=('lso_kpt8', 'lso_kpt9'), id=95, color=[0, 128, 255]),\n        96:\n        dict(link=('lso_kpt9', 'lso_kpt10'), id=96, color=[0, 128, 255]),\n        97:\n        dict(link=('lso_kpt10', 'lso_kpt11'), id=97, color=[0, 128, 255]),\n        98:\n        dict(link=('lso_kpt11', 'lso_kpt12'), id=98, color=[0, 128, 255]),\n        99:\n        dict(link=('lso_kpt12', 'lso_kpt13'), id=99, color=[0, 128, 255]),\n        100:\n        dict(link=('lso_kpt13', 'lso_kpt14'), id=100, color=[0, 128, 255]),\n        101:\n        dict(link=('lso_kpt14', 'lso_kpt15'), id=101, color=[0, 128, 255]),\n        102:\n        dict(link=('lso_kpt15', 'lso_kpt16'), id=102, color=[0, 128, 255]),\n        103:\n        dict(link=('lso_kpt16', 'lso_kpt17'), id=103, color=[0, 128, 255]),\n        104:\n        dict(link=('lso_kpt17', 'lso_kpt18'), id=104, color=[0, 128, 255]),\n        105:\n        dict(link=('lso_kpt18', 'lso_kpt19'), id=105, color=[0, 128, 255]),\n        106:\n        dict(link=('lso_kpt19', 'lso_kpt20'), id=106, color=[0, 128, 255]),\n        107:\n        dict(link=('lso_kpt20', 'lso_kpt39'), id=107, color=[0, 128, 255]),\n        108:\n        dict(link=('lso_kpt39', 'lso_kpt38'), id=108, color=[0, 128, 255]),\n        109:\n        dict(link=('lso_kpt38', 'lso_kpt4'), id=109, color=[0, 128, 255]),\n        110:\n        dict(link=('lso_kpt4', 'lso_kpt3'), id=110, color=[0, 128, 255]),\n        111:\n        dict(link=('lso_kpt3', 'lso_kpt2'), id=111, color=[0, 128, 255]),\n        112:\n        dict(link=('lso_kpt1', 'lso_kpt6'), id=112, color=[0, 128, 255]),\n        113:\n        dict(link=('lso_kpt6', 'lso_kpt33'), id=113, color=[0, 128, 255]),\n        114:\n        dict(link=('lso_kpt33', 'lso_kpt32'), id=114, color=[0, 128, 255]),\n        115:\n        dict(link=('lso_kpt32', 'lso_kpt31'), id=115, color=[0, 128, 255]),\n        116:\n        dict(link=('lso_kpt31', 'lso_kpt30'), id=116, color=[0, 128, 255]),\n        117:\n        dict(link=('lso_kpt30', 'lso_kpt29'), id=117, color=[0, 128, 255]),\n        118:\n        dict(link=('lso_kpt29', 'lso_kpt28'), id=118, color=[0, 128, 255]),\n        119:\n        dict(link=('lso_kpt28', 'lso_kpt27'), id=119, color=[0, 128, 255]),\n        120:\n        dict(link=('lso_kpt27', 'lso_kpt26'), id=120, color=[0, 128, 255]),\n        121:\n        dict(link=('lso_kpt26', 'lso_kpt25'), id=121, color=[0, 128, 255]),\n        122:\n        dict(link=('lso_kpt25', 'lso_kpt24'), id=122, color=[0, 128, 255]),\n        123:\n        dict(link=('lso_kpt24', 'lso_kpt23'), id=123, color=[0, 128, 255]),\n        124:\n        dict(link=('lso_kpt23', 'lso_kpt22'), id=124, color=[0, 128, 255]),\n        125:\n        dict(link=('lso_kpt22', 'lso_kpt21'), id=125, color=[0, 128, 255]),\n        126:\n        dict(link=('lso_kpt21', 'lso_kpt37'), id=126, color=[0, 128, 255]),\n        127:\n        dict(link=('lso_kpt37', 'lso_kpt36'), id=127, color=[0, 128, 255]),\n        128:\n        dict(link=('lso_kpt36', 'lso_kpt35'), id=128, color=[0, 128, 255]),\n        129:\n        dict(link=('lso_kpt35', 'lso_kpt34'), id=129, color=[0, 128, 255]),\n        130:\n        dict(link=('lso_kpt34', 'lso_kpt5'), id=130, color=[0, 128, 255]),\n        131:\n        dict(link=('lso_kpt5', 'lso_kpt6'), id=131, color=[0, 128, 255]),\n        # vest\n        132:\n        dict(link=('vest_kpt1', 'vest_kpt2'), id=132, color=[0, 128, 128]),\n        133:\n        dict(link=('vest_kpt2', 'vest_kpt7'), id=133, color=[0, 128, 128]),\n        134:\n        dict(link=('vest_kpt7', 'vest_kpt8'), id=134, color=[0, 128, 128]),\n        135:\n        dict(link=('vest_kpt8', 'vest_kpt9'), id=135, color=[0, 128, 128]),\n        136:\n        dict(link=('vest_kpt9', 'vest_kpt10'), id=136, color=[0, 128, 128]),\n        137:\n        dict(link=('vest_kpt10', 'vest_kpt11'), id=137, color=[0, 128, 128]),\n        138:\n        dict(link=('vest_kpt11', 'vest_kpt12'), id=138, color=[0, 128, 128]),\n        139:\n        dict(link=('vest_kpt12', 'vest_kpt13'), id=139, color=[0, 128, 128]),\n        140:\n        dict(link=('vest_kpt13', 'vest_kpt14'), id=140, color=[0, 128, 128]),\n        141:\n        dict(link=('vest_kpt14', 'vest_kpt15'), id=141, color=[0, 128, 128]),\n        142:\n        dict(link=('vest_kpt15', 'vest_kpt6'), id=142, color=[0, 128, 128]),\n        143:\n        dict(link=('vest_kpt6', 'vest_kpt1'), id=143, color=[0, 128, 128]),\n        144:\n        dict(link=('vest_kpt2', 'vest_kpt3'), id=144, color=[0, 128, 128]),\n        145:\n        dict(link=('vest_kpt3', 'vest_kpt4'), id=145, color=[0, 128, 128]),\n        146:\n        dict(link=('vest_kpt4', 'vest_kpt5'), id=146, color=[0, 128, 128]),\n        147:\n        dict(link=('vest_kpt5', 'vest_kpt6'), id=147, color=[0, 128, 128]),\n        # sling\n        148:\n        dict(link=('sling_kpt1', 'sling_kpt2'), id=148, color=[0, 0, 128]),\n        149:\n        dict(link=('sling_kpt2', 'sling_kpt8'), id=149, color=[0, 0, 128]),\n        150:\n        dict(link=('sling_kpt8', 'sling_kpt9'), id=150, color=[0, 0, 128]),\n        151:\n        dict(link=('sling_kpt9', 'sling_kpt10'), id=151, color=[0, 0, 128]),\n        152:\n        dict(link=('sling_kpt10', 'sling_kpt11'), id=152, color=[0, 0, 128]),\n        153:\n        dict(link=('sling_kpt11', 'sling_kpt12'), id=153, color=[0, 0, 128]),\n        154:\n        dict(link=('sling_kpt12', 'sling_kpt13'), id=154, color=[0, 0, 128]),\n        155:\n        dict(link=('sling_kpt13', 'sling_kpt14'), id=155, color=[0, 0, 128]),\n        156:\n        dict(link=('sling_kpt14', 'sling_kpt6'), id=156, color=[0, 0, 128]),\n        157:\n        dict(link=('sling_kpt2', 'sling_kpt7'), id=157, color=[0, 0, 128]),\n        158:\n        dict(link=('sling_kpt6', 'sling_kpt15'), id=158, color=[0, 0, 128]),\n        159:\n        dict(link=('sling_kpt2', 'sling_kpt3'), id=159, color=[0, 0, 128]),\n        160:\n        dict(link=('sling_kpt3', 'sling_kpt4'), id=160, color=[0, 0, 128]),\n        161:\n        dict(link=('sling_kpt4', 'sling_kpt5'), id=161, color=[0, 0, 128]),\n        162:\n        dict(link=('sling_kpt5', 'sling_kpt6'), id=162, color=[0, 0, 128]),\n        163:\n        dict(link=('sling_kpt1', 'sling_kpt6'), id=163, color=[0, 0, 128]),\n        # shorts\n        164:\n        dict(\n            link=('shorts_kpt1', 'shorts_kpt4'), id=164, color=[128, 128,\n                                                                128]),\n        165:\n        dict(\n            link=('shorts_kpt4', 'shorts_kpt5'), id=165, color=[128, 128,\n                                                                128]),\n        166:\n        dict(\n            link=('shorts_kpt5', 'shorts_kpt6'), id=166, color=[128, 128,\n                                                                128]),\n        167:\n        dict(\n            link=('shorts_kpt6', 'shorts_kpt7'), id=167, color=[128, 128,\n                                                                128]),\n        168:\n        dict(\n            link=('shorts_kpt7', 'shorts_kpt8'), id=168, color=[128, 128,\n                                                                128]),\n        169:\n        dict(\n            link=('shorts_kpt8', 'shorts_kpt9'), id=169, color=[128, 128,\n                                                                128]),\n        170:\n        dict(\n            link=('shorts_kpt9', 'shorts_kpt10'),\n            id=170,\n            color=[128, 128, 128]),\n        171:\n        dict(\n            link=('shorts_kpt10', 'shorts_kpt3'),\n            id=171,\n            color=[128, 128, 128]),\n        172:\n        dict(\n            link=('shorts_kpt3', 'shorts_kpt2'), id=172, color=[128, 128,\n                                                                128]),\n        173:\n        dict(\n            link=('shorts_kpt2', 'shorts_kpt1'), id=173, color=[128, 128,\n                                                                128]),\n        # trousers\n        174:\n        dict(\n            link=('trousers_kpt1', 'trousers_kpt4'),\n            id=174,\n            color=[128, 0, 128]),\n        175:\n        dict(\n            link=('trousers_kpt4', 'trousers_kpt5'),\n            id=175,\n            color=[128, 0, 128]),\n        176:\n        dict(\n            link=('trousers_kpt5', 'trousers_kpt6'),\n            id=176,\n            color=[128, 0, 128]),\n        177:\n        dict(\n            link=('trousers_kpt6', 'trousers_kpt7'),\n            id=177,\n            color=[128, 0, 128]),\n        178:\n        dict(\n            link=('trousers_kpt7', 'trousers_kpt8'),\n            id=178,\n            color=[128, 0, 128]),\n        179:\n        dict(\n            link=('trousers_kpt8', 'trousers_kpt9'),\n            id=179,\n            color=[128, 0, 128]),\n        180:\n        dict(\n            link=('trousers_kpt9', 'trousers_kpt10'),\n            id=180,\n            color=[128, 0, 128]),\n        181:\n        dict(\n            link=('trousers_kpt10', 'trousers_kpt11'),\n            id=181,\n            color=[128, 0, 128]),\n        182:\n        dict(\n            link=('trousers_kpt11', 'trousers_kpt12'),\n            id=182,\n            color=[128, 0, 128]),\n        183:\n        dict(\n            link=('trousers_kpt12', 'trousers_kpt13'),\n            id=183,\n            color=[128, 0, 128]),\n        184:\n        dict(\n            link=('trousers_kpt13', 'trousers_kpt14'),\n            id=184,\n            color=[128, 0, 128]),\n        185:\n        dict(\n            link=('trousers_kpt14', 'trousers_kpt3'),\n            id=185,\n            color=[128, 0, 128]),\n        186:\n        dict(\n            link=('trousers_kpt3', 'trousers_kpt2'),\n            id=186,\n            color=[128, 0, 128]),\n        187:\n        dict(\n            link=('trousers_kpt2', 'trousers_kpt1'),\n            id=187,\n            color=[128, 0, 128]),\n        # skirt\n        188:\n        dict(link=('skirt_kpt1', 'skirt_kpt4'), id=188, color=[64, 128, 128]),\n        189:\n        dict(link=('skirt_kpt4', 'skirt_kpt5'), id=189, color=[64, 128, 128]),\n        190:\n        dict(link=('skirt_kpt5', 'skirt_kpt6'), id=190, color=[64, 128, 128]),\n        191:\n        dict(link=('skirt_kpt6', 'skirt_kpt7'), id=191, color=[64, 128, 128]),\n        192:\n        dict(link=('skirt_kpt7', 'skirt_kpt8'), id=192, color=[64, 128, 128]),\n        193:\n        dict(link=('skirt_kpt8', 'skirt_kpt3'), id=193, color=[64, 128, 128]),\n        194:\n        dict(link=('skirt_kpt3', 'skirt_kpt2'), id=194, color=[64, 128, 128]),\n        195:\n        dict(link=('skirt_kpt2', 'skirt_kpt1'), id=195, color=[64, 128, 128]),\n        # short_sleeved_dress\n        196:\n        dict(link=('ssd_kpt1', 'ssd_kpt2'), id=196, color=[64, 64, 128]),\n        197:\n        dict(link=('ssd_kpt2', 'ssd_kpt7'), id=197, color=[64, 64, 128]),\n        198:\n        dict(link=('ssd_kpt7', 'ssd_kpt8'), id=198, color=[64, 64, 128]),\n        199:\n        dict(link=('ssd_kpt8', 'ssd_kpt9'), id=199, color=[64, 64, 128]),\n        200:\n        dict(link=('ssd_kpt9', 'ssd_kpt10'), id=200, color=[64, 64, 128]),\n        201:\n        dict(link=('ssd_kpt10', 'ssd_kpt11'), id=201, color=[64, 64, 128]),\n        202:\n        dict(link=('ssd_kpt11', 'ssd_kpt12'), id=202, color=[64, 64, 128]),\n        203:\n        dict(link=('ssd_kpt12', 'ssd_kpt13'), id=203, color=[64, 64, 128]),\n        204:\n        dict(link=('ssd_kpt13', 'ssd_kpt14'), id=204, color=[64, 64, 128]),\n        205:\n        dict(link=('ssd_kpt14', 'ssd_kpt15'), id=205, color=[64, 64, 128]),\n        206:\n        dict(link=('ssd_kpt15', 'ssd_kpt16'), id=206, color=[64, 64, 128]),\n        207:\n        dict(link=('ssd_kpt16', 'ssd_kpt17'), id=207, color=[64, 64, 128]),\n        208:\n        dict(link=('ssd_kpt17', 'ssd_kpt18'), id=208, color=[64, 64, 128]),\n        209:\n        dict(link=('ssd_kpt18', 'ssd_kpt19'), id=209, color=[64, 64, 128]),\n        210:\n        dict(link=('ssd_kpt19', 'ssd_kpt20'), id=210, color=[64, 64, 128]),\n        211:\n        dict(link=('ssd_kpt20', 'ssd_kpt21'), id=211, color=[64, 64, 128]),\n        212:\n        dict(link=('ssd_kpt21', 'ssd_kpt22'), id=212, color=[64, 64, 128]),\n        213:\n        dict(link=('ssd_kpt22', 'ssd_kpt23'), id=213, color=[64, 64, 128]),\n        214:\n        dict(link=('ssd_kpt23', 'ssd_kpt24'), id=214, color=[64, 64, 128]),\n        215:\n        dict(link=('ssd_kpt24', 'ssd_kpt25'), id=215, color=[64, 64, 128]),\n        216:\n        dict(link=('ssd_kpt25', 'ssd_kpt26'), id=216, color=[64, 64, 128]),\n        217:\n        dict(link=('ssd_kpt26', 'ssd_kpt27'), id=217, color=[64, 64, 128]),\n        218:\n        dict(link=('ssd_kpt27', 'ssd_kpt28'), id=218, color=[64, 64, 128]),\n        219:\n        dict(link=('ssd_kpt28', 'ssd_kpt29'), id=219, color=[64, 64, 128]),\n        220:\n        dict(link=('ssd_kpt29', 'ssd_kpt6'), id=220, color=[64, 64, 128]),\n        221:\n        dict(link=('ssd_kpt6', 'ssd_kpt5'), id=221, color=[64, 64, 128]),\n        222:\n        dict(link=('ssd_kpt5', 'ssd_kpt4'), id=222, color=[64, 64, 128]),\n        223:\n        dict(link=('ssd_kpt4', 'ssd_kpt3'), id=223, color=[64, 64, 128]),\n        224:\n        dict(link=('ssd_kpt3', 'ssd_kpt2'), id=224, color=[64, 64, 128]),\n        225:\n        dict(link=('ssd_kpt6', 'ssd_kpt1'), id=225, color=[64, 64, 128]),\n        # long_sleeved_dress\n        226:\n        dict(link=('lsd_kpt1', 'lsd_kpt2'), id=226, color=[128, 64, 0]),\n        227:\n        dict(link=('lsd_kpt2', 'lsd_kpt7'), id=228, color=[128, 64, 0]),\n        228:\n        dict(link=('lsd_kpt7', 'lsd_kpt8'), id=228, color=[128, 64, 0]),\n        229:\n        dict(link=('lsd_kpt8', 'lsd_kpt9'), id=229, color=[128, 64, 0]),\n        230:\n        dict(link=('lsd_kpt9', 'lsd_kpt10'), id=230, color=[128, 64, 0]),\n        231:\n        dict(link=('lsd_kpt10', 'lsd_kpt11'), id=231, color=[128, 64, 0]),\n        232:\n        dict(link=('lsd_kpt11', 'lsd_kpt12'), id=232, color=[128, 64, 0]),\n        233:\n        dict(link=('lsd_kpt12', 'lsd_kpt13'), id=233, color=[128, 64, 0]),\n        234:\n        dict(link=('lsd_kpt13', 'lsd_kpt14'), id=234, color=[128, 64, 0]),\n        235:\n        dict(link=('lsd_kpt14', 'lsd_kpt15'), id=235, color=[128, 64, 0]),\n        236:\n        dict(link=('lsd_kpt15', 'lsd_kpt16'), id=236, color=[128, 64, 0]),\n        237:\n        dict(link=('lsd_kpt16', 'lsd_kpt17'), id=237, color=[128, 64, 0]),\n        238:\n        dict(link=('lsd_kpt17', 'lsd_kpt18'), id=238, color=[128, 64, 0]),\n        239:\n        dict(link=('lsd_kpt18', 'lsd_kpt19'), id=239, color=[128, 64, 0]),\n        240:\n        dict(link=('lsd_kpt19', 'lsd_kpt20'), id=240, color=[128, 64, 0]),\n        241:\n        dict(link=('lsd_kpt20', 'lsd_kpt21'), id=241, color=[128, 64, 0]),\n        242:\n        dict(link=('lsd_kpt21', 'lsd_kpt22'), id=242, color=[128, 64, 0]),\n        243:\n        dict(link=('lsd_kpt22', 'lsd_kpt23'), id=243, color=[128, 64, 0]),\n        244:\n        dict(link=('lsd_kpt23', 'lsd_kpt24'), id=244, color=[128, 64, 0]),\n        245:\n        dict(link=('lsd_kpt24', 'lsd_kpt25'), id=245, color=[128, 64, 0]),\n        246:\n        dict(link=('lsd_kpt25', 'lsd_kpt26'), id=246, color=[128, 64, 0]),\n        247:\n        dict(link=('lsd_kpt26', 'lsd_kpt27'), id=247, color=[128, 64, 0]),\n        248:\n        dict(link=('lsd_kpt27', 'lsd_kpt28'), id=248, color=[128, 64, 0]),\n        249:\n        dict(link=('lsd_kpt28', 'lsd_kpt29'), id=249, color=[128, 64, 0]),\n        250:\n        dict(link=('lsd_kpt29', 'lsd_kpt30'), id=250, color=[128, 64, 0]),\n        251:\n        dict(link=('lsd_kpt30', 'lsd_kpt31'), id=251, color=[128, 64, 0]),\n        252:\n        dict(link=('lsd_kpt31', 'lsd_kpt32'), id=252, color=[128, 64, 0]),\n        253:\n        dict(link=('lsd_kpt32', 'lsd_kpt33'), id=253, color=[128, 64, 0]),\n        254:\n        dict(link=('lsd_kpt33', 'lsd_kpt34'), id=254, color=[128, 64, 0]),\n        255:\n        dict(link=('lsd_kpt34', 'lsd_kpt35'), id=255, color=[128, 64, 0]),\n        256:\n        dict(link=('lsd_kpt35', 'lsd_kpt36'), id=256, color=[128, 64, 0]),\n        257:\n        dict(link=('lsd_kpt36', 'lsd_kpt37'), id=257, color=[128, 64, 0]),\n        258:\n        dict(link=('lsd_kpt37', 'lsd_kpt6'), id=258, color=[128, 64, 0]),\n        259:\n        dict(link=('lsd_kpt6', 'lsd_kpt5'), id=259, color=[128, 64, 0]),\n        260:\n        dict(link=('lsd_kpt5', 'lsd_kpt4'), id=260, color=[128, 64, 0]),\n        261:\n        dict(link=('lsd_kpt4', 'lsd_kpt3'), id=261, color=[128, 64, 0]),\n        262:\n        dict(link=('lsd_kpt3', 'lsd_kpt2'), id=262, color=[128, 64, 0]),\n        263:\n        dict(link=('lsd_kpt6', 'lsd_kpt1'), id=263, color=[128, 64, 0]),\n        # vest_dress\n        264:\n        dict(link=('vd_kpt1', 'vd_kpt2'), id=264, color=[128, 64, 255]),\n        265:\n        dict(link=('vd_kpt2', 'vd_kpt7'), id=265, color=[128, 64, 255]),\n        266:\n        dict(link=('vd_kpt7', 'vd_kpt8'), id=266, color=[128, 64, 255]),\n        267:\n        dict(link=('vd_kpt8', 'vd_kpt9'), id=267, color=[128, 64, 255]),\n        268:\n        dict(link=('vd_kpt9', 'vd_kpt10'), id=268, color=[128, 64, 255]),\n        269:\n        dict(link=('vd_kpt10', 'vd_kpt11'), id=269, color=[128, 64, 255]),\n        270:\n        dict(link=('vd_kpt11', 'vd_kpt12'), id=270, color=[128, 64, 255]),\n        271:\n        dict(link=('vd_kpt12', 'vd_kpt13'), id=271, color=[128, 64, 255]),\n        272:\n        dict(link=('vd_kpt13', 'vd_kpt14'), id=272, color=[128, 64, 255]),\n        273:\n        dict(link=('vd_kpt14', 'vd_kpt15'), id=273, color=[128, 64, 255]),\n        274:\n        dict(link=('vd_kpt15', 'vd_kpt16'), id=274, color=[128, 64, 255]),\n        275:\n        dict(link=('vd_kpt16', 'vd_kpt17'), id=275, color=[128, 64, 255]),\n        276:\n        dict(link=('vd_kpt17', 'vd_kpt18'), id=276, color=[128, 64, 255]),\n        277:\n        dict(link=('vd_kpt18', 'vd_kpt19'), id=277, color=[128, 64, 255]),\n        278:\n        dict(link=('vd_kpt19', 'vd_kpt6'), id=278, color=[128, 64, 255]),\n        279:\n        dict(link=('vd_kpt6', 'vd_kpt5'), id=279, color=[128, 64, 255]),\n        280:\n        dict(link=('vd_kpt5', 'vd_kpt4'), id=280, color=[128, 64, 255]),\n        281:\n        dict(link=('vd_kpt4', 'vd_kpt3'), id=281, color=[128, 64, 255]),\n        282:\n        dict(link=('vd_kpt3', 'vd_kpt2'), id=282, color=[128, 64, 255]),\n        283:\n        dict(link=('vd_kpt6', 'vd_kpt1'), id=283, color=[128, 64, 255]),\n        # sling_dress\n        284:\n        dict(link=('sd_kpt1', 'sd_kpt2'), id=284, color=[128, 64, 0]),\n        285:\n        dict(link=('sd_kpt2', 'sd_kpt8'), id=285, color=[128, 64, 0]),\n        286:\n        dict(link=('sd_kpt8', 'sd_kpt9'), id=286, color=[128, 64, 0]),\n        287:\n        dict(link=('sd_kpt9', 'sd_kpt10'), id=287, color=[128, 64, 0]),\n        288:\n        dict(link=('sd_kpt10', 'sd_kpt11'), id=288, color=[128, 64, 0]),\n        289:\n        dict(link=('sd_kpt11', 'sd_kpt12'), id=289, color=[128, 64, 0]),\n        290:\n        dict(link=('sd_kpt12', 'sd_kpt13'), id=290, color=[128, 64, 0]),\n        291:\n        dict(link=('sd_kpt13', 'sd_kpt14'), id=291, color=[128, 64, 0]),\n        292:\n        dict(link=('sd_kpt14', 'sd_kpt15'), id=292, color=[128, 64, 0]),\n        293:\n        dict(link=('sd_kpt15', 'sd_kpt16'), id=293, color=[128, 64, 0]),\n        294:\n        dict(link=('sd_kpt16', 'sd_kpt17'), id=294, color=[128, 64, 0]),\n        295:\n        dict(link=('sd_kpt17', 'sd_kpt18'), id=295, color=[128, 64, 0]),\n        296:\n        dict(link=('sd_kpt18', 'sd_kpt6'), id=296, color=[128, 64, 0]),\n        297:\n        dict(link=('sd_kpt6', 'sd_kpt5'), id=297, color=[128, 64, 0]),\n        298:\n        dict(link=('sd_kpt5', 'sd_kpt4'), id=298, color=[128, 64, 0]),\n        299:\n        dict(link=('sd_kpt4', 'sd_kpt3'), id=299, color=[128, 64, 0]),\n        300:\n        dict(link=('sd_kpt3', 'sd_kpt2'), id=300, color=[128, 64, 0]),\n        301:\n        dict(link=('sd_kpt2', 'sd_kpt7'), id=301, color=[128, 64, 0]),\n        302:\n        dict(link=('sd_kpt6', 'sd_kpt19'), id=302, color=[128, 64, 0]),\n        303:\n        dict(link=('sd_kpt6', 'sd_kpt1'), id=303, color=[128, 64, 0]),\n    },\n    joint_weights=[1.] * 294,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/deepfashion_full.py",
    "content": "dataset_info = dict(\n    dataset_name='deepfashion_full',\n    paper_info=dict(\n        author='Liu, Ziwei and Luo, Ping and Qiu, Shi '\n        'and Wang, Xiaogang and Tang, Xiaoou',\n        title='DeepFashion: Powering Robust Clothes Recognition '\n        'and Retrieval with Rich Annotations',\n        container='Proceedings of IEEE Conference on Computer '\n        'Vision and Pattern Recognition (CVPR)',\n        year='2016',\n        homepage='http://mmlab.ie.cuhk.edu.hk/projects/'\n        'DeepFashion/LandmarkDetection.html',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left collar',\n            id=0,\n            color=[255, 255, 255],\n            type='',\n            swap='right collar'),\n        1:\n        dict(\n            name='right collar',\n            id=1,\n            color=[255, 255, 255],\n            type='',\n            swap='left collar'),\n        2:\n        dict(\n            name='left sleeve',\n            id=2,\n            color=[255, 255, 255],\n            type='',\n            swap='right sleeve'),\n        3:\n        dict(\n            name='right sleeve',\n            id=3,\n            color=[255, 255, 255],\n            type='',\n            swap='left sleeve'),\n        4:\n        dict(\n            name='left waistline',\n            id=0,\n            color=[255, 255, 255],\n            type='',\n            swap='right waistline'),\n        5:\n        dict(\n            name='right waistline',\n            id=1,\n            color=[255, 255, 255],\n            type='',\n            swap='left waistline'),\n        6:\n        dict(\n            name='left hem',\n            id=2,\n            color=[255, 255, 255],\n            type='',\n            swap='right hem'),\n        7:\n        dict(\n            name='right hem',\n            id=3,\n            color=[255, 255, 255],\n            type='',\n            swap='left hem'),\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 8,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/deepfashion_lower.py",
    "content": "dataset_info = dict(\n    dataset_name='deepfashion_lower',\n    paper_info=dict(\n        author='Liu, Ziwei and Luo, Ping and Qiu, Shi '\n        'and Wang, Xiaogang and Tang, Xiaoou',\n        title='DeepFashion: Powering Robust Clothes Recognition '\n        'and Retrieval with Rich Annotations',\n        container='Proceedings of IEEE Conference on Computer '\n        'Vision and Pattern Recognition (CVPR)',\n        year='2016',\n        homepage='http://mmlab.ie.cuhk.edu.hk/projects/'\n        'DeepFashion/LandmarkDetection.html',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left waistline',\n            id=0,\n            color=[255, 255, 255],\n            type='',\n            swap='right waistline'),\n        1:\n        dict(\n            name='right waistline',\n            id=1,\n            color=[255, 255, 255],\n            type='',\n            swap='left waistline'),\n        2:\n        dict(\n            name='left hem',\n            id=2,\n            color=[255, 255, 255],\n            type='',\n            swap='right hem'),\n        3:\n        dict(\n            name='right hem',\n            id=3,\n            color=[255, 255, 255],\n            type='',\n            swap='left hem'),\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 4,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/deepfashion_upper.py",
    "content": "dataset_info = dict(\n    dataset_name='deepfashion_upper',\n    paper_info=dict(\n        author='Liu, Ziwei and Luo, Ping and Qiu, Shi '\n        'and Wang, Xiaogang and Tang, Xiaoou',\n        title='DeepFashion: Powering Robust Clothes Recognition '\n        'and Retrieval with Rich Annotations',\n        container='Proceedings of IEEE Conference on Computer '\n        'Vision and Pattern Recognition (CVPR)',\n        year='2016',\n        homepage='http://mmlab.ie.cuhk.edu.hk/projects/'\n        'DeepFashion/LandmarkDetection.html',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left collar',\n            id=0,\n            color=[255, 255, 255],\n            type='',\n            swap='right collar'),\n        1:\n        dict(\n            name='right collar',\n            id=1,\n            color=[255, 255, 255],\n            type='',\n            swap='left collar'),\n        2:\n        dict(\n            name='left sleeve',\n            id=2,\n            color=[255, 255, 255],\n            type='',\n            swap='right sleeve'),\n        3:\n        dict(\n            name='right sleeve',\n            id=3,\n            color=[255, 255, 255],\n            type='',\n            swap='left sleeve'),\n        4:\n        dict(\n            name='left hem',\n            id=4,\n            color=[255, 255, 255],\n            type='',\n            swap='right hem'),\n        5:\n        dict(\n            name='right hem',\n            id=5,\n            color=[255, 255, 255],\n            type='',\n            swap='left hem'),\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 6,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/exlpose.py",
    "content": "dataset_info = dict(\n    dataset_name='exlpose',\n    paper_info=dict(\n        author='Sohyun Lee, Jaesung Rim, Boseung Jeong, Geonu Kim,'\n        'ByungJu Woo, Haechan Lee, Sunghyun Cho, Suha Kwak',\n        title='Human Pose Estimation in Extremely Low-Light Conditions',\n        container='arXiv',\n        year='2023',\n        homepage='https://arxiv.org/abs/2303.15410',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left_shoulder',\n            id=0,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        1:\n        dict(\n            name='right_shoulder',\n            id=1,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        2:\n        dict(\n            name='left_elbow',\n            id=2,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        3:\n        dict(\n            name='right_elbow',\n            id=3,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        4:\n        dict(\n            name='left_wrist',\n            id=4,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        5:\n        dict(\n            name='right_wrist',\n            id=5,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        6:\n        dict(\n            name='left_hip',\n            id=6,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        7:\n        dict(\n            name='right_hip',\n            id=7,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        8:\n        dict(\n            name='left_knee',\n            id=8,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='left_ankle',\n            id=10,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        11:\n        dict(\n            name='right_ankle',\n            id=11,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        12:\n        dict(name='head', id=12, color=[51, 153, 255], type='upper', swap=''),\n        13:\n        dict(name='neck', id=13, color=[51, 153, 255], type='upper', swap='')\n    },\n    skeleton_info={\n        0: dict(link=('head', 'neck'), id=0, color=[51, 153, 255]),\n        1: dict(link=('neck', 'left_shoulder'), id=1, color=[51, 153, 255]),\n        2: dict(link=('neck', 'right_shoulder'), id=2, color=[51, 153, 255]),\n        3: dict(link=('left_shoulder', 'left_elbow'), id=3, color=[0, 255, 0]),\n        4: dict(link=('left_elbow', 'left_wrist'), id=4, color=[0, 255, 0]),\n        5: dict(\n            link=('right_shoulder', 'right_elbow'), id=5, color=[255, 128, 0]),\n        6:\n        dict(link=('right_elbow', 'right_wrist'), id=6, color=[255, 128, 0]),\n        7: dict(link=('neck', 'right_hip'), id=7, color=[51, 153, 255]),\n        8: dict(link=('neck', 'left_hip'), id=8, color=[51, 153, 255]),\n        9: dict(link=('right_hip', 'right_knee'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('right_knee', 'right_ankle'), id=10, color=[255, 128, 0]),\n        11: dict(link=('left_hip', 'left_knee'), id=11, color=[0, 255, 0]),\n        12: dict(link=('left_knee', 'left_ankle'), id=12, color=[0, 255, 0]),\n    },\n    joint_weights=[\n        0.2, 0.2, 0.2, 1.3, 1.5, 0.2, 1.3, 1.5, 0.2, 0.2, 0.5, 0.2, 0.2, 0.5\n    ],\n    sigmas=[\n        0.079, 0.079, 0.072, 0.072, 0.062, 0.062, 0.107, 0.107, 0.087, 0.087,\n        0.089, 0.089, 0.079, 0.079\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/fly.py",
    "content": "dataset_info = dict(\n    dataset_name='fly',\n    paper_info=dict(\n        author='Pereira, Talmo D and Aldarondo, Diego E and '\n        'Willmore, Lindsay and Kislin, Mikhail and '\n        'Wang, Samuel S-H and Murthy, Mala and Shaevitz, Joshua W',\n        title='Fast animal pose estimation using deep neural networks',\n        container='Nature methods',\n        year='2019',\n        homepage='https://github.com/jgraving/DeepPoseKit-Data',\n    ),\n    keypoint_info={\n        0:\n        dict(name='head', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='eyeL', id=1, color=[255, 255, 255], type='', swap='eyeR'),\n        2:\n        dict(name='eyeR', id=2, color=[255, 255, 255], type='', swap='eyeL'),\n        3:\n        dict(name='neck', id=3, color=[255, 255, 255], type='', swap=''),\n        4:\n        dict(name='thorax', id=4, color=[255, 255, 255], type='', swap=''),\n        5:\n        dict(name='abdomen', id=5, color=[255, 255, 255], type='', swap=''),\n        6:\n        dict(\n            name='forelegR1',\n            id=6,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL1'),\n        7:\n        dict(\n            name='forelegR2',\n            id=7,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL2'),\n        8:\n        dict(\n            name='forelegR3',\n            id=8,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL3'),\n        9:\n        dict(\n            name='forelegR4',\n            id=9,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL4'),\n        10:\n        dict(\n            name='midlegR1',\n            id=10,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL1'),\n        11:\n        dict(\n            name='midlegR2',\n            id=11,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL2'),\n        12:\n        dict(\n            name='midlegR3',\n            id=12,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL3'),\n        13:\n        dict(\n            name='midlegR4',\n            id=13,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL4'),\n        14:\n        dict(\n            name='hindlegR1',\n            id=14,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL1'),\n        15:\n        dict(\n            name='hindlegR2',\n            id=15,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL2'),\n        16:\n        dict(\n            name='hindlegR3',\n            id=16,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL3'),\n        17:\n        dict(\n            name='hindlegR4',\n            id=17,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL4'),\n        18:\n        dict(\n            name='forelegL1',\n            id=18,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR1'),\n        19:\n        dict(\n            name='forelegL2',\n            id=19,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR2'),\n        20:\n        dict(\n            name='forelegL3',\n            id=20,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR3'),\n        21:\n        dict(\n            name='forelegL4',\n            id=21,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR4'),\n        22:\n        dict(\n            name='midlegL1',\n            id=22,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR1'),\n        23:\n        dict(\n            name='midlegL2',\n            id=23,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR2'),\n        24:\n        dict(\n            name='midlegL3',\n            id=24,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR3'),\n        25:\n        dict(\n            name='midlegL4',\n            id=25,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR4'),\n        26:\n        dict(\n            name='hindlegL1',\n            id=26,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR1'),\n        27:\n        dict(\n            name='hindlegL2',\n            id=27,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR2'),\n        28:\n        dict(\n            name='hindlegL3',\n            id=28,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR3'),\n        29:\n        dict(\n            name='hindlegL4',\n            id=29,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR4'),\n        30:\n        dict(\n            name='wingL', id=30, color=[255, 255, 255], type='', swap='wingR'),\n        31:\n        dict(\n            name='wingR', id=31, color=[255, 255, 255], type='', swap='wingL'),\n    },\n    skeleton_info={\n        0: dict(link=('eyeL', 'head'), id=0, color=[255, 255, 255]),\n        1: dict(link=('eyeR', 'head'), id=1, color=[255, 255, 255]),\n        2: dict(link=('neck', 'head'), id=2, color=[255, 255, 255]),\n        3: dict(link=('thorax', 'neck'), id=3, color=[255, 255, 255]),\n        4: dict(link=('abdomen', 'thorax'), id=4, color=[255, 255, 255]),\n        5: dict(link=('forelegR2', 'forelegR1'), id=5, color=[255, 255, 255]),\n        6: dict(link=('forelegR3', 'forelegR2'), id=6, color=[255, 255, 255]),\n        7: dict(link=('forelegR4', 'forelegR3'), id=7, color=[255, 255, 255]),\n        8: dict(link=('midlegR2', 'midlegR1'), id=8, color=[255, 255, 255]),\n        9: dict(link=('midlegR3', 'midlegR2'), id=9, color=[255, 255, 255]),\n        10: dict(link=('midlegR4', 'midlegR3'), id=10, color=[255, 255, 255]),\n        11:\n        dict(link=('hindlegR2', 'hindlegR1'), id=11, color=[255, 255, 255]),\n        12:\n        dict(link=('hindlegR3', 'hindlegR2'), id=12, color=[255, 255, 255]),\n        13:\n        dict(link=('hindlegR4', 'hindlegR3'), id=13, color=[255, 255, 255]),\n        14:\n        dict(link=('forelegL2', 'forelegL1'), id=14, color=[255, 255, 255]),\n        15:\n        dict(link=('forelegL3', 'forelegL2'), id=15, color=[255, 255, 255]),\n        16:\n        dict(link=('forelegL4', 'forelegL3'), id=16, color=[255, 255, 255]),\n        17: dict(link=('midlegL2', 'midlegL1'), id=17, color=[255, 255, 255]),\n        18: dict(link=('midlegL3', 'midlegL2'), id=18, color=[255, 255, 255]),\n        19: dict(link=('midlegL4', 'midlegL3'), id=19, color=[255, 255, 255]),\n        20:\n        dict(link=('hindlegL2', 'hindlegL1'), id=20, color=[255, 255, 255]),\n        21:\n        dict(link=('hindlegL3', 'hindlegL2'), id=21, color=[255, 255, 255]),\n        22:\n        dict(link=('hindlegL4', 'hindlegL3'), id=22, color=[255, 255, 255]),\n        23: dict(link=('wingL', 'neck'), id=23, color=[255, 255, 255]),\n        24: dict(link=('wingR', 'neck'), id=24, color=[255, 255, 255])\n    },\n    joint_weights=[1.] * 32,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/freihand2d.py",
    "content": "dataset_info = dict(\n    dataset_name='freihand',\n    paper_info=dict(\n        author='Zimmermann, Christian and Ceylan, Duygu and '\n        'Yang, Jimei and Russell, Bryan and '\n        'Argus, Max and Brox, Thomas',\n        title='Freihand: A dataset for markerless capture of hand pose '\n        'and shape from single rgb images',\n        container='Proceedings of the IEEE International '\n        'Conference on Computer Vision',\n        year='2019',\n        homepage='https://lmb.informatik.uni-freiburg.de/projects/freihand/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='wrist', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='thumb1', id=1, color=[255, 128, 0], type='', swap=''),\n        2:\n        dict(name='thumb2', id=2, color=[255, 128, 0], type='', swap=''),\n        3:\n        dict(name='thumb3', id=3, color=[255, 128, 0], type='', swap=''),\n        4:\n        dict(name='thumb4', id=4, color=[255, 128, 0], type='', swap=''),\n        5:\n        dict(\n            name='forefinger1', id=5, color=[255, 153, 255], type='', swap=''),\n        6:\n        dict(\n            name='forefinger2', id=6, color=[255, 153, 255], type='', swap=''),\n        7:\n        dict(\n            name='forefinger3', id=7, color=[255, 153, 255], type='', swap=''),\n        8:\n        dict(\n            name='forefinger4', id=8, color=[255, 153, 255], type='', swap=''),\n        9:\n        dict(\n            name='middle_finger1',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        10:\n        dict(\n            name='middle_finger2',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        11:\n        dict(\n            name='middle_finger3',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        12:\n        dict(\n            name='middle_finger4',\n            id=12,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        13:\n        dict(\n            name='ring_finger1', id=13, color=[255, 51, 51], type='', swap=''),\n        14:\n        dict(\n            name='ring_finger2', id=14, color=[255, 51, 51], type='', swap=''),\n        15:\n        dict(\n            name='ring_finger3', id=15, color=[255, 51, 51], type='', swap=''),\n        16:\n        dict(\n            name='ring_finger4', id=16, color=[255, 51, 51], type='', swap=''),\n        17:\n        dict(name='pinky_finger1', id=17, color=[0, 255, 0], type='', swap=''),\n        18:\n        dict(name='pinky_finger2', id=18, color=[0, 255, 0], type='', swap=''),\n        19:\n        dict(name='pinky_finger3', id=19, color=[0, 255, 0], type='', swap=''),\n        20:\n        dict(name='pinky_finger4', id=20, color=[0, 255, 0], type='', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('wrist', 'thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('thumb1', 'thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('thumb2', 'thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('thumb3', 'thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('wrist', 'forefinger1'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('forefinger1', 'forefinger2'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('forefinger2', 'forefinger3'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('forefinger3', 'forefinger4'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('wrist', 'middle_finger1'), id=8, color=[102, 178, 255]),\n        9:\n        dict(\n            link=('middle_finger1', 'middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('middle_finger2', 'middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('middle_finger3', 'middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(link=('wrist', 'ring_finger1'), id=12, color=[255, 51, 51]),\n        13:\n        dict(\n            link=('ring_finger1', 'ring_finger2'), id=13, color=[255, 51, 51]),\n        14:\n        dict(\n            link=('ring_finger2', 'ring_finger3'), id=14, color=[255, 51, 51]),\n        15:\n        dict(\n            link=('ring_finger3', 'ring_finger4'), id=15, color=[255, 51, 51]),\n        16:\n        dict(link=('wrist', 'pinky_finger1'), id=16, color=[0, 255, 0]),\n        17:\n        dict(\n            link=('pinky_finger1', 'pinky_finger2'), id=17, color=[0, 255, 0]),\n        18:\n        dict(\n            link=('pinky_finger2', 'pinky_finger3'), id=18, color=[0, 255, 0]),\n        19:\n        dict(\n            link=('pinky_finger3', 'pinky_finger4'), id=19, color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 21,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/h36m.py",
    "content": "dataset_info = dict(\n    dataset_name='h36m',\n    paper_info=dict(\n        author='Ionescu, Catalin and Papava, Dragos and '\n        'Olaru, Vlad and Sminchisescu, Cristian',\n        title='Human3.6M: Large Scale Datasets and Predictive '\n        'Methods for 3D Human Sensing in Natural Environments',\n        container='IEEE Transactions on Pattern Analysis and '\n        'Machine Intelligence',\n        year='2014',\n        homepage='http://vision.imar.ro/human3.6m/description.php',\n    ),\n    keypoint_info={\n        0:\n        dict(name='root', id=0, color=[51, 153, 255], type='lower', swap=''),\n        1:\n        dict(\n            name='right_hip',\n            id=1,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        2:\n        dict(\n            name='right_knee',\n            id=2,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        3:\n        dict(\n            name='right_foot',\n            id=3,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_foot'),\n        4:\n        dict(\n            name='left_hip',\n            id=4,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        5:\n        dict(\n            name='left_knee',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        6:\n        dict(\n            name='left_foot',\n            id=6,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_foot'),\n        7:\n        dict(name='spine', id=7, color=[51, 153, 255], type='upper', swap=''),\n        8:\n        dict(name='thorax', id=8, color=[51, 153, 255], type='upper', swap=''),\n        9:\n        dict(\n            name='neck_base',\n            id=9,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        10:\n        dict(name='head', id=10, color=[51, 153, 255], type='upper', swap=''),\n        11:\n        dict(\n            name='left_shoulder',\n            id=11,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        12:\n        dict(\n            name='left_elbow',\n            id=12,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        13:\n        dict(\n            name='left_wrist',\n            id=13,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        14:\n        dict(\n            name='right_shoulder',\n            id=14,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        15:\n        dict(\n            name='right_elbow',\n            id=15,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        16:\n        dict(\n            name='right_wrist',\n            id=16,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist')\n    },\n    skeleton_info={\n        0:\n        dict(link=('root', 'left_hip'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_hip', 'left_knee'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('left_knee', 'left_foot'), id=2, color=[0, 255, 0]),\n        3:\n        dict(link=('root', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('right_hip', 'right_knee'), id=4, color=[255, 128, 0]),\n        5:\n        dict(link=('right_knee', 'right_foot'), id=5, color=[255, 128, 0]),\n        6:\n        dict(link=('root', 'spine'), id=6, color=[51, 153, 255]),\n        7:\n        dict(link=('spine', 'thorax'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('thorax', 'neck_base'), id=8, color=[51, 153, 255]),\n        9:\n        dict(link=('neck_base', 'head'), id=9, color=[51, 153, 255]),\n        10:\n        dict(link=('thorax', 'left_shoulder'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('left_shoulder', 'left_elbow'), id=11, color=[0, 255, 0]),\n        12:\n        dict(link=('left_elbow', 'left_wrist'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('thorax', 'right_shoulder'), id=13, color=[255, 128, 0]),\n        14:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=14, color=[255, 128,\n                                                                  0]),\n        15:\n        dict(link=('right_elbow', 'right_wrist'), id=15, color=[255, 128, 0])\n    },\n    joint_weights=[1.] * 17,\n    sigmas=[],\n    stats_info=dict(bbox_center=(528., 427.), bbox_scale=400.))\n"
  },
  {
    "path": "configs/_base_/datasets/h3wb.py",
    "content": "dataset_info = dict(\n    dataset_name='h3wb',\n    paper_info=dict(\n        author='Yue Zhu, Nermin Samet, David Picard',\n        title='H3WB: Human3.6M 3D WholeBody Dataset and Benchmark',\n        container='International Conf. on Computer Vision (ICCV)',\n        year='2023',\n        homepage='https://github.com/wholebody3d/wholebody3d',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(\n            name='left_big_toe',\n            id=17,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_big_toe'),\n        18:\n        dict(\n            name='left_small_toe',\n            id=18,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_small_toe'),\n        19:\n        dict(\n            name='left_heel',\n            id=19,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_heel'),\n        20:\n        dict(\n            name='right_big_toe',\n            id=20,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_big_toe'),\n        21:\n        dict(\n            name='right_small_toe',\n            id=21,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_small_toe'),\n        22:\n        dict(\n            name='right_heel',\n            id=22,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_heel'),\n        23:\n        dict(\n            name='face-0',\n            id=23,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-16'),\n        24:\n        dict(\n            name='face-1',\n            id=24,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-15'),\n        25:\n        dict(\n            name='face-2',\n            id=25,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-14'),\n        26:\n        dict(\n            name='face-3',\n            id=26,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-13'),\n        27:\n        dict(\n            name='face-4',\n            id=27,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-12'),\n        28:\n        dict(\n            name='face-5',\n            id=28,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-11'),\n        29:\n        dict(\n            name='face-6',\n            id=29,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-10'),\n        30:\n        dict(\n            name='face-7',\n            id=30,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-9'),\n        31:\n        dict(name='face-8', id=31, color=[247, 34, 5], type='upper', swap=''),\n        32:\n        dict(\n            name='face-9',\n            id=32,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-7'),\n        33:\n        dict(\n            name='face-10',\n            id=33,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-6'),\n        34:\n        dict(\n            name='face-11',\n            id=34,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-5'),\n        35:\n        dict(\n            name='face-12',\n            id=35,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-4'),\n        36:\n        dict(\n            name='face-13',\n            id=36,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-3'),\n        37:\n        dict(\n            name='face-14',\n            id=37,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-2'),\n        38:\n        dict(\n            name='face-15',\n            id=38,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-1'),\n        39:\n        dict(\n            name='face-16',\n            id=39,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-0'),\n        40:\n        dict(\n            name='face-17',\n            id=40,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-26'),\n        41:\n        dict(\n            name='face-18',\n            id=41,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-25'),\n        42:\n        dict(\n            name='face-19',\n            id=42,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-24'),\n        43:\n        dict(\n            name='face-20',\n            id=43,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-23'),\n        44:\n        dict(\n            name='face-21',\n            id=44,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-22'),\n        45:\n        dict(\n            name='face-22',\n            id=45,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-21'),\n        46:\n        dict(\n            name='face-23',\n            id=46,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-20'),\n        47:\n        dict(\n            name='face-24',\n            id=47,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-19'),\n        48:\n        dict(\n            name='face-25',\n            id=48,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-18'),\n        49:\n        dict(\n            name='face-26',\n            id=49,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-17'),\n        50:\n        dict(name='face-27', id=50, color=[247, 34, 5], type='upper', swap=''),\n        51:\n        dict(name='face-28', id=51, color=[247, 34, 5], type='upper', swap=''),\n        52:\n        dict(name='face-29', id=52, color=[247, 34, 5], type='upper', swap=''),\n        53:\n        dict(name='face-30', id=53, color=[247, 34, 5], type='upper', swap=''),\n        54:\n        dict(\n            name='face-31',\n            id=54,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-35'),\n        55:\n        dict(\n            name='face-32',\n            id=55,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-34'),\n        56:\n        dict(name='face-33', id=56, color=[247, 34, 5], type='upper', swap=''),\n        57:\n        dict(\n            name='face-34',\n            id=57,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-32'),\n        58:\n        dict(\n            name='face-35',\n            id=58,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-31'),\n        59:\n        dict(\n            name='face-36',\n            id=59,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-45'),\n        60:\n        dict(\n            name='face-37',\n            id=60,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-44'),\n        61:\n        dict(\n            name='face-38',\n            id=61,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-43'),\n        62:\n        dict(\n            name='face-39',\n            id=62,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-42'),\n        63:\n        dict(\n            name='face-40',\n            id=63,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-47'),\n        64:\n        dict(\n            name='face-41',\n            id=64,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-46'),\n        65:\n        dict(\n            name='face-42',\n            id=65,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-39'),\n        66:\n        dict(\n            name='face-43',\n            id=66,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-38'),\n        67:\n        dict(\n            name='face-44',\n            id=67,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-37'),\n        68:\n        dict(\n            name='face-45',\n            id=68,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-36'),\n        69:\n        dict(\n            name='face-46',\n            id=69,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-41'),\n        70:\n        dict(\n            name='face-47',\n            id=70,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-40'),\n        71:\n        dict(\n            name='face-48',\n            id=71,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-54'),\n        72:\n        dict(\n            name='face-49',\n            id=72,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-53'),\n        73:\n        dict(\n            name='face-50',\n            id=73,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-52'),\n        74:\n        dict(name='face-51', id=74, color=[247, 34, 5], type='upper', swap=''),\n        75:\n        dict(\n            name='face-52',\n            id=75,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-50'),\n        76:\n        dict(\n            name='face-53',\n            id=76,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-49'),\n        77:\n        dict(\n            name='face-54',\n            id=77,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-48'),\n        78:\n        dict(\n            name='face-55',\n            id=78,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-59'),\n        79:\n        dict(\n            name='face-56',\n            id=79,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-58'),\n        80:\n        dict(name='face-57', id=80, color=[247, 34, 5], type='upper', swap=''),\n        81:\n        dict(\n            name='face-58',\n            id=81,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-56'),\n        82:\n        dict(\n            name='face-59',\n            id=82,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-55'),\n        83:\n        dict(\n            name='face-60',\n            id=83,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-64'),\n        84:\n        dict(\n            name='face-61',\n            id=84,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-63'),\n        85:\n        dict(name='face-62', id=85, color=[247, 34, 5], type='upper', swap=''),\n        86:\n        dict(\n            name='face-63',\n            id=86,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-61'),\n        87:\n        dict(\n            name='face-64',\n            id=87,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-60'),\n        88:\n        dict(\n            name='face-65',\n            id=88,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-67'),\n        89:\n        dict(name='face-66', id=89, color=[247, 34, 5], type='upper', swap=''),\n        90:\n        dict(\n            name='face-67',\n            id=90,\n            color=[247, 34, 5],\n            type='upper',\n            swap='face-65'),\n        91:\n        dict(\n            name='left_hand_root',\n            id=91,\n            color=[247, 34, 5],\n            type='',\n            swap='right_hand_root'),\n        92:\n        dict(\n            name='left_thumb1',\n            id=92,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb1'),\n        93:\n        dict(\n            name='left_thumb2',\n            id=93,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb2'),\n        94:\n        dict(\n            name='left_thumb3',\n            id=94,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb3'),\n        95:\n        dict(\n            name='left_thumb4',\n            id=95,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb4'),\n        96:\n        dict(\n            name='left_forefinger1',\n            id=96,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger1'),\n        97:\n        dict(\n            name='left_forefinger2',\n            id=97,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger2'),\n        98:\n        dict(\n            name='left_forefinger3',\n            id=98,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger3'),\n        99:\n        dict(\n            name='left_forefinger4',\n            id=99,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger4'),\n        100:\n        dict(\n            name='left_middle_finger1',\n            id=100,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger1'),\n        101:\n        dict(\n            name='left_middle_finger2',\n            id=101,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger2'),\n        102:\n        dict(\n            name='left_middle_finger3',\n            id=102,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger3'),\n        103:\n        dict(\n            name='left_middle_finger4',\n            id=103,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger4'),\n        104:\n        dict(\n            name='left_ring_finger1',\n            id=104,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger1'),\n        105:\n        dict(\n            name='left_ring_finger2',\n            id=105,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger2'),\n        106:\n        dict(\n            name='left_ring_finger3',\n            id=106,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger3'),\n        107:\n        dict(\n            name='left_ring_finger4',\n            id=107,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger4'),\n        108:\n        dict(\n            name='left_pinky_finger1',\n            id=108,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger1'),\n        109:\n        dict(\n            name='left_pinky_finger2',\n            id=109,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger2'),\n        110:\n        dict(\n            name='left_pinky_finger3',\n            id=110,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger3'),\n        111:\n        dict(\n            name='left_pinky_finger4',\n            id=111,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger4'),\n        112:\n        dict(\n            name='right_hand_root',\n            id=112,\n            color=[247, 34, 5],\n            type='',\n            swap='left_hand_root'),\n        113:\n        dict(\n            name='right_thumb1',\n            id=113,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb1'),\n        114:\n        dict(\n            name='right_thumb2',\n            id=114,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb2'),\n        115:\n        dict(\n            name='right_thumb3',\n            id=115,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb3'),\n        116:\n        dict(\n            name='right_thumb4',\n            id=116,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb4'),\n        117:\n        dict(\n            name='right_forefinger1',\n            id=117,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger1'),\n        118:\n        dict(\n            name='right_forefinger2',\n            id=118,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger2'),\n        119:\n        dict(\n            name='right_forefinger3',\n            id=119,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger3'),\n        120:\n        dict(\n            name='right_forefinger4',\n            id=120,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger4'),\n        121:\n        dict(\n            name='right_middle_finger1',\n            id=121,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger1'),\n        122:\n        dict(\n            name='right_middle_finger2',\n            id=122,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger2'),\n        123:\n        dict(\n            name='right_middle_finger3',\n            id=123,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger3'),\n        124:\n        dict(\n            name='right_middle_finger4',\n            id=124,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger4'),\n        125:\n        dict(\n            name='right_ring_finger1',\n            id=125,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger1'),\n        126:\n        dict(\n            name='right_ring_finger2',\n            id=126,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger2'),\n        127:\n        dict(\n            name='right_ring_finger3',\n            id=127,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger3'),\n        128:\n        dict(\n            name='right_ring_finger4',\n            id=128,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger4'),\n        129:\n        dict(\n            name='right_pinky_finger1',\n            id=129,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger1'),\n        130:\n        dict(\n            name='right_pinky_finger2',\n            id=130,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger2'),\n        131:\n        dict(\n            name='right_pinky_finger3',\n            id=131,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger3'),\n        132:\n        dict(\n            name='right_pinky_finger4',\n            id=132,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger4')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('left_ankle', 'left_big_toe'), id=19, color=[0, 255, 0]),\n        20:\n        dict(link=('left_ankle', 'left_small_toe'), id=20, color=[0, 255, 0]),\n        21:\n        dict(link=('left_ankle', 'left_heel'), id=21, color=[0, 255, 0]),\n        22:\n        dict(\n            link=('right_ankle', 'right_big_toe'), id=22, color=[255, 128, 0]),\n        23:\n        dict(\n            link=('right_ankle', 'right_small_toe'),\n            id=23,\n            color=[255, 128, 0]),\n        24:\n        dict(link=('right_ankle', 'right_heel'), id=24, color=[255, 128, 0]),\n        25:\n        dict(\n            link=('left_hand_root', 'left_thumb1'), id=25, color=[255, 128,\n                                                                  0]),\n        26:\n        dict(link=('left_thumb1', 'left_thumb2'), id=26, color=[255, 128, 0]),\n        27:\n        dict(link=('left_thumb2', 'left_thumb3'), id=27, color=[255, 128, 0]),\n        28:\n        dict(link=('left_thumb3', 'left_thumb4'), id=28, color=[255, 128, 0]),\n        29:\n        dict(\n            link=('left_hand_root', 'left_forefinger1'),\n            id=29,\n            color=[255, 153, 255]),\n        30:\n        dict(\n            link=('left_forefinger1', 'left_forefinger2'),\n            id=30,\n            color=[255, 153, 255]),\n        31:\n        dict(\n            link=('left_forefinger2', 'left_forefinger3'),\n            id=31,\n            color=[255, 153, 255]),\n        32:\n        dict(\n            link=('left_forefinger3', 'left_forefinger4'),\n            id=32,\n            color=[255, 153, 255]),\n        33:\n        dict(\n            link=('left_hand_root', 'left_middle_finger1'),\n            id=33,\n            color=[102, 178, 255]),\n        34:\n        dict(\n            link=('left_middle_finger1', 'left_middle_finger2'),\n            id=34,\n            color=[102, 178, 255]),\n        35:\n        dict(\n            link=('left_middle_finger2', 'left_middle_finger3'),\n            id=35,\n            color=[102, 178, 255]),\n        36:\n        dict(\n            link=('left_middle_finger3', 'left_middle_finger4'),\n            id=36,\n            color=[102, 178, 255]),\n        37:\n        dict(\n            link=('left_hand_root', 'left_ring_finger1'),\n            id=37,\n            color=[255, 51, 51]),\n        38:\n        dict(\n            link=('left_ring_finger1', 'left_ring_finger2'),\n            id=38,\n            color=[255, 51, 51]),\n        39:\n        dict(\n            link=('left_ring_finger2', 'left_ring_finger3'),\n            id=39,\n            color=[255, 51, 51]),\n        40:\n        dict(\n            link=('left_ring_finger3', 'left_ring_finger4'),\n            id=40,\n            color=[255, 51, 51]),\n        41:\n        dict(\n            link=('left_hand_root', 'left_pinky_finger1'),\n            id=41,\n            color=[0, 255, 0]),\n        42:\n        dict(\n            link=('left_pinky_finger1', 'left_pinky_finger2'),\n            id=42,\n            color=[0, 255, 0]),\n        43:\n        dict(\n            link=('left_pinky_finger2', 'left_pinky_finger3'),\n            id=43,\n            color=[0, 255, 0]),\n        44:\n        dict(\n            link=('left_pinky_finger3', 'left_pinky_finger4'),\n            id=44,\n            color=[0, 255, 0]),\n        45:\n        dict(\n            link=('right_hand_root', 'right_thumb1'),\n            id=45,\n            color=[255, 128, 0]),\n        46:\n        dict(\n            link=('right_thumb1', 'right_thumb2'), id=46, color=[255, 128, 0]),\n        47:\n        dict(\n            link=('right_thumb2', 'right_thumb3'), id=47, color=[255, 128, 0]),\n        48:\n        dict(\n            link=('right_thumb3', 'right_thumb4'), id=48, color=[255, 128, 0]),\n        49:\n        dict(\n            link=('right_hand_root', 'right_forefinger1'),\n            id=49,\n            color=[255, 153, 255]),\n        50:\n        dict(\n            link=('right_forefinger1', 'right_forefinger2'),\n            id=50,\n            color=[255, 153, 255]),\n        51:\n        dict(\n            link=('right_forefinger2', 'right_forefinger3'),\n            id=51,\n            color=[255, 153, 255]),\n        52:\n        dict(\n            link=('right_forefinger3', 'right_forefinger4'),\n            id=52,\n            color=[255, 153, 255]),\n        53:\n        dict(\n            link=('right_hand_root', 'right_middle_finger1'),\n            id=53,\n            color=[102, 178, 255]),\n        54:\n        dict(\n            link=('right_middle_finger1', 'right_middle_finger2'),\n            id=54,\n            color=[102, 178, 255]),\n        55:\n        dict(\n            link=('right_middle_finger2', 'right_middle_finger3'),\n            id=55,\n            color=[102, 178, 255]),\n        56:\n        dict(\n            link=('right_middle_finger3', 'right_middle_finger4'),\n            id=56,\n            color=[102, 178, 255]),\n        57:\n        dict(\n            link=('right_hand_root', 'right_ring_finger1'),\n            id=57,\n            color=[255, 51, 51]),\n        58:\n        dict(\n            link=('right_ring_finger1', 'right_ring_finger2'),\n            id=58,\n            color=[255, 51, 51]),\n        59:\n        dict(\n            link=('right_ring_finger2', 'right_ring_finger3'),\n            id=59,\n            color=[255, 51, 51]),\n        60:\n        dict(\n            link=('right_ring_finger3', 'right_ring_finger4'),\n            id=60,\n            color=[255, 51, 51]),\n        61:\n        dict(\n            link=('right_hand_root', 'right_pinky_finger1'),\n            id=61,\n            color=[0, 255, 0]),\n        62:\n        dict(\n            link=('right_pinky_finger1', 'right_pinky_finger2'),\n            id=62,\n            color=[0, 255, 0]),\n        63:\n        dict(\n            link=('right_pinky_finger2', 'right_pinky_finger3'),\n            id=63,\n            color=[0, 255, 0]),\n        64:\n        dict(\n            link=('right_pinky_finger3', 'right_pinky_finger4'),\n            id=64,\n            color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 133,\n    # 'https://github.com/jin-s13/COCO-WholeBody/blob/master/'\n    # 'evaluation/myeval_wholebody.py#L175'\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.068, 0.066, 0.066,\n        0.092, 0.094, 0.094, 0.042, 0.043, 0.044, 0.043, 0.040, 0.035, 0.031,\n        0.025, 0.020, 0.023, 0.029, 0.032, 0.037, 0.038, 0.043, 0.041, 0.045,\n        0.013, 0.012, 0.011, 0.011, 0.012, 0.012, 0.011, 0.011, 0.013, 0.015,\n        0.009, 0.007, 0.007, 0.007, 0.012, 0.009, 0.008, 0.016, 0.010, 0.017,\n        0.011, 0.009, 0.011, 0.009, 0.007, 0.013, 0.008, 0.011, 0.012, 0.010,\n        0.034, 0.008, 0.008, 0.009, 0.008, 0.008, 0.007, 0.010, 0.008, 0.009,\n        0.009, 0.009, 0.007, 0.007, 0.008, 0.011, 0.008, 0.008, 0.008, 0.01,\n        0.008, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024, 0.035,\n        0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02, 0.019,\n        0.022, 0.031, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024,\n        0.035, 0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02,\n        0.019, 0.022, 0.031\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/halpe.py",
    "content": "dataset_info = dict(\n    dataset_name='halpe',\n    paper_info=dict(\n        author='Li, Yong-Lu and Xu, Liang and Liu, Xinpeng and Huang, Xijie'\n        ' and Xu, Yue and Wang, Shiyi and Fang, Hao-Shu'\n        ' and Ma, Ze and Chen, Mingyang and Lu, Cewu',\n        title='PaStaNet: Toward Human Activity Knowledge Engine',\n        container='CVPR',\n        year='2020',\n        homepage='https://github.com/Fang-Haoshu/Halpe-FullBody/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(name='head', id=17, color=[255, 128, 0], type='upper', swap=''),\n        18:\n        dict(name='neck', id=18, color=[255, 128, 0], type='upper', swap=''),\n        19:\n        dict(name='hip', id=19, color=[255, 128, 0], type='lower', swap=''),\n        20:\n        dict(\n            name='left_big_toe',\n            id=20,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_big_toe'),\n        21:\n        dict(\n            name='right_big_toe',\n            id=21,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_big_toe'),\n        22:\n        dict(\n            name='left_small_toe',\n            id=22,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_small_toe'),\n        23:\n        dict(\n            name='right_small_toe',\n            id=23,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_small_toe'),\n        24:\n        dict(\n            name='left_heel',\n            id=24,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_heel'),\n        25:\n        dict(\n            name='right_heel',\n            id=25,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_heel'),\n        26:\n        dict(\n            name='face-0',\n            id=26,\n            color=[255, 255, 255],\n            type='',\n            swap='face-16'),\n        27:\n        dict(\n            name='face-1',\n            id=27,\n            color=[255, 255, 255],\n            type='',\n            swap='face-15'),\n        28:\n        dict(\n            name='face-2',\n            id=28,\n            color=[255, 255, 255],\n            type='',\n            swap='face-14'),\n        29:\n        dict(\n            name='face-3',\n            id=29,\n            color=[255, 255, 255],\n            type='',\n            swap='face-13'),\n        30:\n        dict(\n            name='face-4',\n            id=30,\n            color=[255, 255, 255],\n            type='',\n            swap='face-12'),\n        31:\n        dict(\n            name='face-5',\n            id=31,\n            color=[255, 255, 255],\n            type='',\n            swap='face-11'),\n        32:\n        dict(\n            name='face-6',\n            id=32,\n            color=[255, 255, 255],\n            type='',\n            swap='face-10'),\n        33:\n        dict(\n            name='face-7',\n            id=33,\n            color=[255, 255, 255],\n            type='',\n            swap='face-9'),\n        34:\n        dict(name='face-8', id=34, color=[255, 255, 255], type='', swap=''),\n        35:\n        dict(\n            name='face-9',\n            id=35,\n            color=[255, 255, 255],\n            type='',\n            swap='face-7'),\n        36:\n        dict(\n            name='face-10',\n            id=36,\n            color=[255, 255, 255],\n            type='',\n            swap='face-6'),\n        37:\n        dict(\n            name='face-11',\n            id=37,\n            color=[255, 255, 255],\n            type='',\n            swap='face-5'),\n        38:\n        dict(\n            name='face-12',\n            id=38,\n            color=[255, 255, 255],\n            type='',\n            swap='face-4'),\n        39:\n        dict(\n            name='face-13',\n            id=39,\n            color=[255, 255, 255],\n            type='',\n            swap='face-3'),\n        40:\n        dict(\n            name='face-14',\n            id=40,\n            color=[255, 255, 255],\n            type='',\n            swap='face-2'),\n        41:\n        dict(\n            name='face-15',\n            id=41,\n            color=[255, 255, 255],\n            type='',\n            swap='face-1'),\n        42:\n        dict(\n            name='face-16',\n            id=42,\n            color=[255, 255, 255],\n            type='',\n            swap='face-0'),\n        43:\n        dict(\n            name='face-17',\n            id=43,\n            color=[255, 255, 255],\n            type='',\n            swap='face-26'),\n        44:\n        dict(\n            name='face-18',\n            id=44,\n            color=[255, 255, 255],\n            type='',\n            swap='face-25'),\n        45:\n        dict(\n            name='face-19',\n            id=45,\n            color=[255, 255, 255],\n            type='',\n            swap='face-24'),\n        46:\n        dict(\n            name='face-20',\n            id=46,\n            color=[255, 255, 255],\n            type='',\n            swap='face-23'),\n        47:\n        dict(\n            name='face-21',\n            id=47,\n            color=[255, 255, 255],\n            type='',\n            swap='face-22'),\n        48:\n        dict(\n            name='face-22',\n            id=48,\n            color=[255, 255, 255],\n            type='',\n            swap='face-21'),\n        49:\n        dict(\n            name='face-23',\n            id=49,\n            color=[255, 255, 255],\n            type='',\n            swap='face-20'),\n        50:\n        dict(\n            name='face-24',\n            id=50,\n            color=[255, 255, 255],\n            type='',\n            swap='face-19'),\n        51:\n        dict(\n            name='face-25',\n            id=51,\n            color=[255, 255, 255],\n            type='',\n            swap='face-18'),\n        52:\n        dict(\n            name='face-26',\n            id=52,\n            color=[255, 255, 255],\n            type='',\n            swap='face-17'),\n        53:\n        dict(name='face-27', id=53, color=[255, 255, 255], type='', swap=''),\n        54:\n        dict(name='face-28', id=54, color=[255, 255, 255], type='', swap=''),\n        55:\n        dict(name='face-29', id=55, color=[255, 255, 255], type='', swap=''),\n        56:\n        dict(name='face-30', id=56, color=[255, 255, 255], type='', swap=''),\n        57:\n        dict(\n            name='face-31',\n            id=57,\n            color=[255, 255, 255],\n            type='',\n            swap='face-35'),\n        58:\n        dict(\n            name='face-32',\n            id=58,\n            color=[255, 255, 255],\n            type='',\n            swap='face-34'),\n        59:\n        dict(name='face-33', id=59, color=[255, 255, 255], type='', swap=''),\n        60:\n        dict(\n            name='face-34',\n            id=60,\n            color=[255, 255, 255],\n            type='',\n            swap='face-32'),\n        61:\n        dict(\n            name='face-35',\n            id=61,\n            color=[255, 255, 255],\n            type='',\n            swap='face-31'),\n        62:\n        dict(\n            name='face-36',\n            id=62,\n            color=[255, 255, 255],\n            type='',\n            swap='face-45'),\n        63:\n        dict(\n            name='face-37',\n            id=63,\n            color=[255, 255, 255],\n            type='',\n            swap='face-44'),\n        64:\n        dict(\n            name='face-38',\n            id=64,\n            color=[255, 255, 255],\n            type='',\n            swap='face-43'),\n        65:\n        dict(\n            name='face-39',\n            id=65,\n            color=[255, 255, 255],\n            type='',\n            swap='face-42'),\n        66:\n        dict(\n            name='face-40',\n            id=66,\n            color=[255, 255, 255],\n            type='',\n            swap='face-47'),\n        67:\n        dict(\n            name='face-41',\n            id=67,\n            color=[255, 255, 255],\n            type='',\n            swap='face-46'),\n        68:\n        dict(\n            name='face-42',\n            id=68,\n            color=[255, 255, 255],\n            type='',\n            swap='face-39'),\n        69:\n        dict(\n            name='face-43',\n            id=69,\n            color=[255, 255, 255],\n            type='',\n            swap='face-38'),\n        70:\n        dict(\n            name='face-44',\n            id=70,\n            color=[255, 255, 255],\n            type='',\n            swap='face-37'),\n        71:\n        dict(\n            name='face-45',\n            id=71,\n            color=[255, 255, 255],\n            type='',\n            swap='face-36'),\n        72:\n        dict(\n            name='face-46',\n            id=72,\n            color=[255, 255, 255],\n            type='',\n            swap='face-41'),\n        73:\n        dict(\n            name='face-47',\n            id=73,\n            color=[255, 255, 255],\n            type='',\n            swap='face-40'),\n        74:\n        dict(\n            name='face-48',\n            id=74,\n            color=[255, 255, 255],\n            type='',\n            swap='face-54'),\n        75:\n        dict(\n            name='face-49',\n            id=75,\n            color=[255, 255, 255],\n            type='',\n            swap='face-53'),\n        76:\n        dict(\n            name='face-50',\n            id=76,\n            color=[255, 255, 255],\n            type='',\n            swap='face-52'),\n        77:\n        dict(name='face-51', id=77, color=[255, 255, 255], type='', swap=''),\n        78:\n        dict(\n            name='face-52',\n            id=78,\n            color=[255, 255, 255],\n            type='',\n            swap='face-50'),\n        79:\n        dict(\n            name='face-53',\n            id=79,\n            color=[255, 255, 255],\n            type='',\n            swap='face-49'),\n        80:\n        dict(\n            name='face-54',\n            id=80,\n            color=[255, 255, 255],\n            type='',\n            swap='face-48'),\n        81:\n        dict(\n            name='face-55',\n            id=81,\n            color=[255, 255, 255],\n            type='',\n            swap='face-59'),\n        82:\n        dict(\n            name='face-56',\n            id=82,\n            color=[255, 255, 255],\n            type='',\n            swap='face-58'),\n        83:\n        dict(name='face-57', id=83, color=[255, 255, 255], type='', swap=''),\n        84:\n        dict(\n            name='face-58',\n            id=84,\n            color=[255, 255, 255],\n            type='',\n            swap='face-56'),\n        85:\n        dict(\n            name='face-59',\n            id=85,\n            color=[255, 255, 255],\n            type='',\n            swap='face-55'),\n        86:\n        dict(\n            name='face-60',\n            id=86,\n            color=[255, 255, 255],\n            type='',\n            swap='face-64'),\n        87:\n        dict(\n            name='face-61',\n            id=87,\n            color=[255, 255, 255],\n            type='',\n            swap='face-63'),\n        88:\n        dict(name='face-62', id=88, color=[255, 255, 255], type='', swap=''),\n        89:\n        dict(\n            name='face-63',\n            id=89,\n            color=[255, 255, 255],\n            type='',\n            swap='face-61'),\n        90:\n        dict(\n            name='face-64',\n            id=90,\n            color=[255, 255, 255],\n            type='',\n            swap='face-60'),\n        91:\n        dict(\n            name='face-65',\n            id=91,\n            color=[255, 255, 255],\n            type='',\n            swap='face-67'),\n        92:\n        dict(name='face-66', id=92, color=[255, 255, 255], type='', swap=''),\n        93:\n        dict(\n            name='face-67',\n            id=93,\n            color=[255, 255, 255],\n            type='',\n            swap='face-65'),\n        94:\n        dict(\n            name='left_hand_root',\n            id=94,\n            color=[255, 255, 255],\n            type='',\n            swap='right_hand_root'),\n        95:\n        dict(\n            name='left_thumb1',\n            id=95,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb1'),\n        96:\n        dict(\n            name='left_thumb2',\n            id=96,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb2'),\n        97:\n        dict(\n            name='left_thumb3',\n            id=97,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb3'),\n        98:\n        dict(\n            name='left_thumb4',\n            id=98,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb4'),\n        99:\n        dict(\n            name='left_forefinger1',\n            id=99,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger1'),\n        100:\n        dict(\n            name='left_forefinger2',\n            id=100,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger2'),\n        101:\n        dict(\n            name='left_forefinger3',\n            id=101,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger3'),\n        102:\n        dict(\n            name='left_forefinger4',\n            id=102,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger4'),\n        103:\n        dict(\n            name='left_middle_finger1',\n            id=103,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger1'),\n        104:\n        dict(\n            name='left_middle_finger2',\n            id=104,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger2'),\n        105:\n        dict(\n            name='left_middle_finger3',\n            id=105,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger3'),\n        106:\n        dict(\n            name='left_middle_finger4',\n            id=106,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger4'),\n        107:\n        dict(\n            name='left_ring_finger1',\n            id=107,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger1'),\n        108:\n        dict(\n            name='left_ring_finger2',\n            id=108,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger2'),\n        109:\n        dict(\n            name='left_ring_finger3',\n            id=109,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger3'),\n        110:\n        dict(\n            name='left_ring_finger4',\n            id=110,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger4'),\n        111:\n        dict(\n            name='left_pinky_finger1',\n            id=111,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger1'),\n        112:\n        dict(\n            name='left_pinky_finger2',\n            id=112,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger2'),\n        113:\n        dict(\n            name='left_pinky_finger3',\n            id=113,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger3'),\n        114:\n        dict(\n            name='left_pinky_finger4',\n            id=114,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger4'),\n        115:\n        dict(\n            name='right_hand_root',\n            id=115,\n            color=[255, 255, 255],\n            type='',\n            swap='left_hand_root'),\n        116:\n        dict(\n            name='right_thumb1',\n            id=116,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb1'),\n        117:\n        dict(\n            name='right_thumb2',\n            id=117,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb2'),\n        118:\n        dict(\n            name='right_thumb3',\n            id=118,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb3'),\n        119:\n        dict(\n            name='right_thumb4',\n            id=119,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb4'),\n        120:\n        dict(\n            name='right_forefinger1',\n            id=120,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger1'),\n        121:\n        dict(\n            name='right_forefinger2',\n            id=121,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger2'),\n        122:\n        dict(\n            name='right_forefinger3',\n            id=122,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger3'),\n        123:\n        dict(\n            name='right_forefinger4',\n            id=123,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger4'),\n        124:\n        dict(\n            name='right_middle_finger1',\n            id=124,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger1'),\n        125:\n        dict(\n            name='right_middle_finger2',\n            id=125,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger2'),\n        126:\n        dict(\n            name='right_middle_finger3',\n            id=126,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger3'),\n        127:\n        dict(\n            name='right_middle_finger4',\n            id=127,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger4'),\n        128:\n        dict(\n            name='right_ring_finger1',\n            id=128,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger1'),\n        129:\n        dict(\n            name='right_ring_finger2',\n            id=129,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger2'),\n        130:\n        dict(\n            name='right_ring_finger3',\n            id=130,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger3'),\n        131:\n        dict(\n            name='right_ring_finger4',\n            id=131,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger4'),\n        132:\n        dict(\n            name='right_pinky_finger1',\n            id=132,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger1'),\n        133:\n        dict(\n            name='right_pinky_finger2',\n            id=133,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger2'),\n        134:\n        dict(\n            name='right_pinky_finger3',\n            id=134,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger3'),\n        135:\n        dict(\n            name='right_pinky_finger4',\n            id=135,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger4')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('left_hip', 'hip'), id=2, color=[0, 255, 0]),\n        3:\n        dict(link=('right_ankle', 'right_knee'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('right_knee', 'right_hip'), id=4, color=[255, 128, 0]),\n        5:\n        dict(link=('right_hip', 'hip'), id=5, color=[255, 128, 0]),\n        6:\n        dict(link=('head', 'neck'), id=6, color=[51, 153, 255]),\n        7:\n        dict(link=('neck', 'hip'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('neck', 'left_shoulder'), id=8, color=[0, 255, 0]),\n        9:\n        dict(link=('left_shoulder', 'left_elbow'), id=9, color=[0, 255, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('neck', 'right_shoulder'), id=11, color=[255, 128, 0]),\n        12:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=12, color=[255, 128,\n                                                                  0]),\n        13:\n        dict(link=('right_elbow', 'right_wrist'), id=13, color=[255, 128, 0]),\n        14:\n        dict(link=('left_eye', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('nose', 'left_eye'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('nose', 'right_eye'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_eye', 'left_ear'), id=17, color=[51, 153, 255]),\n        18:\n        dict(link=('right_eye', 'right_ear'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('left_ear', 'left_shoulder'), id=19, color=[51, 153, 255]),\n        20:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=20, color=[51, 153, 255]),\n        21:\n        dict(link=('left_ankle', 'left_big_toe'), id=21, color=[0, 255, 0]),\n        22:\n        dict(link=('left_ankle', 'left_small_toe'), id=22, color=[0, 255, 0]),\n        23:\n        dict(link=('left_ankle', 'left_heel'), id=23, color=[0, 255, 0]),\n        24:\n        dict(\n            link=('right_ankle', 'right_big_toe'), id=24, color=[255, 128, 0]),\n        25:\n        dict(\n            link=('right_ankle', 'right_small_toe'),\n            id=25,\n            color=[255, 128, 0]),\n        26:\n        dict(link=('right_ankle', 'right_heel'), id=26, color=[255, 128, 0]),\n        27:\n        dict(link=('left_wrist', 'left_thumb1'), id=27, color=[255, 128, 0]),\n        28:\n        dict(link=('left_thumb1', 'left_thumb2'), id=28, color=[255, 128, 0]),\n        29:\n        dict(link=('left_thumb2', 'left_thumb3'), id=29, color=[255, 128, 0]),\n        30:\n        dict(link=('left_thumb3', 'left_thumb4'), id=30, color=[255, 128, 0]),\n        31:\n        dict(\n            link=('left_wrist', 'left_forefinger1'),\n            id=31,\n            color=[255, 153, 255]),\n        32:\n        dict(\n            link=('left_forefinger1', 'left_forefinger2'),\n            id=32,\n            color=[255, 153, 255]),\n        33:\n        dict(\n            link=('left_forefinger2', 'left_forefinger3'),\n            id=33,\n            color=[255, 153, 255]),\n        34:\n        dict(\n            link=('left_forefinger3', 'left_forefinger4'),\n            id=34,\n            color=[255, 153, 255]),\n        35:\n        dict(\n            link=('left_wrist', 'left_middle_finger1'),\n            id=35,\n            color=[102, 178, 255]),\n        36:\n        dict(\n            link=('left_middle_finger1', 'left_middle_finger2'),\n            id=36,\n            color=[102, 178, 255]),\n        37:\n        dict(\n            link=('left_middle_finger2', 'left_middle_finger3'),\n            id=37,\n            color=[102, 178, 255]),\n        38:\n        dict(\n            link=('left_middle_finger3', 'left_middle_finger4'),\n            id=38,\n            color=[102, 178, 255]),\n        39:\n        dict(\n            link=('left_wrist', 'left_ring_finger1'),\n            id=39,\n            color=[255, 51, 51]),\n        40:\n        dict(\n            link=('left_ring_finger1', 'left_ring_finger2'),\n            id=40,\n            color=[255, 51, 51]),\n        41:\n        dict(\n            link=('left_ring_finger2', 'left_ring_finger3'),\n            id=41,\n            color=[255, 51, 51]),\n        42:\n        dict(\n            link=('left_ring_finger3', 'left_ring_finger4'),\n            id=42,\n            color=[255, 51, 51]),\n        43:\n        dict(\n            link=('left_wrist', 'left_pinky_finger1'),\n            id=43,\n            color=[0, 255, 0]),\n        44:\n        dict(\n            link=('left_pinky_finger1', 'left_pinky_finger2'),\n            id=44,\n            color=[0, 255, 0]),\n        45:\n        dict(\n            link=('left_pinky_finger2', 'left_pinky_finger3'),\n            id=45,\n            color=[0, 255, 0]),\n        46:\n        dict(\n            link=('left_pinky_finger3', 'left_pinky_finger4'),\n            id=46,\n            color=[0, 255, 0]),\n        47:\n        dict(link=('right_wrist', 'right_thumb1'), id=47, color=[255, 128, 0]),\n        48:\n        dict(\n            link=('right_thumb1', 'right_thumb2'), id=48, color=[255, 128, 0]),\n        49:\n        dict(\n            link=('right_thumb2', 'right_thumb3'), id=49, color=[255, 128, 0]),\n        50:\n        dict(\n            link=('right_thumb3', 'right_thumb4'), id=50, color=[255, 128, 0]),\n        51:\n        dict(\n            link=('right_wrist', 'right_forefinger1'),\n            id=51,\n            color=[255, 153, 255]),\n        52:\n        dict(\n            link=('right_forefinger1', 'right_forefinger2'),\n            id=52,\n            color=[255, 153, 255]),\n        53:\n        dict(\n            link=('right_forefinger2', 'right_forefinger3'),\n            id=53,\n            color=[255, 153, 255]),\n        54:\n        dict(\n            link=('right_forefinger3', 'right_forefinger4'),\n            id=54,\n            color=[255, 153, 255]),\n        55:\n        dict(\n            link=('right_wrist', 'right_middle_finger1'),\n            id=55,\n            color=[102, 178, 255]),\n        56:\n        dict(\n            link=('right_middle_finger1', 'right_middle_finger2'),\n            id=56,\n            color=[102, 178, 255]),\n        57:\n        dict(\n            link=('right_middle_finger2', 'right_middle_finger3'),\n            id=57,\n            color=[102, 178, 255]),\n        58:\n        dict(\n            link=('right_middle_finger3', 'right_middle_finger4'),\n            id=58,\n            color=[102, 178, 255]),\n        59:\n        dict(\n            link=('right_wrist', 'right_ring_finger1'),\n            id=59,\n            color=[255, 51, 51]),\n        60:\n        dict(\n            link=('right_ring_finger1', 'right_ring_finger2'),\n            id=60,\n            color=[255, 51, 51]),\n        61:\n        dict(\n            link=('right_ring_finger2', 'right_ring_finger3'),\n            id=61,\n            color=[255, 51, 51]),\n        62:\n        dict(\n            link=('right_ring_finger3', 'right_ring_finger4'),\n            id=62,\n            color=[255, 51, 51]),\n        63:\n        dict(\n            link=('right_wrist', 'right_pinky_finger1'),\n            id=63,\n            color=[0, 255, 0]),\n        64:\n        dict(\n            link=('right_pinky_finger1', 'right_pinky_finger2'),\n            id=64,\n            color=[0, 255, 0]),\n        65:\n        dict(\n            link=('right_pinky_finger2', 'right_pinky_finger3'),\n            id=65,\n            color=[0, 255, 0]),\n        66:\n        dict(\n            link=('right_pinky_finger3', 'right_pinky_finger4'),\n            id=66,\n            color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 136,\n\n    # 'https://github.com/Fang-Haoshu/Halpe-FullBody/blob/master/'\n    # 'HalpeCOCOAPI/PythonAPI/halpecocotools/cocoeval.py#L245'\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.08, 0.08, 0.08,\n        0.089, 0.089, 0.089, 0.089, 0.089, 0.089, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015, 0.015,\n        0.015, 0.015, 0.015, 0.015, 0.015, 0.015\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/halpe26.py",
    "content": "dataset_info = dict(\n    dataset_name='halpe26',\n    paper_info=dict(\n        author='Li, Yong-Lu and Xu, Liang and Liu, Xinpeng and Huang, Xijie'\n        ' and Xu, Yue and Wang, Shiyi and Fang, Hao-Shu'\n        ' and Ma, Ze and Chen, Mingyang and Lu, Cewu',\n        title='PaStaNet: Toward Human Activity Knowledge Engine',\n        container='CVPR',\n        year='2020',\n        homepage='https://github.com/Fang-Haoshu/Halpe-FullBody/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(name='head', id=17, color=[255, 128, 0], type='upper', swap=''),\n        18:\n        dict(name='neck', id=18, color=[255, 128, 0], type='upper', swap=''),\n        19:\n        dict(name='hip', id=19, color=[255, 128, 0], type='lower', swap=''),\n        20:\n        dict(\n            name='left_big_toe',\n            id=20,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_big_toe'),\n        21:\n        dict(\n            name='right_big_toe',\n            id=21,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_big_toe'),\n        22:\n        dict(\n            name='left_small_toe',\n            id=22,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_small_toe'),\n        23:\n        dict(\n            name='right_small_toe',\n            id=23,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_small_toe'),\n        24:\n        dict(\n            name='left_heel',\n            id=24,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_heel'),\n        25:\n        dict(\n            name='right_heel',\n            id=25,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_heel')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('left_hip', 'hip'), id=2, color=[0, 255, 0]),\n        3:\n        dict(link=('right_ankle', 'right_knee'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('right_knee', 'right_hip'), id=4, color=[255, 128, 0]),\n        5:\n        dict(link=('right_hip', 'hip'), id=5, color=[255, 128, 0]),\n        6:\n        dict(link=('head', 'neck'), id=6, color=[51, 153, 255]),\n        7:\n        dict(link=('neck', 'hip'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('neck', 'left_shoulder'), id=8, color=[0, 255, 0]),\n        9:\n        dict(link=('left_shoulder', 'left_elbow'), id=9, color=[0, 255, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('neck', 'right_shoulder'), id=11, color=[255, 128, 0]),\n        12:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=12, color=[255, 128,\n                                                                  0]),\n        13:\n        dict(link=('right_elbow', 'right_wrist'), id=13, color=[255, 128, 0]),\n        14:\n        dict(link=('left_eye', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('nose', 'left_eye'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('nose', 'right_eye'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_eye', 'left_ear'), id=17, color=[51, 153, 255]),\n        18:\n        dict(link=('right_eye', 'right_ear'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('left_ear', 'left_shoulder'), id=19, color=[51, 153, 255]),\n        20:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=20, color=[51, 153, 255]),\n        21:\n        dict(link=('left_ankle', 'left_big_toe'), id=21, color=[0, 255, 0]),\n        22:\n        dict(link=('left_ankle', 'left_small_toe'), id=22, color=[0, 255, 0]),\n        23:\n        dict(link=('left_ankle', 'left_heel'), id=23, color=[0, 255, 0]),\n        24:\n        dict(\n            link=('right_ankle', 'right_big_toe'), id=24, color=[255, 128, 0]),\n        25:\n        dict(\n            link=('right_ankle', 'right_small_toe'),\n            id=25,\n            color=[255, 128, 0]),\n        26:\n        dict(link=('right_ankle', 'right_heel'), id=26, color=[255, 128, 0]),\n    },\n    # the joint_weights is modified by MMPose Team\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ] + [1., 1., 1.2] + [1.5] * 6,\n\n    # 'https://github.com/Fang-Haoshu/Halpe-FullBody/blob/master/'\n    # 'HalpeCOCOAPI/PythonAPI/halpecocotools/cocoeval.py#L245'\n    sigmas=[\n        0.026,\n        0.025,\n        0.025,\n        0.035,\n        0.035,\n        0.079,\n        0.079,\n        0.072,\n        0.072,\n        0.062,\n        0.062,\n        0.107,\n        0.107,\n        0.087,\n        0.087,\n        0.089,\n        0.089,\n        0.026,\n        0.026,\n        0.066,\n        0.079,\n        0.079,\n        0.079,\n        0.079,\n        0.079,\n        0.079,\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/horse10.py",
    "content": "dataset_info = dict(\n    dataset_name='horse10',\n    paper_info=dict(\n        author='Mathis, Alexander and Biasi, Thomas and '\n        'Schneider, Steffen and '\n        'Yuksekgonul, Mert and Rogers, Byron and '\n        'Bethge, Matthias and '\n        'Mathis, Mackenzie W',\n        title='Pretraining boosts out-of-domain robustness '\n        'for pose estimation',\n        container='Proceedings of the IEEE/CVF Winter Conference on '\n        'Applications of Computer Vision',\n        year='2021',\n        homepage='http://www.mackenziemathislab.org/horse10',\n    ),\n    keypoint_info={\n        0:\n        dict(name='Nose', id=0, color=[255, 153, 255], type='upper', swap=''),\n        1:\n        dict(name='Eye', id=1, color=[255, 153, 255], type='upper', swap=''),\n        2:\n        dict(\n            name='Nearknee',\n            id=2,\n            color=[255, 102, 255],\n            type='upper',\n            swap=''),\n        3:\n        dict(\n            name='Nearfrontfetlock',\n            id=3,\n            color=[255, 102, 255],\n            type='upper',\n            swap=''),\n        4:\n        dict(\n            name='Nearfrontfoot',\n            id=4,\n            color=[255, 102, 255],\n            type='upper',\n            swap=''),\n        5:\n        dict(\n            name='Offknee', id=5, color=[255, 102, 255], type='upper',\n            swap=''),\n        6:\n        dict(\n            name='Offfrontfetlock',\n            id=6,\n            color=[255, 102, 255],\n            type='upper',\n            swap=''),\n        7:\n        dict(\n            name='Offfrontfoot',\n            id=7,\n            color=[255, 102, 255],\n            type='upper',\n            swap=''),\n        8:\n        dict(\n            name='Shoulder',\n            id=8,\n            color=[255, 153, 255],\n            type='upper',\n            swap=''),\n        9:\n        dict(\n            name='Midshoulder',\n            id=9,\n            color=[255, 153, 255],\n            type='upper',\n            swap=''),\n        10:\n        dict(\n            name='Elbow', id=10, color=[255, 153, 255], type='upper', swap=''),\n        11:\n        dict(\n            name='Girth', id=11, color=[255, 153, 255], type='upper', swap=''),\n        12:\n        dict(\n            name='Wither', id=12, color=[255, 153, 255], type='upper',\n            swap=''),\n        13:\n        dict(\n            name='Nearhindhock',\n            id=13,\n            color=[255, 51, 255],\n            type='lower',\n            swap=''),\n        14:\n        dict(\n            name='Nearhindfetlock',\n            id=14,\n            color=[255, 51, 255],\n            type='lower',\n            swap=''),\n        15:\n        dict(\n            name='Nearhindfoot',\n            id=15,\n            color=[255, 51, 255],\n            type='lower',\n            swap=''),\n        16:\n        dict(name='Hip', id=16, color=[255, 153, 255], type='lower', swap=''),\n        17:\n        dict(\n            name='Stifle', id=17, color=[255, 153, 255], type='lower',\n            swap=''),\n        18:\n        dict(\n            name='Offhindhock',\n            id=18,\n            color=[255, 51, 255],\n            type='lower',\n            swap=''),\n        19:\n        dict(\n            name='Offhindfetlock',\n            id=19,\n            color=[255, 51, 255],\n            type='lower',\n            swap=''),\n        20:\n        dict(\n            name='Offhindfoot',\n            id=20,\n            color=[255, 51, 255],\n            type='lower',\n            swap=''),\n        21:\n        dict(\n            name='Ischium',\n            id=21,\n            color=[255, 153, 255],\n            type='lower',\n            swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('Nose', 'Eye'), id=0, color=[255, 153, 255]),\n        1:\n        dict(link=('Eye', 'Wither'), id=1, color=[255, 153, 255]),\n        2:\n        dict(link=('Wither', 'Hip'), id=2, color=[255, 153, 255]),\n        3:\n        dict(link=('Hip', 'Ischium'), id=3, color=[255, 153, 255]),\n        4:\n        dict(link=('Ischium', 'Stifle'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('Stifle', 'Girth'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('Girth', 'Elbow'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('Elbow', 'Shoulder'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('Shoulder', 'Midshoulder'), id=8, color=[255, 153, 255]),\n        9:\n        dict(link=('Midshoulder', 'Wither'), id=9, color=[255, 153, 255]),\n        10:\n        dict(\n            link=('Nearknee', 'Nearfrontfetlock'),\n            id=10,\n            color=[255, 102, 255]),\n        11:\n        dict(\n            link=('Nearfrontfetlock', 'Nearfrontfoot'),\n            id=11,\n            color=[255, 102, 255]),\n        12:\n        dict(\n            link=('Offknee', 'Offfrontfetlock'), id=12, color=[255, 102, 255]),\n        13:\n        dict(\n            link=('Offfrontfetlock', 'Offfrontfoot'),\n            id=13,\n            color=[255, 102, 255]),\n        14:\n        dict(\n            link=('Nearhindhock', 'Nearhindfetlock'),\n            id=14,\n            color=[255, 51, 255]),\n        15:\n        dict(\n            link=('Nearhindfetlock', 'Nearhindfoot'),\n            id=15,\n            color=[255, 51, 255]),\n        16:\n        dict(\n            link=('Offhindhock', 'Offhindfetlock'),\n            id=16,\n            color=[255, 51, 255]),\n        17:\n        dict(\n            link=('Offhindfetlock', 'Offhindfoot'),\n            id=17,\n            color=[255, 51, 255])\n    },\n    joint_weights=[1.] * 22,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/humanart.py",
    "content": "dataset_info = dict(\n    dataset_name='Human-Art',\n    paper_info=dict(\n        author='Ju, Xuan and Zeng, Ailing and '\n        'Wang, Jianan and Xu, Qiang and Zhang, Lei',\n        title='Human-Art: A Versatile Human-Centric Dataset '\n        'Bridging Natural and Artificial Scenes',\n        container='Proceedings of the IEEE/CVF Conference on '\n        'Computer Vision and Pattern Recognition',\n        year='2023',\n        homepage='https://idea-research.github.io/HumanArt/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/humanart21.py",
    "content": "dataset_info = dict(\n    dataset_name='Human-Art',\n    paper_info=dict(\n        author='Ju, Xuan and Zeng, Ailing and '\n        'Wang, Jianan and Xu, Qiang and Zhang, Lei',\n        title='Human-Art: A Versatile Human-Centric Dataset '\n        'Bridging Natural and Artificial Scenes',\n        container='Proceedings of the IEEE/CVF Conference on '\n        'Computer Vision and Pattern Recognition',\n        year='2023',\n        homepage='https://idea-research.github.io/HumanArt/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(\n            name='left_finger',\n            id=17,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_finger'),\n        18:\n        dict(\n            name='right_finger',\n            id=18,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_finger'),\n        19:\n        dict(\n            name='left_toe',\n            id=19,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_toe'),\n        20:\n        dict(\n            name='right_toe',\n            id=20,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_toe'),\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('left_ankle', 'left_toe'), id=19, color=[0, 255, 0]),\n        20:\n        dict(link=('right_ankle', 'right_toe'), id=20, color=[255, 128, 0]),\n        21:\n        dict(link=('left_wrist', 'left_finger'), id=21, color=[0, 255, 0]),\n        22:\n        dict(link=('right_wrist', 'right_finger'), id=22, color=[255, 128, 0]),\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5, 1., 1., 1., 1.\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.089, 0.089, 0.089,\n        0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/humanart_aic.py",
    "content": "dataset_info = dict(\n    dataset_name='humanart',\n    paper_info=[\n        dict(\n            author='Ju, Xuan and Zeng, Ailing and '\n            'Wang, Jianan and Xu, Qiang and Zhang, '\n            'Lei',\n            title='Human-Art: A Versatile Human-Centric Dataset '\n            'Bridging Natural and Artificial Scenes',\n            container='CVPR',\n            year='2023',\n            homepage='https://idea-research.github.io/HumanArt/',\n        ),\n        dict(\n            author='Wu, Jiahong and Zheng, He and Zhao, Bo and '\n            'Li, Yixin and Yan, Baoming and Liang, Rui and '\n            'Wang, Wenjia and Zhou, Shipei and Lin, Guosen and '\n            'Fu, Yanwei and others',\n            title='Ai challenger: A large-scale dataset for going '\n            'deeper in image understanding',\n            container='arXiv',\n            year='2017',\n            homepage='https://github.com/AIChallenger/AI_Challenger_2017',\n        ),\n    ],\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(\n            name='head_top',\n            id=17,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        18:\n        dict(name='neck', id=18, color=[51, 153, 255], type='upper', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('head_top', 'neck'), id=11, color=[51, 153, 255]),\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5, 1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.026, 0.026\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/interhand2d.py",
    "content": "dataset_info = dict(\n    dataset_name='interhand2d',\n    paper_info=dict(\n        author='Moon, Gyeongsik and Yu, Shoou-I and Wen, He and '\n        'Shiratori, Takaaki and Lee, Kyoung Mu',\n        title='InterHand2.6M: A dataset and baseline for 3D '\n        'interacting hand pose estimation from a single RGB image',\n        container='arXiv',\n        year='2020',\n        homepage='https://mks0601.github.io/InterHand2.6M/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='thumb4', id=0, color=[255, 128, 0], type='', swap=''),\n        1:\n        dict(name='thumb3', id=1, color=[255, 128, 0], type='', swap=''),\n        2:\n        dict(name='thumb2', id=2, color=[255, 128, 0], type='', swap=''),\n        3:\n        dict(name='thumb1', id=3, color=[255, 128, 0], type='', swap=''),\n        4:\n        dict(\n            name='forefinger4', id=4, color=[255, 153, 255], type='', swap=''),\n        5:\n        dict(\n            name='forefinger3', id=5, color=[255, 153, 255], type='', swap=''),\n        6:\n        dict(\n            name='forefinger2', id=6, color=[255, 153, 255], type='', swap=''),\n        7:\n        dict(\n            name='forefinger1', id=7, color=[255, 153, 255], type='', swap=''),\n        8:\n        dict(\n            name='middle_finger4',\n            id=8,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        9:\n        dict(\n            name='middle_finger3',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        10:\n        dict(\n            name='middle_finger2',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        11:\n        dict(\n            name='middle_finger1',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        12:\n        dict(\n            name='ring_finger4', id=12, color=[255, 51, 51], type='', swap=''),\n        13:\n        dict(\n            name='ring_finger3', id=13, color=[255, 51, 51], type='', swap=''),\n        14:\n        dict(\n            name='ring_finger2', id=14, color=[255, 51, 51], type='', swap=''),\n        15:\n        dict(\n            name='ring_finger1', id=15, color=[255, 51, 51], type='', swap=''),\n        16:\n        dict(name='pinky_finger4', id=16, color=[0, 255, 0], type='', swap=''),\n        17:\n        dict(name='pinky_finger3', id=17, color=[0, 255, 0], type='', swap=''),\n        18:\n        dict(name='pinky_finger2', id=18, color=[0, 255, 0], type='', swap=''),\n        19:\n        dict(name='pinky_finger1', id=19, color=[0, 255, 0], type='', swap=''),\n        20:\n        dict(name='wrist', id=20, color=[255, 255, 255], type='', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('wrist', 'thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('thumb1', 'thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('thumb2', 'thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('thumb3', 'thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('wrist', 'forefinger1'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('forefinger1', 'forefinger2'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('forefinger2', 'forefinger3'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('forefinger3', 'forefinger4'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('wrist', 'middle_finger1'), id=8, color=[102, 178, 255]),\n        9:\n        dict(\n            link=('middle_finger1', 'middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('middle_finger2', 'middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('middle_finger3', 'middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(link=('wrist', 'ring_finger1'), id=12, color=[255, 51, 51]),\n        13:\n        dict(\n            link=('ring_finger1', 'ring_finger2'), id=13, color=[255, 51, 51]),\n        14:\n        dict(\n            link=('ring_finger2', 'ring_finger3'), id=14, color=[255, 51, 51]),\n        15:\n        dict(\n            link=('ring_finger3', 'ring_finger4'), id=15, color=[255, 51, 51]),\n        16:\n        dict(link=('wrist', 'pinky_finger1'), id=16, color=[0, 255, 0]),\n        17:\n        dict(\n            link=('pinky_finger1', 'pinky_finger2'), id=17, color=[0, 255, 0]),\n        18:\n        dict(\n            link=('pinky_finger2', 'pinky_finger3'), id=18, color=[0, 255, 0]),\n        19:\n        dict(\n            link=('pinky_finger3', 'pinky_finger4'), id=19, color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 21,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/interhand3d.py",
    "content": "dataset_info = dict(\n    dataset_name='interhand3d',\n    paper_info=dict(\n        author='Moon, Gyeongsik and Yu, Shoou-I and Wen, He and '\n        'Shiratori, Takaaki and Lee, Kyoung Mu',\n        title='InterHand2.6M: A dataset and baseline for 3D '\n        'interacting hand pose estimation from a single RGB image',\n        container='arXiv',\n        year='2020',\n        homepage='https://mks0601.github.io/InterHand2.6M/',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_thumb4',\n            id=0,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb4'),\n        1:\n        dict(\n            name='right_thumb3',\n            id=1,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb3'),\n        2:\n        dict(\n            name='right_thumb2',\n            id=2,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb2'),\n        3:\n        dict(\n            name='right_thumb1',\n            id=3,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb1'),\n        4:\n        dict(\n            name='right_forefinger4',\n            id=4,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger4'),\n        5:\n        dict(\n            name='right_forefinger3',\n            id=5,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger3'),\n        6:\n        dict(\n            name='right_forefinger2',\n            id=6,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger2'),\n        7:\n        dict(\n            name='right_forefinger1',\n            id=7,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger1'),\n        8:\n        dict(\n            name='right_middle_finger4',\n            id=8,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger4'),\n        9:\n        dict(\n            name='right_middle_finger3',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger3'),\n        10:\n        dict(\n            name='right_middle_finger2',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger2'),\n        11:\n        dict(\n            name='right_middle_finger1',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger1'),\n        12:\n        dict(\n            name='right_ring_finger4',\n            id=12,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger4'),\n        13:\n        dict(\n            name='right_ring_finger3',\n            id=13,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger3'),\n        14:\n        dict(\n            name='right_ring_finger2',\n            id=14,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger2'),\n        15:\n        dict(\n            name='right_ring_finger1',\n            id=15,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger1'),\n        16:\n        dict(\n            name='right_pinky_finger4',\n            id=16,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger4'),\n        17:\n        dict(\n            name='right_pinky_finger3',\n            id=17,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger3'),\n        18:\n        dict(\n            name='right_pinky_finger2',\n            id=18,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger2'),\n        19:\n        dict(\n            name='right_pinky_finger1',\n            id=19,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger1'),\n        20:\n        dict(\n            name='right_wrist',\n            id=20,\n            color=[255, 255, 255],\n            type='',\n            swap='left_wrist'),\n        21:\n        dict(\n            name='left_thumb4',\n            id=21,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb4'),\n        22:\n        dict(\n            name='left_thumb3',\n            id=22,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb3'),\n        23:\n        dict(\n            name='left_thumb2',\n            id=23,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb2'),\n        24:\n        dict(\n            name='left_thumb1',\n            id=24,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb1'),\n        25:\n        dict(\n            name='left_forefinger4',\n            id=25,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger4'),\n        26:\n        dict(\n            name='left_forefinger3',\n            id=26,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger3'),\n        27:\n        dict(\n            name='left_forefinger2',\n            id=27,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger2'),\n        28:\n        dict(\n            name='left_forefinger1',\n            id=28,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger1'),\n        29:\n        dict(\n            name='left_middle_finger4',\n            id=29,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger4'),\n        30:\n        dict(\n            name='left_middle_finger3',\n            id=30,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger3'),\n        31:\n        dict(\n            name='left_middle_finger2',\n            id=31,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger2'),\n        32:\n        dict(\n            name='left_middle_finger1',\n            id=32,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger1'),\n        33:\n        dict(\n            name='left_ring_finger4',\n            id=33,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger4'),\n        34:\n        dict(\n            name='left_ring_finger3',\n            id=34,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger3'),\n        35:\n        dict(\n            name='left_ring_finger2',\n            id=35,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger2'),\n        36:\n        dict(\n            name='left_ring_finger1',\n            id=36,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger1'),\n        37:\n        dict(\n            name='left_pinky_finger4',\n            id=37,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger4'),\n        38:\n        dict(\n            name='left_pinky_finger3',\n            id=38,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger3'),\n        39:\n        dict(\n            name='left_pinky_finger2',\n            id=39,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger2'),\n        40:\n        dict(\n            name='left_pinky_finger1',\n            id=40,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger1'),\n        41:\n        dict(\n            name='left_wrist',\n            id=41,\n            color=[255, 255, 255],\n            type='',\n            swap='right_wrist'),\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_wrist', 'right_thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('right_thumb1', 'right_thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('right_thumb2', 'right_thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_thumb3', 'right_thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(\n            link=('right_wrist', 'right_forefinger1'),\n            id=4,\n            color=[255, 153, 255]),\n        5:\n        dict(\n            link=('right_forefinger1', 'right_forefinger2'),\n            id=5,\n            color=[255, 153, 255]),\n        6:\n        dict(\n            link=('right_forefinger2', 'right_forefinger3'),\n            id=6,\n            color=[255, 153, 255]),\n        7:\n        dict(\n            link=('right_forefinger3', 'right_forefinger4'),\n            id=7,\n            color=[255, 153, 255]),\n        8:\n        dict(\n            link=('right_wrist', 'right_middle_finger1'),\n            id=8,\n            color=[102, 178, 255]),\n        9:\n        dict(\n            link=('right_middle_finger1', 'right_middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('right_middle_finger2', 'right_middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('right_middle_finger3', 'right_middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(\n            link=('right_wrist', 'right_ring_finger1'),\n            id=12,\n            color=[255, 51, 51]),\n        13:\n        dict(\n            link=('right_ring_finger1', 'right_ring_finger2'),\n            id=13,\n            color=[255, 51, 51]),\n        14:\n        dict(\n            link=('right_ring_finger2', 'right_ring_finger3'),\n            id=14,\n            color=[255, 51, 51]),\n        15:\n        dict(\n            link=('right_ring_finger3', 'right_ring_finger4'),\n            id=15,\n            color=[255, 51, 51]),\n        16:\n        dict(\n            link=('right_wrist', 'right_pinky_finger1'),\n            id=16,\n            color=[0, 255, 0]),\n        17:\n        dict(\n            link=('right_pinky_finger1', 'right_pinky_finger2'),\n            id=17,\n            color=[0, 255, 0]),\n        18:\n        dict(\n            link=('right_pinky_finger2', 'right_pinky_finger3'),\n            id=18,\n            color=[0, 255, 0]),\n        19:\n        dict(\n            link=('right_pinky_finger3', 'right_pinky_finger4'),\n            id=19,\n            color=[0, 255, 0]),\n        20:\n        dict(link=('left_wrist', 'left_thumb1'), id=20, color=[255, 128, 0]),\n        21:\n        dict(link=('left_thumb1', 'left_thumb2'), id=21, color=[255, 128, 0]),\n        22:\n        dict(link=('left_thumb2', 'left_thumb3'), id=22, color=[255, 128, 0]),\n        23:\n        dict(link=('left_thumb3', 'left_thumb4'), id=23, color=[255, 128, 0]),\n        24:\n        dict(\n            link=('left_wrist', 'left_forefinger1'),\n            id=24,\n            color=[255, 153, 255]),\n        25:\n        dict(\n            link=('left_forefinger1', 'left_forefinger2'),\n            id=25,\n            color=[255, 153, 255]),\n        26:\n        dict(\n            link=('left_forefinger2', 'left_forefinger3'),\n            id=26,\n            color=[255, 153, 255]),\n        27:\n        dict(\n            link=('left_forefinger3', 'left_forefinger4'),\n            id=27,\n            color=[255, 153, 255]),\n        28:\n        dict(\n            link=('left_wrist', 'left_middle_finger1'),\n            id=28,\n            color=[102, 178, 255]),\n        29:\n        dict(\n            link=('left_middle_finger1', 'left_middle_finger2'),\n            id=29,\n            color=[102, 178, 255]),\n        30:\n        dict(\n            link=('left_middle_finger2', 'left_middle_finger3'),\n            id=30,\n            color=[102, 178, 255]),\n        31:\n        dict(\n            link=('left_middle_finger3', 'left_middle_finger4'),\n            id=31,\n            color=[102, 178, 255]),\n        32:\n        dict(\n            link=('left_wrist', 'left_ring_finger1'),\n            id=32,\n            color=[255, 51, 51]),\n        33:\n        dict(\n            link=('left_ring_finger1', 'left_ring_finger2'),\n            id=33,\n            color=[255, 51, 51]),\n        34:\n        dict(\n            link=('left_ring_finger2', 'left_ring_finger3'),\n            id=34,\n            color=[255, 51, 51]),\n        35:\n        dict(\n            link=('left_ring_finger3', 'left_ring_finger4'),\n            id=35,\n            color=[255, 51, 51]),\n        36:\n        dict(\n            link=('left_wrist', 'left_pinky_finger1'),\n            id=36,\n            color=[0, 255, 0]),\n        37:\n        dict(\n            link=('left_pinky_finger1', 'left_pinky_finger2'),\n            id=37,\n            color=[0, 255, 0]),\n        38:\n        dict(\n            link=('left_pinky_finger2', 'left_pinky_finger3'),\n            id=38,\n            color=[0, 255, 0]),\n        39:\n        dict(\n            link=('left_pinky_finger3', 'left_pinky_finger4'),\n            id=39,\n            color=[0, 255, 0]),\n    },\n    joint_weights=[1.] * 42,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/jhmdb.py",
    "content": "dataset_info = dict(\n    dataset_name='jhmdb',\n    paper_info=dict(\n        author='H. Jhuang and J. Gall and S. Zuffi and '\n        'C. Schmid and M. J. Black',\n        title='Towards understanding action recognition',\n        container='International Conf. on Computer Vision (ICCV)',\n        year='2013',\n        homepage='http://jhmdb.is.tue.mpg.de/dataset',\n    ),\n    keypoint_info={\n        0:\n        dict(name='neck', id=0, color=[255, 128, 0], type='upper', swap=''),\n        1:\n        dict(name='belly', id=1, color=[255, 128, 0], type='upper', swap=''),\n        2:\n        dict(name='head', id=2, color=[255, 128, 0], type='upper', swap=''),\n        3:\n        dict(\n            name='right_shoulder',\n            id=3,\n            color=[0, 255, 0],\n            type='upper',\n            swap='left_shoulder'),\n        4:\n        dict(\n            name='left_shoulder',\n            id=4,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        5:\n        dict(\n            name='right_hip',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='left_hip'),\n        6:\n        dict(\n            name='left_hip',\n            id=6,\n            color=[51, 153, 255],\n            type='lower',\n            swap='right_hip'),\n        7:\n        dict(\n            name='right_elbow',\n            id=7,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_elbow'),\n        8:\n        dict(\n            name='left_elbow',\n            id=8,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_elbow'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[51, 153, 255],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='left_knee',\n            id=10,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_knee'),\n        11:\n        dict(\n            name='right_wrist',\n            id=11,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        12:\n        dict(\n            name='left_wrist',\n            id=12,\n            color=[255, 128, 0],\n            type='upper',\n            swap='right_wrist'),\n        13:\n        dict(\n            name='right_ankle',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='left_ankle'),\n        14:\n        dict(\n            name='left_ankle',\n            id=14,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle')\n    },\n    skeleton_info={\n        0: dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        1: dict(link=('right_knee', 'right_hip'), id=1, color=[255, 128, 0]),\n        2: dict(link=('right_hip', 'belly'), id=2, color=[255, 128, 0]),\n        3: dict(link=('belly', 'left_hip'), id=3, color=[0, 255, 0]),\n        4: dict(link=('left_hip', 'left_knee'), id=4, color=[0, 255, 0]),\n        5: dict(link=('left_knee', 'left_ankle'), id=5, color=[0, 255, 0]),\n        6: dict(link=('belly', 'neck'), id=6, color=[51, 153, 255]),\n        7: dict(link=('neck', 'head'), id=7, color=[51, 153, 255]),\n        8: dict(link=('neck', 'right_shoulder'), id=8, color=[255, 128, 0]),\n        9: dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('right_elbow', 'right_wrist'), id=10, color=[255, 128, 0]),\n        11: dict(link=('neck', 'left_shoulder'), id=11, color=[0, 255, 0]),\n        12:\n        dict(link=('left_shoulder', 'left_elbow'), id=12, color=[0, 255, 0]),\n        13: dict(link=('left_elbow', 'left_wrist'), id=13, color=[0, 255, 0])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.2, 1.2, 1.5, 1.5, 1.5, 1.5\n    ],\n    # Adapted from COCO dataset.\n    sigmas=[\n        0.025, 0.107, 0.025, 0.079, 0.079, 0.107, 0.107, 0.072, 0.072, 0.087,\n        0.087, 0.062, 0.062, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/lapa.py",
    "content": "dataset_info = dict(\n    dataset_name='lapa',\n    paper_info=dict(\n        author='Liu, Yinglu and Shi, Hailin and Shen, Hao and Si, '\n        'Yue and Wang, Xiaobo and Mei, Tao',\n        title='A New Dataset and Boundary-Attention Semantic '\n        'Segmentation for Face Parsing.',\n        container='Proceedings of the AAAI Conference on '\n        'Artificial Intelligence 2020',\n        year='2020',\n        homepage='https://github.com/JDAI-CV/lapa-dataset',\n    ),\n    keypoint_info={\n        0:\n        dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap='kpt-32'),\n        1:\n        dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap='kpt-31'),\n        2:\n        dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap='kpt-30'),\n        3:\n        dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap='kpt-29'),\n        4:\n        dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap='kpt-28'),\n        5:\n        dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap='kpt-27'),\n        6:\n        dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap='kpt-26'),\n        7:\n        dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap='kpt-25'),\n        8:\n        dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap='kpt-24'),\n        9:\n        dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap='kpt-23'),\n        10:\n        dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap='kpt-22'),\n        11:\n        dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap='kpt-21'),\n        12:\n        dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap='kpt-20'),\n        13:\n        dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap='kpt-19'),\n        14:\n        dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap='kpt-18'),\n        15:\n        dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap='kpt-17'),\n        16:\n        dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap=''),\n        17:\n        dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap='kpt-15'),\n        18:\n        dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap='kpt-14'),\n        19:\n        dict(name='kpt-19', id=19, color=[255, 0, 0], type='', swap='kpt-13'),\n        20:\n        dict(name='kpt-20', id=20, color=[255, 0, 0], type='', swap='kpt-12'),\n        21:\n        dict(name='kpt-21', id=21, color=[255, 0, 0], type='', swap='kpt-11'),\n        22:\n        dict(name='kpt-22', id=22, color=[255, 0, 0], type='', swap='kpt-10'),\n        23:\n        dict(name='kpt-23', id=23, color=[255, 0, 0], type='', swap='kpt-9'),\n        24:\n        dict(name='kpt-24', id=24, color=[255, 0, 0], type='', swap='kpt-8'),\n        25:\n        dict(name='kpt-25', id=25, color=[255, 0, 0], type='', swap='kpt-7'),\n        26:\n        dict(name='kpt-26', id=26, color=[255, 0, 0], type='', swap='kpt-6'),\n        27:\n        dict(name='kpt-27', id=27, color=[255, 0, 0], type='', swap='kpt-5'),\n        28:\n        dict(name='kpt-28', id=28, color=[255, 0, 0], type='', swap='kpt-4'),\n        29:\n        dict(name='kpt-29', id=29, color=[255, 0, 0], type='', swap='kpt-3'),\n        30:\n        dict(name='kpt-30', id=30, color=[255, 0, 0], type='', swap='kpt-2'),\n        31:\n        dict(name='kpt-31', id=31, color=[255, 0, 0], type='', swap='kpt-1'),\n        32:\n        dict(name='kpt-32', id=32, color=[255, 0, 0], type='', swap='kpt-0'),\n        33:\n        dict(name='kpt-33', id=33, color=[255, 0, 0], type='', swap='kpt-46'),\n        34:\n        dict(name='kpt-34', id=34, color=[255, 0, 0], type='', swap='kpt-45'),\n        35:\n        dict(name='kpt-35', id=35, color=[255, 0, 0], type='', swap='kpt-44'),\n        36:\n        dict(name='kpt-36', id=36, color=[255, 0, 0], type='', swap='kpt-43'),\n        37:\n        dict(name='kpt-37', id=37, color=[255, 0, 0], type='', swap='kpt-42'),\n        38:\n        dict(name='kpt-38', id=38, color=[255, 0, 0], type='', swap='kpt-50'),\n        39:\n        dict(name='kpt-39', id=39, color=[255, 0, 0], type='', swap='kpt-49'),\n        40:\n        dict(name='kpt-40', id=40, color=[255, 0, 0], type='', swap='kpt-48'),\n        41:\n        dict(name='kpt-41', id=41, color=[255, 0, 0], type='', swap='kpt-47'),\n        42:\n        dict(name='kpt-42', id=42, color=[255, 0, 0], type='', swap='kpt-37'),\n        43:\n        dict(name='kpt-43', id=43, color=[255, 0, 0], type='', swap='kpt-36'),\n        44:\n        dict(name='kpt-44', id=44, color=[255, 0, 0], type='', swap='kpt-35'),\n        45:\n        dict(name='kpt-45', id=45, color=[255, 0, 0], type='', swap='kpt-34'),\n        46:\n        dict(name='kpt-46', id=46, color=[255, 0, 0], type='', swap='kpt-33'),\n        47:\n        dict(name='kpt-47', id=47, color=[255, 0, 0], type='', swap='kpt-41'),\n        48:\n        dict(name='kpt-48', id=48, color=[255, 0, 0], type='', swap='kpt-40'),\n        49:\n        dict(name='kpt-49', id=49, color=[255, 0, 0], type='', swap='kpt-39'),\n        50:\n        dict(name='kpt-50', id=50, color=[255, 0, 0], type='', swap='kpt-38'),\n        51:\n        dict(name='kpt-51', id=51, color=[255, 0, 0], type='', swap=''),\n        52:\n        dict(name='kpt-52', id=52, color=[255, 0, 0], type='', swap=''),\n        53:\n        dict(name='kpt-53', id=53, color=[255, 0, 0], type='', swap=''),\n        54:\n        dict(name='kpt-54', id=54, color=[255, 0, 0], type='', swap=''),\n        55:\n        dict(name='kpt-55', id=55, color=[255, 0, 0], type='', swap='kpt-65'),\n        56:\n        dict(name='kpt-56', id=56, color=[255, 0, 0], type='', swap='kpt-64'),\n        57:\n        dict(name='kpt-57', id=57, color=[255, 0, 0], type='', swap='kpt-63'),\n        58:\n        dict(name='kpt-58', id=58, color=[255, 0, 0], type='', swap='kpt-62'),\n        59:\n        dict(name='kpt-59', id=59, color=[255, 0, 0], type='', swap='kpt-61'),\n        60:\n        dict(name='kpt-60', id=60, color=[255, 0, 0], type='', swap=''),\n        61:\n        dict(name='kpt-61', id=61, color=[255, 0, 0], type='', swap='kpt-59'),\n        62:\n        dict(name='kpt-62', id=62, color=[255, 0, 0], type='', swap='kpt-58'),\n        63:\n        dict(name='kpt-63', id=63, color=[255, 0, 0], type='', swap='kpt-57'),\n        64:\n        dict(name='kpt-64', id=64, color=[255, 0, 0], type='', swap='kpt-56'),\n        65:\n        dict(name='kpt-65', id=65, color=[255, 0, 0], type='', swap='kpt-55'),\n        66:\n        dict(name='kpt-66', id=66, color=[255, 0, 0], type='', swap='kpt-79'),\n        67:\n        dict(name='kpt-67', id=67, color=[255, 0, 0], type='', swap='kpt-78'),\n        68:\n        dict(name='kpt-68', id=68, color=[255, 0, 0], type='', swap='kpt-77'),\n        69:\n        dict(name='kpt-69', id=69, color=[255, 0, 0], type='', swap='kpt-76'),\n        70:\n        dict(name='kpt-70', id=70, color=[255, 0, 0], type='', swap='kpt-75'),\n        71:\n        dict(name='kpt-71', id=71, color=[255, 0, 0], type='', swap='kpt-82'),\n        72:\n        dict(name='kpt-72', id=72, color=[255, 0, 0], type='', swap='kpt-81'),\n        73:\n        dict(name='kpt-73', id=73, color=[255, 0, 0], type='', swap='kpt-80'),\n        74:\n        dict(name='kpt-74', id=74, color=[255, 0, 0], type='', swap='kpt-83'),\n        75:\n        dict(name='kpt-75', id=75, color=[255, 0, 0], type='', swap='kpt-70'),\n        76:\n        dict(name='kpt-76', id=76, color=[255, 0, 0], type='', swap='kpt-69'),\n        77:\n        dict(name='kpt-77', id=77, color=[255, 0, 0], type='', swap='kpt-68'),\n        78:\n        dict(name='kpt-78', id=78, color=[255, 0, 0], type='', swap='kpt-67'),\n        79:\n        dict(name='kpt-79', id=79, color=[255, 0, 0], type='', swap='kpt-66'),\n        80:\n        dict(name='kpt-80', id=80, color=[255, 0, 0], type='', swap='kpt-73'),\n        81:\n        dict(name='kpt-81', id=81, color=[255, 0, 0], type='', swap='kpt-72'),\n        82:\n        dict(name='kpt-82', id=82, color=[255, 0, 0], type='', swap='kpt-71'),\n        83:\n        dict(name='kpt-83', id=83, color=[255, 0, 0], type='', swap='kpt-74'),\n        84:\n        dict(name='kpt-84', id=84, color=[255, 0, 0], type='', swap='kpt-90'),\n        85:\n        dict(name='kpt-85', id=85, color=[255, 0, 0], type='', swap='kpt-89'),\n        86:\n        dict(name='kpt-86', id=86, color=[255, 0, 0], type='', swap='kpt-88'),\n        87:\n        dict(name='kpt-87', id=87, color=[255, 0, 0], type='', swap=''),\n        88:\n        dict(name='kpt-88', id=88, color=[255, 0, 0], type='', swap='kpt-86'),\n        89:\n        dict(name='kpt-89', id=89, color=[255, 0, 0], type='', swap='kpt-85'),\n        90:\n        dict(name='kpt-90', id=90, color=[255, 0, 0], type='', swap='kpt-84'),\n        91:\n        dict(name='kpt-91', id=91, color=[255, 0, 0], type='', swap='kpt-95'),\n        92:\n        dict(name='kpt-92', id=92, color=[255, 0, 0], type='', swap='kpt-94'),\n        93:\n        dict(name='kpt-93', id=93, color=[255, 0, 0], type='', swap=''),\n        94:\n        dict(name='kpt-94', id=94, color=[255, 0, 0], type='', swap='kpt-92'),\n        95:\n        dict(name='kpt-95', id=95, color=[255, 0, 0], type='', swap='kpt-91'),\n        96:\n        dict(name='kpt-96', id=96, color=[255, 0, 0], type='', swap='kpt-100'),\n        97:\n        dict(name='kpt-97', id=97, color=[255, 0, 0], type='', swap='kpt-99'),\n        98:\n        dict(name='kpt-98', id=98, color=[255, 0, 0], type='', swap=''),\n        99:\n        dict(name='kpt-99', id=99, color=[255, 0, 0], type='', swap='kpt-97'),\n        100:\n        dict(\n            name='kpt-100', id=100, color=[255, 0, 0], type='', swap='kpt-96'),\n        101:\n        dict(\n            name='kpt-101', id=101, color=[255, 0, 0], type='',\n            swap='kpt-103'),\n        102:\n        dict(name='kpt-102', id=102, color=[255, 0, 0], type='', swap=''),\n        103:\n        dict(\n            name='kpt-103', id=103, color=[255, 0, 0], type='',\n            swap='kpt-101'),\n        104:\n        dict(\n            name='kpt-104', id=104, color=[255, 0, 0], type='',\n            swap='kpt-105'),\n        105:\n        dict(\n            name='kpt-105', id=105, color=[255, 0, 0], type='', swap='kpt-104')\n    },\n    skeleton_info={},\n    joint_weights=[\n        0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8,\n        0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8, 0.8,\n        0.8, 0.8, 0.8, 0.8, 0.8, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,\n        1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0,\n        1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 2.0, 2.0, 2.0, 2.0,\n        2.0, 2.0, 2.0, 2.0, 1.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 2.0, 1.0,\n        1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.5,\n        1.5, 1.5, 1.5, 1.5, 1.5, 1.5, 1.0, 1.0\n    ],\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/locust.py",
    "content": "dataset_info = dict(\n    dataset_name='locust',\n    paper_info=dict(\n        author='Graving, Jacob M and Chae, Daniel and Naik, Hemal and '\n        'Li, Liang and Koger, Benjamin and Costelloe, Blair R and '\n        'Couzin, Iain D',\n        title='DeepPoseKit, a software toolkit for fast and robust '\n        'animal pose estimation using deep learning',\n        container='Elife',\n        year='2019',\n        homepage='https://github.com/jgraving/DeepPoseKit-Data',\n    ),\n    keypoint_info={\n        0:\n        dict(name='head', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='neck', id=1, color=[255, 255, 255], type='', swap=''),\n        2:\n        dict(name='thorax', id=2, color=[255, 255, 255], type='', swap=''),\n        3:\n        dict(name='abdomen1', id=3, color=[255, 255, 255], type='', swap=''),\n        4:\n        dict(name='abdomen2', id=4, color=[255, 255, 255], type='', swap=''),\n        5:\n        dict(\n            name='anttipL',\n            id=5,\n            color=[255, 255, 255],\n            type='',\n            swap='anttipR'),\n        6:\n        dict(\n            name='antbaseL',\n            id=6,\n            color=[255, 255, 255],\n            type='',\n            swap='antbaseR'),\n        7:\n        dict(name='eyeL', id=7, color=[255, 255, 255], type='', swap='eyeR'),\n        8:\n        dict(\n            name='forelegL1',\n            id=8,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR1'),\n        9:\n        dict(\n            name='forelegL2',\n            id=9,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR2'),\n        10:\n        dict(\n            name='forelegL3',\n            id=10,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR3'),\n        11:\n        dict(\n            name='forelegL4',\n            id=11,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR4'),\n        12:\n        dict(\n            name='midlegL1',\n            id=12,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR1'),\n        13:\n        dict(\n            name='midlegL2',\n            id=13,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR2'),\n        14:\n        dict(\n            name='midlegL3',\n            id=14,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR3'),\n        15:\n        dict(\n            name='midlegL4',\n            id=15,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegR4'),\n        16:\n        dict(\n            name='hindlegL1',\n            id=16,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR1'),\n        17:\n        dict(\n            name='hindlegL2',\n            id=17,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR2'),\n        18:\n        dict(\n            name='hindlegL3',\n            id=18,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR3'),\n        19:\n        dict(\n            name='hindlegL4',\n            id=19,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR4'),\n        20:\n        dict(\n            name='anttipR',\n            id=20,\n            color=[255, 255, 255],\n            type='',\n            swap='anttipL'),\n        21:\n        dict(\n            name='antbaseR',\n            id=21,\n            color=[255, 255, 255],\n            type='',\n            swap='antbaseL'),\n        22:\n        dict(name='eyeR', id=22, color=[255, 255, 255], type='', swap='eyeL'),\n        23:\n        dict(\n            name='forelegR1',\n            id=23,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL1'),\n        24:\n        dict(\n            name='forelegR2',\n            id=24,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL2'),\n        25:\n        dict(\n            name='forelegR3',\n            id=25,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL3'),\n        26:\n        dict(\n            name='forelegR4',\n            id=26,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL4'),\n        27:\n        dict(\n            name='midlegR1',\n            id=27,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL1'),\n        28:\n        dict(\n            name='midlegR2',\n            id=28,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL2'),\n        29:\n        dict(\n            name='midlegR3',\n            id=29,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL3'),\n        30:\n        dict(\n            name='midlegR4',\n            id=30,\n            color=[255, 255, 255],\n            type='',\n            swap='midlegL4'),\n        31:\n        dict(\n            name='hindlegR1',\n            id=31,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL1'),\n        32:\n        dict(\n            name='hindlegR2',\n            id=32,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL2'),\n        33:\n        dict(\n            name='hindlegR3',\n            id=33,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL3'),\n        34:\n        dict(\n            name='hindlegR4',\n            id=34,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL4')\n    },\n    skeleton_info={\n        0: dict(link=('neck', 'head'), id=0, color=[255, 255, 255]),\n        1: dict(link=('thorax', 'neck'), id=1, color=[255, 255, 255]),\n        2: dict(link=('abdomen1', 'thorax'), id=2, color=[255, 255, 255]),\n        3: dict(link=('abdomen2', 'abdomen1'), id=3, color=[255, 255, 255]),\n        4: dict(link=('antbaseL', 'anttipL'), id=4, color=[255, 255, 255]),\n        5: dict(link=('eyeL', 'antbaseL'), id=5, color=[255, 255, 255]),\n        6: dict(link=('forelegL2', 'forelegL1'), id=6, color=[255, 255, 255]),\n        7: dict(link=('forelegL3', 'forelegL2'), id=7, color=[255, 255, 255]),\n        8: dict(link=('forelegL4', 'forelegL3'), id=8, color=[255, 255, 255]),\n        9: dict(link=('midlegL2', 'midlegL1'), id=9, color=[255, 255, 255]),\n        10: dict(link=('midlegL3', 'midlegL2'), id=10, color=[255, 255, 255]),\n        11: dict(link=('midlegL4', 'midlegL3'), id=11, color=[255, 255, 255]),\n        12:\n        dict(link=('hindlegL2', 'hindlegL1'), id=12, color=[255, 255, 255]),\n        13:\n        dict(link=('hindlegL3', 'hindlegL2'), id=13, color=[255, 255, 255]),\n        14:\n        dict(link=('hindlegL4', 'hindlegL3'), id=14, color=[255, 255, 255]),\n        15: dict(link=('antbaseR', 'anttipR'), id=15, color=[255, 255, 255]),\n        16: dict(link=('eyeR', 'antbaseR'), id=16, color=[255, 255, 255]),\n        17:\n        dict(link=('forelegR2', 'forelegR1'), id=17, color=[255, 255, 255]),\n        18:\n        dict(link=('forelegR3', 'forelegR2'), id=18, color=[255, 255, 255]),\n        19:\n        dict(link=('forelegR4', 'forelegR3'), id=19, color=[255, 255, 255]),\n        20: dict(link=('midlegR2', 'midlegR1'), id=20, color=[255, 255, 255]),\n        21: dict(link=('midlegR3', 'midlegR2'), id=21, color=[255, 255, 255]),\n        22: dict(link=('midlegR4', 'midlegR3'), id=22, color=[255, 255, 255]),\n        23:\n        dict(link=('hindlegR2', 'hindlegR1'), id=23, color=[255, 255, 255]),\n        24:\n        dict(link=('hindlegR3', 'hindlegR2'), id=24, color=[255, 255, 255]),\n        25:\n        dict(link=('hindlegR4', 'hindlegR3'), id=25, color=[255, 255, 255])\n    },\n    joint_weights=[1.] * 35,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/macaque.py",
    "content": "dataset_info = dict(\n    dataset_name='macaque',\n    paper_info=dict(\n        author='Labuguen, Rollyn and Matsumoto, Jumpei and '\n        'Negrete, Salvador and Nishimaru, Hiroshi and '\n        'Nishijo, Hisao and Takada, Masahiko and '\n        'Go, Yasuhiro and Inoue, Ken-ichi and Shibata, Tomohiro',\n        title='MacaquePose: A novel \"in the wild\" macaque monkey pose dataset '\n        'for markerless motion capture',\n        container='bioRxiv',\n        year='2020',\n        homepage='http://www.pri.kyoto-u.ac.jp/datasets/'\n        'macaquepose/index.html',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/mhp.py",
    "content": "dataset_info = dict(\n    dataset_name='mhp',\n    paper_info=dict(\n        author='Zhao, Jian and Li, Jianshu and Cheng, Yu and '\n        'Sim, Terence and Yan, Shuicheng and Feng, Jiashi',\n        title='Understanding humans in crowded scenes: '\n        'Deep nested adversarial learning and a '\n        'new benchmark for multi-human parsing',\n        container='Proceedings of the 26th ACM '\n        'international conference on Multimedia',\n        year='2018',\n        homepage='https://lv-mhp.github.io/dataset',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_ankle',\n            id=0,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        1:\n        dict(\n            name='right_knee',\n            id=1,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        2:\n        dict(\n            name='right_hip',\n            id=2,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        3:\n        dict(\n            name='left_hip',\n            id=3,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        4:\n        dict(\n            name='left_knee',\n            id=4,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        5:\n        dict(\n            name='left_ankle',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        6:\n        dict(name='pelvis', id=6, color=[51, 153, 255], type='lower', swap=''),\n        7:\n        dict(name='thorax', id=7, color=[51, 153, 255], type='upper', swap=''),\n        8:\n        dict(\n            name='upper_neck',\n            id=8,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        9:\n        dict(\n            name='head_top', id=9, color=[51, 153, 255], type='upper',\n            swap=''),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='right_elbow',\n            id=11,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        12:\n        dict(\n            name='right_shoulder',\n            id=12,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        13:\n        dict(\n            name='left_shoulder',\n            id=13,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        14:\n        dict(\n            name='left_elbow',\n            id=14,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        15:\n        dict(\n            name='left_wrist',\n            id=15,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist')\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('right_knee', 'right_hip'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('right_hip', 'pelvis'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('pelvis', 'left_hip'), id=3, color=[0, 255, 0]),\n        4:\n        dict(link=('left_hip', 'left_knee'), id=4, color=[0, 255, 0]),\n        5:\n        dict(link=('left_knee', 'left_ankle'), id=5, color=[0, 255, 0]),\n        6:\n        dict(link=('pelvis', 'thorax'), id=6, color=[51, 153, 255]),\n        7:\n        dict(link=('thorax', 'upper_neck'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('upper_neck', 'head_top'), id=8, color=[51, 153, 255]),\n        9:\n        dict(link=('upper_neck', 'right_shoulder'), id=9, color=[255, 128, 0]),\n        10:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=10, color=[255, 128,\n                                                                  0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('upper_neck', 'left_shoulder'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('left_shoulder', 'left_elbow'), id=13, color=[0, 255, 0]),\n        14:\n        dict(link=('left_elbow', 'left_wrist'), id=14, color=[0, 255, 0])\n    },\n    joint_weights=[\n        1.5, 1.2, 1., 1., 1.2, 1.5, 1., 1., 1., 1., 1.5, 1.2, 1., 1., 1.2, 1.5\n    ],\n    # Adapted from COCO dataset.\n    sigmas=[\n        0.089, 0.083, 0.107, 0.107, 0.083, 0.089, 0.026, 0.026, 0.026, 0.026,\n        0.062, 0.072, 0.179, 0.179, 0.072, 0.062\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/mpi_inf_3dhp.py",
    "content": "dataset_info = dict(\n    dataset_name='mpi_inf_3dhp',\n    paper_info=dict(\n        author='ehta, Dushyant and Rhodin, Helge and Casas, Dan and '\n        'Fua, Pascal and Sotnychenko, Oleksandr and Xu, Weipeng and '\n        'Theobalt, Christian',\n        title='Monocular 3D Human Pose Estimation In The Wild Using Improved '\n        'CNN Supervision',\n        container='2017 international conference on 3D vision (3DV)',\n        year='2017',\n        homepage='http://gvv.mpi-inf.mpg.de/3dhp-dataset',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='head_top', id=0, color=[51, 153, 255], type='upper',\n            swap=''),\n        1:\n        dict(name='neck', id=1, color=[51, 153, 255], type='upper', swap=''),\n        2:\n        dict(\n            name='right_shoulder',\n            id=2,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        3:\n        dict(\n            name='right_elbow',\n            id=3,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        4:\n        dict(\n            name='right_wrist',\n            id=4,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='left_elbow',\n            id=6,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        7:\n        dict(\n            name='left_wrist',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        8:\n        dict(\n            name='right_hip',\n            id=8,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='right_ankle',\n            id=10,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='left_knee',\n            id=12,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        13:\n        dict(\n            name='left_ankle',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        14:\n        dict(name='root', id=14, color=[51, 153, 255], type='lower', swap=''),\n        15:\n        dict(name='spine', id=15, color=[51, 153, 255], type='upper', swap=''),\n        16:\n        dict(name='head', id=16, color=[51, 153, 255], type='upper', swap='')\n    },\n    skeleton_info={\n        0: dict(link=('neck', 'right_shoulder'), id=0, color=[255, 128, 0]),\n        1: dict(\n            link=('right_shoulder', 'right_elbow'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('right_elbow', 'right_wrist'), id=2, color=[255, 128, 0]),\n        3: dict(link=('neck', 'left_shoulder'), id=3, color=[0, 255, 0]),\n        4: dict(link=('left_shoulder', 'left_elbow'), id=4, color=[0, 255, 0]),\n        5: dict(link=('left_elbow', 'left_wrist'), id=5, color=[0, 255, 0]),\n        6: dict(link=('root', 'right_hip'), id=6, color=[255, 128, 0]),\n        7: dict(link=('right_hip', 'right_knee'), id=7, color=[255, 128, 0]),\n        8: dict(link=('right_knee', 'right_ankle'), id=8, color=[255, 128, 0]),\n        9: dict(link=('root', 'left_hip'), id=9, color=[0, 255, 0]),\n        10: dict(link=('left_hip', 'left_knee'), id=10, color=[0, 255, 0]),\n        11: dict(link=('left_knee', 'left_ankle'), id=11, color=[0, 255, 0]),\n        12: dict(link=('head_top', 'head'), id=12, color=[51, 153, 255]),\n        13: dict(link=('head', 'neck'), id=13, color=[51, 153, 255]),\n        14: dict(link=('neck', 'spine'), id=14, color=[51, 153, 255]),\n        15: dict(link=('spine', 'root'), id=15, color=[51, 153, 255])\n    },\n    joint_weights=[1.] * 17,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/mpii.py",
    "content": "dataset_info = dict(\n    dataset_name='mpii',\n    paper_info=dict(\n        author='Mykhaylo Andriluka and Leonid Pishchulin and '\n        'Peter Gehler and Schiele, Bernt',\n        title='2D Human Pose Estimation: New Benchmark and '\n        'State of the Art Analysis',\n        container='IEEE Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2014',\n        homepage='http://human-pose.mpi-inf.mpg.de/',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_ankle',\n            id=0,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        1:\n        dict(\n            name='right_knee',\n            id=1,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        2:\n        dict(\n            name='right_hip',\n            id=2,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        3:\n        dict(\n            name='left_hip',\n            id=3,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        4:\n        dict(\n            name='left_knee',\n            id=4,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        5:\n        dict(\n            name='left_ankle',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        6:\n        dict(name='pelvis', id=6, color=[51, 153, 255], type='lower', swap=''),\n        7:\n        dict(name='thorax', id=7, color=[51, 153, 255], type='upper', swap=''),\n        8:\n        dict(\n            name='upper_neck',\n            id=8,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        9:\n        dict(\n            name='head_top', id=9, color=[51, 153, 255], type='upper',\n            swap=''),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='right_elbow',\n            id=11,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        12:\n        dict(\n            name='right_shoulder',\n            id=12,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        13:\n        dict(\n            name='left_shoulder',\n            id=13,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        14:\n        dict(\n            name='left_elbow',\n            id=14,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        15:\n        dict(\n            name='left_wrist',\n            id=15,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist')\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('right_knee', 'right_hip'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('right_hip', 'pelvis'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('pelvis', 'left_hip'), id=3, color=[0, 255, 0]),\n        4:\n        dict(link=('left_hip', 'left_knee'), id=4, color=[0, 255, 0]),\n        5:\n        dict(link=('left_knee', 'left_ankle'), id=5, color=[0, 255, 0]),\n        6:\n        dict(link=('pelvis', 'thorax'), id=6, color=[51, 153, 255]),\n        7:\n        dict(link=('thorax', 'upper_neck'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('upper_neck', 'head_top'), id=8, color=[51, 153, 255]),\n        9:\n        dict(link=('upper_neck', 'right_shoulder'), id=9, color=[255, 128, 0]),\n        10:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=10, color=[255, 128,\n                                                                  0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('upper_neck', 'left_shoulder'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('left_shoulder', 'left_elbow'), id=13, color=[0, 255, 0]),\n        14:\n        dict(link=('left_elbow', 'left_wrist'), id=14, color=[0, 255, 0])\n    },\n    joint_weights=[\n        1.5, 1.2, 1., 1., 1.2, 1.5, 1., 1., 1., 1., 1.5, 1.2, 1., 1., 1.2, 1.5\n    ],\n    # Adapted from COCO dataset.\n    sigmas=[\n        0.089, 0.083, 0.107, 0.107, 0.083, 0.089, 0.026, 0.026, 0.026, 0.026,\n        0.062, 0.072, 0.179, 0.179, 0.072, 0.062\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/mpii_trb.py",
    "content": "dataset_info = dict(\n    dataset_name='mpii_trb',\n    paper_info=dict(\n        author='Duan, Haodong and Lin, Kwan-Yee and Jin, Sheng and '\n        'Liu, Wentao and Qian, Chen and Ouyang, Wanli',\n        title='TRB: A Novel Triplet Representation for '\n        'Understanding 2D Human Body',\n        container='Proceedings of the IEEE International '\n        'Conference on Computer Vision',\n        year='2019',\n        homepage='https://github.com/kennymckormick/'\n        'Triplet-Representation-of-human-Body',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='left_shoulder',\n            id=0,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        1:\n        dict(\n            name='right_shoulder',\n            id=1,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        2:\n        dict(\n            name='left_elbow',\n            id=2,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        3:\n        dict(\n            name='right_elbow',\n            id=3,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        4:\n        dict(\n            name='left_wrist',\n            id=4,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        5:\n        dict(\n            name='right_wrist',\n            id=5,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        6:\n        dict(\n            name='left_hip',\n            id=6,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        7:\n        dict(\n            name='right_hip',\n            id=7,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        8:\n        dict(\n            name='left_knee',\n            id=8,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        9:\n        dict(\n            name='right_knee',\n            id=9,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        10:\n        dict(\n            name='left_ankle',\n            id=10,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        11:\n        dict(\n            name='right_ankle',\n            id=11,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        12:\n        dict(name='head', id=12, color=[51, 153, 255], type='upper', swap=''),\n        13:\n        dict(name='neck', id=13, color=[51, 153, 255], type='upper', swap=''),\n        14:\n        dict(\n            name='right_neck',\n            id=14,\n            color=[255, 255, 255],\n            type='upper',\n            swap='left_neck'),\n        15:\n        dict(\n            name='left_neck',\n            id=15,\n            color=[255, 255, 255],\n            type='upper',\n            swap='right_neck'),\n        16:\n        dict(\n            name='medial_right_shoulder',\n            id=16,\n            color=[255, 255, 255],\n            type='upper',\n            swap='medial_left_shoulder'),\n        17:\n        dict(\n            name='lateral_right_shoulder',\n            id=17,\n            color=[255, 255, 255],\n            type='upper',\n            swap='lateral_left_shoulder'),\n        18:\n        dict(\n            name='medial_right_bow',\n            id=18,\n            color=[255, 255, 255],\n            type='upper',\n            swap='medial_left_bow'),\n        19:\n        dict(\n            name='lateral_right_bow',\n            id=19,\n            color=[255, 255, 255],\n            type='upper',\n            swap='lateral_left_bow'),\n        20:\n        dict(\n            name='medial_right_wrist',\n            id=20,\n            color=[255, 255, 255],\n            type='upper',\n            swap='medial_left_wrist'),\n        21:\n        dict(\n            name='lateral_right_wrist',\n            id=21,\n            color=[255, 255, 255],\n            type='upper',\n            swap='lateral_left_wrist'),\n        22:\n        dict(\n            name='medial_left_shoulder',\n            id=22,\n            color=[255, 255, 255],\n            type='upper',\n            swap='medial_right_shoulder'),\n        23:\n        dict(\n            name='lateral_left_shoulder',\n            id=23,\n            color=[255, 255, 255],\n            type='upper',\n            swap='lateral_right_shoulder'),\n        24:\n        dict(\n            name='medial_left_bow',\n            id=24,\n            color=[255, 255, 255],\n            type='upper',\n            swap='medial_right_bow'),\n        25:\n        dict(\n            name='lateral_left_bow',\n            id=25,\n            color=[255, 255, 255],\n            type='upper',\n            swap='lateral_right_bow'),\n        26:\n        dict(\n            name='medial_left_wrist',\n            id=26,\n            color=[255, 255, 255],\n            type='upper',\n            swap='medial_right_wrist'),\n        27:\n        dict(\n            name='lateral_left_wrist',\n            id=27,\n            color=[255, 255, 255],\n            type='upper',\n            swap='lateral_right_wrist'),\n        28:\n        dict(\n            name='medial_right_hip',\n            id=28,\n            color=[255, 255, 255],\n            type='lower',\n            swap='medial_left_hip'),\n        29:\n        dict(\n            name='lateral_right_hip',\n            id=29,\n            color=[255, 255, 255],\n            type='lower',\n            swap='lateral_left_hip'),\n        30:\n        dict(\n            name='medial_right_knee',\n            id=30,\n            color=[255, 255, 255],\n            type='lower',\n            swap='medial_left_knee'),\n        31:\n        dict(\n            name='lateral_right_knee',\n            id=31,\n            color=[255, 255, 255],\n            type='lower',\n            swap='lateral_left_knee'),\n        32:\n        dict(\n            name='medial_right_ankle',\n            id=32,\n            color=[255, 255, 255],\n            type='lower',\n            swap='medial_left_ankle'),\n        33:\n        dict(\n            name='lateral_right_ankle',\n            id=33,\n            color=[255, 255, 255],\n            type='lower',\n            swap='lateral_left_ankle'),\n        34:\n        dict(\n            name='medial_left_hip',\n            id=34,\n            color=[255, 255, 255],\n            type='lower',\n            swap='medial_right_hip'),\n        35:\n        dict(\n            name='lateral_left_hip',\n            id=35,\n            color=[255, 255, 255],\n            type='lower',\n            swap='lateral_right_hip'),\n        36:\n        dict(\n            name='medial_left_knee',\n            id=36,\n            color=[255, 255, 255],\n            type='lower',\n            swap='medial_right_knee'),\n        37:\n        dict(\n            name='lateral_left_knee',\n            id=37,\n            color=[255, 255, 255],\n            type='lower',\n            swap='lateral_right_knee'),\n        38:\n        dict(\n            name='medial_left_ankle',\n            id=38,\n            color=[255, 255, 255],\n            type='lower',\n            swap='medial_right_ankle'),\n        39:\n        dict(\n            name='lateral_left_ankle',\n            id=39,\n            color=[255, 255, 255],\n            type='lower',\n            swap='lateral_right_ankle'),\n    },\n    skeleton_info={\n        0:\n        dict(link=('head', 'neck'), id=0, color=[51, 153, 255]),\n        1:\n        dict(link=('neck', 'left_shoulder'), id=1, color=[51, 153, 255]),\n        2:\n        dict(link=('neck', 'right_shoulder'), id=2, color=[51, 153, 255]),\n        3:\n        dict(link=('left_shoulder', 'left_elbow'), id=3, color=[0, 255, 0]),\n        4:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=4, color=[255, 128, 0]),\n        5:\n        dict(link=('left_elbow', 'left_wrist'), id=5, color=[0, 255, 0]),\n        6:\n        dict(link=('right_elbow', 'right_wrist'), id=6, color=[255, 128, 0]),\n        7:\n        dict(link=('left_shoulder', 'left_hip'), id=7, color=[51, 153, 255]),\n        8:\n        dict(link=('right_shoulder', 'right_hip'), id=8, color=[51, 153, 255]),\n        9:\n        dict(link=('left_hip', 'right_hip'), id=9, color=[51, 153, 255]),\n        10:\n        dict(link=('left_hip', 'left_knee'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_hip', 'right_knee'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_knee', 'left_ankle'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('right_knee', 'right_ankle'), id=13, color=[255, 128, 0]),\n        14:\n        dict(link=('right_neck', 'left_neck'), id=14, color=[255, 255, 255]),\n        15:\n        dict(\n            link=('medial_right_shoulder', 'lateral_right_shoulder'),\n            id=15,\n            color=[255, 255, 255]),\n        16:\n        dict(\n            link=('medial_right_bow', 'lateral_right_bow'),\n            id=16,\n            color=[255, 255, 255]),\n        17:\n        dict(\n            link=('medial_right_wrist', 'lateral_right_wrist'),\n            id=17,\n            color=[255, 255, 255]),\n        18:\n        dict(\n            link=('medial_left_shoulder', 'lateral_left_shoulder'),\n            id=18,\n            color=[255, 255, 255]),\n        19:\n        dict(\n            link=('medial_left_bow', 'lateral_left_bow'),\n            id=19,\n            color=[255, 255, 255]),\n        20:\n        dict(\n            link=('medial_left_wrist', 'lateral_left_wrist'),\n            id=20,\n            color=[255, 255, 255]),\n        21:\n        dict(\n            link=('medial_right_hip', 'lateral_right_hip'),\n            id=21,\n            color=[255, 255, 255]),\n        22:\n        dict(\n            link=('medial_right_knee', 'lateral_right_knee'),\n            id=22,\n            color=[255, 255, 255]),\n        23:\n        dict(\n            link=('medial_right_ankle', 'lateral_right_ankle'),\n            id=23,\n            color=[255, 255, 255]),\n        24:\n        dict(\n            link=('medial_left_hip', 'lateral_left_hip'),\n            id=24,\n            color=[255, 255, 255]),\n        25:\n        dict(\n            link=('medial_left_knee', 'lateral_left_knee'),\n            id=25,\n            color=[255, 255, 255]),\n        26:\n        dict(\n            link=('medial_left_ankle', 'lateral_left_ankle'),\n            id=26,\n            color=[255, 255, 255])\n    },\n    joint_weights=[1.] * 40,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/ochuman.py",
    "content": "dataset_info = dict(\n    dataset_name='ochuman',\n    paper_info=dict(\n        author='Zhang, Song-Hai and Li, Ruilong and Dong, Xin and '\n        'Rosin, Paul and Cai, Zixi and Han, Xi and '\n        'Yang, Dingcheng and Huang, Haozhi and Hu, Shi-Min',\n        title='Pose2seg: Detection free human instance segmentation',\n        container='Proceedings of the IEEE conference on computer '\n        'vision and pattern recognition',\n        year='2019',\n        homepage='https://github.com/liruilong940607/OCHumanApi',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/onehand10k.py",
    "content": "dataset_info = dict(\n    dataset_name='onehand10k',\n    paper_info=dict(\n        author='Wang, Yangang and Peng, Cong and Liu, Yebin',\n        title='Mask-pose cascaded cnn for 2d hand pose estimation '\n        'from single color image',\n        container='IEEE Transactions on Circuits and Systems '\n        'for Video Technology',\n        year='2018',\n        homepage='https://www.yangangwang.com/papers/WANG-MCC-2018-10.html',\n    ),\n    keypoint_info={\n        0:\n        dict(name='wrist', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='thumb1', id=1, color=[255, 128, 0], type='', swap=''),\n        2:\n        dict(name='thumb2', id=2, color=[255, 128, 0], type='', swap=''),\n        3:\n        dict(name='thumb3', id=3, color=[255, 128, 0], type='', swap=''),\n        4:\n        dict(name='thumb4', id=4, color=[255, 128, 0], type='', swap=''),\n        5:\n        dict(\n            name='forefinger1', id=5, color=[255, 153, 255], type='', swap=''),\n        6:\n        dict(\n            name='forefinger2', id=6, color=[255, 153, 255], type='', swap=''),\n        7:\n        dict(\n            name='forefinger3', id=7, color=[255, 153, 255], type='', swap=''),\n        8:\n        dict(\n            name='forefinger4', id=8, color=[255, 153, 255], type='', swap=''),\n        9:\n        dict(\n            name='middle_finger1',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        10:\n        dict(\n            name='middle_finger2',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        11:\n        dict(\n            name='middle_finger3',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        12:\n        dict(\n            name='middle_finger4',\n            id=12,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        13:\n        dict(\n            name='ring_finger1', id=13, color=[255, 51, 51], type='', swap=''),\n        14:\n        dict(\n            name='ring_finger2', id=14, color=[255, 51, 51], type='', swap=''),\n        15:\n        dict(\n            name='ring_finger3', id=15, color=[255, 51, 51], type='', swap=''),\n        16:\n        dict(\n            name='ring_finger4', id=16, color=[255, 51, 51], type='', swap=''),\n        17:\n        dict(name='pinky_finger1', id=17, color=[0, 255, 0], type='', swap=''),\n        18:\n        dict(name='pinky_finger2', id=18, color=[0, 255, 0], type='', swap=''),\n        19:\n        dict(name='pinky_finger3', id=19, color=[0, 255, 0], type='', swap=''),\n        20:\n        dict(name='pinky_finger4', id=20, color=[0, 255, 0], type='', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('wrist', 'thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('thumb1', 'thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('thumb2', 'thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('thumb3', 'thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('wrist', 'forefinger1'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('forefinger1', 'forefinger2'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('forefinger2', 'forefinger3'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('forefinger3', 'forefinger4'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('wrist', 'middle_finger1'), id=8, color=[102, 178, 255]),\n        9:\n        dict(\n            link=('middle_finger1', 'middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('middle_finger2', 'middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('middle_finger3', 'middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(link=('wrist', 'ring_finger1'), id=12, color=[255, 51, 51]),\n        13:\n        dict(\n            link=('ring_finger1', 'ring_finger2'), id=13, color=[255, 51, 51]),\n        14:\n        dict(\n            link=('ring_finger2', 'ring_finger3'), id=14, color=[255, 51, 51]),\n        15:\n        dict(\n            link=('ring_finger3', 'ring_finger4'), id=15, color=[255, 51, 51]),\n        16:\n        dict(link=('wrist', 'pinky_finger1'), id=16, color=[0, 255, 0]),\n        17:\n        dict(\n            link=('pinky_finger1', 'pinky_finger2'), id=17, color=[0, 255, 0]),\n        18:\n        dict(\n            link=('pinky_finger2', 'pinky_finger3'), id=18, color=[0, 255, 0]),\n        19:\n        dict(\n            link=('pinky_finger3', 'pinky_finger4'), id=19, color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 21,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/panoptic_body3d.py",
    "content": "dataset_info = dict(\n    dataset_name='panoptic_pose_3d',\n    paper_info=dict(\n        author='Joo, Hanbyul and Simon, Tomas and  Li, Xulong'\n        'and Liu, Hao and Tan, Lei and Gui, Lin and Banerjee, Sean'\n        'and Godisart, Timothy and Nabbe, Bart and Matthews, Iain'\n        'and Kanade, Takeo and Nobuhara, Shohei and Sheikh, Yaser',\n        title='Panoptic Studio: A Massively Multiview System '\n        'for Interaction Motion Capture',\n        container='IEEE Transactions on Pattern Analysis'\n        ' and Machine Intelligence',\n        year='2017',\n        homepage='http://domedb.perception.cs.cmu.edu',\n    ),\n    keypoint_info={\n        0:\n        dict(name='neck', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(name='nose', id=1, color=[51, 153, 255], type='upper', swap=''),\n        2:\n        dict(name='mid_hip', id=2, color=[0, 255, 0], type='lower', swap=''),\n        3:\n        dict(\n            name='left_shoulder',\n            id=3,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        4:\n        dict(\n            name='left_elbow',\n            id=4,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        5:\n        dict(\n            name='left_wrist',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        6:\n        dict(\n            name='left_hip',\n            id=6,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        7:\n        dict(\n            name='left_knee',\n            id=7,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        8:\n        dict(\n            name='left_ankle',\n            id=8,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        9:\n        dict(\n            name='right_shoulder',\n            id=9,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        10:\n        dict(\n            name='right_elbow',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        11:\n        dict(\n            name='right_wrist',\n            id=11,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='right_knee',\n            id=13,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        14:\n        dict(\n            name='right_ankle',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        15:\n        dict(\n            name='left_eye',\n            id=15,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        16:\n        dict(\n            name='left_ear',\n            id=16,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        17:\n        dict(\n            name='right_eye',\n            id=17,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        18:\n        dict(\n            name='right_ear',\n            id=18,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear')\n    },\n    skeleton_info={\n        0: dict(link=('nose', 'neck'), id=0, color=[51, 153, 255]),\n        1: dict(link=('neck', 'left_shoulder'), id=1, color=[0, 255, 0]),\n        2: dict(link=('neck', 'right_shoulder'), id=2, color=[255, 128, 0]),\n        3: dict(link=('left_shoulder', 'left_elbow'), id=3, color=[0, 255, 0]),\n        4: dict(\n            link=('right_shoulder', 'right_elbow'), id=4, color=[255, 128, 0]),\n        5: dict(link=('left_elbow', 'left_wrist'), id=5, color=[0, 255, 0]),\n        6:\n        dict(link=('right_elbow', 'right_wrist'), id=6, color=[255, 128, 0]),\n        7: dict(link=('left_ankle', 'left_knee'), id=7, color=[0, 255, 0]),\n        8: dict(link=('left_knee', 'left_hip'), id=8, color=[0, 255, 0]),\n        9: dict(link=('right_ankle', 'right_knee'), id=9, color=[255, 128, 0]),\n        10: dict(link=('right_knee', 'right_hip'), id=10, color=[255, 128, 0]),\n        11: dict(link=('mid_hip', 'left_hip'), id=11, color=[0, 255, 0]),\n        12: dict(link=('mid_hip', 'right_hip'), id=12, color=[255, 128, 0]),\n        13: dict(link=('mid_hip', 'neck'), id=13, color=[51, 153, 255]),\n    },\n    joint_weights=[\n        1.0, 1.0, 1.0, 1.0, 1.2, 1.5, 1.0, 1.2, 1.5, 1.0, 1.2, 1.5, 1.0, 1.2,\n        1.5, 1.0, 1.0, 1.0, 1.0\n    ],\n    sigmas=[\n        0.026, 0.026, 0.107, 0.079, 0.072, 0.062, 0.107, 0.087, 0.089, 0.079,\n        0.072, 0.062, 0.107, 0.087, 0.089, 0.025, 0.035, 0.025, 0.035\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/panoptic_hand2d.py",
    "content": "dataset_info = dict(\n    dataset_name='panoptic_hand2d',\n    paper_info=dict(\n        author='Simon, Tomas and Joo, Hanbyul and '\n        'Matthews, Iain and Sheikh, Yaser',\n        title='Hand keypoint detection in single images using '\n        'multiview bootstrapping',\n        container='Proceedings of the IEEE conference on '\n        'Computer Vision and Pattern Recognition',\n        year='2017',\n        homepage='http://domedb.perception.cs.cmu.edu/handdb.html',\n    ),\n    keypoint_info={\n        0:\n        dict(name='wrist', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='thumb1', id=1, color=[255, 128, 0], type='', swap=''),\n        2:\n        dict(name='thumb2', id=2, color=[255, 128, 0], type='', swap=''),\n        3:\n        dict(name='thumb3', id=3, color=[255, 128, 0], type='', swap=''),\n        4:\n        dict(name='thumb4', id=4, color=[255, 128, 0], type='', swap=''),\n        5:\n        dict(\n            name='forefinger1', id=5, color=[255, 153, 255], type='', swap=''),\n        6:\n        dict(\n            name='forefinger2', id=6, color=[255, 153, 255], type='', swap=''),\n        7:\n        dict(\n            name='forefinger3', id=7, color=[255, 153, 255], type='', swap=''),\n        8:\n        dict(\n            name='forefinger4', id=8, color=[255, 153, 255], type='', swap=''),\n        9:\n        dict(\n            name='middle_finger1',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        10:\n        dict(\n            name='middle_finger2',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        11:\n        dict(\n            name='middle_finger3',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        12:\n        dict(\n            name='middle_finger4',\n            id=12,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        13:\n        dict(\n            name='ring_finger1', id=13, color=[255, 51, 51], type='', swap=''),\n        14:\n        dict(\n            name='ring_finger2', id=14, color=[255, 51, 51], type='', swap=''),\n        15:\n        dict(\n            name='ring_finger3', id=15, color=[255, 51, 51], type='', swap=''),\n        16:\n        dict(\n            name='ring_finger4', id=16, color=[255, 51, 51], type='', swap=''),\n        17:\n        dict(name='pinky_finger1', id=17, color=[0, 255, 0], type='', swap=''),\n        18:\n        dict(name='pinky_finger2', id=18, color=[0, 255, 0], type='', swap=''),\n        19:\n        dict(name='pinky_finger3', id=19, color=[0, 255, 0], type='', swap=''),\n        20:\n        dict(name='pinky_finger4', id=20, color=[0, 255, 0], type='', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('wrist', 'thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('thumb1', 'thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('thumb2', 'thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('thumb3', 'thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('wrist', 'forefinger1'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('forefinger1', 'forefinger2'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('forefinger2', 'forefinger3'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('forefinger3', 'forefinger4'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('wrist', 'middle_finger1'), id=8, color=[102, 178, 255]),\n        9:\n        dict(\n            link=('middle_finger1', 'middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('middle_finger2', 'middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('middle_finger3', 'middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(link=('wrist', 'ring_finger1'), id=12, color=[255, 51, 51]),\n        13:\n        dict(\n            link=('ring_finger1', 'ring_finger2'), id=13, color=[255, 51, 51]),\n        14:\n        dict(\n            link=('ring_finger2', 'ring_finger3'), id=14, color=[255, 51, 51]),\n        15:\n        dict(\n            link=('ring_finger3', 'ring_finger4'), id=15, color=[255, 51, 51]),\n        16:\n        dict(link=('wrist', 'pinky_finger1'), id=16, color=[0, 255, 0]),\n        17:\n        dict(\n            link=('pinky_finger1', 'pinky_finger2'), id=17, color=[0, 255, 0]),\n        18:\n        dict(\n            link=('pinky_finger2', 'pinky_finger3'), id=18, color=[0, 255, 0]),\n        19:\n        dict(\n            link=('pinky_finger3', 'pinky_finger4'), id=19, color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 21,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/posetrack18.py",
    "content": "dataset_info = dict(\n    dataset_name='posetrack18',\n    paper_info=dict(\n        author='Andriluka, Mykhaylo and Iqbal, Umar and '\n        'Insafutdinov, Eldar and Pishchulin, Leonid and '\n        'Milan, Anton and Gall, Juergen and Schiele, Bernt',\n        title='Posetrack: A benchmark for human pose estimation and tracking',\n        container='Proceedings of the IEEE Conference on '\n        'Computer Vision and Pattern Recognition',\n        year='2018',\n        homepage='https://posetrack.net/users/download.php',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='head_bottom',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        2:\n        dict(\n            name='head_top', id=2, color=[51, 153, 255], type='upper',\n            swap=''),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('nose', 'head_bottom'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'head_top'), id=13, color=[51, 153, 255]),\n        14:\n        dict(\n            link=('head_bottom', 'left_shoulder'), id=14, color=[51, 153,\n                                                                 255]),\n        15:\n        dict(\n            link=('head_bottom', 'right_shoulder'),\n            id=15,\n            color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/rhd2d.py",
    "content": "dataset_info = dict(\n    dataset_name='rhd2d',\n    paper_info=dict(\n        author='Christian Zimmermann and Thomas Brox',\n        title='Learning to Estimate 3D Hand Pose from Single RGB Images',\n        container='arXiv',\n        year='2017',\n        homepage='https://lmb.informatik.uni-freiburg.de/resources/'\n        'datasets/RenderedHandposeDataset.en.html',\n    ),\n    # In RHD, 1-4: left thumb [tip to palm], which means the finger is from\n    # tip to palm, so as other fingers. Please refer to\n    # `https://lmb.informatik.uni-freiburg.de/resources/datasets/\n    # RenderedHandpose/README` for details of keypoint definition.\n    # But in COCO-WholeBody-Hand, FreiHand, CMU Panoptic HandDB, it is in\n    # inverse order. Pay attention to this if you want to combine RHD with\n    # other hand datasets to train a single model.\n    # Also, note that 'keypoint_info' will not directly affect the order of\n    # the keypoint in the dataset. It is mostly for visualization & storing\n    # information about flip_pairs.\n    keypoint_info={\n        0:\n        dict(name='wrist', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='thumb4', id=1, color=[255, 128, 0], type='', swap=''),\n        2:\n        dict(name='thumb3', id=2, color=[255, 128, 0], type='', swap=''),\n        3:\n        dict(name='thumb2', id=3, color=[255, 128, 0], type='', swap=''),\n        4:\n        dict(name='thumb1', id=4, color=[255, 128, 0], type='', swap=''),\n        5:\n        dict(\n            name='forefinger4', id=5, color=[255, 153, 255], type='', swap=''),\n        6:\n        dict(\n            name='forefinger3', id=6, color=[255, 153, 255], type='', swap=''),\n        7:\n        dict(\n            name='forefinger2', id=7, color=[255, 153, 255], type='', swap=''),\n        8:\n        dict(\n            name='forefinger1', id=8, color=[255, 153, 255], type='', swap=''),\n        9:\n        dict(\n            name='middle_finger4',\n            id=9,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        10:\n        dict(\n            name='middle_finger3',\n            id=10,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        11:\n        dict(\n            name='middle_finger2',\n            id=11,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        12:\n        dict(\n            name='middle_finger1',\n            id=12,\n            color=[102, 178, 255],\n            type='',\n            swap=''),\n        13:\n        dict(\n            name='ring_finger4', id=13, color=[255, 51, 51], type='', swap=''),\n        14:\n        dict(\n            name='ring_finger3', id=14, color=[255, 51, 51], type='', swap=''),\n        15:\n        dict(\n            name='ring_finger2', id=15, color=[255, 51, 51], type='', swap=''),\n        16:\n        dict(\n            name='ring_finger1', id=16, color=[255, 51, 51], type='', swap=''),\n        17:\n        dict(name='pinky_finger4', id=17, color=[0, 255, 0], type='', swap=''),\n        18:\n        dict(name='pinky_finger3', id=18, color=[0, 255, 0], type='', swap=''),\n        19:\n        dict(name='pinky_finger2', id=19, color=[0, 255, 0], type='', swap=''),\n        20:\n        dict(name='pinky_finger1', id=20, color=[0, 255, 0], type='', swap='')\n    },\n    skeleton_info={\n        0:\n        dict(link=('wrist', 'thumb1'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('thumb1', 'thumb2'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('thumb2', 'thumb3'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('thumb3', 'thumb4'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('wrist', 'forefinger1'), id=4, color=[255, 153, 255]),\n        5:\n        dict(link=('forefinger1', 'forefinger2'), id=5, color=[255, 153, 255]),\n        6:\n        dict(link=('forefinger2', 'forefinger3'), id=6, color=[255, 153, 255]),\n        7:\n        dict(link=('forefinger3', 'forefinger4'), id=7, color=[255, 153, 255]),\n        8:\n        dict(link=('wrist', 'middle_finger1'), id=8, color=[102, 178, 255]),\n        9:\n        dict(\n            link=('middle_finger1', 'middle_finger2'),\n            id=9,\n            color=[102, 178, 255]),\n        10:\n        dict(\n            link=('middle_finger2', 'middle_finger3'),\n            id=10,\n            color=[102, 178, 255]),\n        11:\n        dict(\n            link=('middle_finger3', 'middle_finger4'),\n            id=11,\n            color=[102, 178, 255]),\n        12:\n        dict(link=('wrist', 'ring_finger1'), id=12, color=[255, 51, 51]),\n        13:\n        dict(\n            link=('ring_finger1', 'ring_finger2'), id=13, color=[255, 51, 51]),\n        14:\n        dict(\n            link=('ring_finger2', 'ring_finger3'), id=14, color=[255, 51, 51]),\n        15:\n        dict(\n            link=('ring_finger3', 'ring_finger4'), id=15, color=[255, 51, 51]),\n        16:\n        dict(link=('wrist', 'pinky_finger1'), id=16, color=[0, 255, 0]),\n        17:\n        dict(\n            link=('pinky_finger1', 'pinky_finger2'), id=17, color=[0, 255, 0]),\n        18:\n        dict(\n            link=('pinky_finger2', 'pinky_finger3'), id=18, color=[0, 255, 0]),\n        19:\n        dict(\n            link=('pinky_finger3', 'pinky_finger4'), id=19, color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 21,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/shelf.py",
    "content": "dataset_info = dict(\n    dataset_name='shelf',\n    paper_info=dict(\n        author='Belagiannis, Vasileios and Amin, Sikandar and Andriluka, '\n        'Mykhaylo and Schiele, Bernt and Navab, Nassir and Ilic, Slobodan',\n        title='3D Pictorial Structures for Multiple Human Pose Estimation',\n        container='IEEE Computer Society Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2014',\n        homepage='http://campar.in.tum.de/Chair/MultiHumanPose',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_ankle',\n            id=0,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        1:\n        dict(\n            name='right_knee',\n            id=1,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        2:\n        dict(\n            name='right_hip',\n            id=2,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        3:\n        dict(\n            name='left_hip',\n            id=3,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        4:\n        dict(\n            name='left_knee',\n            id=4,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        5:\n        dict(\n            name='left_ankle',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        6:\n        dict(\n            name='right_wrist',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        7:\n        dict(\n            name='right_elbow',\n            id=7,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        8:\n        dict(\n            name='right_shoulder',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        9:\n        dict(\n            name='left_shoulder',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        10:\n        dict(\n            name='left_elbow',\n            id=10,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        11:\n        dict(\n            name='left_wrist',\n            id=11,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        12:\n        dict(\n            name='bottom_head',\n            id=12,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n        13:\n        dict(\n            name='top_head',\n            id=13,\n            color=[51, 153, 255],\n            type='upper',\n            swap=''),\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        1:\n        dict(link=('right_knee', 'right_hip'), id=1, color=[255, 128, 0]),\n        2:\n        dict(link=('left_hip', 'left_knee'), id=2, color=[0, 255, 0]),\n        3:\n        dict(link=('left_knee', 'left_ankle'), id=3, color=[0, 255, 0]),\n        4:\n        dict(link=('right_hip', 'left_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('right_wrist', 'right_elbow'), id=5, color=[255, 128, 0]),\n        6:\n        dict(\n            link=('right_elbow', 'right_shoulder'), id=6, color=[255, 128, 0]),\n        7:\n        dict(link=('left_shoulder', 'left_elbow'), id=7, color=[0, 255, 0]),\n        8:\n        dict(link=('left_elbow', 'left_wrist'), id=8, color=[0, 255, 0]),\n        9:\n        dict(link=('right_hip', 'right_shoulder'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_hip', 'left_shoulder'), id=10, color=[0, 255, 0]),\n        11:\n        dict(\n            link=('right_shoulder', 'bottom_head'), id=11, color=[255, 128,\n                                                                  0]),\n        12:\n        dict(link=('left_shoulder', 'bottom_head'), id=12, color=[0, 255, 0]),\n        13:\n        dict(link=('bottom_head', 'top_head'), id=13, color=[51, 153, 255]),\n    },\n    joint_weights=[\n        1.5, 1.2, 1.0, 1.0, 1.2, 1.5, 1.5, 1.2, 1.0, 1.0, 1.2, 1.5, 1.0, 1.0\n    ],\n    sigmas=[\n        0.089, 0.087, 0.107, 0.107, 0.087, 0.089, 0.062, 0.072, 0.079, 0.079,\n        0.072, 0.062, 0.026, 0.026\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/ubody2d.py",
    "content": "dataset_info = dict(\n    dataset_name='ubody2d',\n    paper_info=dict(\n        author='Jing Lin, Ailing Zeng, Haoqian Wang, Lei Zhang, Yu Li',\n        title='One-Stage 3D Whole-Body Mesh Recovery with Component Aware'\n        'Transformer',\n        container='IEEE Computer Society Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2023',\n        homepage='https://github.com/IDEA-Research/OSX',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        2:\n        dict(\n            name='right_eye',\n            id=2,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_eye'),\n        3:\n        dict(\n            name='left_ear',\n            id=3,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_ear'),\n        4:\n        dict(\n            name='right_ear',\n            id=4,\n            color=[51, 153, 255],\n            type='upper',\n            swap='left_ear'),\n        5:\n        dict(\n            name='left_shoulder',\n            id=5,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_shoulder'),\n        6:\n        dict(\n            name='right_shoulder',\n            id=6,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_shoulder'),\n        7:\n        dict(\n            name='left_elbow',\n            id=7,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_elbow'),\n        8:\n        dict(\n            name='right_elbow',\n            id=8,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_elbow'),\n        9:\n        dict(\n            name='left_wrist',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='right_wrist'),\n        10:\n        dict(\n            name='right_wrist',\n            id=10,\n            color=[255, 128, 0],\n            type='upper',\n            swap='left_wrist'),\n        11:\n        dict(\n            name='left_hip',\n            id=11,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_hip'),\n        12:\n        dict(\n            name='right_hip',\n            id=12,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_hip'),\n        13:\n        dict(\n            name='left_knee',\n            id=13,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_knee'),\n        14:\n        dict(\n            name='right_knee',\n            id=14,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_knee'),\n        15:\n        dict(\n            name='left_ankle',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='right_ankle'),\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        17:\n        dict(\n            name='left_big_toe',\n            id=17,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_big_toe'),\n        18:\n        dict(\n            name='left_small_toe',\n            id=18,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_small_toe'),\n        19:\n        dict(\n            name='left_heel',\n            id=19,\n            color=[255, 128, 0],\n            type='lower',\n            swap='right_heel'),\n        20:\n        dict(\n            name='right_big_toe',\n            id=20,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_big_toe'),\n        21:\n        dict(\n            name='right_small_toe',\n            id=21,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_small_toe'),\n        22:\n        dict(\n            name='right_heel',\n            id=22,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_heel'),\n        23:\n        dict(\n            name='face-0',\n            id=23,\n            color=[255, 255, 255],\n            type='',\n            swap='face-16'),\n        24:\n        dict(\n            name='face-1',\n            id=24,\n            color=[255, 255, 255],\n            type='',\n            swap='face-15'),\n        25:\n        dict(\n            name='face-2',\n            id=25,\n            color=[255, 255, 255],\n            type='',\n            swap='face-14'),\n        26:\n        dict(\n            name='face-3',\n            id=26,\n            color=[255, 255, 255],\n            type='',\n            swap='face-13'),\n        27:\n        dict(\n            name='face-4',\n            id=27,\n            color=[255, 255, 255],\n            type='',\n            swap='face-12'),\n        28:\n        dict(\n            name='face-5',\n            id=28,\n            color=[255, 255, 255],\n            type='',\n            swap='face-11'),\n        29:\n        dict(\n            name='face-6',\n            id=29,\n            color=[255, 255, 255],\n            type='',\n            swap='face-10'),\n        30:\n        dict(\n            name='face-7',\n            id=30,\n            color=[255, 255, 255],\n            type='',\n            swap='face-9'),\n        31:\n        dict(name='face-8', id=31, color=[255, 255, 255], type='', swap=''),\n        32:\n        dict(\n            name='face-9',\n            id=32,\n            color=[255, 255, 255],\n            type='',\n            swap='face-7'),\n        33:\n        dict(\n            name='face-10',\n            id=33,\n            color=[255, 255, 255],\n            type='',\n            swap='face-6'),\n        34:\n        dict(\n            name='face-11',\n            id=34,\n            color=[255, 255, 255],\n            type='',\n            swap='face-5'),\n        35:\n        dict(\n            name='face-12',\n            id=35,\n            color=[255, 255, 255],\n            type='',\n            swap='face-4'),\n        36:\n        dict(\n            name='face-13',\n            id=36,\n            color=[255, 255, 255],\n            type='',\n            swap='face-3'),\n        37:\n        dict(\n            name='face-14',\n            id=37,\n            color=[255, 255, 255],\n            type='',\n            swap='face-2'),\n        38:\n        dict(\n            name='face-15',\n            id=38,\n            color=[255, 255, 255],\n            type='',\n            swap='face-1'),\n        39:\n        dict(\n            name='face-16',\n            id=39,\n            color=[255, 255, 255],\n            type='',\n            swap='face-0'),\n        40:\n        dict(\n            name='face-17',\n            id=40,\n            color=[255, 255, 255],\n            type='',\n            swap='face-26'),\n        41:\n        dict(\n            name='face-18',\n            id=41,\n            color=[255, 255, 255],\n            type='',\n            swap='face-25'),\n        42:\n        dict(\n            name='face-19',\n            id=42,\n            color=[255, 255, 255],\n            type='',\n            swap='face-24'),\n        43:\n        dict(\n            name='face-20',\n            id=43,\n            color=[255, 255, 255],\n            type='',\n            swap='face-23'),\n        44:\n        dict(\n            name='face-21',\n            id=44,\n            color=[255, 255, 255],\n            type='',\n            swap='face-22'),\n        45:\n        dict(\n            name='face-22',\n            id=45,\n            color=[255, 255, 255],\n            type='',\n            swap='face-21'),\n        46:\n        dict(\n            name='face-23',\n            id=46,\n            color=[255, 255, 255],\n            type='',\n            swap='face-20'),\n        47:\n        dict(\n            name='face-24',\n            id=47,\n            color=[255, 255, 255],\n            type='',\n            swap='face-19'),\n        48:\n        dict(\n            name='face-25',\n            id=48,\n            color=[255, 255, 255],\n            type='',\n            swap='face-18'),\n        49:\n        dict(\n            name='face-26',\n            id=49,\n            color=[255, 255, 255],\n            type='',\n            swap='face-17'),\n        50:\n        dict(name='face-27', id=50, color=[255, 255, 255], type='', swap=''),\n        51:\n        dict(name='face-28', id=51, color=[255, 255, 255], type='', swap=''),\n        52:\n        dict(name='face-29', id=52, color=[255, 255, 255], type='', swap=''),\n        53:\n        dict(name='face-30', id=53, color=[255, 255, 255], type='', swap=''),\n        54:\n        dict(\n            name='face-31',\n            id=54,\n            color=[255, 255, 255],\n            type='',\n            swap='face-35'),\n        55:\n        dict(\n            name='face-32',\n            id=55,\n            color=[255, 255, 255],\n            type='',\n            swap='face-34'),\n        56:\n        dict(name='face-33', id=56, color=[255, 255, 255], type='', swap=''),\n        57:\n        dict(\n            name='face-34',\n            id=57,\n            color=[255, 255, 255],\n            type='',\n            swap='face-32'),\n        58:\n        dict(\n            name='face-35',\n            id=58,\n            color=[255, 255, 255],\n            type='',\n            swap='face-31'),\n        59:\n        dict(\n            name='face-36',\n            id=59,\n            color=[255, 255, 255],\n            type='',\n            swap='face-45'),\n        60:\n        dict(\n            name='face-37',\n            id=60,\n            color=[255, 255, 255],\n            type='',\n            swap='face-44'),\n        61:\n        dict(\n            name='face-38',\n            id=61,\n            color=[255, 255, 255],\n            type='',\n            swap='face-43'),\n        62:\n        dict(\n            name='face-39',\n            id=62,\n            color=[255, 255, 255],\n            type='',\n            swap='face-42'),\n        63:\n        dict(\n            name='face-40',\n            id=63,\n            color=[255, 255, 255],\n            type='',\n            swap='face-47'),\n        64:\n        dict(\n            name='face-41',\n            id=64,\n            color=[255, 255, 255],\n            type='',\n            swap='face-46'),\n        65:\n        dict(\n            name='face-42',\n            id=65,\n            color=[255, 255, 255],\n            type='',\n            swap='face-39'),\n        66:\n        dict(\n            name='face-43',\n            id=66,\n            color=[255, 255, 255],\n            type='',\n            swap='face-38'),\n        67:\n        dict(\n            name='face-44',\n            id=67,\n            color=[255, 255, 255],\n            type='',\n            swap='face-37'),\n        68:\n        dict(\n            name='face-45',\n            id=68,\n            color=[255, 255, 255],\n            type='',\n            swap='face-36'),\n        69:\n        dict(\n            name='face-46',\n            id=69,\n            color=[255, 255, 255],\n            type='',\n            swap='face-41'),\n        70:\n        dict(\n            name='face-47',\n            id=70,\n            color=[255, 255, 255],\n            type='',\n            swap='face-40'),\n        71:\n        dict(\n            name='face-48',\n            id=71,\n            color=[255, 255, 255],\n            type='',\n            swap='face-54'),\n        72:\n        dict(\n            name='face-49',\n            id=72,\n            color=[255, 255, 255],\n            type='',\n            swap='face-53'),\n        73:\n        dict(\n            name='face-50',\n            id=73,\n            color=[255, 255, 255],\n            type='',\n            swap='face-52'),\n        74:\n        dict(name='face-51', id=74, color=[255, 255, 255], type='', swap=''),\n        75:\n        dict(\n            name='face-52',\n            id=75,\n            color=[255, 255, 255],\n            type='',\n            swap='face-50'),\n        76:\n        dict(\n            name='face-53',\n            id=76,\n            color=[255, 255, 255],\n            type='',\n            swap='face-49'),\n        77:\n        dict(\n            name='face-54',\n            id=77,\n            color=[255, 255, 255],\n            type='',\n            swap='face-48'),\n        78:\n        dict(\n            name='face-55',\n            id=78,\n            color=[255, 255, 255],\n            type='',\n            swap='face-59'),\n        79:\n        dict(\n            name='face-56',\n            id=79,\n            color=[255, 255, 255],\n            type='',\n            swap='face-58'),\n        80:\n        dict(name='face-57', id=80, color=[255, 255, 255], type='', swap=''),\n        81:\n        dict(\n            name='face-58',\n            id=81,\n            color=[255, 255, 255],\n            type='',\n            swap='face-56'),\n        82:\n        dict(\n            name='face-59',\n            id=82,\n            color=[255, 255, 255],\n            type='',\n            swap='face-55'),\n        83:\n        dict(\n            name='face-60',\n            id=83,\n            color=[255, 255, 255],\n            type='',\n            swap='face-64'),\n        84:\n        dict(\n            name='face-61',\n            id=84,\n            color=[255, 255, 255],\n            type='',\n            swap='face-63'),\n        85:\n        dict(name='face-62', id=85, color=[255, 255, 255], type='', swap=''),\n        86:\n        dict(\n            name='face-63',\n            id=86,\n            color=[255, 255, 255],\n            type='',\n            swap='face-61'),\n        87:\n        dict(\n            name='face-64',\n            id=87,\n            color=[255, 255, 255],\n            type='',\n            swap='face-60'),\n        88:\n        dict(\n            name='face-65',\n            id=88,\n            color=[255, 255, 255],\n            type='',\n            swap='face-67'),\n        89:\n        dict(name='face-66', id=89, color=[255, 255, 255], type='', swap=''),\n        90:\n        dict(\n            name='face-67',\n            id=90,\n            color=[255, 255, 255],\n            type='',\n            swap='face-65'),\n        91:\n        dict(\n            name='left_hand_root',\n            id=91,\n            color=[255, 255, 255],\n            type='',\n            swap='right_hand_root'),\n        92:\n        dict(\n            name='left_thumb1',\n            id=92,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb1'),\n        93:\n        dict(\n            name='left_thumb2',\n            id=93,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb2'),\n        94:\n        dict(\n            name='left_thumb3',\n            id=94,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb3'),\n        95:\n        dict(\n            name='left_thumb4',\n            id=95,\n            color=[255, 128, 0],\n            type='',\n            swap='right_thumb4'),\n        96:\n        dict(\n            name='left_forefinger1',\n            id=96,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger1'),\n        97:\n        dict(\n            name='left_forefinger2',\n            id=97,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger2'),\n        98:\n        dict(\n            name='left_forefinger3',\n            id=98,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger3'),\n        99:\n        dict(\n            name='left_forefinger4',\n            id=99,\n            color=[255, 153, 255],\n            type='',\n            swap='right_forefinger4'),\n        100:\n        dict(\n            name='left_middle_finger1',\n            id=100,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger1'),\n        101:\n        dict(\n            name='left_middle_finger2',\n            id=101,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger2'),\n        102:\n        dict(\n            name='left_middle_finger3',\n            id=102,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger3'),\n        103:\n        dict(\n            name='left_middle_finger4',\n            id=103,\n            color=[102, 178, 255],\n            type='',\n            swap='right_middle_finger4'),\n        104:\n        dict(\n            name='left_ring_finger1',\n            id=104,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger1'),\n        105:\n        dict(\n            name='left_ring_finger2',\n            id=105,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger2'),\n        106:\n        dict(\n            name='left_ring_finger3',\n            id=106,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger3'),\n        107:\n        dict(\n            name='left_ring_finger4',\n            id=107,\n            color=[255, 51, 51],\n            type='',\n            swap='right_ring_finger4'),\n        108:\n        dict(\n            name='left_pinky_finger1',\n            id=108,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger1'),\n        109:\n        dict(\n            name='left_pinky_finger2',\n            id=109,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger2'),\n        110:\n        dict(\n            name='left_pinky_finger3',\n            id=110,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger3'),\n        111:\n        dict(\n            name='left_pinky_finger4',\n            id=111,\n            color=[0, 255, 0],\n            type='',\n            swap='right_pinky_finger4'),\n        112:\n        dict(\n            name='right_hand_root',\n            id=112,\n            color=[255, 255, 255],\n            type='',\n            swap='left_hand_root'),\n        113:\n        dict(\n            name='right_thumb1',\n            id=113,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb1'),\n        114:\n        dict(\n            name='right_thumb2',\n            id=114,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb2'),\n        115:\n        dict(\n            name='right_thumb3',\n            id=115,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb3'),\n        116:\n        dict(\n            name='right_thumb4',\n            id=116,\n            color=[255, 128, 0],\n            type='',\n            swap='left_thumb4'),\n        117:\n        dict(\n            name='right_forefinger1',\n            id=117,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger1'),\n        118:\n        dict(\n            name='right_forefinger2',\n            id=118,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger2'),\n        119:\n        dict(\n            name='right_forefinger3',\n            id=119,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger3'),\n        120:\n        dict(\n            name='right_forefinger4',\n            id=120,\n            color=[255, 153, 255],\n            type='',\n            swap='left_forefinger4'),\n        121:\n        dict(\n            name='right_middle_finger1',\n            id=121,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger1'),\n        122:\n        dict(\n            name='right_middle_finger2',\n            id=122,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger2'),\n        123:\n        dict(\n            name='right_middle_finger3',\n            id=123,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger3'),\n        124:\n        dict(\n            name='right_middle_finger4',\n            id=124,\n            color=[102, 178, 255],\n            type='',\n            swap='left_middle_finger4'),\n        125:\n        dict(\n            name='right_ring_finger1',\n            id=125,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger1'),\n        126:\n        dict(\n            name='right_ring_finger2',\n            id=126,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger2'),\n        127:\n        dict(\n            name='right_ring_finger3',\n            id=127,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger3'),\n        128:\n        dict(\n            name='right_ring_finger4',\n            id=128,\n            color=[255, 51, 51],\n            type='',\n            swap='left_ring_finger4'),\n        129:\n        dict(\n            name='right_pinky_finger1',\n            id=129,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger1'),\n        130:\n        dict(\n            name='right_pinky_finger2',\n            id=130,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger2'),\n        131:\n        dict(\n            name='right_pinky_finger3',\n            id=131,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger3'),\n        132:\n        dict(\n            name='right_pinky_finger4',\n            id=132,\n            color=[0, 255, 0],\n            type='',\n            swap='left_pinky_finger4')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        1:\n        dict(link=('left_knee', 'left_hip'), id=1, color=[0, 255, 0]),\n        2:\n        dict(link=('right_ankle', 'right_knee'), id=2, color=[255, 128, 0]),\n        3:\n        dict(link=('right_knee', 'right_hip'), id=3, color=[255, 128, 0]),\n        4:\n        dict(link=('left_hip', 'right_hip'), id=4, color=[51, 153, 255]),\n        5:\n        dict(link=('left_shoulder', 'left_hip'), id=5, color=[51, 153, 255]),\n        6:\n        dict(link=('right_shoulder', 'right_hip'), id=6, color=[51, 153, 255]),\n        7:\n        dict(\n            link=('left_shoulder', 'right_shoulder'),\n            id=7,\n            color=[51, 153, 255]),\n        8:\n        dict(link=('left_shoulder', 'left_elbow'), id=8, color=[0, 255, 0]),\n        9:\n        dict(\n            link=('right_shoulder', 'right_elbow'), id=9, color=[255, 128, 0]),\n        10:\n        dict(link=('left_elbow', 'left_wrist'), id=10, color=[0, 255, 0]),\n        11:\n        dict(link=('right_elbow', 'right_wrist'), id=11, color=[255, 128, 0]),\n        12:\n        dict(link=('left_eye', 'right_eye'), id=12, color=[51, 153, 255]),\n        13:\n        dict(link=('nose', 'left_eye'), id=13, color=[51, 153, 255]),\n        14:\n        dict(link=('nose', 'right_eye'), id=14, color=[51, 153, 255]),\n        15:\n        dict(link=('left_eye', 'left_ear'), id=15, color=[51, 153, 255]),\n        16:\n        dict(link=('right_eye', 'right_ear'), id=16, color=[51, 153, 255]),\n        17:\n        dict(link=('left_ear', 'left_shoulder'), id=17, color=[51, 153, 255]),\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255]),\n        19:\n        dict(link=('left_ankle', 'left_big_toe'), id=19, color=[0, 255, 0]),\n        20:\n        dict(link=('left_ankle', 'left_small_toe'), id=20, color=[0, 255, 0]),\n        21:\n        dict(link=('left_ankle', 'left_heel'), id=21, color=[0, 255, 0]),\n        22:\n        dict(\n            link=('right_ankle', 'right_big_toe'), id=22, color=[255, 128, 0]),\n        23:\n        dict(\n            link=('right_ankle', 'right_small_toe'),\n            id=23,\n            color=[255, 128, 0]),\n        24:\n        dict(link=('right_ankle', 'right_heel'), id=24, color=[255, 128, 0]),\n        25:\n        dict(\n            link=('left_hand_root', 'left_thumb1'), id=25, color=[255, 128,\n                                                                  0]),\n        26:\n        dict(link=('left_thumb1', 'left_thumb2'), id=26, color=[255, 128, 0]),\n        27:\n        dict(link=('left_thumb2', 'left_thumb3'), id=27, color=[255, 128, 0]),\n        28:\n        dict(link=('left_thumb3', 'left_thumb4'), id=28, color=[255, 128, 0]),\n        29:\n        dict(\n            link=('left_hand_root', 'left_forefinger1'),\n            id=29,\n            color=[255, 153, 255]),\n        30:\n        dict(\n            link=('left_forefinger1', 'left_forefinger2'),\n            id=30,\n            color=[255, 153, 255]),\n        31:\n        dict(\n            link=('left_forefinger2', 'left_forefinger3'),\n            id=31,\n            color=[255, 153, 255]),\n        32:\n        dict(\n            link=('left_forefinger3', 'left_forefinger4'),\n            id=32,\n            color=[255, 153, 255]),\n        33:\n        dict(\n            link=('left_hand_root', 'left_middle_finger1'),\n            id=33,\n            color=[102, 178, 255]),\n        34:\n        dict(\n            link=('left_middle_finger1', 'left_middle_finger2'),\n            id=34,\n            color=[102, 178, 255]),\n        35:\n        dict(\n            link=('left_middle_finger2', 'left_middle_finger3'),\n            id=35,\n            color=[102, 178, 255]),\n        36:\n        dict(\n            link=('left_middle_finger3', 'left_middle_finger4'),\n            id=36,\n            color=[102, 178, 255]),\n        37:\n        dict(\n            link=('left_hand_root', 'left_ring_finger1'),\n            id=37,\n            color=[255, 51, 51]),\n        38:\n        dict(\n            link=('left_ring_finger1', 'left_ring_finger2'),\n            id=38,\n            color=[255, 51, 51]),\n        39:\n        dict(\n            link=('left_ring_finger2', 'left_ring_finger3'),\n            id=39,\n            color=[255, 51, 51]),\n        40:\n        dict(\n            link=('left_ring_finger3', 'left_ring_finger4'),\n            id=40,\n            color=[255, 51, 51]),\n        41:\n        dict(\n            link=('left_hand_root', 'left_pinky_finger1'),\n            id=41,\n            color=[0, 255, 0]),\n        42:\n        dict(\n            link=('left_pinky_finger1', 'left_pinky_finger2'),\n            id=42,\n            color=[0, 255, 0]),\n        43:\n        dict(\n            link=('left_pinky_finger2', 'left_pinky_finger3'),\n            id=43,\n            color=[0, 255, 0]),\n        44:\n        dict(\n            link=('left_pinky_finger3', 'left_pinky_finger4'),\n            id=44,\n            color=[0, 255, 0]),\n        45:\n        dict(\n            link=('right_hand_root', 'right_thumb1'),\n            id=45,\n            color=[255, 128, 0]),\n        46:\n        dict(\n            link=('right_thumb1', 'right_thumb2'), id=46, color=[255, 128, 0]),\n        47:\n        dict(\n            link=('right_thumb2', 'right_thumb3'), id=47, color=[255, 128, 0]),\n        48:\n        dict(\n            link=('right_thumb3', 'right_thumb4'), id=48, color=[255, 128, 0]),\n        49:\n        dict(\n            link=('right_hand_root', 'right_forefinger1'),\n            id=49,\n            color=[255, 153, 255]),\n        50:\n        dict(\n            link=('right_forefinger1', 'right_forefinger2'),\n            id=50,\n            color=[255, 153, 255]),\n        51:\n        dict(\n            link=('right_forefinger2', 'right_forefinger3'),\n            id=51,\n            color=[255, 153, 255]),\n        52:\n        dict(\n            link=('right_forefinger3', 'right_forefinger4'),\n            id=52,\n            color=[255, 153, 255]),\n        53:\n        dict(\n            link=('right_hand_root', 'right_middle_finger1'),\n            id=53,\n            color=[102, 178, 255]),\n        54:\n        dict(\n            link=('right_middle_finger1', 'right_middle_finger2'),\n            id=54,\n            color=[102, 178, 255]),\n        55:\n        dict(\n            link=('right_middle_finger2', 'right_middle_finger3'),\n            id=55,\n            color=[102, 178, 255]),\n        56:\n        dict(\n            link=('right_middle_finger3', 'right_middle_finger4'),\n            id=56,\n            color=[102, 178, 255]),\n        57:\n        dict(\n            link=('right_hand_root', 'right_ring_finger1'),\n            id=57,\n            color=[255, 51, 51]),\n        58:\n        dict(\n            link=('right_ring_finger1', 'right_ring_finger2'),\n            id=58,\n            color=[255, 51, 51]),\n        59:\n        dict(\n            link=('right_ring_finger2', 'right_ring_finger3'),\n            id=59,\n            color=[255, 51, 51]),\n        60:\n        dict(\n            link=('right_ring_finger3', 'right_ring_finger4'),\n            id=60,\n            color=[255, 51, 51]),\n        61:\n        dict(\n            link=('right_hand_root', 'right_pinky_finger1'),\n            id=61,\n            color=[0, 255, 0]),\n        62:\n        dict(\n            link=('right_pinky_finger1', 'right_pinky_finger2'),\n            id=62,\n            color=[0, 255, 0]),\n        63:\n        dict(\n            link=('right_pinky_finger2', 'right_pinky_finger3'),\n            id=63,\n            color=[0, 255, 0]),\n        64:\n        dict(\n            link=('right_pinky_finger3', 'right_pinky_finger4'),\n            id=64,\n            color=[0, 255, 0])\n    },\n    joint_weights=[1.] * 133,\n    # 'https://github.com/jin-s13/COCO-WholeBody/blob/master/'\n    # 'evaluation/myeval_wholebody.py#L175'\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089, 0.068, 0.066, 0.066,\n        0.092, 0.094, 0.094, 0.042, 0.043, 0.044, 0.043, 0.040, 0.035, 0.031,\n        0.025, 0.020, 0.023, 0.029, 0.032, 0.037, 0.038, 0.043, 0.041, 0.045,\n        0.013, 0.012, 0.011, 0.011, 0.012, 0.012, 0.011, 0.011, 0.013, 0.015,\n        0.009, 0.007, 0.007, 0.007, 0.012, 0.009, 0.008, 0.016, 0.010, 0.017,\n        0.011, 0.009, 0.011, 0.009, 0.007, 0.013, 0.008, 0.011, 0.012, 0.010,\n        0.034, 0.008, 0.008, 0.009, 0.008, 0.008, 0.007, 0.010, 0.008, 0.009,\n        0.009, 0.009, 0.007, 0.007, 0.008, 0.011, 0.008, 0.008, 0.008, 0.01,\n        0.008, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024, 0.035,\n        0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02, 0.019,\n        0.022, 0.031, 0.029, 0.022, 0.035, 0.037, 0.047, 0.026, 0.025, 0.024,\n        0.035, 0.018, 0.024, 0.022, 0.026, 0.017, 0.021, 0.021, 0.032, 0.02,\n        0.019, 0.022, 0.031\n    ])\n"
  },
  {
    "path": "configs/_base_/datasets/ubody3d.py",
    "content": "dataset_info = dict(\n    dataset_name='ubody3d',\n    paper_info=dict(\n        author='Jing Lin, Ailing Zeng, Haoqian Wang, Lei Zhang, Yu Li',\n        title='One-Stage 3D Whole-Body Mesh Recovery with Component Aware'\n        'Transformer',\n        container='IEEE Computer Society Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2023',\n        homepage='https://github.com/IDEA-Research/OSX',\n    ),\n    keypoint_info={\n        0:\n        dict(name='Pelvis', id=0, color=[0, 255, 0], type='', swap=''),\n        1:\n        dict(\n            name='L_Hip', id=1, color=[0, 255, 0], type='lower', swap='R_Hip'),\n        2:\n        dict(\n            name='R_Hip', id=2, color=[0, 255, 0], type='lower', swap='L_Hip'),\n        3:\n        dict(\n            name='L_Knee',\n            id=3,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_Knee'),\n        4:\n        dict(\n            name='R_Knee',\n            id=4,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_Knee'),\n        5:\n        dict(\n            name='L_Ankle',\n            id=5,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_Ankle'),\n        6:\n        dict(\n            name='R_Ankle',\n            id=6,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_Ankle'),\n        7:\n        dict(name='Neck', id=7, color=[0, 255, 0], type='upper', swap=''),\n        8:\n        dict(\n            name='L_Shoulder',\n            id=8,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_Shoulder'),\n        9:\n        dict(\n            name='R_Shoulder',\n            id=9,\n            color=[0, 255, 0],\n            type='upper',\n            swap='L_Shoulder'),\n        10:\n        dict(\n            name='L_Elbow',\n            id=10,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_Elbow'),\n        11:\n        dict(\n            name='R_Elbow',\n            id=11,\n            color=[0, 255, 0],\n            type='upper',\n            swap='L_Elbow'),\n        12:\n        dict(\n            name='L_Wrist',\n            id=12,\n            color=[0, 255, 0],\n            type='upper',\n            swap='R_Wrist'),\n        13:\n        dict(\n            name='R_Wrist',\n            id=13,\n            color=[0, 255, 0],\n            type='upper',\n            swap='L_Wrist'),\n        14:\n        dict(\n            name='L_Big_toe',\n            id=14,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_Big_toe'),\n        15:\n        dict(\n            name='L_Small_toe',\n            id=15,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_Small_toe'),\n        16:\n        dict(\n            name='L_Heel',\n            id=16,\n            color=[0, 255, 0],\n            type='lower',\n            swap='R_Heel'),\n        17:\n        dict(\n            name='R_Big_toe',\n            id=17,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_Big_toe'),\n        18:\n        dict(\n            name='R_Small_toe',\n            id=18,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_Small_toe'),\n        19:\n        dict(\n            name='R_Heel',\n            id=19,\n            color=[0, 255, 0],\n            type='lower',\n            swap='L_Heel'),\n        20:\n        dict(\n            name='L_Ear', id=20, color=[0, 255, 0], type='upper',\n            swap='R_Ear'),\n        21:\n        dict(\n            name='R_Ear', id=21, color=[0, 255, 0], type='upper',\n            swap='L_Ear'),\n        22:\n        dict(name='L_Eye', id=22, color=[0, 255, 0], type='', swap='R_Eye'),\n        23:\n        dict(name='R_Eye', id=23, color=[0, 255, 0], type='', swap='L_Eye'),\n        24:\n        dict(name='Nose', id=24, color=[0, 255, 0], type='upper', swap=''),\n        25:\n        dict(\n            name='L_Thumb_1',\n            id=25,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Thumb_1'),\n        26:\n        dict(\n            name='L_Thumb_2',\n            id=26,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Thumb_2'),\n        27:\n        dict(\n            name='L_Thumb_3',\n            id=27,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Thumb_3'),\n        28:\n        dict(\n            name='L_Thumb_4',\n            id=28,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Thumb_4'),\n        29:\n        dict(\n            name='L_Index_1',\n            id=29,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Index_1'),\n        30:\n        dict(\n            name='L_Index_2',\n            id=30,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Index_2'),\n        31:\n        dict(\n            name='L_Index_3',\n            id=31,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Index_3'),\n        32:\n        dict(\n            name='L_Index_4',\n            id=32,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Index_4'),\n        33:\n        dict(\n            name='L_Middle_1',\n            id=33,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Middle_1'),\n        34:\n        dict(\n            name='L_Middle_2',\n            id=34,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Middle_2'),\n        35:\n        dict(\n            name='L_Middle_3',\n            id=35,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Middle_3'),\n        36:\n        dict(\n            name='L_Middle_4',\n            id=36,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Middle_4'),\n        37:\n        dict(\n            name='L_Ring_1',\n            id=37,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Ring_1'),\n        38:\n        dict(\n            name='L_Ring_2',\n            id=38,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Ring_2'),\n        39:\n        dict(\n            name='L_Ring_3',\n            id=39,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Ring_3'),\n        40:\n        dict(\n            name='L_Ring_4',\n            id=40,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Ring_4'),\n        41:\n        dict(\n            name='L_Pinky_1',\n            id=41,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Pinky_1'),\n        42:\n        dict(\n            name='L_Pinky_2',\n            id=42,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Pinky_2'),\n        43:\n        dict(\n            name='L_Pinky_3',\n            id=43,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Pinky_3'),\n        44:\n        dict(\n            name='L_Pinky_4',\n            id=44,\n            color=[255, 128, 0],\n            type='',\n            swap='R_Pinky_4'),\n        45:\n        dict(\n            name='R_Thumb_1',\n            id=45,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Thumb_1'),\n        46:\n        dict(\n            name='R_Thumb_2',\n            id=46,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Thumb_2'),\n        47:\n        dict(\n            name='R_Thumb_3',\n            id=47,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Thumb_3'),\n        48:\n        dict(\n            name='R_Thumb_4',\n            id=48,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Thumb_4'),\n        49:\n        dict(\n            name='R_Index_1',\n            id=49,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Index_1'),\n        50:\n        dict(\n            name='R_Index_2',\n            id=50,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Index_2'),\n        51:\n        dict(\n            name='R_Index_3',\n            id=51,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Index_3'),\n        52:\n        dict(\n            name='R_Index_4',\n            id=52,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Index_4'),\n        53:\n        dict(\n            name='R_Middle_1',\n            id=53,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Middle_1'),\n        54:\n        dict(\n            name='R_Middle_2',\n            id=54,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Middle_2'),\n        55:\n        dict(\n            name='R_Middle_3',\n            id=55,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Middle_3'),\n        56:\n        dict(\n            name='R_Middle_4',\n            id=56,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Middle_4'),\n        57:\n        dict(\n            name='R_Ring_1',\n            id=57,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Ring_1'),\n        58:\n        dict(\n            name='R_Ring_2',\n            id=58,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Ring_2'),\n        59:\n        dict(\n            name='R_Ring_3',\n            id=59,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Ring_3'),\n        60:\n        dict(\n            name='R_Ring_4',\n            id=60,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Ring_4'),\n        61:\n        dict(\n            name='R_Pinky_1',\n            id=61,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Pinky_1'),\n        62:\n        dict(\n            name='R_Pinky_2',\n            id=62,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Pinky_2'),\n        63:\n        dict(\n            name='R_Pinky_3',\n            id=63,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Pinky_3'),\n        64:\n        dict(\n            name='R_Pinky_4',\n            id=64,\n            color=[255, 128, 0],\n            type='',\n            swap='L_Pinky_4'),\n        65:\n        dict(name='Face_1', id=65, color=[255, 255, 255], type='', swap=''),\n        66:\n        dict(name='Face_2', id=66, color=[255, 255, 255], type='', swap=''),\n        67:\n        dict(\n            name='Face_3',\n            id=67,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_4'),\n        68:\n        dict(\n            name='Face_4',\n            id=68,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_3'),\n        69:\n        dict(\n            name='Face_5',\n            id=69,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_14'),\n        70:\n        dict(\n            name='Face_6',\n            id=70,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_13'),\n        71:\n        dict(\n            name='Face_7',\n            id=71,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_12'),\n        72:\n        dict(\n            name='Face_8',\n            id=72,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_11'),\n        73:\n        dict(\n            name='Face_9',\n            id=73,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_10'),\n        74:\n        dict(\n            name='Face_10',\n            id=74,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_9'),\n        75:\n        dict(\n            name='Face_11',\n            id=75,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_8'),\n        76:\n        dict(\n            name='Face_12',\n            id=76,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_7'),\n        77:\n        dict(\n            name='Face_13',\n            id=77,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_6'),\n        78:\n        dict(\n            name='Face_14',\n            id=78,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_5'),\n        79:\n        dict(name='Face_15', id=79, color=[255, 255, 255], type='', swap=''),\n        80:\n        dict(name='Face_16', id=80, color=[255, 255, 255], type='', swap=''),\n        81:\n        dict(name='Face_17', id=81, color=[255, 255, 255], type='', swap=''),\n        82:\n        dict(name='Face_18', id=82, color=[255, 255, 255], type='', swap=''),\n        83:\n        dict(\n            name='Face_19',\n            id=83,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_23'),\n        84:\n        dict(\n            name='Face_20',\n            id=84,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_22'),\n        85:\n        dict(name='Face_21', id=85, color=[255, 255, 255], type='', swap=''),\n        86:\n        dict(\n            name='Face_22',\n            id=86,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_20'),\n        87:\n        dict(\n            name='Face_23',\n            id=87,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_19'),\n        88:\n        dict(\n            name='Face_24',\n            id=88,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_33'),\n        89:\n        dict(\n            name='Face_25',\n            id=89,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_32'),\n        90:\n        dict(\n            name='Face_26',\n            id=90,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_31'),\n        91:\n        dict(\n            name='Face_27',\n            id=91,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_30'),\n        92:\n        dict(\n            name='Face_28',\n            id=92,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_35'),\n        93:\n        dict(\n            name='Face_29',\n            id=93,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_34'),\n        94:\n        dict(\n            name='Face_30',\n            id=94,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_27'),\n        95:\n        dict(\n            name='Face_31',\n            id=95,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_26'),\n        96:\n        dict(\n            name='Face_32',\n            id=96,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_25'),\n        97:\n        dict(\n            name='Face_33',\n            id=97,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_24'),\n        98:\n        dict(\n            name='Face_34',\n            id=98,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_29'),\n        99:\n        dict(\n            name='Face_35',\n            id=99,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_28'),\n        100:\n        dict(\n            name='Face_36',\n            id=100,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_42'),\n        101:\n        dict(\n            name='Face_37',\n            id=101,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_41'),\n        102:\n        dict(\n            name='Face_38',\n            id=102,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_40'),\n        103:\n        dict(name='Face_39', id=103, color=[255, 255, 255], type='', swap=''),\n        104:\n        dict(\n            name='Face_40',\n            id=104,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_38'),\n        105:\n        dict(\n            name='Face_41',\n            id=105,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_37'),\n        106:\n        dict(\n            name='Face_42',\n            id=106,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_36'),\n        107:\n        dict(\n            name='Face_43',\n            id=107,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_47'),\n        108:\n        dict(\n            name='Face_44',\n            id=108,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_46'),\n        109:\n        dict(name='Face_45', id=109, color=[255, 255, 255], type='', swap=''),\n        110:\n        dict(\n            name='Face_46',\n            id=110,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_44'),\n        111:\n        dict(\n            name='Face_47',\n            id=111,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_43'),\n        112:\n        dict(\n            name='Face_48',\n            id=112,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_52'),\n        113:\n        dict(\n            name='Face_49',\n            id=113,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_51'),\n        114:\n        dict(name='Face_50', id=114, color=[255, 255, 255], type='', swap=''),\n        115:\n        dict(\n            name='Face_51',\n            id=115,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_49'),\n        116:\n        dict(\n            name='Face_52',\n            id=116,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_48'),\n        117:\n        dict(\n            name='Face_53',\n            id=117,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_55'),\n        118:\n        dict(name='Face_54', id=118, color=[255, 255, 255], type='', swap=''),\n        119:\n        dict(\n            name='Face_55',\n            id=119,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_53'),\n        120:\n        dict(\n            name='Face_56',\n            id=120,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_72'),\n        121:\n        dict(\n            name='Face_57',\n            id=121,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_71'),\n        122:\n        dict(\n            name='Face_58',\n            id=122,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_70'),\n        123:\n        dict(\n            name='Face_59',\n            id=123,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_69'),\n        124:\n        dict(\n            name='Face_60',\n            id=124,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_68'),\n        125:\n        dict(\n            name='Face_61',\n            id=125,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_67'),\n        126:\n        dict(\n            name='Face_62',\n            id=126,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_66'),\n        127:\n        dict(\n            name='Face_63',\n            id=127,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_65'),\n        128:\n        dict(name='Face_64', id=128, color=[255, 255, 255], type='', swap=''),\n        129:\n        dict(\n            name='Face_65',\n            id=129,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_63'),\n        130:\n        dict(\n            name='Face_66',\n            id=130,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_62'),\n        131:\n        dict(\n            name='Face_67',\n            id=131,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_61'),\n        132:\n        dict(\n            name='Face_68',\n            id=132,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_60'),\n        133:\n        dict(\n            name='Face_69',\n            id=133,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_59'),\n        134:\n        dict(\n            name='Face_70',\n            id=134,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_58'),\n        135:\n        dict(\n            name='Face_71',\n            id=135,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_57'),\n        136:\n        dict(\n            name='Face_72',\n            id=136,\n            color=[255, 255, 255],\n            type='',\n            swap='Face_56'),\n    },\n    skeleton_info={\n        0: dict(link=('L_Ankle', 'L_Knee'), id=0, color=[0, 255, 0]),\n        1: dict(link=('L_Knee', 'L_Hip'), id=1, color=[0, 255, 0]),\n        2: dict(link=('R_Ankle', 'R_Knee'), id=2, color=[0, 255, 0]),\n        3: dict(link=('R_Knee', 'R_Hip'), id=3, color=[0, 255, 0]),\n        4: dict(link=('L_Hip', 'R_Hip'), id=4, color=[0, 255, 0]),\n        5: dict(link=('L_Shoulder', 'L_Hip'), id=5, color=[0, 255, 0]),\n        6: dict(link=('R_Shoulder', 'R_Hip'), id=6, color=[0, 255, 0]),\n        7: dict(link=('L_Shoulder', 'R_Shoulder'), id=7, color=[0, 255, 0]),\n        8: dict(link=('L_Shoulder', 'L_Elbow'), id=8, color=[0, 255, 0]),\n        9: dict(link=('R_Shoulder', 'R_Elbow'), id=9, color=[0, 255, 0]),\n        10: dict(link=('L_Elbow', 'L_Wrist'), id=10, color=[0, 255, 0]),\n        11: dict(link=('R_Elbow', 'R_Wrist'), id=11, color=[255, 128, 0]),\n        12: dict(link=('L_Eye', 'R_Eye'), id=12, color=[255, 128, 0]),\n        13: dict(link=('Nose', 'L_Eye'), id=13, color=[255, 128, 0]),\n        14: dict(link=('Nose', 'R_Eye'), id=14, color=[255, 128, 0]),\n        15: dict(link=('L_Eye', 'L_Ear'), id=15, color=[255, 128, 0]),\n        16: dict(link=('R_Eye', 'R_Ear'), id=16, color=[255, 128, 0]),\n        17: dict(link=('L_Ear', 'L_Shoulder'), id=17, color=[255, 128, 0]),\n        18: dict(link=('R_Ear', 'R_Shoulder'), id=18, color=[255, 128, 0]),\n        19: dict(link=('L_Ankle', 'L_Big_toe'), id=19, color=[255, 128, 0]),\n        20: dict(link=('L_Ankle', 'L_Small_toe'), id=20, color=[255, 128, 0]),\n        21: dict(link=('L_Ankle', 'L_Heel'), id=21, color=[255, 128, 0]),\n        22: dict(link=('R_Ankle', 'R_Big_toe'), id=22, color=[255, 128, 0]),\n        23: dict(link=('R_Ankle', 'R_Small_toe'), id=23, color=[255, 128, 0]),\n        24: dict(link=('R_Ankle', 'R_Heel'), id=24, color=[255, 128, 0]),\n        25: dict(link=('L_Wrist', 'L_Thumb_1'), id=25, color=[255, 128, 0]),\n        26: dict(link=('L_Thumb_1', 'L_Thumb_2'), id=26, color=[255, 128, 0]),\n        27: dict(link=('L_Thumb_2', 'L_Thumb_3'), id=27, color=[255, 128, 0]),\n        28: dict(link=('L_Thumb_3', 'L_Thumb_4'), id=28, color=[255, 128, 0]),\n        29: dict(link=('L_Wrist', 'L_Index_1'), id=29, color=[255, 128, 0]),\n        30: dict(link=('L_Index_1', 'L_Index_2'), id=30, color=[255, 128, 0]),\n        31:\n        dict(link=('L_Index_2', 'L_Index_3'), id=31, color=[255, 255, 255]),\n        32:\n        dict(link=('L_Index_3', 'L_Index_4'), id=32, color=[255, 255, 255]),\n        33: dict(link=('L_Wrist', 'L_Middle_1'), id=33, color=[255, 255, 255]),\n        34:\n        dict(link=('L_Middle_1', 'L_Middle_2'), id=34, color=[255, 255, 255]),\n        35:\n        dict(link=('L_Middle_2', 'L_Middle_3'), id=35, color=[255, 255, 255]),\n        36:\n        dict(link=('L_Middle_3', 'L_Middle_4'), id=36, color=[255, 255, 255]),\n        37: dict(link=('L_Wrist', 'L_Ring_1'), id=37, color=[255, 255, 255]),\n        38: dict(link=('L_Ring_1', 'L_Ring_2'), id=38, color=[255, 255, 255]),\n        39: dict(link=('L_Ring_2', 'L_Ring_3'), id=39, color=[255, 255, 255]),\n        40: dict(link=('L_Ring_3', 'L_Ring_4'), id=40, color=[255, 255, 255]),\n        41: dict(link=('L_Wrist', 'L_Pinky_1'), id=41, color=[255, 255, 255]),\n        42:\n        dict(link=('L_Pinky_1', 'L_Pinky_2'), id=42, color=[255, 255, 255]),\n        43:\n        dict(link=('L_Pinky_2', 'L_Pinky_3'), id=43, color=[255, 255, 255]),\n        44:\n        dict(link=('L_Pinky_3', 'L_Pinky_4'), id=44, color=[255, 255, 255]),\n        45: dict(link=('R_Wrist', 'R_Thumb_1'), id=45, color=[255, 255, 255]),\n        46:\n        dict(link=('R_Thumb_1', 'R_Thumb_2'), id=46, color=[255, 255, 255]),\n        47:\n        dict(link=('R_Thumb_2', 'R_Thumb_3'), id=47, color=[255, 255, 255]),\n        48:\n        dict(link=('R_Thumb_3', 'R_Thumb_4'), id=48, color=[255, 255, 255]),\n        49: dict(link=('R_Wrist', 'R_Index_1'), id=49, color=[255, 255, 255]),\n        50:\n        dict(link=('R_Index_1', 'R_Index_2'), id=50, color=[255, 255, 255]),\n        51:\n        dict(link=('R_Index_2', 'R_Index_3'), id=51, color=[255, 255, 255]),\n        52:\n        dict(link=('R_Index_3', 'R_Index_4'), id=52, color=[255, 255, 255]),\n        53: dict(link=('R_Wrist', 'R_Middle_1'), id=53, color=[255, 255, 255]),\n        54:\n        dict(link=('R_Middle_1', 'R_Middle_2'), id=54, color=[255, 255, 255]),\n        55:\n        dict(link=('R_Middle_2', 'R_Middle_3'), id=55, color=[255, 255, 255]),\n        56:\n        dict(link=('R_Middle_3', 'R_Middle_4'), id=56, color=[255, 255, 255]),\n        57: dict(link=('R_Wrist', 'R_Pinky_1'), id=57, color=[255, 255, 255]),\n        58:\n        dict(link=('R_Pinky_1', 'R_Pinky_2'), id=58, color=[255, 255, 255]),\n        59:\n        dict(link=('R_Pinky_2', 'R_Pinky_3'), id=59, color=[255, 255, 255]),\n        60:\n        dict(link=('R_Pinky_3', 'R_Pinky_4'), id=60, color=[255, 255, 255]),\n    },\n    joint_weights=[1.] * 137,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/wflw.py",
    "content": "dataset_info = dict(\n    dataset_name='wflw',\n    paper_info=dict(\n        author='Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, '\n        'Quan and Cai, Yici and Zhou, Qiang',\n        title='Look at boundary: A boundary-aware face alignment algorithm',\n        container='Proceedings of the IEEE conference on computer '\n        'vision and pattern recognition',\n        year='2018',\n        homepage='https://wywu.github.io/projects/LAB/WFLW.html',\n    ),\n    keypoint_info={\n        0: dict(name='kpt-0', id=0, color=[255, 0, 0], type='', swap='kpt-32'),\n        1: dict(name='kpt-1', id=1, color=[255, 0, 0], type='', swap='kpt-31'),\n        2: dict(name='kpt-2', id=2, color=[255, 0, 0], type='', swap='kpt-30'),\n        3: dict(name='kpt-3', id=3, color=[255, 0, 0], type='', swap='kpt-29'),\n        4: dict(name='kpt-4', id=4, color=[255, 0, 0], type='', swap='kpt-28'),\n        5: dict(name='kpt-5', id=5, color=[255, 0, 0], type='', swap='kpt-27'),\n        6: dict(name='kpt-6', id=6, color=[255, 0, 0], type='', swap='kpt-26'),\n        7: dict(name='kpt-7', id=7, color=[255, 0, 0], type='', swap='kpt-25'),\n        8: dict(name='kpt-8', id=8, color=[255, 0, 0], type='', swap='kpt-24'),\n        9: dict(name='kpt-9', id=9, color=[255, 0, 0], type='', swap='kpt-23'),\n        10:\n        dict(name='kpt-10', id=10, color=[255, 0, 0], type='', swap='kpt-22'),\n        11:\n        dict(name='kpt-11', id=11, color=[255, 0, 0], type='', swap='kpt-21'),\n        12:\n        dict(name='kpt-12', id=12, color=[255, 0, 0], type='', swap='kpt-20'),\n        13:\n        dict(name='kpt-13', id=13, color=[255, 0, 0], type='', swap='kpt-19'),\n        14:\n        dict(name='kpt-14', id=14, color=[255, 0, 0], type='', swap='kpt-18'),\n        15:\n        dict(name='kpt-15', id=15, color=[255, 0, 0], type='', swap='kpt-17'),\n        16: dict(name='kpt-16', id=16, color=[255, 0, 0], type='', swap=''),\n        17:\n        dict(name='kpt-17', id=17, color=[255, 0, 0], type='', swap='kpt-15'),\n        18:\n        dict(name='kpt-18', id=18, color=[255, 0, 0], type='', swap='kpt-14'),\n        19:\n        dict(name='kpt-19', id=19, color=[255, 0, 0], type='', swap='kpt-13'),\n        20:\n        dict(name='kpt-20', id=20, color=[255, 0, 0], type='', swap='kpt-12'),\n        21:\n        dict(name='kpt-21', id=21, color=[255, 0, 0], type='', swap='kpt-11'),\n        22:\n        dict(name='kpt-22', id=22, color=[255, 0, 0], type='', swap='kpt-10'),\n        23:\n        dict(name='kpt-23', id=23, color=[255, 0, 0], type='', swap='kpt-9'),\n        24:\n        dict(name='kpt-24', id=24, color=[255, 0, 0], type='', swap='kpt-8'),\n        25:\n        dict(name='kpt-25', id=25, color=[255, 0, 0], type='', swap='kpt-7'),\n        26:\n        dict(name='kpt-26', id=26, color=[255, 0, 0], type='', swap='kpt-6'),\n        27:\n        dict(name='kpt-27', id=27, color=[255, 0, 0], type='', swap='kpt-5'),\n        28:\n        dict(name='kpt-28', id=28, color=[255, 0, 0], type='', swap='kpt-4'),\n        29:\n        dict(name='kpt-29', id=29, color=[255, 0, 0], type='', swap='kpt-3'),\n        30:\n        dict(name='kpt-30', id=30, color=[255, 0, 0], type='', swap='kpt-2'),\n        31:\n        dict(name='kpt-31', id=31, color=[255, 0, 0], type='', swap='kpt-1'),\n        32:\n        dict(name='kpt-32', id=32, color=[255, 0, 0], type='', swap='kpt-0'),\n        33:\n        dict(name='kpt-33', id=33, color=[255, 0, 0], type='', swap='kpt-46'),\n        34:\n        dict(name='kpt-34', id=34, color=[255, 0, 0], type='', swap='kpt-45'),\n        35:\n        dict(name='kpt-35', id=35, color=[255, 0, 0], type='', swap='kpt-44'),\n        36:\n        dict(name='kpt-36', id=36, color=[255, 0, 0], type='', swap='kpt-43'),\n        37: dict(\n            name='kpt-37', id=37, color=[255, 0, 0], type='', swap='kpt-42'),\n        38: dict(\n            name='kpt-38', id=38, color=[255, 0, 0], type='', swap='kpt-50'),\n        39: dict(\n            name='kpt-39', id=39, color=[255, 0, 0], type='', swap='kpt-49'),\n        40: dict(\n            name='kpt-40', id=40, color=[255, 0, 0], type='', swap='kpt-48'),\n        41: dict(\n            name='kpt-41', id=41, color=[255, 0, 0], type='', swap='kpt-47'),\n        42: dict(\n            name='kpt-42', id=42, color=[255, 0, 0], type='', swap='kpt-37'),\n        43: dict(\n            name='kpt-43', id=43, color=[255, 0, 0], type='', swap='kpt-36'),\n        44: dict(\n            name='kpt-44', id=44, color=[255, 0, 0], type='', swap='kpt-35'),\n        45: dict(\n            name='kpt-45', id=45, color=[255, 0, 0], type='', swap='kpt-34'),\n        46: dict(\n            name='kpt-46', id=46, color=[255, 0, 0], type='', swap='kpt-33'),\n        47: dict(\n            name='kpt-47', id=47, color=[255, 0, 0], type='', swap='kpt-41'),\n        48: dict(\n            name='kpt-48', id=48, color=[255, 0, 0], type='', swap='kpt-40'),\n        49: dict(\n            name='kpt-49', id=49, color=[255, 0, 0], type='', swap='kpt-39'),\n        50: dict(\n            name='kpt-50', id=50, color=[255, 0, 0], type='', swap='kpt-38'),\n        51: dict(name='kpt-51', id=51, color=[255, 0, 0], type='', swap=''),\n        52: dict(name='kpt-52', id=52, color=[255, 0, 0], type='', swap=''),\n        53: dict(name='kpt-53', id=53, color=[255, 0, 0], type='', swap=''),\n        54: dict(name='kpt-54', id=54, color=[255, 0, 0], type='', swap=''),\n        55: dict(\n            name='kpt-55', id=55, color=[255, 0, 0], type='', swap='kpt-59'),\n        56: dict(\n            name='kpt-56', id=56, color=[255, 0, 0], type='', swap='kpt-58'),\n        57: dict(name='kpt-57', id=57, color=[255, 0, 0], type='', swap=''),\n        58: dict(\n            name='kpt-58', id=58, color=[255, 0, 0], type='', swap='kpt-56'),\n        59: dict(\n            name='kpt-59', id=59, color=[255, 0, 0], type='', swap='kpt-55'),\n        60: dict(\n            name='kpt-60', id=60, color=[255, 0, 0], type='', swap='kpt-72'),\n        61: dict(\n            name='kpt-61', id=61, color=[255, 0, 0], type='', swap='kpt-71'),\n        62: dict(\n            name='kpt-62', id=62, color=[255, 0, 0], type='', swap='kpt-70'),\n        63: dict(\n            name='kpt-63', id=63, color=[255, 0, 0], type='', swap='kpt-69'),\n        64: dict(\n            name='kpt-64', id=64, color=[255, 0, 0], type='', swap='kpt-68'),\n        65: dict(\n            name='kpt-65', id=65, color=[255, 0, 0], type='', swap='kpt-75'),\n        66: dict(\n            name='kpt-66', id=66, color=[255, 0, 0], type='', swap='kpt-74'),\n        67: dict(\n            name='kpt-67', id=67, color=[255, 0, 0], type='', swap='kpt-73'),\n        68: dict(\n            name='kpt-68', id=68, color=[255, 0, 0], type='', swap='kpt-64'),\n        69: dict(\n            name='kpt-69', id=69, color=[255, 0, 0], type='', swap='kpt-63'),\n        70: dict(\n            name='kpt-70', id=70, color=[255, 0, 0], type='', swap='kpt-62'),\n        71: dict(\n            name='kpt-71', id=71, color=[255, 0, 0], type='', swap='kpt-61'),\n        72: dict(\n            name='kpt-72', id=72, color=[255, 0, 0], type='', swap='kpt-60'),\n        73: dict(\n            name='kpt-73', id=73, color=[255, 0, 0], type='', swap='kpt-67'),\n        74: dict(\n            name='kpt-74', id=74, color=[255, 0, 0], type='', swap='kpt-66'),\n        75: dict(\n            name='kpt-75', id=75, color=[255, 0, 0], type='', swap='kpt-65'),\n        76: dict(\n            name='kpt-76', id=76, color=[255, 0, 0], type='', swap='kpt-82'),\n        77: dict(\n            name='kpt-77', id=77, color=[255, 0, 0], type='', swap='kpt-81'),\n        78: dict(\n            name='kpt-78', id=78, color=[255, 0, 0], type='', swap='kpt-80'),\n        79: dict(name='kpt-79', id=79, color=[255, 0, 0], type='', swap=''),\n        80: dict(\n            name='kpt-80', id=80, color=[255, 0, 0], type='', swap='kpt-78'),\n        81: dict(\n            name='kpt-81', id=81, color=[255, 0, 0], type='', swap='kpt-77'),\n        82: dict(\n            name='kpt-82', id=82, color=[255, 0, 0], type='', swap='kpt-76'),\n        83: dict(\n            name='kpt-83', id=83, color=[255, 0, 0], type='', swap='kpt-87'),\n        84: dict(\n            name='kpt-84', id=84, color=[255, 0, 0], type='', swap='kpt-86'),\n        85: dict(name='kpt-85', id=85, color=[255, 0, 0], type='', swap=''),\n        86: dict(\n            name='kpt-86', id=86, color=[255, 0, 0], type='', swap='kpt-84'),\n        87: dict(\n            name='kpt-87', id=87, color=[255, 0, 0], type='', swap='kpt-83'),\n        88: dict(\n            name='kpt-88', id=88, color=[255, 0, 0], type='', swap='kpt-92'),\n        89: dict(\n            name='kpt-89', id=89, color=[255, 0, 0], type='', swap='kpt-91'),\n        90: dict(name='kpt-90', id=90, color=[255, 0, 0], type='', swap=''),\n        91: dict(\n            name='kpt-91', id=91, color=[255, 0, 0], type='', swap='kpt-89'),\n        92: dict(\n            name='kpt-92', id=92, color=[255, 0, 0], type='', swap='kpt-88'),\n        93: dict(\n            name='kpt-93', id=93, color=[255, 0, 0], type='', swap='kpt-95'),\n        94: dict(name='kpt-94', id=94, color=[255, 0, 0], type='', swap=''),\n        95: dict(\n            name='kpt-95', id=95, color=[255, 0, 0], type='', swap='kpt-93'),\n        96: dict(\n            name='kpt-96', id=96, color=[255, 0, 0], type='', swap='kpt-97'),\n        97: dict(\n            name='kpt-97', id=97, color=[255, 0, 0], type='', swap='kpt-96')\n    },\n    skeleton_info={},\n    joint_weights=[1.] * 98,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/datasets/zebra.py",
    "content": "dataset_info = dict(\n    dataset_name='zebra',\n    paper_info=dict(\n        author='Graving, Jacob M and Chae, Daniel and Naik, Hemal and '\n        'Li, Liang and Koger, Benjamin and Costelloe, Blair R and '\n        'Couzin, Iain D',\n        title='DeepPoseKit, a software toolkit for fast and robust '\n        'animal pose estimation using deep learning',\n        container='Elife',\n        year='2019',\n        homepage='https://github.com/jgraving/DeepPoseKit-Data',\n    ),\n    keypoint_info={\n        0:\n        dict(name='snout', id=0, color=[255, 255, 255], type='', swap=''),\n        1:\n        dict(name='head', id=1, color=[255, 255, 255], type='', swap=''),\n        2:\n        dict(name='neck', id=2, color=[255, 255, 255], type='', swap=''),\n        3:\n        dict(\n            name='forelegL1',\n            id=3,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegR1'),\n        4:\n        dict(\n            name='forelegR1',\n            id=4,\n            color=[255, 255, 255],\n            type='',\n            swap='forelegL1'),\n        5:\n        dict(\n            name='hindlegL1',\n            id=5,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegR1'),\n        6:\n        dict(\n            name='hindlegR1',\n            id=6,\n            color=[255, 255, 255],\n            type='',\n            swap='hindlegL1'),\n        7:\n        dict(name='tailbase', id=7, color=[255, 255, 255], type='', swap=''),\n        8:\n        dict(name='tailtip', id=8, color=[255, 255, 255], type='', swap='')\n    },\n    skeleton_info={\n        0: dict(link=('head', 'snout'), id=0, color=[255, 255, 255]),\n        1: dict(link=('neck', 'head'), id=1, color=[255, 255, 255]),\n        2: dict(link=('forelegL1', 'neck'), id=2, color=[255, 255, 255]),\n        3: dict(link=('forelegR1', 'neck'), id=3, color=[255, 255, 255]),\n        4: dict(link=('hindlegL1', 'tailbase'), id=4, color=[255, 255, 255]),\n        5: dict(link=('hindlegR1', 'tailbase'), id=5, color=[255, 255, 255]),\n        6: dict(link=('tailbase', 'neck'), id=6, color=[255, 255, 255]),\n        7: dict(link=('tailtip', 'tailbase'), id=7, color=[255, 255, 255])\n    },\n    joint_weights=[1.] * 9,\n    sigmas=[])\n"
  },
  {
    "path": "configs/_base_/default_runtime.py",
    "content": "default_scope = 'mmpose'\n\n# hooks\ndefault_hooks = dict(\n    timer=dict(type='IterTimerHook'),\n    logger=dict(type='LoggerHook', interval=50),\n    param_scheduler=dict(type='ParamSchedulerHook'),\n    checkpoint=dict(type='CheckpointHook', interval=10),\n    sampler_seed=dict(type='DistSamplerSeedHook'),\n    visualization=dict(type='PoseVisualizationHook', enable=False),\n    badcase=dict(\n        type='BadCaseAnalysisHook',\n        enable=False,\n        out_dir='badcase',\n        metric_type='loss',\n        badcase_thr=5))\n\n# custom hooks\ncustom_hooks = [\n    # Synchronize model buffers such as running_mean and running_var in BN\n    # at the end of each epoch\n    dict(type='SyncBuffersHook')\n]\n\n# multi-processing backend\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'),\n)\n\n# visualizer\nvis_backends = [\n    dict(type='LocalVisBackend'),\n    # dict(type='TensorboardVisBackend'),\n    # dict(type='WandbVisBackend'),\n]\nvisualizer = dict(\n    type='PoseLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# logger\nlog_processor = dict(\n    type='LogProcessor', window_size=50, by_epoch=True, num_digits=6)\nlog_level = 'INFO'\nload_from = None\nresume = False\n\n# file I/O backend\nbackend_args = dict(backend='local')\n\n# training/validation/testing progress\ntrain_cfg = dict(by_epoch=True)\nval_cfg = dict()\ntest_cfg = dict()\n"
  },
  {
    "path": "configs/animal_2d_keypoint/README.md",
    "content": "# 2D Animal Keypoint Detection\n\n2D animal keypoint detection (animal pose estimation) aims to detect the key-point of different species, including rats,\ndogs, macaques, and cheetah. It provides detailed behavioral analysis for neuroscience, medical and ecology applications.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_animal_keypoint.md) to prepare data.\n\n## Demo\n\nPlease follow [DEMO](/demo/docs/en/2d_animal_demo.md) to generate fancy demos.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187655602-907db86e-710b-447a-8ec9-5b623d43d160.gif\" height=\"500px\" alt><br>\n\n<img src=\"https://user-images.githubusercontent.com/11788150/114201893-4446ec00-9989-11eb-808b-5718c47c7b23.gif\" height=\"140px\" alt><br>\n\n<img src=\"https://user-images.githubusercontent.com/11788150/114205282-b5d46980-998c-11eb-9d6b-85ba47f81252.gif\" height=\"140px\" alt><br>\n\n<img src=\"https://user-images.githubusercontent.com/11788150/114023530-944c8280-98a5-11eb-86b0-5f6d3e232af0.gif\" height=\"140px\" alt><br>\n"
  },
  {
    "path": "configs/animal_2d_keypoint/rtmpose/README.md",
    "content": "# RTMPose\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency.\nIn order to bridge this gap, we empirically study five aspects that affect the performance of multi-person pose estimation algorithms: paradigm, backbone network, localization algorithm, training strategy, and deployment inference, and present a high-performance real-time multi-person pose estimation framework, **RTMPose**, based on MMPose.\nOur RTMPose-m achieves **75.8% AP** on COCO with **90+ FPS** on an Intel i7-11700 CPU and **430+ FPS** on an NVIDIA GTX 1660 Ti GPU, and RTMPose-l achieves **67.0% AP** on COCO-WholeBody with **130+ FPS**, outperforming existing open-source libraries.\nTo further evaluate RTMPose's capability in critical real-time applications, we also report the performance after deploying on the mobile device.\n\n## Results and Models\n\n### AP-10K Dataset\n\nResults on AP-10K validation set\n\n|   Model   | Input Size |  AP   |             Details and Download             |\n| :-------: | :--------: | :---: | :------------------------------------------: |\n| RTMPose-m |  256x256   | 0.722 | [rtmpose_cp10k.md](./ap10k/rtmpose_ap10k.md) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose-m_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/pose/ap10k/',\n#         f'{data_root}': 's3://openmmlab/datasets/pose/ap10k/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose_ap10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\nResults on AP-10K validation set\n\n| Arch                                       | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP<sup>M</sup> | AP<sup>L</sup> |                    ckpt                     |                    log                     |\n| :----------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :------------: | :------------: | :-----------------------------------------: | :----------------------------------------: |\n| [rtmpose-m](/configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose-m_8xb64-210e_ap10k-256x256.py) |  256x256   | 0.722 |      0.939      |      0.788      |     0.569      |     0.728      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose_ap10k.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose-m_8xb64-210e_ap10k-256x256.py\n  In Collection: RTMPose\n  Alias: animal\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: AP-10K\n  Name: rtmpose-m_8xb64-210e_ap10k-256x256\n  Results:\n  - Dataset: AP-10K\n    Metrics:\n      AP: 0.722\n      AP@0.5: 0.939\n      AP@0.75: 0.788\n      AP (L): 0.728\n      AP (M): 0.569\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/README.md",
    "content": "# Top-down heatmap-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes Instead of estimating keypoint coordinates directly, the pose estimator will produce heatmaps which represent the\nlikelihood of being a keypoint, following the paradigm introduced in [Simple Baselines for Human Pose Estimation and Tracking](http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\" height=400>\n</div>\n\n## Results and Models\n\n### Animal-Pose Dataset\n\nResults on AnimalPose validation set (1117 instances)\n\n|   Model    | Input Size |  AP   |  AR   |                   Details and Download                    |\n| :--------: | :--------: | :---: | :---: | :-------------------------------------------------------: |\n| HRNet-w32  |  256x256   | 0.740 | 0.780 |  [hrnet_animalpose.md](./animalpose/hrnet_animalpose.md)  |\n| HRNet-w48  |  256x256   | 0.738 | 0.778 |  [hrnet_animalpose.md](./animalpose/hrnet_animalpose.md)  |\n| ResNet-152 |  256x256   | 0.704 | 0.748 | [resnet_animalpose.md](./animalpose/resnet_animalpose.md) |\n| ResNet-101 |  256x256   | 0.696 | 0.736 | [resnet_animalpose.md](./animalpose/resnet_animalpose.md) |\n| ResNet-50  |  256x256   | 0.691 | 0.736 | [resnet_animalpose.md](./animalpose/resnet_animalpose.md) |\n\n### AP-10K Dataset\n\nResults on AP-10K validation set\n\n|   Model    | Input Size |  AP   |                 Details and Download                 |\n| :--------: | :--------: | :---: | :--------------------------------------------------: |\n| HRNet-w48  |  256x256   | 0.728 |       [hrnet_ap10k.md](./ap10k/hrnet_ap10k.md)       |\n| HRNet-w32  |  256x256   | 0.722 |       [hrnet_ap10k.md](./ap10k/hrnet_ap10k.md)       |\n| ResNet-101 |  256x256   | 0.681 |      [resnet_ap10k.md](./ap10k/resnet_ap10k.md)      |\n| ResNet-50  |  256x256   | 0.680 |      [resnet_ap10k.md](./ap10k/resnet_ap10k.md)      |\n| CSPNeXt-m  |  256x256   | 0.703 | [cspnext_udp_ap10k.md](./ap10k/cspnext_udp_ap10k.md) |\n\n### Desert Locust Dataset\n\nResults on Desert Locust test set\n\n|   Model    | Input Size |  AUC  | EPE  |             Details and Download              |\n| :--------: | :--------: | :---: | :--: | :-------------------------------------------: |\n| ResNet-152 |  160x160   | 0.925 | 1.49 | [resnet_locust.md](./locust/resnet_locust.md) |\n| ResNet-101 |  160x160   | 0.907 | 2.03 | [resnet_locust.md](./locust/resnet_locust.md) |\n| ResNet-50  |  160x160   | 0.900 | 2.27 | [resnet_locust.md](./locust/resnet_locust.md) |\n\n### Grévy’s Zebra Dataset\n\nResults on Grévy’s Zebra test set\n\n|   Model    | Input Size |  AUC  | EPE  |            Details and Download            |\n| :--------: | :--------: | :---: | :--: | :----------------------------------------: |\n| ResNet-152 |  160x160   | 0.921 | 1.67 | [resnet_zebra.md](./zebra/resnet_zebra.md) |\n| ResNet-101 |  160x160   | 0.915 | 1.83 | [resnet_zebra.md](./zebra/resnet_zebra.md) |\n| ResNet-50  |  160x160   | 0.914 | 1.87 | [resnet_zebra.md](./zebra/resnet_zebra.md) |\n\n### Animal-Kingdom Dataset\n\nResults on AnimalKingdom test set\n\n|   Model   | Input Size |     class     | PCK(0.05) |                 Details and Download                  |\n| :-------: | :--------: | :-----------: | :-------: | :---------------------------------------------------: |\n| HRNet-w32 |  256x256   |      P1       |  0.6323   | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n| HRNet-w32 |  256x256   |      P2       |  0.3741   | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n| HRNet-w32 |  256x256   |  P3_mammals   |   0.571   | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n| HRNet-w32 |  256x256   | P3_amphibians |  0.5358   | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n| HRNet-w32 |  256x256   |  P3_reptiles  |   0.51    | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n| HRNet-w32 |  256x256   |   P3_birds    |  0.7671   | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n| HRNet-w32 |  256x256   |   P3_fishes   |  0.6406   | [hrnet_animalkingdom.md](./ak/hrnet_animalkingdom.md) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/hrnet_animalkingdom.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://sutdcv.github.io/Animal-Kingdom/\">AnimalKingdom (CVPR'2022)</a></summary>\n\n```bibtex\n@InProceedings{\n    Ng_2022_CVPR,\n    author    = {Ng, Xun Long and Ong, Kian Eng and Zheng, Qichen and Ni, Yun and Yeo, Si Yong and Liu, Jun},\n    title     = {Animal Kingdom: A Large and Diverse Dataset for Animal Behavior Understanding},\n    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n    month     = {June},\n    year      = {2022},\n    pages     = {19023-19034}\n }\n```\n\n</details>\n\nResults on AnimalKingdom validation set\n\n| Arch                                                   | Input Size | PCK(0.05) | Official Repo | Paper  | ckpt                                                   | log                                                    |\n| ------------------------------------------------------ | ---------- | --------- | ------------- | ------ | ------------------------------------------------------ | ------------------------------------------------------ |\n| [P1_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256.py) | 256x256    | 0.6323    | 0.6342        | 0.6606 | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256-08bf96cb_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256-08bf96cb_20230519.json) |\n| [P2_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256.py) | 256x256    | 0.3741    | 0.3726        | 0.393  | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256-2396cc58_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256-2396cc58_20230519.json) |\n| [P3_mammals_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256.py) | 256x256    | 0.571     | 0.5719        | 0.6159 | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256-e8aadf02_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256-e8aadf02_20230519.json) |\n| [P3_amphibians_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256.py) | 256x256    | 0.5358    | 0.5432        | 0.5674 | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256-845085f9_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256-845085f9_20230519.json) |\n| [P3_reptiles_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256.py) | 256x256    | 0.51      | 0.5           | 0.5606 | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256-e8440c16_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256-e8440c16_20230519.json) |\n| [P3_birds_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256.py) | 256x256    | 0.7671    | 0.7636        | 0.7735 | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256-566feff5_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256-566feff5_20230519.json) |\n| [P3_fishes_hrnet_w32](configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256.py) | 256x256    | 0.6406    | 0.636         | 0.6825 | [ckpt](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256-76c3999f_20230519.pth) | [log](https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256-76c3999f_20230519.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/hrnet_animalkingdom.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: AnimalKingdom_P1\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.6323\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256-08bf96cb_20230519.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AnimalKingdom_P2\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.3741\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256-2396cc58_20230519.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AnimalKingdom_P3_amphibian\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.5358\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256-845085f9_20230519.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AnimalKingdom_P3_bird\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.7671\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256-566feff5_20230519.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AnimalKingdom_P3_fish\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.6406\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256-76c3999f_20230519.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AnimalKingdom_P3_mammal\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.571\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256-e8aadf02_20230519.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AnimalKingdom_P3_reptile\n  Name: td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256\n  Results:\n  - Dataset: AnimalKingdom\n    Metrics:\n      PCK: 0.51\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/animal_2d_keypoint/topdown_heatmap/animal_kingdom/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256-e8440c16_20230519.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P1-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P1/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P1/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P2-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P2/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P2/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_amphibian-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_amphibian/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_amphibian/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_bird-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_bird/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_bird/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_fish-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_fish/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_fish/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_mammal-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_mammal/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_mammal/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ak/td-hm_hrnet-w32_8xb32-300e_animalkingdom_P3_reptile-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='AdamW',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=23,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalKingdomDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ak/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_reptile/train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ak_P3_reptile/test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [dict(type='PCKAccuracy', thr=0.05), dict(type='AUC')]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/hrnet_animalpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n\nResults on AnimalPose validation set (1117 instances)\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32](/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py) |  256x256   | 0.740 |      0.959      |      0.833      | 0.780 |      0.965      | [ckpt](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth) | [log](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256_20210426.log.json) |\n| [pose_hrnet_w48](/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w48_8xb64-210e_animalpose-256x256.py) |  256x256   | 0.738 |      0.958      |      0.831      | 0.778 |      0.962      | [ckpt](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_animalpose_256x256-34644726_20210426.pth) | [log](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_animalpose_256x256_20210426.log.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/hrnet_animalpose.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: Animal-Pose\n  Name: td-hm_hrnet-w32_8xb64-210e_animalpose-256x256\n  Results:\n  - Dataset: Animal-Pose\n    Metrics:\n      AP: 0.740\n      AP@0.5: 0.959\n      AP@0.75: 0.833\n      AR: 0.780\n      AR@0.5: 0.965\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w48_8xb64-210e_animalpose-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: Animal-Pose\n  Name: td-hm_hrnet-w48_8xb64-210e_animalpose-256x256\n  Results:\n  - Dataset: Animal-Pose\n    Metrics:\n      AP: 0.738\n      AP@0.5: 0.958\n      AP@0.75: 0.831\n      AR: 0.778\n      AR@0.5: 0.962\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_animalpose_256x256-34644726_20210426.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/resnet_animalpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n\nResults on AnimalPose validation set (1117 instances)\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_50](/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res50_8xb64-210e_animalpose-256x256.py) |  256x256   | 0.691 |      0.947      |      0.770      | 0.736 |      0.955      | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res50_animalpose_256x256-e1f30bff_20210426.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res50_animalpose_256x256_20210426.log.json) |\n| [pose_resnet_101](/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res101_8xb64-210e_animalpose-256x256.py) |  256x256   | 0.696 |      0.948      |      0.774      | 0.736 |      0.951      | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res101_animalpose_256x256-85563f4a_20210426.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res101_animalpose_256x256_20210426.log.json) |\n| [pose_resnet_152](/configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res152_8xb32-210e_animalpose-256x256.py) |  256x256   | 0.704 |      0.938      |      0.786      | 0.748 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res152_animalpose_256x256-a0a7506c_20210426.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res152_animalpose_256x256_20210426.log.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/resnet_animalpose.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res50_8xb64-210e_animalpose-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: Animal-Pose\n  Name: td-hm_res50_8xb64-210e_animalpose-256x256\n  Results:\n  - Dataset: Animal-Pose\n    Metrics:\n      AP: 0.691\n      AP@0.5: 0.947\n      AP@0.75: 0.770\n      AR: 0.736\n      AR@0.5: 0.955\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res50_animalpose_256x256-e1f30bff_20210426.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res101_8xb64-210e_animalpose-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: Animal-Pose\n  Name: td-hm_res101_8xb64-210e_animalpose-256x256\n  Results:\n  - Dataset: Animal-Pose\n    Metrics:\n      AP: 0.696\n      AP@0.5: 0.948\n      AP@0.75: 0.774\n      AR: 0.736\n      AR@0.5: 0.951\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res101_animalpose_256x256-85563f4a_20210426.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res152_8xb32-210e_animalpose-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: Animal-Pose\n  Name: td-hm_res152_8xb32-210e_animalpose-256x256\n  Results:\n  - Dataset: Animal-Pose\n    Metrics:\n      AP: 0.704\n      AP@0.5: 0.938\n      AP@0.75: 0.786\n      AR: 0.748\n      AR@0.5: 0.946\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res152_animalpose_256x256-a0a7506c_20210426.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=20,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/animalpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric', ann_file=data_root + 'annotations/animalpose_val.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w48_8xb64-210e_animalpose-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=20,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/animalpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric', ann_file=data_root + 'annotations/animalpose_val.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res101_8xb64-210e_animalpose-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=20,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/animalpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric', ann_file=data_root + 'annotations/animalpose_val.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res152_8xb32-210e_animalpose-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=20,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/animalpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric', ann_file=data_root + 'annotations/animalpose_val.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_res50_8xb64-210e_animalpose-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=20,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AnimalPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/animalpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/animalpose_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric', ann_file=data_root + 'annotations/animalpose_val.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/cspnext-m_udp_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/cspnext_udp_ap10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\nResults on AP-10K validation set\n\n| Arch                                       | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP<sup>M</sup> | AP<sup>L</sup> |                    ckpt                     |                    log                     |\n| :----------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :------------: | :------------: | :-----------------------------------------: | :----------------------------------------: |\n| [pose_cspnext_m](/configs/animal_2d_keypoint/topdown_heatmap/ap10k/cspnext-m_udp_8xb64-210e_ap10k-256x256.py) |  256x256   | 0.703 |      0.944      |      0.776      |     0.513      |     0.710      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-ap10k_pt-in1k_210e-256x256-1f2d947a_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-ap10k_pt-in1k_210e-256x256-1f2d947a_20230123.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/cspnext_udp_ap10k.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ap10k/cspnext-m_udp_8xb64-210e_ap10k-256x256.py\n  In Collection: UDP\n  Metadata:\n    Architecture: &id001\n    - UDP\n    - HRNet\n    Training Data: AP-10K\n  Name: cspnext-m_udp_8xb64-210e_ap10k-256x256\n  Results:\n  - Dataset: AP-10K\n    Metrics:\n      AP: 0.703\n      AP@0.5: 0.944\n      AP@0.75: 0.776\n      AP (L): 0.71\n      AP (M): 0.513\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-ap10k_pt-in1k_210e-256x256-1f2d947a_20230123.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/hrnet_ap10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\nResults on AP-10K validation set\n\n| Arch                                       | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP<sup>M</sup> | AP<sup>L</sup> |                    ckpt                     |                    log                     |\n| :----------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :------------: | :------------: | :-----------------------------------------: | :----------------------------------------: |\n| [pose_hrnet_w32](/configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_hrnet-w32_8xb64-210e_ap10k-256x256.py) |  256x256   | 0.722 |      0.935      |      0.789      |     0.557      |     0.729      | [ckpt](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_ap10k_256x256-18aac840_20211029.pth) | [log](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_ap10k_256x256-18aac840_20211029.log.json) |\n| [pose_hrnet_w48](/configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_hrnet-w48_8xb64-210e_ap10k-256x256.py) |  256x256   | 0.728 |      0.936      |      0.802      |     0.577      |     0.735      | [ckpt](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_ap10k_256x256-d95ab412_20211029.pth) | [log](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_ap10k_256x256-d95ab412_20211029.log.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/hrnet_ap10k.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_hrnet-w32_8xb64-210e_ap10k-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: AP-10K\n  Name: td-hm_hrnet-w32_8xb64-210e_ap10k-256x256\n  Results:\n  - Dataset: AP-10K\n    Metrics:\n      AP: 0.722\n      AP@0.5: 0.935\n      AP@0.75: 0.789\n      AP (L): 0.729\n      AP (M): 0.557\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_ap10k_256x256-18aac840_20211029.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_hrnet-w48_8xb64-210e_ap10k-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: AP-10K\n  Name: td-hm_hrnet-w48_8xb64-210e_ap10k-256x256\n  Results:\n  - Dataset: AP-10K\n    Metrics:\n      AP: 0.728\n      AP@0.5: 0.936\n      AP@0.75: 0.802\n      AP (L): 0.735\n      AP (M): 0.577\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w48_ap10k_256x256-d95ab412_20211029.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/resnet_ap10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\nResults on AP-10K validation set\n\n| Arch                                       | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP<sup>M</sup> | AP<sup>L</sup> |                    ckpt                     |                    log                     |\n| :----------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :------------: | :------------: | :-----------------------------------------: | :----------------------------------------: |\n| [pose_resnet_50](/configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_res50_8xb64-210e_ap10k-256x256.py) |  256x256   | 0.680 |      0.926      |      0.738      |     0.552      |     0.687      | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res50_ap10k_256x256-35760eb8_20211029.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res50_ap10k_256x256-35760eb8_20211029.log.json) |\n| [pose_resnet_101](/configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_res101_8xb64-210e_ap10k-256x256.py) |  256x256   | 0.681 |      0.921      |      0.751      |     0.545      |     0.690      | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res101_ap10k_256x256-9edfafb9_20211029.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res101_ap10k_256x256-9edfafb9_20211029.log.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/resnet_ap10k.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_res50_8xb64-210e_ap10k-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: AP-10K\n  Name: td-hm_res50_8xb64-210e_ap10k-256x256\n  Results:\n  - Dataset: AP-10K\n    Metrics:\n      AP: 0.680\n      AP@0.5: 0.926\n      AP@0.75: 0.738\n      AP (L): 0.687\n      AP (M): 0.552\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res50_ap10k_256x256-35760eb8_20211029.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_res101_8xb64-210e_ap10k-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: AP-10K\n  Name: td-hm_res101_8xb64-210e_ap10k-256x256\n  Results:\n  - Dataset: AP-10K\n    Metrics:\n      AP: 0.681\n      AP@0.5: 0.921\n      AP@0.75: 0.751\n      AP (L): 0.690\n      AP (M): 0.545\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res101_ap10k_256x256-9edfafb9_20211029.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_hrnet-w32_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_hrnet-w48_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_res101_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/ap10k/td-hm_res50_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/locust/resnet_locust.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Desert Locust (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\nResults on Desert Locust test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_resnet_50](/configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res50_8xb64-210e_locust-160x160.py) |  160x160   |  1.000  | 0.900 | 2.27 | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res50_locust_160x160-9efca22b_20210407.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res50_locust_160x160_20210407.log.json) |\n| [pose_resnet_101](/configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res101_8xb64-210e_locust-160x160.py) |  160x160   |  1.000  | 0.907 | 2.03 | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res101_locust_160x160-d77986b3_20210407.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res101_locust_160x160_20210407.log.json) |\n| [pose_resnet_152](/configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res152_8xb32-210e_locust-160x160.py) |  160x160   |  1.000  | 0.925 | 1.49 | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res152_locust_160x160-4ea9b372_20210407.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res152_locust_160x160_20210407.log.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/locust/resnet_locust.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res50_8xb64-210e_locust-160x160.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: Desert Locust\n  Name: td-hm_res50_8xb64-210e_locust-160x160\n  Results:\n  - Dataset: Desert Locust\n    Metrics:\n      AUC: 0.9\n      EPE: 2.27\n      PCK@0.2: 1\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res50_locust_160x160-9efca22b_20210407.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res101_8xb64-210e_locust-160x160.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: Desert Locust\n  Name: td-hm_res101_8xb64-210e_locust-160x160\n  Results:\n  - Dataset: Desert Locust\n    Metrics:\n      AUC: 0.907\n      EPE: 2.03\n      PCK@0.2: 1\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res101_locust_160x160-d77986b3_20210407.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res152_8xb32-210e_locust-160x160.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: Desert Locust\n  Name: td-hm_res152_8xb32-210e_locust-160x160\n  Results:\n  - Dataset: Desert Locust\n    Metrics:\n      AUC: 0.925\n      EPE: 1.49\n      PCK@0.2: 1.0\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res152_locust_160x160-4ea9b372_20210407.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res101_8xb64-210e_locust-160x160.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(160, 160), heatmap_size=(40, 40), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=35,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'LocustDataset'\ndata_mode = 'topdown'\ndata_root = 'data/locust/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/locust_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/locust_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res152_8xb32-210e_locust-160x160.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(160, 160), heatmap_size=(40, 40), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=35,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'LocustDataset'\ndata_mode = 'topdown'\ndata_root = 'data/locust/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/locust_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/locust_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/locust/td-hm_res50_8xb64-210e_locust-160x160.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(160, 160), heatmap_size=(40, 40), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=35,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'LocustDataset'\ndata_mode = 'topdown'\ndata_root = 'data/locust/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/locust_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/locust_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/zebra/resnet_zebra.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Grévy’s Zebra (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\nResults on Grévy’s Zebra test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_resnet_50](/configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res50_8xb64-210e_zebra-160x160.py) |  160x160   |  1.000  | 0.914 | 1.87 | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res50_zebra_160x160-5a104833_20210407.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res50_zebra_160x160_20210407.log.json) |\n| [pose_resnet_101](/configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res101_8xb64-210e_zebra-160x160.py) |  160x160   |  1.000  | 0.915 | 1.83 | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res101_zebra_160x160-e8cb2010_20210407.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res101_zebra_160x160_20210407.log.json) |\n| [pose_resnet_152](/configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res152_8xb32-210e_zebra-160x160.py) |  160x160   |  1.000  | 0.921 | 1.67 | [ckpt](https://download.openmmlab.com/mmpose/animal/resnet/res152_zebra_160x160-05de71dd_20210407.pth) | [log](https://download.openmmlab.com/mmpose/animal/resnet/res152_zebra_160x160_20210407.log.json) |\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/zebra/resnet_zebra.yml",
    "content": "Models:\n- Config: configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res50_8xb64-210e_zebra-160x160.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: \"Gr\\xE9vy\\u2019s Zebra\"\n  Name: td-hm_res50_8xb64-210e_zebra-160x160\n  Results:\n  - Dataset: \"Gr\\xE9vy\\u2019s Zebra\"\n    Metrics:\n      AUC: 0.914\n      EPE: 1.87\n      PCK@0.2: 1.0\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res50_zebra_160x160-5a104833_20210407.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res101_8xb64-210e_zebra-160x160.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: \"Gr\\xE9vy\\u2019s Zebra\"\n  Name: td-hm_res101_8xb64-210e_zebra-160x160\n  Results:\n  - Dataset: \"Gr\\xE9vy\\u2019s Zebra\"\n    Metrics:\n      AUC: 0.915\n      EPE: 1.83\n      PCK@0.2: 1.0\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res101_zebra_160x160-e8cb2010_20210407.pth\n- Config: configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res152_8xb32-210e_zebra-160x160.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: \"Gr\\xE9vy\\u2019s Zebra\"\n  Name: td-hm_res152_8xb32-210e_zebra-160x160\n  Results:\n  - Dataset: \"Gr\\xE9vy\\u2019s Zebra\"\n    Metrics:\n      AUC: 0.921\n      EPE: 1.67\n      PCK@0.2: 1.0\n    Task: Animal 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/animal/resnet/res152_zebra_160x160-05de71dd_20210407.pth\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res101_8xb64-210e_zebra-160x160.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(160, 160), heatmap_size=(40, 40), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=9,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'ZebraDataset'\ndata_mode = 'topdown'\ndata_root = 'data/zebra/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/zebra_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/zebra_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res152_8xb32-210e_zebra-160x160.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(160, 160), heatmap_size=(40, 40), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=9,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'ZebraDataset'\ndata_mode = 'topdown'\ndata_root = 'data/zebra/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/zebra_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/zebra_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/animal_2d_keypoint/topdown_heatmap/zebra/td-hm_res50_8xb64-210e_zebra-160x160.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(160, 160), heatmap_size=(40, 40), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=9,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'ZebraDataset'\ndata_mode = 'topdown'\ndata_root = 'data/zebra/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/zebra_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/zebra_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/README.md",
    "content": "# Human Body 2D Pose Estimation\n\nMulti-person human pose estimation is defined as the task of detecting the poses (or keypoints) of all people from an input image.\n\nExisting approaches can be categorized into top-down and bottom-up approaches.\n\nTop-down methods (e.g. DeepPose) divide the task into two stages: human detection and pose estimation. They perform human detection first, followed by single-person pose estimation given human bounding boxes.\n\nBottom-up approaches (e.g. Associative Embedding) first detect all the keypoints and then group/associate them into person instances.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_body_keypoint.md) to prepare data.\n\n## Demo\n\nPlease follow [Demo](/demo/docs/en/2d_human_pose_demo.md#2d-human-pose-demo) to run demos.\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/87690686/187824368-1f1631c3-52bf-4b45-bf9a-a70cd6551e1a.jpg\" height=\"500px\" alt><br>\n</div>\n"
  },
  {
    "path": "configs/body_2d_keypoint/associative_embedding/README.md",
    "content": "# Associative embedding: End-to-end learning for joint detection and grouping (AE)\n\nAssociative Embedding is one of the most popular 2D bottom-up pose estimation approaches, that first detect all the keypoints and then group/associate them into person instances.\n\nIn order to group all the predicted keypoints to individuals, a tag is also predicted for each detected keypoint. Tags of the same person are similar, while tags of different people are different. Thus the keypoints can be grouped according to the tags.\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146514181-84f22623-6b73-4656-89b8-9e7f551e9cc0.png\">\n</div>\n"
  },
  {
    "path": "configs/body_2d_keypoint/associative_embedding/coco/ae_hrnet-w32_8xb24-300e_coco-512x512.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1.5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=300,\n        milestones=[200, 260],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=192)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', interval=50))\n\n# codec settings\ncodec = dict(\n    type='AssociativeEmbedding',\n    input_size=(512, 512),\n    heatmap_size=(128, 128),\n    sigma=2,\n    decode_topk=30,\n    decode_center_shift=0.5,\n    decode_keypoint_order=[\n        0, 1, 2, 3, 4, 5, 6, 11, 12, 7, 8, 9, 10, 13, 14, 15, 16\n    ],\n    decode_max_instances=30)\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='AssociativeEmbeddingHead',\n        in_channels=32,\n        num_keypoints=17,\n        tag_dim=1,\n        tag_per_keypoint=True,\n        deconv_out_channels=None,\n        keypoint_loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        tag_loss=dict(type='AssociativeEmbeddingLoss', loss_weight=0.001),\n        # The heatmap will be resized to the input size before decoding\n        # if ``restore_heatmap_size==True``\n        decoder=dict(codec, heatmap_size=codec['input_size'])),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        shift_heatmap=False,\n        restore_heatmap_size=True,\n        align_corners=False))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = []\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=64,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=24,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none',\n    score_mode='bbox',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/associative_embedding/coco/hrnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1611.05424\">Associative Embedding (NIPS'2017)</a></summary>\n\n```bibtex\n@inproceedings{newell2017associative,\n  title={Associative embedding: End-to-end learning for joint detection and grouping},\n  author={Newell, Alejandro and Huang, Zhiao and Deng, Jia},\n  booktitle={Advances in neural information processing systems},\n  pages={2277--2287},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 without multi-scale test\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [HRNet-w32](/configs/body_2d_keypoint/associative_embedding/coco/ae_hrnet-w32_8xb24-300e_coco-512x512.py) |  512x512   | 0.656 |      0.864      |      0.719      | 0.711 |      0.893      | [ckpt](https://download.openmmlab.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth) | [log](https://download.openmmlab.com/mmpose/bottom_up/hrnet_w32_coco_512x512_20200816.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/associative_embedding/coco/hrnet_coco.yml",
    "content": "Collections:\n- Name: AE\n  Paper:\n    Title: \"Associative embedding: End-to-end learning for joint detection and grouping\"\n    URL: https://arxiv.org/abs/1611.05424\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/associative_embedding.md\nModels:\n- Config: configs/body_2d_keypoint/associative_embedding/coco/ae_hrnet-w32_8xb24-300e_coco-512x512.py\n  In Collection: AE\n  Metadata:\n    Architecture:\n    - AE\n    - HRNet\n    Training Data: COCO\n  Name: ae_hrnet-w32_8xb24-300e_coco-512x512\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.656\n      AP@0.5: 0.864\n      AP@0.75: 0.719\n      AR: 0.711\n      AR@0.5: 0.893\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/bottom_up/hrnet_w32_coco_512x512-bcb8c247_20200816.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/cid/coco/cid_hrnet-w32_8xb20-140e_coco-512x512.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=140, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=140,\n        milestones=[90, 120],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=160)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='DecoupledHeatmap', input_size=(512, 512), heatmap_size=(128, 128))\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256),\n                multiscale_output=True)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='CIDHead',\n        in_channels=480,\n        num_keypoints=17,\n        gfd_channels=32,\n        coupled_heatmap_loss=dict(type='FocalHeatmapLoss', loss_weight=1.0),\n        decoupled_heatmap_loss=dict(type='FocalHeatmapLoss', loss_weight=4.0),\n        contrastive_loss=dict(\n            type='InfoNCELoss', temperature=0.05, loss_weight=1.0),\n        decoder=codec,\n    ),\n    train_cfg=dict(max_train_instances=200),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        shift_heatmap=False,\n        align_corners=False))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='BottomupRandomAffine', input_size=codec['input_size']),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='BottomupGetHeatmapMask'),\n    dict(type='PackPoseInputs'),\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=64,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=20,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_thr=0.8,\n    score_mode='keypoint',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/cid/coco/cid_hrnet-w48_8xb20-140e_coco-512x512.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=140, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=140,\n        milestones=[90, 120],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=160)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='DecoupledHeatmap', input_size=(512, 512), heatmap_size=(128, 128))\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384),\n                multiscale_output=True)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='CIDHead',\n        in_channels=720,\n        num_keypoints=17,\n        gfd_channels=48,\n        coupled_heatmap_loss=dict(type='FocalHeatmapLoss', loss_weight=1.0),\n        decoupled_heatmap_loss=dict(type='FocalHeatmapLoss', loss_weight=4.0),\n        contrastive_loss=dict(\n            type='InfoNCELoss', temperature=0.05, loss_weight=1.0),\n        decoder=codec,\n    ),\n    train_cfg=dict(max_train_instances=200),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        shift_heatmap=False,\n        align_corners=False))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='BottomupRandomAffine', input_size=codec['input_size']),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='BottomupGetHeatmapMask'),\n    dict(type='PackPoseInputs'),\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=64,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=20,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_thr=0.8,\n    score_mode='keypoint',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/cid/coco/hrnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/CVPR2022/html/Wang_Contextual_Instance_Decoupling_for_Robust_Multi-Person_Pose_Estimation_CVPR_2022_paper.html\">CID (CVPR'2022)</a></summary>\n\n```bibtex\n@InProceedings{Wang_2022_CVPR,\n    author    = {Wang, Dongkai and Zhang, Shiliang},\n    title     = {Contextual Instance Decoupling for Robust Multi-Person Pose Estimation},\n    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n    month     = {June},\n    year      = {2022},\n    pages     = {11060-11068}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 without multi-scale test\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [CID](/configs/body_2d_keypoint/cid/coco/cid_hrnet-w32_8xb20-140e_coco-512x512.py) |  512x512   | 0.704 |      0.894      |      0.775      | 0.753 |      0.928      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/cid/coco/cid_hrnet-w32_8xb20-140e_coco-512x512_42b7e6e6-20230207.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/cid/coco/cid_hrnet-w32_8xb20-140e_coco-512x512_20230207.json) |\n| [CID](/configs/body_2d_keypoint/cid/coco/cid_hrnet-w48_8xb20-140e_coco-512x512.py) |  512x512   | 0.715 |      0.900      |      0.782      | 0.765 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/cid/coco/cid_hrnet-w48_8xb20-140e_coco-512x512_a36c3ecf-20230207.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/cid/coco/cid_hrnet-w48_8xb20-140e_coco-512x512_20230207.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/cid/coco/hrnet_coco.yml",
    "content": "Collections:\n- Name: CID\n  Paper:\n    Title: Contextual Instance Decoupling for Robust Multi-Person Pose Estimation\n    URL: https://openaccess.thecvf.com/content/CVPR2022/html/Wang_Contextual_Instance_Decoupling_for_Robust_Multi-Person_Pose_Estimation_CVPR_2022_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/cid.md\nModels:\n- Config: configs/body_2d_keypoint/cid/coco/cid_hrnet-w32_8xb20-140e_coco-512x512.py\n  In Collection: CID\n  Metadata:\n    Architecture: &id001\n    - CID\n    - HRNet\n    Training Data: COCO\n  Name: cid_hrnet-w32_8xb20-140e_coco-512x512\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.704\n      AP@0.5: 0.894\n      AP@0.75: 0.775\n      AR: 0.753\n      AR@0.5: 0.928\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/cid/coco/cid_hrnet-w32_8xb20-140e_coco-512x512_42b7e6e6-20230207.pth\n- Config: configs/body_2d_keypoint/cid/coco/cid_hrnet-w48_8xb20-140e_coco-512x512.py\n  In Collection: CID\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: cid_hrnet-w48_8xb20-140e_coco-512x512\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.715\n      AP@0.5: 0.9\n      AP@0.75: 0.782\n      AR: 0.765\n      AR@0.5: 0.935\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/cid/coco/cid_hrnet-w48_8xb20-140e_coco-512x512_a36c3ecf-20230207.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/README.md",
    "content": "# Bottom-up Human Pose Estimation via Disentangled Keypoint Regression (DEKR)\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.02300\">DEKR (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{geng2021bottom,\n  title={Bottom-up human pose estimation via disentangled keypoint regression},\n  author={Geng, Zigang and Sun, Ke and Xiao, Bin and Zhang, Zhaoxiang and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={14676--14686},\n  year={2021}\n}\n```\n\n</details>\n\nDEKR is a popular 2D bottom-up pose estimation approach that simultaneously detects all the instances and regresses the offsets from the instance centers to joints.\n\nIn order to predict the offsets more accurately, the offsets of different joints are regressed using separated branches with deformable convolutional layers. Thus convolution kernels with different shapes are adopted to extract features for the corresponding joint.\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=140, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=140,\n        milestones=[90, 120],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=80)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='SPR',\n    input_size=(512, 512),\n    heatmap_size=(128, 128),\n    sigma=(4, 2),\n    minimal_diagonal_length=32**0.5,\n    generate_keypoint_heatmaps=True,\n    decode_max_instances=30)\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256),\n                multiscale_output=True)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='DEKRHead',\n        in_channels=480,\n        num_keypoints=17,\n        heatmap_loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        displacement_loss=dict(\n            type='SoftWeightSmoothL1Loss',\n            use_target_weight=True,\n            supervise_empty=False,\n            beta=1 / 9,\n            loss_weight=0.002,\n        ),\n        decoder=codec,\n        # This rescore net is adapted from the official repo.\n        # If you are not using the original COCO dataset for training,\n        # please make sure to remove the `rescore_cfg` item\n        rescore_cfg=dict(\n            in_channels=74,\n            norm_indexes=(5, 6),\n            init_cfg=dict(\n                type='Pretrained',\n                checkpoint='https://download.openmmlab.com/mmpose/'\n                'pretrain_models/kpt_rescore_coco-33d58c5c.pth')),\n    ),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        nms_dist_thr=0.05,\n        shift_heatmap=True,\n        align_corners=False))\n\n# enable DDP training when rescore net is used\nfind_unused_parameters = True\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='BottomupRandomAffine', input_size=codec['input_size']),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='BottomupGetHeatmapMask'),\n    dict(type='PackPoseInputs'),\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=32,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=10,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none',\n    score_mode='keypoint',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w48_8xb10-140e_coco-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=140, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=140,\n        milestones=[90, 120],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=80)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='SPR',\n    input_size=(640, 640),\n    heatmap_size=(160, 160),\n    sigma=(4, 2),\n    minimal_diagonal_length=32**0.5,\n    generate_keypoint_heatmaps=True,\n    decode_max_instances=30)\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384),\n                multiscale_output=True)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='DEKRHead',\n        in_channels=720,\n        num_keypoints=17,\n        num_heatmap_filters=48,\n        heatmap_loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        displacement_loss=dict(\n            type='SoftWeightSmoothL1Loss',\n            use_target_weight=True,\n            supervise_empty=False,\n            beta=1 / 9,\n            loss_weight=0.002,\n        ),\n        decoder=codec,\n        # This rescore net is adapted from the official repo.\n        # If you are not using the original COCO dataset for training,\n        # please make sure to remove the `rescore_cfg` item\n        rescore_cfg=dict(\n            in_channels=74,\n            norm_indexes=(5, 6),\n            init_cfg=dict(\n                type='Pretrained',\n                checkpoint='https://download.openmmlab.com/mmpose/'\n                'pretrain_models/kpt_rescore_coco-33d58c5c.pth')),\n    ),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        nms_dist_thr=0.05,\n        shift_heatmap=True,\n        align_corners=False))\n\n# enable DDP training when rescore net is used\nfind_unused_parameters = True\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='BottomupRandomAffine', input_size=codec['input_size']),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='BottomupGetHeatmapMask'),\n    dict(type='PackPoseInputs'),\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=32,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=10,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none',\n    score_mode='keypoint',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/coco/hrnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.02300\">DEKR (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{geng2021bottom,\n  title={Bottom-up human pose estimation via disentangled keypoint regression},\n  author={Geng, Zigang and Sun, Ke and Xiao, Bin and Zhang, Zhaoxiang and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={14676--14686},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 without multi-scale test\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [HRNet-w32](/configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512.py) |  512x512   | 0.686 |      0.868      |      0.750      | 0.735 |      0.898      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512_ac7c17bf-20221228.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512_20221228.json) |\n| [HRNet-w48](/configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w48_8xb10-140e_coco-640x640.py) |  640x640   | 0.714 |      0.883      |      0.777      | 0.762 |      0.915      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w48_8xb10-140e_coco-640x640_74796c32-20230124.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w48_8xb10-140e_coco-640x640_20230124.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/coco/hrnet_coco.yml",
    "content": "Collections:\n- Name: DEKR\n  Paper:\n    Title: Bottom-up human pose estimation via disentangled keypoint regression\n    URL: https://arxiv.org/abs/2104.02300\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/dekr.md\nModels:\n- Config: configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512.py\n  In Collection: DEKR\n  Metadata:\n    Architecture: &id001\n    - DEKR\n    - HRNet\n    Training Data: COCO\n  Name: dekr_hrnet-w32_8xb10-140e_coco-512x512\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.686\n      AP@0.5: 0.868\n      AP@0.75: 0.750\n      AR: 0.735\n      AR@0.5: 0.898\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512_ac7c17bf-20221228.pth\n- Config: configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w48_8xb10-140e_coco-640x640.py\n  In Collection: DEKR\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: dekr_hrnet-w48_8xb10-140e_coco-640x640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.714\n      AP@0.5: 0.883\n      AP@0.75: 0.777\n      AR: 0.762\n      AR@0.5: 0.915\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w48_8xb10-140e_coco-640x640_74796c32-20230124.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w32_8xb10-300e_crowdpose-512x512.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=20)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=300,\n        milestones=[200, 260],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=80)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='SPR',\n    input_size=(512, 512),\n    heatmap_size=(128, 128),\n    sigma=(4, 2),\n    minimal_diagonal_length=32**0.5,\n    generate_keypoint_heatmaps=True,\n    decode_max_instances=30)\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256),\n                multiscale_output=True)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='DEKRHead',\n        in_channels=480,\n        num_keypoints=14,\n        heatmap_loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        displacement_loss=dict(\n            type='SoftWeightSmoothL1Loss',\n            use_target_weight=True,\n            supervise_empty=False,\n            beta=1 / 9,\n            loss_weight=0.004,\n        ),\n        decoder=codec,\n        # This rescore net is adapted from the official repo.\n        # If you are not using the original CrowdPose dataset for training,\n        # please make sure to remove the `rescore_cfg` item\n        rescore_cfg=dict(\n            in_channels=59,\n            norm_indexes=(0, 1),\n            init_cfg=dict(\n                type='Pretrained',\n                checkpoint='https://download.openmmlab.com/mmpose/'\n                'pretrain_models/kpt_rescore_crowdpose-300c7efe.pth')),\n    ),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        nms_dist_thr=0.05,\n        shift_heatmap=True,\n        align_corners=False))\n\n# enable DDP training when rescore net is used\nfind_unused_parameters = True\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='BottomupRandomAffine', input_size=codec['input_size']),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=32,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=10,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    nms_mode='none',\n    score_mode='keypoint',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w48_8xb5-300e_crowdpose-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=300, val_interval=20)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=300,\n        milestones=[200, 260],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=40)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='SPR',\n    input_size=(640, 640),\n    heatmap_size=(160, 160),\n    sigma=(4, 2),\n    minimal_diagonal_length=32**0.5,\n    generate_keypoint_heatmaps=True,\n    decode_max_instances=30)\n\n# model settings\nmodel = dict(\n    type='BottomupPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384),\n                multiscale_output=True)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='DEKRHead',\n        in_channels=720,\n        num_keypoints=14,\n        num_heatmap_filters=48,\n        heatmap_loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        displacement_loss=dict(\n            type='SoftWeightSmoothL1Loss',\n            use_target_weight=True,\n            supervise_empty=False,\n            beta=1 / 9,\n            loss_weight=0.004,\n        ),\n        decoder=codec,\n        # This rescore net is adapted from the official repo.\n        # If you are not using the original CrowdPose dataset for training,\n        # please make sure to remove the `rescore_cfg` item\n        rescore_cfg=dict(\n            in_channels=59,\n            norm_indexes=(0, 1),\n            init_cfg=dict(\n                type='Pretrained',\n                checkpoint='https://download.openmmlab.com/mmpose/'\n                'pretrain_models/kpt_rescore_crowdpose-300c7efe.pth')),\n    ),\n    test_cfg=dict(\n        multiscale_test=False,\n        flip_test=True,\n        nms_dist_thr=0.05,\n        shift_heatmap=True,\n        align_corners=False))\n\n# enable DDP training when rescore net is used\nfind_unused_parameters = True\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='BottomupRandomAffine', input_size=codec['input_size']),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize',\n        input_size=codec['input_size'],\n        size_factor=32,\n        resize_mode='expand'),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=5,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    nms_mode='none',\n    score_mode='keypoint',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/crowdpose/hrnet_crowdpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.02300\">DEKR (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{geng2021bottom,\n  title={Bottom-up human pose estimation via disentangled keypoint regression},\n  author={Geng, Zigang and Sun, Ke and Xiao, Bin and Zhang, Zhaoxiang and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={14676--14686},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\nResults on CrowdPose test without multi-scale test\n\n| Arch                                           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                      ckpt                      |                      log                      |\n| :--------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :--------------------------------------------: | :-------------------------------------------: |\n| [HRNet-w32](/configs/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w32_8xb10-300e_crowdpose-512x512.py) |  512x512   | 0.663 |      0.857      |      0.714      | 0.740  | 0.671  | 0.576  | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w32_8xb10-300e_crowdpose-512x512_147bae97-20221228.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w32_8xb10-300e_crowdpose-512x512_20221228.json) |\n| [HRNet-w48](/configs/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w48_8xb5-300e_crowdpose-640x640.py) |  640x640   | 0.679 |      0.869      |      0.731      | 0.753  | 0.688  | 0.593  | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w48_8xb5-300e_crowdpose-640x640_4ea6031e-20230128.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w48_8xb5-300e_crowdpose-640x640_20230128.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/dekr/crowdpose/hrnet_crowdpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w32_8xb10-300e_crowdpose-512x512.py\n  In Collection: DEKR\n  Metadata:\n    Architecture: &id001\n    - DEKR\n    - HRNet\n    Training Data: CrowdPose\n  Name: dekr_hrnet-w32_8xb10-300e_crowdpose-512x512\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.663\n      AP@0.5: 0.857\n      AP@0.75: 0.714\n      AP (E): 0.74\n      AP (M): 0.671\n      AP (L): 0.576\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w32_8xb10-300e_crowdpose-512x512_147bae97-20221228.pth\n- Config: configs/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w48_8xb5-300e_crowdpose-640x640.py\n  In Collection: DEKR\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: dekr_hrnet-w48_8xb5-300e_crowdpose-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.679\n      AP@0.5: 0.869\n      AP@0.75: 0.731\n      AP (E): 0.753\n      AP (M): 0.688\n      AP (L): 0.593\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/crowdpose/dekr_hrnet-w48_8xb5-300e_crowdpose-640x640_4ea6031e-20230128.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/edpose/coco/edpose_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/2302.01593.pdf\">ED-Pose (ICLR'2023)</a></summary>\n\n```bibtex\n@inproceedings{\nyang2023explicit,\ntitle={Explicit Box Detection Unifies End-to-End Multi-Person Pose Estimation},\nauthor={Jie Yang and Ailing Zeng and Shilong Liu and Feng Li and Ruimao Zhang and Lei Zhang},\nbooktitle={International Conference on Learning Representations},\nyear={2023},\nurl={https://openreview.net/forum?id=s4WVupnJjmX}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017.\n\n| Arch                                          | BackBone  |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                      ckpt                      |                      log                      |\n| :-------------------------------------------- | :-------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :--------------------------------------------: | :-------------------------------------------: |\n| [edpose_res50_coco](/configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py) | ResNet-50 | 0.716 |      0.897      |      0.783      | 0.793 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/edpose/coco/edpose_res50_coco_3rdparty.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/edpose/coco/edpose_res50_coco_3rdparty.json) |\n\nThe checkpoint is converted from the official repo. The training of EDPose is not supported yet. It will be supported in the future updates.\n\nThe above config follows [Pure Python style](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/config.html#a-pure-python-style-configuration-file-beta). Please install `mmengine>=0.8.2` to use this config.\n"
  },
  {
    "path": "configs/body_2d_keypoint/edpose/coco/edpose_coco.yml",
    "content": "Collections:\n- Name: ED-Pose\n  Paper:\n    Title: Explicit Box Detection Unifies End-to-End Multi-Person Pose Estimation\n    URL: https://arxiv.org/pdf/2302.01593.pdf\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/edpose.md\nModels:\n- Config: configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py\n  In Collection: ED-Pose\n  Alias: edpose\n  Metadata:\n    Architecture: &id001\n    - ED-Pose\n    - ResNet\n    Training Data: COCO\n  Name: edpose_res50_8xb2-50e_coco-800x1333\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.716\n      AP@0.5: 0.897\n      AP@0.75: 0.783\n      AR: 0.793\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/edpose/coco/edpose_res50_coco_3rdparty.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/edpose/coco/edpose_res50_8xb2-50e_coco-800x1333.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *  # noqa\n\nfrom mmcv.transforms import RandomChoice, RandomChoiceResize\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import LinearLR, MultiStepLR\nfrom torch.nn import GroupNorm\nfrom torch.optim import Adam\n\nfrom mmpose.codecs import EDPoseLabel\nfrom mmpose.datasets import (BottomupRandomChoiceResize, BottomupRandomCrop,\n                             CocoDataset, LoadImage, PackPoseInputs,\n                             RandomFlip)\nfrom mmpose.evaluation import CocoMetric\nfrom mmpose.models import (BottomupPoseEstimator, ChannelMapper, EDPoseHead,\n                           PoseDataPreprocessor, ResNet)\nfrom mmpose.models.utils import FrozenBatchNorm2d\n\n# runtime\ntrain_cfg.update(max_epochs=50, val_interval=10)  # noqa\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type=Adam,\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(type=LinearLR, begin=0, end=500, start_factor=0.001,\n         by_epoch=False),  # warm-up\n    dict(\n        type=MultiStepLR,\n        begin=0,\n        end=140,\n        milestones=[33, 45],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=80)\n\n# hooks\ndefault_hooks.update(  # noqa\n    checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(type=EDPoseLabel, num_select=50, num_keypoints=17)\n\n# model settings\nmodel = dict(\n    type=BottomupPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True,\n        pad_size_divisor=1),\n    backbone=dict(\n        type=ResNet,\n        depth=50,\n        num_stages=4,\n        out_indices=(1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type=FrozenBatchNorm2d, requires_grad=False),\n        norm_eval=True,\n        style='pytorch',\n        init_cfg=dict(\n            type=PretrainedInit, checkpoint='torchvision://resnet50')),\n    neck=dict(\n        type=ChannelMapper,\n        in_channels=[512, 1024, 2048],\n        kernel_size=1,\n        out_channels=256,\n        act_cfg=None,\n        norm_cfg=dict(type=GroupNorm, num_groups=32),\n        num_outs=4),\n    head=dict(\n        type=EDPoseHead,\n        num_queries=900,\n        num_feature_levels=4,\n        num_keypoints=17,\n        as_two_stage=True,\n        encoder=dict(\n            num_layers=6,\n            layer_cfg=dict(  # DeformableDetrTransformerEncoderLayer\n                self_attn_cfg=dict(  # MultiScaleDeformableAttention\n                    embed_dims=256,\n                    num_heads=8,\n                    num_levels=4,\n                    num_points=4,\n                    batch_first=True),\n                ffn_cfg=dict(\n                    embed_dims=256,\n                    feedforward_channels=2048,\n                    num_fcs=2,\n                    ffn_drop=0.0))),\n        decoder=dict(\n            num_layers=6,\n            embed_dims=256,\n            layer_cfg=dict(  # DeformableDetrTransformerDecoderLayer\n                self_attn_cfg=dict(  # MultiheadAttention\n                    embed_dims=256,\n                    num_heads=8,\n                    batch_first=True),\n                cross_attn_cfg=dict(  # MultiScaleDeformableAttention\n                    embed_dims=256,\n                    batch_first=True),\n                ffn_cfg=dict(\n                    embed_dims=256, feedforward_channels=2048, ffn_drop=0.1)),\n            query_dim=4,\n            num_feature_levels=4,\n            num_group=100,\n            num_dn=100,\n            num_box_decoder_layers=2,\n            return_intermediate=True),\n        out_head=dict(num_classes=2),\n        positional_encoding=dict(\n            num_pos_feats=128,\n            temperatureH=20,\n            temperatureW=20,\n            normalize=True),\n        denosing_cfg=dict(\n            dn_box_noise_scale=0.4,\n            dn_label_noise_ratio=0.5,\n            dn_labelbook_size=100,\n            dn_attn_mask_type_list=['match2dn', 'dn2dn', 'group2group']),\n        data_decoder=codec),\n    test_cfg=dict(Pmultiscale_test=False, flip_test=False, num_select=50),\n    train_cfg=dict())\n\n# enable DDP training when rescore net is used\nfind_unused_parameters = True\n\n# base dataset settings\ndataset_type = CocoDataset\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(\n        type=RandomChoice,\n        transforms=[\n            [\n                dict(\n                    type=RandomChoiceResize,\n                    scales=[(480, 1333), (512, 1333), (544, 1333), (576, 1333),\n                            (608, 1333), (640, 1333), (672, 1333), (704, 1333),\n                            (736, 1333), (768, 1333), (800, 1333)],\n                    keep_ratio=True)\n            ],\n            [\n                dict(\n                    type=BottomupRandomChoiceResize,\n                    # The radio of all image in train dataset < 7\n                    # follow the original implement\n                    scales=[(400, 4200), (500, 4200), (600, 4200)],\n                    keep_ratio=True),\n                dict(\n                    type=BottomupRandomCrop,\n                    crop_type='absolute_range',\n                    crop_size=(384, 600),\n                    allow_negative_crop=True),\n                dict(\n                    type=BottomupRandomChoiceResize,\n                    scales=[(480, 1333), (512, 1333), (544, 1333), (576, 1333),\n                            (608, 1333), (640, 1333), (672, 1333), (704, 1333),\n                            (736, 1333), (768, 1333), (800, 1333)],\n                    keep_ratio=True)\n            ]\n        ]),\n    dict(type=PackPoseInputs),\n]\n\nval_pipeline = [\n    dict(type=LoadImage),\n    dict(\n        type=BottomupRandomChoiceResize,\n        scales=[(800, 1333)],\n        keep_ratio=True,\n        backend='pillow'),\n    dict(\n        type=PackPoseInputs,\n        meta_keys=('id', 'img_id', 'img_path', 'crowd_index', 'ori_shape',\n                   'img_shape', 'input_size', 'input_center', 'input_scale',\n                   'flip', 'flip_direction', 'flip_indices', 'raw_ann_info',\n                   'skeleton_links'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=1,\n    num_workers=1,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=8,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type=CocoMetric,\n    nms_mode='none',\n    score_mode='keypoint',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/README.md",
    "content": "# Top-down integral-regression-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. At the 2nd stage, integral regression based methods use a simple integral operation relates and unifies the heatmap and joint regression differentiably, thus obtain the keypoint coordinates given the features extracted from the bounding box area, following the paradigm introduced in [Integral Human Pose Regression](https://arxiv.org/abs/1711.08229).\n\n## Results and Models\n\n### COCO Dataset\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n|        Model         | Input Size |  AP   |  AR   |                 Details and Download                  |\n| :------------------: | :--------: | :---: | :---: | :---------------------------------------------------: |\n| ResNet-50+Debias-IPR |  256x256   | 0.675 | 0.765 | [resnet_debias_coco.md](./coco/resnet_debias_coco.md) |\n|    ResNet-50+DSNT    |  256x256   | 0.674 | 0.764 |   [resnet_dsnt_coco.md](./coco/resnet_dsnt_coco.md)   |\n|    ResNet-50+IPR     |  256x256   | 0.633 | 0.730 |    [resnet_ipr_coco.md](./coco/resnet_ipr_coco.md)    |\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/ipr_res50_8xb64-210e_coco-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='IntegralRegressionLabel',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2.0,\n    normalize=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n    ),\n    head=dict(\n        type='DSNTHead',\n        in_channels=2048,\n        in_featuremap_size=(8, 8),\n        num_joints=17,\n        loss=dict(\n            type='MultipleLossWrapper',\n            losses=[\n                dict(type='SmoothL1Loss', use_target_weight=True),\n                dict(type='KeypointMSELoss', use_target_weight=True)\n            ]),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n        shift_heatmap=True,\n    ),\n    init_cfg=dict(\n        type='Pretrained',\n        checkpoint='https://download.openmmlab.com/mmpose/'\n        'pretrain_models/td-hm_res50_8xb64-210e_coco-256x192.pth'))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/ipr_res50_debias-8xb64-210e_coco-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='IntegralRegressionLabel',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2.0,\n    normalize=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n    ),\n    head=dict(\n        type='DSNTHead',\n        in_channels=2048,\n        in_featuremap_size=(8, 8),\n        num_joints=17,\n        debias=True,\n        beta=10.,\n        loss=dict(\n            type='MultipleLossWrapper',\n            losses=[\n                dict(type='SmoothL1Loss', use_target_weight=True),\n                dict(type='JSDiscretLoss', use_target_weight=True)\n            ]),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n        shift_heatmap=True,\n    ),\n    init_cfg=dict(\n        type='Pretrained',\n        checkpoint='https://download.openmmlab.com/mmpose/'\n        'pretrain_models/td-hm_res50_8xb64-210e_coco-256x192.pth'))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/ipr_res50_dsnt-8xb64-210e_coco-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='IntegralRegressionLabel',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2.0,\n    normalize=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n    ),\n    head=dict(\n        type='DSNTHead',\n        in_channels=2048,\n        in_featuremap_size=(8, 8),\n        num_joints=17,\n        loss=dict(\n            type='MultipleLossWrapper',\n            losses=[\n                dict(type='SmoothL1Loss', use_target_weight=True),\n                dict(type='JSDiscretLoss', use_target_weight=True)\n            ]),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n        shift_heatmap=True,\n    ),\n    init_cfg=dict(\n        type='Pretrained',\n        checkpoint='https://download.openmmlab.com/mmpose/'\n        'pretrain_models/td-hm_res50_8xb64-210e_coco-256x192.pth'))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/resnet_debias_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/ICCV2021/papers/Gu_Removing_the_Bias_of_Integral_Pose_Regression_ICCV_2021_paper.pdf\">Debias IPR (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{gu2021removing,\n    title={Removing the Bias of Integral Pose Regression},\n    author={Gu, Kerui and Yang, Linlin and Yao, Angela},\n    booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n    pages={11067--11076},\n    year={2021}\n  }\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [debias-ipr_resnet_50](/configs/body_2d_keypoint/integral_regression/coco/ipr_res50_debias-8xb64-210e_coco-256x256.py) |  256x256   | 0.675 |      0.872      |      0.740      | 0.765 |      0.928      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_debias-8xb64-210e_coco-256x256-055a7699_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_debias-8xb64-210e_coco-256x256-055a7699_20220913.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/resnet_debias_coco.yml",
    "content": "Collections:\n- Name: DebiasIPR\n  Paper:\n    Title: Removing the Bias of Integral Pose Regression\n    URL: https://openaccess.thecvf.com/content/ICCV2021/papers/Gu_Removing_the_Bias_of_Integral_Pose_Regression_ICCV_2021_paper.pdf\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/debias_ipr.md\nModels:\n- Config: configs/body_2d_keypoint/integral_regression/coco/ipr_res50_debias--8xb64-210e_coco-256x256.py\n  In Collection: DebiasIPR\n  Metadata:\n    Architecture: &id001\n    - Debias\n    - ResNet\n    Training Data: COCO\n  Name: ipr_res50_debias--8xb64-210e_coco-256x256\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.675\n      AP@0.5: 0.872\n      AP@0.75: 0.74\n      AR: 0.765\n      AR@0.5: 0.928\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_debias-8xb64-210e_coco-256x256-055a7699_20220913.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/resnet_dsnt_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1801.07372v2\">DSNT (2018)</a></summary>\n\n```bibtex\n@article{nibali2018numerical,\n  title={Numerical Coordinate Regression with Convolutional Neural Networks},\n  author={Nibali, Aiden and He, Zhen and Morgan, Stuart and Prendergast, Luke},\n  journal={arXiv preprint arXiv:1801.07372},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ipr_resnet_50_dsnt](/configs/body_2d_keypoint/integral_regression/coco/ipr_res50_dsnt-8xb64-210e_coco-256x256.py) |  256x256   | 0.674 |      0.870      |      0.744      | 0.764 |      0.928      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_dsnt-8xb64-210e_coco-256x256-441eedc0_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_dsnt-8xb64-210e_coco-256x256-441eedc0_20220913.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/resnet_dsnt_coco.yml",
    "content": "Collections:\n- Name: DSNT\n  Paper:\n    Title: Numerical Coordinate Regression with Convolutional Neural Networks\n    URL: https://arxiv.org/abs/1801.07372v2\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/dsnt.md\nModels:\n- Config: configs/body_2d_keypoint/integral_regression/coco/ipr_res50_dsnt-8xb64-210e_coco-256x256.py\n  In Collection: DSNT\n  Metadata:\n    Architecture: &id001\n    - DSNT\n    - ResNet\n    Training Data: COCO\n  Name: ipr_res50_dsnt-8xb64-210e_coco-256x256\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.674\n      AP@0.5: 0.87\n      AP@0.75: 0.744\n      AR: 0.764\n      AR@0.5: 0.928\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_dsnt-8xb64-210e_coco-256x256-441eedc0_20220913.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/resnet_ipr_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.08229\">IPR (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{sun2018integral,\n  title={Integral human pose regression},\n  author={Sun, Xiao and Xiao, Bin and Wei, Fangyin and Liang, Shuang and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={529--545},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ipr_resnet_50](/configs/body_2d_keypoint/integral_regression/coco/ipr_res50_8xb64-210e_coco-256x256.py) |  256x256   | 0.633 |      0.860      |      0.703      | 0.730 |      0.919      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_8xb64-210e_coco-256x256-a3898a33_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_8xb64-210e_coco-256x256-a3898a33_20220913.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/integral_regression/coco/resnet_ipr_coco.yml",
    "content": "Collections:\n- Name: IPR\n  Paper:\n    Title: Integral human pose regression\n    URL: https://arxiv.org/abs/1711.08229\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/ipr.md\nModels:\n- Config: configs/body_2d_keypoint/integral_regression/coco/ipr_res50_8xb64-210e_coco-256x256.py\n  In Collection: IPR\n  Metadata:\n    Architecture: &id001\n    - IPR\n    - ResNet\n    Training Data: COCO\n  Name: ipr_res50_8xb64-210e_coco-256x256\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.633\n      AP@0.5: 0.86\n      AP@0.75: 0.703\n      AR: 0.73\n      AR@0.5: 0.919\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/integral_regression/coco/ipr_res50_8xb64-210e_coco-256x256-a3898a33_20220913.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/README.md",
    "content": "# RTMO: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2312.07526\">RTMO</a></summary>\n\n```bibtex\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\nRTMO is a one-stage pose estimation model that seamlessly integrates coordinate classification into the YOLO architecture. It introduces a Dynamic Coordinate Classifier (DCC) module that handles keypoint localization through dual 1D heatmaps. The DCC employs dynamic bin allocation, localizing the coordinate bins to each predicted bounding box to improve efficiency. It also uses learnable bin representations based on positional encodings, enabling computation of bin-keypoint similarity for precise localization.\n\nRTMO is trained end-to-end using a multi-task loss, with losses for bounding box regression, keypoint heatmap classification via a novel MLE loss, keypoint coordinate proxy regression, and keypoint visibility classification. The MLE loss models annotation uncertainty and balances optimization between easy and hard samples.\n\nDuring inference, RTMO employs grid-based dense predictions to simultaneously output human detection boxes and poses in a single pass. It selectively decodes heatmaps only for high-scoring grids after NMS, minimizing computational cost.\n\nCompared to prior one-stage methods that regress keypoint coordinates directly, RTMO achieves higher accuracy through coordinate classification while retaining real-time speeds. It also outperforms lightweight top-down approaches for images with many people, as the latter have inference times that scale linearly with the number of human instances.\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/body7/rtmo-l_16xb16-600e_body7-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\n# data settings\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[(i, i) for i in range(17)])\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\ntrain_dataset = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file=metafile),\n    datasets=[\n        dataset_coco,\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_halpe,\n        dataset_posetrack,\n    ],\n    sample_ratio_factor=[1, 0.3, 0.5, 0.3, 0.3, 0.4, 0.3],\n    test_mode=False,\n    pipeline=train_pipeline_stage1)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=train_dataset)\n\n# val datasets\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_dataset=dataset_coco,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 1.0\ndeepen_factor = 1.0\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_l_8x8_300e_coco/yolox_l_8x8_300e_coco'\n            '_20211126_140236-d3bd2b23.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[256, 512, 1024],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=512,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=512,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=512,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-2,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/body7/rtmo-m_16xb16-600e_body7-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\n# data settings\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[(i, i) for i in range(17)])\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\ntrain_dataset = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file=metafile),\n    datasets=[\n        dataset_coco,\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_halpe,\n        dataset_posetrack,\n    ],\n    sample_ratio_factor=[1, 0.3, 0.5, 0.3, 0.3, 0.4, 0.3],\n    test_mode=False,\n    pipeline=train_pipeline_stage1)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=train_dataset)\n\n# val datasets\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_dataset=dataset_coco,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.75\ndeepen_factor = 0.67\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'pretrained_models/yolox_m_8x8_300e_coco_20230829.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[192, 384, 768],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=384,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=384,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=384,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-2,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/body7/rtmo-s_8xb32-600e_body7-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\n# data settings\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[(i, i) for i in range(17)])\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\ntrain_dataset = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file=metafile),\n    datasets=[\n        dataset_coco,\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_halpe,\n        dataset_posetrack,\n    ],\n    sample_ratio_factor=[1, 0.3, 0.5, 0.3, 0.3, 0.4, 0.3],\n    test_mode=False,\n    pipeline=train_pipeline_stage1)\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=train_dataset)\n\n# val datasets\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_dataset=dataset_coco,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.5\ndeepen_factor = 0.33\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_s_8x8_300e_coco/yolox_s_8x8_300e_coco_'\n            '20211121_095711-4592a793.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[128, 256, 512],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=256,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=256,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile),\n            use_keypoints_for_center=True),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=256,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1.0,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/body7/rtmo-t_8xb32-600e_body7-416x416.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (416, 416)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(416, 416),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(416, 416),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(416, 416),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\n# data settings\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[(i, i) for i in range(17)])\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\ntrain_dataset = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file=metafile),\n    datasets=[\n        dataset_coco,\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_halpe,\n        dataset_posetrack,\n    ],\n    sample_ratio_factor=[1, 0.3, 0.5, 0.3, 0.3, 0.4, 0.3],\n    test_mode=False,\n    pipeline=train_pipeline_stage1)\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=train_dataset)\n\n# val datasets\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_dataset=dataset_coco,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.375\ndeepen_factor = 0.33\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(320, 640),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_tiny_8x8_300e_coco/yolox_tiny_8x8_300e_coco_'\n            '20211124_171234-b4047906.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[96, 192, 384],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=192,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=192,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile),\n            use_keypoints_for_center=True),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=192,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1.0,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/body7/rtmo_body7.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2312.07526\">RTMO</a></summary>\n\n```bibtex\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2013/html/Jhuang_Towards_Understanding_Action_2013_ICCV_paper.html\">JHMDB (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{Jhuang:ICCV:2013,\n  title = {Towards understanding action recognition},\n  author = {H. Jhuang and J. Gall and S. Zuffi and C. Schmid and M. J. Black},\n  booktitle = {International Conf. on Computer Vision (ICCV)},\n  month = Dec,\n  pages = {3192-3199},\n  year = {2013}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Andriluka_PoseTrack_A_Benchmark_CVPR_2018_paper.html\">PoseTrack18 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{andriluka2018posetrack,\n  title={Posetrack: A benchmark for human pose estimation and tracking},\n  author={Andriluka, Mykhaylo and Iqbal, Umar and Insafutdinov, Eldar and Pishchulin, Leonid and Milan, Anton and Gall, Juergen and Schiele, Bernt},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={5167--5176},\n  year={2018}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2004.00945\">Halpe (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020pastanet,\n  title={PaStaNet: Toward Human Activity Knowledge Engine},\n  author={Li, Yong-Lu and Xu, Liang and Liu, Xinpeng and Huang, Xijie and Xu, Yue and Wang, Shiyi and Fang, Hao-Shu and Ma, Ze and Chen, Mingyang and Lu, Cewu},\n  booktitle={CVPR},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO val2017\n\n| Arch                               | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                ckpt                |                log                |                onnx                |\n| :--------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :--------------------------------: | :-------------------------------: | :--------------------------------: |\n| [RTMO-t](/configs/body_2d_keypoint/rtmo/body7/rtmo-t_8xb32-600e_body7-416x416.py) |  640x640   | 0.574 |      0.803      |      0.613      | 0.611 |      0.836      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-t_8xb32-600e_body7-416x416-f48f75cb_20231219.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-t_8xb32-600e_body7-416x416_20231219.json) | [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-t_8xb32-600e_body7-416x416-f48f75cb_20231219.zip) |\n| [RTMO-s](/configs/body_2d_keypoint/rtmo/body7/rtmo-s_8xb32-600e_body7-640x640.py) |  640x640   | 0.686 |      0.879      |      0.744      | 0.723 |      0.908      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_body7-640x640-dac2bf74_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_body7-640x640_20231211.json) | [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-s_8xb32-600e_body7-640x640-dac2bf74_20231211.zip) |\n| [RTMO-m](/configs/body_2d_keypoint/rtmo/body7/rtmo-m_16xb16-600e_body7-640x640.py) |  640x640   | 0.726 |      0.899      |      0.790      | 0.763 |      0.926      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_body7-640x640-39e78cc4_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_body7-640x640_20231211.json) | [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-m_16xb16-600e_body7-640x640-39e78cc4_20231211.zip) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/body7/rtmo-l_16xb16-600e_body7-640x640.py) |  640x640   | 0.748 |      0.911      |      0.813      | 0.786 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_body7-640x640-b37118ce_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_body7-640x640_20231211.json) | [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-l_16xb16-600e_body7-640x640-b37118ce_20231211.zip) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/body7/rtmo_body7.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/rtmo/body7/rtmo-t_8xb32-600e_body7-416x416.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: &id001\n    - RTMO\n    Training Data: &id002\n    - AI Challenger\n    - COCO\n    - CrowdPose\n    - MPII\n    - sub-JHMDB\n    - Halpe\n    - PoseTrack18\n  Name: rtmo-t_8xb32-600e_body7-416x416\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.574\n      AP@0.5: 0.803\n      AP@0.75: 0.613\n      AR: 0.611\n      AR@0.5: 0.836\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-t_8xb32-600e_body7-416x416-f48f75cb_20231219.pth\n- Config: configs/body_2d_keypoint/rtmo/body7/rtmo-s_8xb32-600e_body7-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmo-s_8xb32-600e_body7-640x640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.686\n      AP@0.5: 0.879\n      AP@0.75: 0.744\n      AR: 0.723\n      AR@0.5: 0.908\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_body7-640x640-dac2bf74_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/body7/rtmo-m_16xb16-600e_body7-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmo-m_16xb16-600e_body7-640x640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.726\n      AP@0.5: 0.899\n      AP@0.75: 0.790\n      AR: 0.763\n      AR@0.5: 0.926\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_body7-640x640-39e78cc4_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/body7/rtmo-l_16xb16-600e_body7-640x640.py\n  In Collection: RTMO\n  Alias: rtmo\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmo-l_16xb16-600e_body7-640x640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.748\n      AP@0.5: 0.911\n      AP@0.75: 0.813\n      AR: 0.786\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_body7-640x640-b37118ce_20231211.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/coco/rtmo-l_16xb16-600e_coco-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_coco)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 1.0\ndeepen_factor = 1.0\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_l_8x8_300e_coco/yolox_l_8x8_300e_coco'\n            '_20211126_140236-d3bd2b23.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[256, 512, 1024],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=512,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=512,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=512,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-2,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/coco/rtmo-m_16xb16-600e_coco-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_coco)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.75\ndeepen_factor = 0.67\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'pretrained_models/yolox_m_8x8_300e_coco_20230829.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[192, 384, 768],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=384,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=384,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=384,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-2,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/coco/rtmo-s_8xb32-600e_coco-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=600, val_interval=20, dynamic_intervals=[(580, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=40, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=280, end=281),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=281,\n        T_max=300,\n        end=580,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=580, end=600),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/coco.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_coco)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            280: {\n                'proxy_target_cc': True,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.5\ndeepen_factor = 0.33\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_s_8x8_300e_coco/yolox_s_8x8_300e_coco_'\n            '20211121_095711-4592a793.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[128, 256, 512],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=256,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=17,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=256,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile),\n            use_keypoints_for_center=True),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=256,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1.0,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/coco/rtmo_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2312.07526\">RTMO</a></summary>\n\n```bibtex\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [RTMO-s](/configs/body_2d_keypoint/rtmo/coco/rtmo-s_8xb32-600e_coco-640x640.py) |  640x640   | 0.677 |      0.878      |      0.737      | 0.715 |      0.908      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_coco-640x640-8db55a59_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_coco-640x640_20231211.json) |\n| [RTMO-m](/configs/body_2d_keypoint/rtmo/coco/rtmo-m_16xb16-600e_coco-640x640.py) |  640x640   | 0.709 |      0.890      |      0.778      | 0.747 |      0.920      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_coco-640x640-6f4e0306_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_coco-640x640_20231211.json) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/coco/rtmo-l_16xb16-600e_coco-640x640.py) |  640x640   | 0.724 |      0.899      |      0.788      | 0.762 |      0.927      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_coco-640x640-516a421f_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_coco-640x640_20231211.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/coco/rtmo_coco.yml",
    "content": "Collections:\n- Name: RTMO\n  Paper:\n    Title: 'RTMO: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation'\n    URL: https://arxiv.org/abs/2312.07526\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/rtmo.md\nModels:\n- Config: configs/body_2d_keypoint/rtmo/coco/rtmo-s_8xb32-600e_coco-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: &id001\n    - RTMO\n    Training Data: CrowdPose\n  Name: rtmo-s_8xb32-600e_coco-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.673\n      AP@0.5: 0.878\n      AP@0.75: 0.737\n      AR: 0.715\n      AR@0.5: 0.908\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_coco-640x640-8db55a59_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/coco/rtmo-m_16xb16-600e_coco-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: rtmo-m_16xb16-600e_coco-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.709\n      AP@0.5: 0.890\n      AP@0.75: 0.778\n      AR: 0.747\n      AR@0.5: 0.920\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_coco-640x640-6f4e0306_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/coco/rtmo-l_16xb16-600e_coco-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: rtmo-l_16xb16-600e_coco-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.724\n      AP@0.5: 0.899\n      AP@0.75: 0.788\n      AR: 0.762\n      AR@0.5: 0.927\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_coco-640x640-516a421f_20231211.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_body7-crowdpose-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=700, val_interval=50, dynamic_intervals=[(670, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=50, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=350,\n        end=349,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=349, end=350),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=350,\n        T_max=320,\n        end=670,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=670, end=700),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/crowdpose.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\n# data settings\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# mapping\naic_crowdpose = [(3, 0), (0, 1), (4, 2), (1, 3), (5, 4), (2, 5),\n                 (9, 6), (6, 7), (10, 8), (7, 9), (11, 10), (8, 11), (12, 12),\n                 (13, 13)]\n\ncoco_crowdpose = [\n    (5, 0),\n    (6, 1),\n    (7, 2),\n    (8, 3),\n    (9, 4),\n    (10, 5),\n    (11, 6),\n    (12, 7),\n    (13, 8),\n    (14, 9),\n    (15, 10),\n    (16, 11),\n]\n\nmpii_crowdpose = [\n    (13, 0),\n    (12, 1),\n    (14, 2),\n    (11, 3),\n    (15, 4),\n    (10, 5),\n    (3, 6),\n    (2, 7),\n    (4, 8),\n    (1, 9),\n    (5, 10),\n    (0, 11),\n    (9, 12),\n    (7, 13),\n]\n\njhmdb_crowdpose = [(4, 0), (3, 1), (8, 2), (7, 3), (12, 4), (11, 5), (6, 6),\n                   (5, 7), (10, 8), (9, 9), (14, 10), (13, 11), (2, 12),\n                   (0, 13)]\n\nhalpe_crowdpose = [\n    (5, 0),\n    (6, 1),\n    (7, 2),\n    (8, 3),\n    (9, 4),\n    (10, 5),\n    (11, 6),\n    (12, 7),\n    (13, 8),\n    (14, 9),\n    (15, 10),\n    (16, 11),\n]\n\nposetrack_crowdpose = [\n    (5, 0),\n    (6, 1),\n    (7, 2),\n    (8, 3),\n    (9, 4),\n    (10, 5),\n    (11, 6),\n    (12, 7),\n    (13, 8),\n    (14, 9),\n    (15, 10),\n    (16, 11),\n    (2, 12),\n    (1, 13),\n]\n\n# train datasets\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=14, mapping=coco_crowdpose)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=14, mapping=aic_crowdpose)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=14,\n            mapping=[(i, i) for i in range(14)])\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=14, mapping=mpii_crowdpose)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=14,\n            mapping=jhmdb_crowdpose)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=14,\n            mapping=halpe_crowdpose)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=14,\n            mapping=posetrack_crowdpose)\n    ],\n)\n\ntrain_dataset_stage1 = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file=metafile),\n    datasets=[\n        dataset_coco,\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_halpe,\n        dataset_posetrack,\n    ],\n    sample_ratio_factor=[1, 0.3, 1, 0.3, 0.3, 0.4, 0.3],\n    test_mode=False,\n    pipeline=train_pipeline_stage1)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=train_dataset_stage1)\n\n# val datasets\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CrowdPoseDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    score_mode='bbox',\n    nms_mode='none',\n    iou_type='keypoints_crowd',\n    prefix='crowdpose',\n    use_area=False,\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=30,\n        new_train_dataset=dataset_crowdpose,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            350: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 1.0\ndeepen_factor = 1.0\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_l_8x8_300e_coco/yolox_l_8x8_300e_coco'\n            '_20211126_140236-d3bd2b23.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[256, 512, 1024],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=512,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=14,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=512,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=512,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-3,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_crowdpose-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=700, val_interval=50, dynamic_intervals=[(670, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=50, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=350,\n        end=349,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=349, end=350),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=350,\n        T_max=320,\n        end=670,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=670, end=700),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/crowdpose.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.2,\n        rotate_factor=30,\n        scale_factor=(0.5, 1.5),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.6, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# train datasets\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_crowdpose)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CrowdPoseDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    score_mode='bbox',\n    nms_mode='none',\n    iou_type='keypoints_crowd',\n    prefix='crowdpose',\n    use_area=False,\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=30,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            350: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 1.0\ndeepen_factor = 1.0\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_l_8x8_300e_coco/yolox_l_8x8_300e_coco'\n            '_20211126_140236-d3bd2b23.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[256, 512, 1024],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=512,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=14,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=512,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=512,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-3,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/crowdpose/rtmo-m_16xb16-700e_crowdpose-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=700, val_interval=50, dynamic_intervals=[(670, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=50, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=350,\n        end=349,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=349, end=350),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=350,\n        T_max=320,\n        end=670,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=670, end=700),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/crowdpose.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.2,\n        rotate_factor=30,\n        scale_factor=(0.5, 1.5),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.6, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# train datasets\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_crowdpose)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CrowdPoseDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    score_mode='bbox',\n    nms_mode='none',\n    iou_type='keypoints_crowd',\n    prefix='crowdpose',\n    use_area=False,\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=30,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            350: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.75\ndeepen_factor = 0.67\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'pretrained_models/yolox_m_8x8_300e_coco_20230829.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[192, 384, 768],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=384,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=14,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=384,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=384,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-3,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/crowdpose/rtmo-s_8xb32-700e_crowdpose-640x640.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=700, val_interval=50, dynamic_intervals=[(670, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=50, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    constructor='ForceDefaultOptimWrapperConstructor',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n        force_default_settings=True,\n        custom_keys=dict({'neck.encoder': dict(lr_mult=0.05)})),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=350,\n        end=349,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    # this scheduler is used to increase the lr from 2e-4 to 5e-4\n    dict(type='ConstantLR', by_epoch=True, factor=2.5, begin=349, end=350),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=350,\n        T_max=320,\n        end=670,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=670, end=700),\n]\n\n# data\ninput_size = (640, 640)\nmetafile = 'configs/_base_/datasets/crowdpose.py'\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.2,\n        rotate_factor=30,\n        scale_factor=(0.5, 1.5),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.6, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='BottomupGetHeatmapMask', get_invalid=True),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\n# train datasets\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_crowdpose)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CrowdPoseDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    score_mode='bbox',\n    nms_mode='none',\n    iou_type='keypoints_crowd',\n    prefix='crowdpose',\n    use_area=False,\n)\ntest_evaluator = val_evaluator\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=30,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(\n        type='RTMOModeSwitchHook',\n        epoch_attributes={\n            350: {\n                'proxy_target_cc': True,\n                'overlaps_power': 1.0,\n                'loss_cls.loss_weight': 2.0,\n                'loss_mle.loss_weight': 5.0,\n                'loss_oks.loss_weight': 10.0\n            },\n        },\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n\n# model\nwiden_factor = 0.5\ndeepen_factor = 0.33\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_s_8x8_300e_coco/yolox_s_8x8_300e_coco_'\n            '20211121_095711-4592a793.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='HybridEncoder',\n        in_channels=[128, 256, 512],\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        hidden_dim=256,\n        output_indices=[1, 2],\n        encoder_cfg=dict(\n            self_attn_cfg=dict(embed_dims=256, num_heads=8, dropout=0.0),\n            ffn_cfg=dict(\n                embed_dims=256,\n                feedforward_channels=1024,\n                ffn_drop=0.0,\n                act_cfg=dict(type='GELU'))),\n        projector=dict(\n            type='ChannelMapper',\n            in_channels=[256, 256],\n            kernel_size=1,\n            out_channels=256,\n            act_cfg=None,\n            norm_cfg=dict(type='BN'),\n            num_outs=2)),\n    head=dict(\n        type='RTMOHead',\n        num_keypoints=14,\n        featmap_strides=(16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            cls_feat_channels=256,\n            channels_per_group=36,\n            pose_vec_channels=256,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        assigner=dict(\n            type='SimOTAAssigner',\n            dynamic_k_indicator='oks',\n            oks_calculator=dict(type='PoseOKS', metainfo=metafile)),\n        prior_generator=dict(\n            type='MlvlPointGenerator',\n            centralize_points=True,\n            strides=[16, 32]),\n        dcc_cfg=dict(\n            in_channels=256,\n            feat_channels=128,\n            num_bins=(192, 256),\n            spe_channels=128,\n            gau_cfg=dict(\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.0,\n                drop_path=0.0,\n                act_fn='SiLU',\n                pos_enc='add')),\n        overlaps_power=0.5,\n        loss_cls=dict(\n            type='VariFocalLoss',\n            reduction='sum',\n            use_target_weight=True,\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo=metafile,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_mle=dict(\n            type='MLECCLoss',\n            use_target_weight=True,\n            loss_weight=1e-3,\n        ),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        input_size=input_size,\n        score_thr=0.1,\n        nms_thr=0.65,\n    ))\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/crowdpose/rtmo_crowdpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2312.07526\">RTMO</a></summary>\n\n```bibtex\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\nResults on COCO val2017\n\n| Arch                                           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                      ckpt                      |                      log                      |\n| :--------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :--------------------------------------------: | :-------------------------------------------: |\n| [RTMO-s](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-s_8xb32-700e_crowdpose-640x640.py) |  640x640   | 0.673 |      0.882      |      0.729      | 0.737  | 0.682  | 0.591  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-700e_crowdpose-640x640-79f81c0d_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-700e_crowdpose-640x640_20231211.json) |\n| [RTMO-m](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-m_16xb16-700e_crowdpose-640x640.py) |  640x640   | 0.711 |      0.897      |      0.771      | 0.774  | 0.719  | 0.634  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rrtmo-m_16xb16-700e_crowdpose-640x640-0eaf670d_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-700e_crowdpose-640x640_20231211.json) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_crowdpose-640x640.py) |  640x640   | 0.732 |      0.907      |      0.793      | 0.792  | 0.741  | 0.653  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_crowdpose-640x640-1008211f_20231211.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_crowdpose-640x640_20231211.json) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_body7-crowdpose-640x640.py)\\* |  640x640   | 0.838 |      0.947      |      0.893      | 0.888  | 0.847  | 0.772  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_body7-crowdpose-640x640-5bafdc11_20231219.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_body7-crowdpose-640x640_20231219.json) |\n\n\\* indicates the model is trained using a combined dataset composed of AI Challenger, COCO, CrowdPose, Halpe, MPII, PoseTrack18 and sub-JHMDB.\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmo/crowdpose/rtmo_crowdpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/rtmo/crowdpose/rtmo-s_8xb32-700e_crowdpose-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: &id001\n    - RTMO\n    Training Data: CrowdPose\n  Name: rtmo-s_8xb32-700e_crowdpose-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.673\n      AP@0.5: 0.882\n      AP@0.75: 0.729\n      AP (E): 0.737\n      AP (M): 0.682\n      AP (L): 0.591\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-700e_crowdpose-640x640-79f81c0d_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/crowdpose/rtmo-m_16xb16-700e_crowdpose-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: rtmo-m_16xb16-700e_crowdpose-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.711\n      AP@0.5: 0.897\n      AP@0.75: 0.771\n      AP (E): 0.774\n      AP (M): 0.719\n      AP (L): 0.634\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rrtmo-m_16xb16-700e_crowdpose-640x640-0eaf670d_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_crowdpose-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: rtmo-l_16xb16-700e_crowdpose-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.732\n      AP@0.5: 0.907\n      AP@0.75: 0.793\n      AP (E): 0.792\n      AP (M): 0.741\n      AP (L): 0.653\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_crowdpose-640x640-1008211f_20231211.pth\n- Config: configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_body7-crowdpose-640x640.py\n  In Collection: RTMO\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: rtmo-l_16xb16-700e_body7-crowdpose-640x640\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.838\n      AP@0.5: 0.947\n      AP@0.75: 0.893\n      AP (E): 0.888\n      AP (M): 0.847\n      AP (L): 0.772\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_body7-crowdpose-640x640-5bafdc11_20231219.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/README.md",
    "content": "# RTMPose\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency.\nIn order to bridge this gap, we empirically study five aspects that affect the performance of multi-person pose estimation algorithms: paradigm, backbone network, localization algorithm, training strategy, and deployment inference, and present a high-performance real-time multi-person pose estimation framework, **RTMPose**, based on MMPose.\nOur RTMPose-m achieves **75.8% AP** on COCO with **90+ FPS** on an Intel i7-11700 CPU and **430+ FPS** on an NVIDIA GTX 1660 Ti GPU, and RTMPose-l achieves **67.0% AP** on COCO-WholeBody with **130+ FPS**, outperforming existing open-source libraries.\nTo further evaluate RTMPose's capability in critical real-time applications, we also report the performance after deploying on the mobile device.\n\n## Results and Models\n\n### COCO Dataset\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n|       Model        | Input Size |  AP   |  AR   |           Details and Download            |\n| :----------------: | :--------: | :---: | :---: | :---------------------------------------: |\n|     RTMPose-t      |  256x192   | 0.682 | 0.736 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n|     RTMPose-s      |  256x192   | 0.716 | 0.768 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n|     RTMPose-m      |  256x192   | 0.746 | 0.795 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n|     RTMPose-l      |  256x192   | 0.758 | 0.806 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n| RTMPose-t-aic-coco |  256x192   | 0.685 | 0.738 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n| RTMPose-s-aic-coco |  256x192   | 0.722 | 0.772 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n| RTMPose-m-aic-coco |  256x192   | 0.758 | 0.806 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n| RTMPose-l-aic-coco |  256x192   | 0.765 | 0.813 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n| RTMPose-m-aic-coco |  384x288   | 0.770 | 0.816 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n| RTMPose-l-aic-coco |  384x288   | 0.773 | 0.819 | [rtmpose_coco.md](./coco/rtmpose_coco.md) |\n\n### MPII Dataset\n\n|   Model   | Input Size | PCKh@0.5 | PCKh@0.1 |           Details and Download            |\n| :-------: | :--------: | :------: | :------: | :---------------------------------------: |\n| RTMPose-m |  256x256   |  0.907   |  0.348   | [rtmpose_mpii.md](./mpii/rtmpose_mpii.md) |\n\n### CrowdPose Dataset\n\nResults on CrowdPose test with [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) human detector\n\n|   Model   | Input Size |  AP   |  AR   |                   Details and Download                   |\n| :-------: | :--------: | :---: | :---: | :------------------------------------------------------: |\n| RTMPose-m |  256x192   | 0.706 | 0.788 | [rtmpose_crowdpose.md](./crowdpose/rtmpose_crowdpose.md) |\n\n### Human-Art Dataset\n\nResults on Human-Art validation dataset with detector having human AP of 56.2 on Human-Art validation dataset\n\n|   Model   | Input Size |  AP   |  AR   |                 Details and Download                  |\n| :-------: | :--------: | :---: | :---: | :---------------------------------------------------: |\n| RTMPose-s |  256x192   | 0.311 | 0.381 | [rtmpose_humanart.md](./humanart/rtmpose_humanart.md) |\n| RTMPose-m |  256x192   | 0.355 | 0.417 | [rtmpose_humanart.md](./humanart/rtmpose_humanart.md) |\n| RTMPose-l |  256x192   | 0.378 | 0.442 | [rtmpose_humanart.md](./humanart/rtmpose_humanart.md) |\n\nResults on Human-Art validation dataset with ground-truth bounding-box\n\n|   Model   | Input Size |  AP   |  AR   |                 Details and Download                  |\n| :-------: | :--------: | :---: | :---: | :---------------------------------------------------: |\n| RTMPose-s |  256x192   | 0.698 | 0.732 | [rtmpose_humanart.md](./humanart/rtmpose_humanart.md) |\n| RTMPose-m |  256x192   | 0.728 | 0.759 | [rtmpose_humanart.md](./humanart/rtmpose_humanart.md) |\n| RTMPose-l |  256x192   | 0.753 | 0.783 | [rtmpose_humanart.md](./humanart/rtmpose_humanart.md) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb256-420e_body8-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 20\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-body7_210e-256x192-5e9558ef_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_val2017.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=ochuman_coco)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\ntest_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n# default_hooks = dict(\n#     checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = [\n    dict(type='PCKAccuracy', thr=0.1),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb256-420e_body8-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 20\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(288, 384),\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-body7_210e-384x288-b15bc30d_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_val2017.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=ochuman_coco)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\ntest_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n# default_hooks = dict(\n#     checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = [\n    dict(type='PCKAccuracy', thr=0.1),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb512-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=5,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=5,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb512-700e_body8-halpe26-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 20\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-body7_210e-256x192-e0c9327b_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.0,\n            drop_path=0.0,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_val2017.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=ochuman_coco)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\ntest_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n# default_hooks = dict(\n#     checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = [\n    dict(type='PCKAccuracy', thr=0.1),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 20\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(288, 384),\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-body7_210e-384x288-b9bc2b57_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.0,\n            drop_path=0.0,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_val2017.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=ochuman_coco)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\ntest_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n# default_hooks = dict(\n#     checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = [\n    dict(type='PCKAccuracy', thr=0.1),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb512-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb512-700e_body8-halpe26-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\n# backend_args = dict(backend='local')\nbackend_args = dict(\n    backend='petrel',\n    path_mapping=dict({\n        f'{data_root}': 's3://openmmlab/datasets/',\n        f'{data_root}': 's3://openmmlab/datasets/'\n    }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\n# default_hooks = dict(\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-s_8xb1024-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 1024\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.0),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.6, 1.4],\n        rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-s_8xb256-420e_body8-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 20\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.0),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-s_udp-body7_210e-256x192-8c9ccbdb_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_val2017.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=ochuman_coco)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\ntest_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n# default_hooks = dict(\n#     checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = [\n    dict(type='PCKAccuracy', thr=0.1),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-t_8xb1024-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 1024\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-body7_210e-256x192-a3775292_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.6, 1.4],\n        rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-t_8xb256-420e_body8-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 20\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-body7_210e-256x192-a3775292_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\naic_coco = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n]\n\ncrowdpose_coco = [\n    (0, 5),\n    (1, 6),\n    (2, 7),\n    (3, 8),\n    (4, 9),\n    (5, 10),\n    (6, 11),\n    (7, 12),\n    (8, 13),\n    (9, 14),\n    (10, 15),\n    (11, 16),\n]\n\nmpii_coco = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nochuman_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nposetrack_coco = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/person_keypoints_val2017.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=aic_coco)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=crowdpose_coco)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=mpii_coco)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=jhmdb_coco)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=halpe_coco)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(type='KeypointConverter', num_keypoints=17, mapping=ochuman_coco)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=17, mapping=posetrack_coco)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\ntest_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n# default_hooks = dict(\n#     checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\n\ntest_evaluator = [\n    dict(type='PCKAccuracy', thr=0.1),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose-x_8xb256-700e_body8-halpe26-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 20\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose_body8-coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n- Results on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset.\n- `*` denotes model trained on 7 public datasets:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [MS COCO](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n- `Body8` denotes the addition of the [OCHuman](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#ochuman) dataset, in addition to the 7 datasets mentioned above, for evaluation.\n\n|                     Config                     | Input Size | AP<sup><br>(COCO) | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | EPE<sup><br>(Body8) | Params(M) | FLOPS(G) |                     Download                      |\n| :--------------------------------------------: | :--------: | :---------------: | :---------------------: | :-----------------: | :-----------------: | :-------: | :------: | :-----------------------------------------------: |\n| [RTMPose-t\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-t_8xb256-420e_body8-256x192.py) |  256x192   |       65.9        |          91.44          |        63.18        |        19.45        |   3.34    |   0.36   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7_420e-256x192-026a1439_20230504.pth) |\n| [RTMPose-s\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-s_8xb256-420e_body8-256x192.py) |  256x192   |       69.7        |          92.45          |        65.15        |        17.85        |   5.47    |   0.68   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.pth) |\n| [RTMPose-m\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py) |  256x192   |       74.9        |          94.25          |        68.59        |        15.12        |   13.59   |   1.93   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth) |\n| [RTMPose-l\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb256-420e_body8-256x192.py) |  256x192   |       76.7        |          95.08          |        70.14        |        13.79        |   27.66   |   4.16   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.pth) |\n| [RTMPose-m\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-384x288.py) |  384x288   |       76.6        |          94.64          |        70.38        |        13.98        |   13.72   |   4.33   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth) |\n| [RTMPose-l\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb256-420e_body8-384x288.py) |  384x288   |       78.3        |          95.36          |        71.58        |        13.08        |   27.79   |   9.35   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.pth) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose_body8-coco.yml",
    "content": "Collections:\n- Name: RTMPose\n  Paper:\n    Title: \"RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\"\n    URL: https://arxiv.org/abs/2303.07399\n  README: https://github.com/open-mmlab/mmpose/blob/main/projects/rtmpose/README.md\nModels:\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-t_8xb256-420e_body8-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: &id002\n    - AI Challenger\n    - COCO\n    - CrowdPose\n    - MPII\n    - sub-JHMDB\n    - Halpe\n    - PoseTrack18\n  Name: rtmpose-t_8xb256-420e_body8-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      AP: 0.659\n      Mean@0.1: 0.914\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7_420e-256x192-026a1439_20230504.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-s_8xb256-420e_body8-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-s_8xb256-420e_body8-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      AP: 0.697\n      Mean@0.1: 0.925\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py\n  In Collection: RTMPose\n  Alias:\n    - human\n    - body\n    - body17\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb256-420e_body8-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      AP: 0.749\n      Mean@0.1: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb256-420e_body8-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-l_8xb256-420e_body8-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      AP: 0.767\n      Mean@0.1: 0.951\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb256-420e_body8-384x288\n  Results:\n  - Dataset: Body8\n    Metrics:\n      AP: 0.766\n      Mean@0.1: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb256-420e_body8-384x288.py\n  In Collection: RTMPose\n  Alias: rtmpose-l\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-l_8xb256-420e_body8-384x288\n  Results:\n  - Dataset: Body8\n    Metrics:\n      AP: 0.783\n      Mean@0.1: 0.964\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose_body8-halpe26.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://github.com/Fang-Haoshu/Halpe-FullBody/\">AlphaPose (TPAMI'2022)</a></summary>\n\n```bibtex\n@article{alphapose,\n  author = {Fang, Hao-Shu and Li, Jiefeng and Tang, Hongyang and Xu, Chao and Zhu, Haoyi and Xiu, Yuliang and Li, Yong-Lu and Lu, Cewu},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  title = {AlphaPose: Whole-Body Regional Multi-Person Pose Estimation and Tracking in Real-Time},\n  year = {2022}\n}\n```\n\n</details>\n\n- `*` denotes model trained on 7 public datasets:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [MS COCO](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n- `Body8` denotes the addition of the [OCHuman](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#ochuman) dataset, in addition to the 7 datasets mentioned above, for evaluation.\n\n|                              Config                              | Input Size | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params(M) | FLOPS(G) |                              Download                               |\n| :--------------------------------------------------------------: | :--------: | :---------------------: | :-----------------: | :-------: | :------: | :-----------------------------------------------------------------: |\n| [RTMPose-t\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-t_8xb1024-700e_body8-halpe26-256x192.py) |  256x192   |          91.89          |        66.35        |   3.51    |   0.37   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7-halpe26_700e-256x192-6020f8a6_20230605.pth) |\n| [RTMPose-s\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-s_8xb1024-700e_body8-halpe26-256x192.py) |  256x192   |          93.01          |        68.62        |   5.70    |   0.70   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.pth) |\n| [RTMPose-m\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb512-700e_body8-halpe26-256x192.py) |  256x192   |          94.75          |        71.91        |   13.93   |   1.95   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.pth) |\n| [RTMPose-l\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb512-700e_body8-halpe26-256x192.py) |  256x192   |          95.37          |        73.19        |   28.11   |   4.19   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-256x192-2abb7558_20230605.pth) |\n| [RTMPose-m\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb512-700e_body8-halpe26-384x288.py) |  384x288   |          95.15          |        73.56        |   14.06   |   4.37   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-384x288-89e6428b_20230605.pth) |\n| [RTMPose-l\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb512-700e_body8-halpe26-384x288.py) |  384x288   |          95.56          |        74.38        |   28.24   |   9.40   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-384x288-734182ce_20230605.pth) |\n| [RTMPose-x\\*](/configs/body_2d_keypoint/rtmpose/body8/rtmpose-x_8xb256-700e_body8-halpe26-384x288.py) |  384x288   |          95.74          |        74.82        |   50.00   |  17.29   | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-body7_pt-body7-halpe26_700e-384x288-7fb6e239_20230606.pth) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/body8/rtmpose_body8-halpe26.yml",
    "content": "Collections:\n- Name: RTMPose\n  Paper:\n    Title: \"RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\"\n    URL: https://arxiv.org/abs/2303.07399\n  README: https://github.com/open-mmlab/mmpose/blob/main/projects/rtmpose/README.md\nModels:\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-t_8xb1024-700e_body8-halpe26-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: &id002\n    - AI Challenger\n    - COCO\n    - CrowdPose\n    - MPII\n    - sub-JHMDB\n    - Halpe\n    - PoseTrack18\n  Name: rtmpose-t_8xb1024-700e_body8-halpe26-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.919\n      AUC: 0.664\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7-halpe26_700e-256x192-6020f8a6_20230605.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-s_8xb1024-700e_body8-halpe26-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-s_8xb1024-700e_body8-halpe26-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.930\n      AUC: 0.682\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb512-700e_body8-halpe26-256x192.py\n  In Collection: RTMPose\n  Alias:  body26\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb512-700e_body8-halpe26-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.947\n      AUC: 0.719\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb512-700e_body8-halpe26-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-l_8xb512-700e_body8-halpe26-256x192\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.954\n      AUC: 0.732\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-256x192-2abb7558_20230605.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb512-700e_body8-halpe26-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb512-700e_body8-halpe26-384x288\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.952\n      AUC: 0.736\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-384x288-89e6428b_20230605.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-l_8xb512-700e_body8-halpe26-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-l_8xb512-700e_body8-halpe26-384x288\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.956\n      AUC: 0.744\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-384x288-734182ce_20230605.pth\n- Config: configs/body_2d_keypoint/rtmpose/body8/rtmpose-x_8xb256-700e_body8-halpe26-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-x_8xb256-700e_body8-halpe26-384x288\n  Results:\n  - Dataset: Body8\n    Metrics:\n      Mean@0.1: 0.957\n      AUC: 0.748\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-body7_pt-body7-halpe26_700e-384x288-7fb6e239_20230606.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_aic-coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(288, 384),\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128 * 2,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(288, 384),\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128 * 2,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.0),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128 * 2,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # Turn off EMA while training the tiny model\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # Turn off EMA while training the tiny model\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [rtmpose-t](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   | 0.682 |      0.883      |      0.759      | 0.736 |      0.920      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.json) |\n| [rtmpose-s](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   | 0.716 |      0.892      |      0.789      | 0.768 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.json) |\n| [rtmpose-m](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   | 0.746 |      0.899      |      0.817      | 0.795 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.json) |\n| [rtmpose-l](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   | 0.758 |      0.906      |      0.826      | 0.806 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.json) |\n| [rtmpose-t-aic-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_aic-coco-256x192.py) |  256x192   | 0.685 |      0.880      |      0.761      | 0.738 |      0.918      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.json) |\n| [rtmpose-s-aic-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_aic-coco-256x192.py) |  256x192   | 0.722 |      0.892      |      0.794      | 0.772 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.json) |\n| [rtmpose-m-aic-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-256x192.py) |  256x192   | 0.758 |      0.903      |      0.826      | 0.806 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.json) |\n| [rtmpose-l-aic-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_aic-coco-256x192.py) |  256x192   | 0.765 |      0.906      |      0.835      | 0.813 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.json) |\n| [rtmpose-m-aic-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-384x288.py) |  384x288   | 0.770 |      0.908      |      0.833      | 0.816 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-384x288-a62a0b32_20230228.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-384x288-a62a0b32_20230228.json) |\n| [rtmpose-l-aic-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_aic-coco-384x288.py) |  384x288   | 0.773 |      0.907      |      0.835      | 0.819 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-384x288-97d6cb0f_20230228.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-384x288-97d6cb0f_20230228.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/coco/rtmpose_coco.yml",
    "content": "Collections:\n- Name: RTMPose\n  Paper:\n    Title: \"RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\"\n    URL: https://arxiv.org/abs/2303.07399\n  README: https://github.com/open-mmlab/mmpose/blob/main/projects/rtmpose/README.md\nModels:\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: COCO\n  Name: rtmpose-t_8xb256-420e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.682\n      AP@0.5: 0.883\n      AP@0.75: 0.759\n      AR: 0.736\n      AR@0.5: 0.92\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: rtmpose-s_8xb256-420e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.716\n      AP@0.5: 0.892\n      AP@0.75: 0.789\n      AR: 0.768\n      AR@0.5: 0.929\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: rtmpose-m_8xb256-420e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.746\n      AP@0.5: 0.899\n      AP@0.75: 0.817\n      AR: 0.795\n      AR@0.5: 0.935\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: rtmpose-l_8xb256-420e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.758\n      AP@0.5: 0.906\n      AP@0.75: 0.826\n      AR: 0.806\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_aic-coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: &id002\n    - COCO\n    - AI Challenger\n  Name: rtmpose-t_8xb256-420e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.685\n      AP@0.5: 0.88\n      AP@0.75: 0.761\n      AR: 0.738\n      AR@0.5: 0.918\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_aic-coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-s_8xb256-420e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.722\n      AP@0.5: 0.892\n      AP@0.75: 0.794\n      AR: 0.772\n      AR@0.5: 0.929\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb256-420e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.758\n      AP@0.5: 0.903\n      AP@0.75: 0.826\n      AR: 0.806\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_aic-coco-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-l_8xb256-420e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.765\n      AP@0.5: 0.906\n      AP@0.75: 0.835\n      AR: 0.813\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb256-420e_aic-coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.770\n      AP@0.5: 0.908\n      AP@0.75: 0.833\n      AR: 0.816\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-384x288-a62a0b32_20230228.pth\n- Config: configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_aic-coco-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-l_8xb256-420e_aic-coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.773\n      AP@0.5: 0.907\n      AP@0.75: 0.835\n      AR: 0.819\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-384x288-97d6cb0f_20230228.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/crowdpose/rtmpose-m_8xb64-210e_crowdpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 5e-4\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=14,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='crowdpose/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'crowdpose/annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/crowdpose/rtmpose_crowdpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\nResults on CrowdPose test with [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) human detector\n\n| Arch                                           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                      ckpt                      |                      log                      |\n| :--------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :--------------------------------------------: | :-------------------------------------------: |\n| [rtmpose-m](/configs/body_2d_keypoint/rtmpose/crowdpose/rtmpose-m_8xb64-210e_crowdpose-256x192.py) |  256x192   | 0.706 |      0.841      |      0.765      | 0.799  | 0.719  | 0.582  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-crowdpose_pt-aic-coco_210e-256x192-e6192cac_20230224.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-crowdpose_pt-aic-coco_210e-256x192-e6192cac_20230224.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/crowdpose/rtmpose_crowdpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/rtmpose/crowdpose/rtmpose-m_8xb64-210e_crowdpose-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: CrowdPose\n  Name: rtmpose-t_8xb256-420e_coco-256x192\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.706\n      AP@0.5: 0.841\n      AP@0.75: 0.765\n      AP (E): 0.799\n      AP (M): 0.719\n      AP (L): 0.582\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-crowdpose_pt-aic-coco_210e-256x192-e6192cac_20230224.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/humanart/rtmpose-l_8xb256-420e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        # bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        # 'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/humanart/rtmpose-m_8xb256-420e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        # bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        # 'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/humanart/rtmpose-s_8xb256-420e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        # bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        # 'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/humanart/rtmpose-t_8xb256-420e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        # bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        # 'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # Turn off EMA while training the tiny model\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/humanart/rtmpose_humanart.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://idea-research.github.io/HumanArt/\">Human-Art (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ju2023humanart,\n    title={Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes},\n    author={Ju, Xuan and Zeng, Ailing and Jianan, Wang and Qiang, Xu and Lei, Zhang},\n    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR),\n    year={2023}}\n```\n\n</details>\n\nResults on Human-Art validation dataset with detector having human AP of 56.2 on Human-Art validation dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [rtmpose-t-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   | 0.161 |      0.283      |      0.154      | 0.221 |      0.373      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.json) |\n| [rtmpose-t-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-t_8xb256-420e_humanart-256x192.py) |  256x192   | 0.249 |      0.395      |      0.256      | 0.323 |      0.485      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.json) |\n| [rtmpose-s-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   | 0.199 |      0.328      |      0.198      | 0.261 |      0.418      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.json) |\n| [rtmpose-s-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-s_8xb256-420e_humanart-256x192.py) |  256x192   | 0.311 |      0.462      |      0.323      | 0.381 |      0.540      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.json) |\n| [rtmpose-m-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   | 0.239 |      0.372      |      0.243      | 0.302 |      0.455      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.json) |\n| [rtmpose-m-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-m_8xb256-420e_humanart-256x192.py) |  256x192   | 0.355 |      0.503      |      0.377      | 0.417 |      0.568      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.json) |\n| [rtmpose-l-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   | 0.260 |      0.393      |      0.267      | 0.323 |      0.472      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.json) |\n| [rtmpose-l-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-l_8xb256-420e_humanart-256x192.py) |  256x192   | 0.378 |      0.521      |      0.399      | 0.442 |      0.584      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.json) |\n\nResults on Human-Art validation dataset with ground-truth bounding-box\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [rtmpose-t-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   | 0.444 |      0.725      |      0.453      | 0.488 |      0.750      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.json) |\n| [rtmpose-t-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-t_8xb256-420e_humanart-256x192.py) |  256x192   | 0.655 |      0.872      |      0.720      | 0.693 |      0.890      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.json) |\n| [rtmpose-s-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   | 0.480 |      0.739      |      0.498      | 0.521 |      0.763      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.json) |\n| [rtmpose-s-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-s_8xb256-420e_humanart-256x192.py) |  256x192   | 0.698 |      0.893      |      0.768      | 0.732 |      0.903      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.json) |\n| [rtmpose-m-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   | 0.532 |      0.765      |      0.563      | 0.571 |      0.789      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.json) |\n| [rtmpose-m-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-m_8xb256-420e_humanart-256x192.py) |  256x192   | 0.728 |      0.895      |      0.791      | 0.759 |      0.906      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.json) |\n| [rtmpose-l-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   | 0.564 |      0.789      |      0.602      | 0.599 |      0.808      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.json) |\n| [rtmpose-l-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-l_8xb256-420e_humanart-256x192.py) |  256x192   | 0.753 |      0.905      |      0.812      | 0.783 |      0.915      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.json) |\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [rtmpose-t-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   | 0.682 |      0.883      |      0.759      | 0.736 |      0.920      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-coco_pt-aic-coco_420e-256x192-e613ba3f_20230127.json) |\n| [rtmpose-t-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-t_8xb256-420e_humanart-256x192.py) |  256x192   | 0.665 |      0.875      |      0.739      | 0.721 |      0.916      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.json) |\n| [rtmpose-s-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   | 0.716 |      0.892      |      0.789      | 0.768 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.json) |\n| [rtmpose-s-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-s_8xb256-420e_humanart-256x192.py) |  256x192   | 0.706 |      0.888      |      0.780      | 0.759 |      0.928      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.json) |\n| [rtmpose-m-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   | 0.746 |      0.899      |      0.817      | 0.795 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco_pt-aic-coco_420e-256x192-d8dd5ca4_20230127.json) |\n| [rtmpose-m-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-m_8xb256-420e_humanart-256x192.py) |  256x192   | 0.725 |      0.892      |      0.795      | 0.775 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.json) |\n| [rtmpose-l-coco](/configs/body_2d_keypoint/rtmpose/coco/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   | 0.758 |      0.906      |      0.826      | 0.806 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco_pt-aic-coco_420e-256x192-1352a4d2_20230127.json) |\n| [rtmpose-l-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-l_8xb256-420e_humanart-256x192.py) |  256x192   | 0.748 |      0.901      |      0.816      | 0.796 |      0.938      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.json) |\n\nResults on COCO val2017 with ground-truth bounding box\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [rtmpose-t-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-t_8xb256-420e_humanart-256x192.py) |  256x192   | 0.679 |      0.895      |      0.755      | 0.710 |      0.907      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.json) |\n| [rtmpose-s-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-s_8xb256-420e_humanart-256x192.py) |  256x192   | 0.725 |      0.916      |      0.798      | 0.753 |      0.925      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.json) |\n| [rtmpose-m-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-m_8xb256-420e_humanart-256x192.py) |  256x192   | 0.744 |      0.916      |      0.818      | 0.770 |      0.930      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.json) |\n| [rtmpose-l-humanart-coco](/configs/body_2d_keypoint/rtmpose/humanart/rtmpose-l_8xb256-420e_humanart-256x192.py) |  256x192   | 0.770 |      0.927      |      0.840      | 0.794 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/humanart/rtmpose_humanart.yml",
    "content": "Collections:\n- Name: RTMPose\n  Paper:\n    Title: \"RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\"\n    URL: https://arxiv.org/abs/2303.07399\n  README: https://github.com/open-mmlab/mmpose/blob/main/projects/rtmpose/README.md\nModels:\n- Config: configs/body_2d_keypoint/rtmpose/humanart/rtmpose-l_8xb256-420e_humanart-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: &id002\n    - COCO\n    - Human-Art\n  Name: rtmpose-l_8xb256-420e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.748\n      AP@0.5: 0.901\n      AP@0.75: 0.816\n      AR: 0.796\n      AR@0.5: 0.938\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.378\n      AP@0.5: 0.521\n      AP@0.75: 0.399\n      AR: 0.442\n      AR@0.5: 0.584\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.753\n      AP@0.5: 0.905\n      AP@0.75: 0.812\n      AR: 0.783\n      AR@0.5: 0.915\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth\n- Config: configs/body_2d_keypoint/rtmpose/humanart/rtmpose-m_8xb256-420e_humanart-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb256-420e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.725\n      AP@0.5: 0.892\n      AP@0.75: 0.795\n      AR: 0.775\n      AR@0.5: 0.929\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.355\n      AP@0.5: 0.503\n      AP@0.75: 0.377\n      AR: 0.417\n      AR@0.5: 0.568\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.728\n      AP@0.5: 0.895\n      AP@0.75: 0.791\n      AR: 0.759\n      AR@0.5: 0.906\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth\n- Config: configs/body_2d_keypoint/rtmpose/humanart/rtmpose-s_8xb256-420e_humanart-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-s_8xb256-420e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.706\n      AP@0.5: 0.888\n      AP@0.75: 0.780\n      AR: 0.759\n      AR@0.5: 0.928\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.311\n      AP@0.5: 0.462\n      AP@0.75: 0.323\n      AR: 0.381\n      AR@0.5: 0.540\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.698\n      AP@0.5: 0.893\n      AP@0.75: 0.768\n      AR: 0.732\n      AR@0.5: 0.903\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth\n- Config: configs/body_2d_keypoint/rtmpose/humanart/rtmpose-t_8xb256-420e_humanart-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-t_8xb256-420e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.665\n      AP@0.5: 0.875\n      AP@0.75: 0.739\n      AR: 0.721\n      AR@0.5: 0.916\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.249\n      AP@0.5: 0.395\n      AP@0.75: 0.256\n      AR: 0.323\n      AR@0.5: 0.485\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.655\n      AP@0.5: 0.872\n      AP@0.75: 0.720\n      AR: 0.693\n      AR@0.5: 0.890\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/mpii/rtmpose-m_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=16,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/pose/MPI/',\n#         f'{data_root}': 's3://openmmlab/datasets/pose/MPI/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/mpii/rtmpose_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                     | Input Size | Mean / w. flip | Mean@0.1 |                           ckpt                           |                           log                            |\n| :------------------------------------------------------- | :--------: | :------------: | :------: | :------------------------------------------------------: | :------------------------------------------------------: |\n| [rtmpose-m](/configs/body_2d_keypoint/rtmpose/mpii/rtmpose-m_8xb64-210e_mpii-256x256.py) |  256x256   |     0.907      |  0.348   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-mpii_pt-aic-coco_210e-256x256-ec4dbec8_20230206.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-mpii_pt-aic-coco_210e-256x256-ec4dbec8_20230206.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/rtmpose/mpii/rtmpose_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/rtmpose/mpii/rtmpose-m_8xb64-210e_mpii-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: MPII\n  Name: rtmpose-m_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.907\n      Mean@0.1: 0.348\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-mpii_pt-aic-coco_210e-256x256-ec4dbec8_20230206.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/README.md",
    "content": "# Top-down SimCC-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. At the 2nd stage, SimCC  based methods reformulate human pose estimation as two classification tasks for horizontal and vertical coordinates, and uniformly divide each pixel into several bins, thus obtain the keypoint coordinates given the features extracted from the bounding box area, following the paradigm introduced in [SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation](https://arxiv.org/abs/2107.03332).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/189811385-6395d118-055b-4bad-89e8-f84ffa2c2aa6.png\">\n</div>\n\n## Results and Models\n\n### COCO Dataset\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n|             Model             | Input Size |  AP   |  AR   |               Details and Download                |\n| :---------------------------: | :--------: | :---: | :---: | :-----------------------------------------------: |\n|        ResNet-50+SimCC        |  384x288   | 0.735 | 0.790 |      [resnet_coco.md](./coco/resnet_coco.md)      |\n|        ResNet-50+SimCC        |  256x192   | 0.721 | 0.781 |      [resnet_coco.md](./coco/resnet_coco.md)      |\n|  S-ViPNAS-MobileNet-V3+SimCC  |  256x192   | 0.695 | 0.755 |      [vipnas_coco.md](./coco/vipnas_coco.md)      |\n| MobileNet-V2+SimCC(wo/deconv) |  256x192   | 0.620 | 0.678 | [mobilenetv2_coco.md](./coco/mobilenetv2_coco.md) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/mobilenetv2_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.03332\">SimCC (ECCV'2022)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2107.03332,\n  title={SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation},\n  author={Li, Yanjie and Yang, Sen and Liu, Peidong and Zhang, Shoukui and Wang, Yunxiao and Wang, Zhicheng and Yang, Wankou and Xia, Shu-Tao},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [simcc_mobilenetv2_wo_deconv](/configs/body_2d_keypoint/simcc/coco/simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192.py) |  256x192   | 0.620 |      0.855      |      0.697      | 0.678 |      0.902      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192-4b0703bb_20221010.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192-4b0703bb_20221010.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/mobilenetv2_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/simcc/coco/simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192.py\n  In Collection: SimCC\n  Metadata:\n    Architecture: &id001\n    - SimCC\n    - MobilenetV2\n    Training Data: COCO\n  Name: simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.62\n      AP@0.5: 0.855\n      AP@0.75: 0.697\n      AR: 0.678\n      AR@0.5: 0.902\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192-4b0703bb_20221010.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/resnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.03332\">SimCC (ECCV'2022)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2107.03332,\n  title={SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation},\n  author={Li, Yanjie and Yang, Sen and Liu, Peidong and Zhang, Shoukui and Wang, Yunxiao and Wang, Zhicheng and Yang, Wankou and Xia, Shu-Tao},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [simcc_resnet_50](/configs/body_2d_keypoint/simcc/coco/simcc_res50_8xb64-210e_coco-256x192.py) |  256x192   | 0.721 |      0.897      |      0.798      | 0.781 |      0.937      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_res50_8xb64-210e_coco-256x192-8e0f5b59_20220919.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_res50_8xb64-210e_coco-256x192-8e0f5b59_20220919.log.json) |\n| [simcc_resnet_50](/configs/body_2d_keypoint/simcc/coco/simcc_res50_8xb32-140e_coco-384x288.py) |  384x288   | 0.735 |      0.899      |      0.800      | 0.790 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_res50_8xb32-140e_coco-384x288-45c3ba34_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_res50_8xb32-140e_coco-384x288-45c3ba34_20220913.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/resnet_coco.yml",
    "content": "Collections:\n- Name: SimCC\n  Paper:\n    Title: A Simple Coordinate Classification Perspective for Human Pose Estimation\n    URL: https://arxiv.org/abs/2107.03332\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/simcc.md\nModels:\n- Config: configs/body_2d_keypoint/simcc/coco/simcc_res50_8xb64-210e_coco-256x192.py\n  In Collection: SimCC\n  Metadata:\n    Architecture: &id001\n    - SimCC\n    - ResNet\n    Training Data: COCO\n  Name: simcc_res50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.721\n      AP@0.5: 0.900\n      AP@0.75: 0.798\n      AR: 0.781\n      AR@0.5: 0.937\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_res50_8xb64-210e_coco-256x192-8e0f5b59_20220919.pth\n- Config: configs/body_2d_keypoint/simcc/coco/simcc_res50_8xb32-140e_coco-384x288.py\n  In Collection: SimCC\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: simcc_res50_8xb32-140e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.735\n      AP@0.5: 0.899\n      AP@0.75: 0.800\n      AR: 0.790\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_res50_8xb32-140e_coco-384x288-45c3ba34_20220913.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel', input_size=(192, 256), sigma=6.0, simcc_split_ratio=2.0)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='mmcls://mobilenet_v2',\n        )),\n    head=dict(\n        type='SimCCHead',\n        in_channels=1280,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        deconv_out_channels=None,\n        loss=dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/simcc_res50_8xb32-140e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=140, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[90, 120],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel', input_size=(288, 384), sigma=6.0, simcc_split_ratio=2.0)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='SimCCHead',\n        in_channels=2048,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        loss=dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/simcc_res50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(type='MultiStepLR', milestones=[170, 200], gamma=0.1, by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel', input_size=(192, 256), sigma=6.0, simcc_split_ratio=2.0)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='SimCCHead',\n        in_channels=2048,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        loss=dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/simcc_vipnas-mbv3_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel', input_size=(192, 256), sigma=6.0, simcc_split_ratio=2.0)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ViPNAS_MobileNetV3'),\n    head=dict(\n        type='SimCCHead',\n        in_channels=160,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        deconv_type='vipnas',\n        deconv_out_channels=(160, 160, 160),\n        deconv_num_groups=(160, 160, 160),\n        loss=dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=data_root + 'person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/vipnas_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.03332\">SimCC (ECCV'2022)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2107.03332,\n  title={SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation},\n  author={Li, Yanjie and Yang, Sen and Liu, Peidong and Zhang, Shoukui and Wang, Yunxiao and Wang, Zhicheng and Yang, Wankou and Xia, Shu-Tao},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2105.10154\">ViPNAS (CVPR'2021)</a></summary>\n\n```bibtex\n@article{xu2021vipnas,\n  title={ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search},\n  author={Xu, Lumin and Guan, Yingda and Jin, Sheng and Liu, Wentao and Qian, Chen and Luo, Ping and Ouyang, Wanli and Wang, Xiaogang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [simcc_S-ViPNAS-MobileNetV3](/configs/body_2d_keypoint/simcc/coco/simcc_vipnas-mbv3_8xb64-210e_coco-256x192.py) |  256x192   | 0.695 |      0.883      |      0.772      | 0.755 |      0.927      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_vipnas-mbv3_8xb64-210e_coco-256x192-719f3489_20220922.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_vipnas-mbv3_8xb64-210e_coco-256x192-719f3489_20220922.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/coco/vipnas_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/simcc/coco/simcc_vipnas-mbv3_8xb64-210e_coco-256x192.py\n  In Collection: SimCC\n  Metadata:\n    Architecture: &id001\n    - SimCC\n    - ViPNAS\n    Training Data: COCO\n  Name: simcc_vipnas-mbv3_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.695\n      AP@0.5: 0.883\n      AP@0.75: 0.772\n      AR: 0.755\n      AR@0.5: 0.927\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/simcc/coco/simcc_vipnas-mbv3_8xb64-210e_coco-256x192-719f3489_20220922.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/simcc/mpii/simcc_res50_wo-deconv-8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel', input_size=(256, 256), sigma=6.0, simcc_split_ratio=2.0)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='SimCCHead',\n        in_channels=2048,\n        out_channels=16,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        deconv_out_channels=None,\n        loss=dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/README.md",
    "content": "# Top-down heatmap-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. Instead of estimating keypoint coordinates directly, the pose estimator will produce heatmaps which represent the likelihood of being a keypoint, following the paradigm introduced in [Simple Baselines for Human Pose Estimation and Tracking](http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\" height=400>\n</div>\n\n## Results and Models\n\n### COCO Dataset\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n|      Model      | Input Size |  AP   |  AR   |                Details and Download                 |\n| :-------------: | :--------: | :---: | :---: | :-------------------------------------------------: |\n|    ViTPose-h    |  256x192   | 0.790 | 0.840 |      [vitpose_coco.md](./coco/vitpose_coco.md)      |\n|  HRNet-w48+UDP  |  256x192   | 0.768 | 0.817 |    [hrnet_udp_coco.md](./coco/hrnet_udp_coco.md)    |\n|   MSPN 4-stg    |  256x192   | 0.765 | 0.826 |         [mspn_coco.md](./coco/mspn_coco.md)         |\n| HRNet-w48+Dark  |  256x192   | 0.764 | 0.814 |   [hrnet_dark_coco.md](./coco/hrnet_dark_coco.md)   |\n|    HRNet-w48    |  256x192   | 0.756 | 0.809 |        [hrnet_coco.md](./coco/hrnet_coco.md)        |\n|   HRFormer-B    |  256x192   | 0.754 | 0.807 |     [hrformer_coco.md](./coco/hrformer_coco.md)     |\n|    RSN-50-3x    |  256x192   | 0.750 | 0.814 |          [rsn_coco.md](./coco/rsn_coco.md)          |\n|    CSPNeXt-l    |  256x192   | 0.750 | 0.800 |  [cspnext_udp_coco.md](./coco/cspnext_udp_coco.md)  |\n|    HRNet-w32    |  256x192   | 0.749 | 0.804 |        [hrnet_coco.md](./coco/hrnet_coco.md)        |\n|     Swin-L      |  256x192   | 0.743 | 0.798 |         [swin_coco.md](./coco/swin_coco.md)         |\n|    ViTPose-s    |  256x192   | 0.739 | 0.792 |      [vitpose_coco.md](./coco/vitpose_coco.md)      |\n|   HRFormer-S    |  256x192   | 0.738 | 0.793 |     [hrformer_coco.md](./coco/hrformer_coco.md)     |\n|     Swin-B      |  256x192   | 0.737 | 0.794 |         [swin_coco.md](./coco/swin_coco.md)         |\n|  SEResNet-101   |  256x192   | 0.734 | 0.790 |     [seresnet_coco.md](./coco/seresnet_coco.md)     |\n|    SCNet-101    |  256x192   | 0.733 | 0.789 |        [scnet_coco.md](./coco/scnet_coco.md)        |\n| ResNet-101+Dark |  256x192   | 0.733 | 0.786 |  [resnet_dark_coco.md](./coco/resnet_dark_coco.md)  |\n|    CSPNeXt-m    |  256x192   | 0.732 | 0.785 |  [cspnext_udp_coco.md](./coco/cspnext_udp_coco.md)  |\n|  ResNetV1d-101  |  256x192   | 0.732 | 0.785 |    [resnetv1d_coco.md](./coco/resnetv1d_coco.md)    |\n|   SEResNet-50   |  256x192   | 0.729 | 0.784 |     [seresnet_coco.md](./coco/seresnet_coco.md)     |\n|    SCNet-50     |  256x192   | 0.728 | 0.784 |        [scnet_coco.md](./coco/scnet_coco.md)        |\n|   ResNet-101    |  256x192   | 0.726 | 0.783 |       [resnet_coco.md](./coco/resnet_coco.md)       |\n|   ResNeXt-101   |  256x192   | 0.726 | 0.781 |      [resnext_coco.md](./coco/resnext_coco.md)      |\n|  HourglassNet   |  256x256   | 0.726 | 0.780 |    [hourglass_coco.md](./coco/hourglass_coco.md)    |\n|   ResNeSt-101   |  256x192   | 0.725 | 0.781 |      [resnest_coco.md](./coco/resnest_coco.md)      |\n|     RSN-50      |  256x192   | 0.724 | 0.790 |          [rsn_coco.md](./coco/rsn_coco.md)          |\n|     Swin-T      |  256x192   | 0.724 | 0.782 |         [swin_coco.md](./coco/swin_coco.md)         |\n|   MSPN 1-stg    |  256x192   | 0.723 | 0.788 |         [mspn_coco.md](./coco/mspn_coco.md)         |\n|  ResNetV1d-50   |  256x192   | 0.722 | 0.777 |    [resnetv1d_coco.md](./coco/resnetv1d_coco.md)    |\n|   ResNeSt-50    |  256x192   | 0.720 | 0.775 |      [resnest_coco.md](./coco/resnest_coco.md)      |\n|    ResNet-50    |  256x192   | 0.718 | 0.774 |       [resnet_coco.md](./coco/resnet_coco.md)       |\n|   ResNeXt-50    |  256x192   | 0.715 | 0.771 |      [resnext_coco.md](./coco/resnext_coco.md)      |\n|      PVT-S      |  256x192   | 0.714 | 0.773 |          [pvt_coco.md](./coco/pvt_coco.md)          |\n|    CSPNeXt-s    |  256x192   | 0.697 | 0.753 |  [cspnext_udp_coco.md](./coco/cspnext_udp_coco.md)  |\n|  LiteHRNet-30   |  256x192   | 0.676 | 0.736 |    [litehrnet_coco.md](./coco/litehrnet_coco.md)    |\n|  CSPNeXt-tiny   |  256x192   | 0.665 | 0.723 |  [cspnext_udp_coco.md](./coco/cspnext_udp_coco.md)  |\n|  MobileNet-v2   |  256x192   | 0.648 | 0.709 |  [mobilenetv2_coco.md](./coco/mobilenetv2_coco.md)  |\n|  LiteHRNet-18   |  256x192   | 0.642 | 0.705 |    [litehrnet_coco.md](./coco/litehrnet_coco.md)    |\n|       CPM       |  256x192   | 0.627 | 0.689 |          [cpm_coco.md](./coco/cpm_coco.md)          |\n|  ShuffleNet-v2  |  256x192   | 0.602 | 0.668 | [shufflenetv2_coco.md](./coco/shufflenetv2_coco.md) |\n|  ShuffleNet-v1  |  256x192   | 0.587 | 0.654 | [shufflenetv1_coco.md](./coco/shufflenetv1_coco.md) |\n|     AlexNet     |  256x192   | 0.448 | 0.521 |      [alexnet_coco.md](./coco/alexnet_coco.md)      |\n\n### MPII Dataset\n\n|     Model      | Input Size | PCKh@0.5 | PCKh@0.1 |                Details and Download                 |\n| :------------: | :--------: | :------: | :------: | :-------------------------------------------------: |\n| HRNet-w48+Dark |  256x256   |  0.905   |  0.360   |   [hrnet_dark_mpii.md](./mpii/hrnet_dark_mpii.md)   |\n|   HRNet-w48    |  256x256   |  0.902   |  0.303   |     [hrnet_mpii.md](./mpii/cspnext_udp_mpii.md)     |\n|   HRNet-w48    |  256x256   |  0.901   |  0.337   |        [hrnet_mpii.md](./mpii/hrnet_mpii.md)        |\n|   HRNet-w32    |  256x256   |  0.900   |  0.334   |        [hrnet_mpii.md](./mpii/hrnet_mpii.md)        |\n|  HourglassNet  |  256x256   |  0.889   |  0.317   |    [hourglass_mpii.md](./mpii/hourglass_mpii.md)    |\n|   ResNet-152   |  256x256   |  0.889   |  0.303   |       [resnet_mpii.md](./mpii/resnet_mpii.md)       |\n| ResNetV1d-152  |  256x256   |  0.888   |  0.300   |    [resnetv1d_mpii.md](./mpii/resnetv1d_mpii.md)    |\n|    SCNet-50    |  256x256   |  0.888   |  0.290   |        [scnet_mpii.md](./mpii/scnet_mpii.md)        |\n|  ResNeXt-152   |  256x256   |  0.887   |  0.294   |      [resnext_mpii.md](./mpii/resnext_mpii.md)      |\n|  SEResNet-50   |  256x256   |  0.884   |  0.292   |     [seresnet_mpii.md](./mpii/seresnet_mpii.md)     |\n|   ResNet-50    |  256x256   |  0.882   |  0.286   |       [resnet_mpii.md](./mpii/resnet_mpii.md)       |\n|  ResNetV1d-50  |  256x256   |  0.881   |  0.290   |    [resnetv1d_mpii.md](./mpii/resnetv1d_mpii.md)    |\n|      CPM       | 368x368\\*  |  0.876   |  0.285   |          [cpm_mpii.md](./mpii/cpm_mpii.md)          |\n|  LiteHRNet-30  |  256x256   |  0.869   |  0.271   |    [litehrnet_mpii.md](./mpii/litehrnet_mpii.md)    |\n|  LiteHRNet-18  |  256x256   |  0.859   |  0.260   |    [litehrnet_mpii.md](./mpii/litehrnet_mpii.md)    |\n|  MobileNet-v2  |  256x256   |  0.854   |  0.234   |  [mobilenetv2_mpii.md](./mpii/mobilenetv2_mpii.md)  |\n| ShuffleNet-v2  |  256x256   |  0.828   |  0.205   | [shufflenetv2_mpii.md](./mpii/shufflenetv2_mpii.md) |\n| ShuffleNet-v1  |  256x256   |  0.824   |  0.195   | [shufflenetv1_mpii.md](./mpii/shufflenetv1_mpii.md) |\n\n### CrowdPose Dataset\n\nResults on CrowdPose test with [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) human detector\n\n|   Model    | Input Size |  AP   |  AR   |                    Details and Download                    |\n| :--------: | :--------: | :---: | :---: | :--------------------------------------------------------: |\n| HRNet-w32  |  256x192   | 0.675 | 0.816 |    [hrnet_crowdpose.md](./crowdpose/hrnet_crowdpose.md)    |\n| CSPNeXt-m  |  256x192   | 0.662 | 0.755 | [hrnet_crowdpose.md](./crowdpose/cspnext_udp_crowdpose.md) |\n| ResNet-101 |  256x192   | 0.647 | 0.800 |   [resnet_crowdpose.md](./crowdpose/resnet_crowdpose.md)   |\n| HRNet-w32  |  256x192   | 0.637 | 0.785 |   [resnet_crowdpose.md](./crowdpose/resnet_crowdpose.md)   |\n\n### AIC Dataset\n\nResults on AIC val set with ground-truth bounding boxes.\n\n|   Model    | Input Size |  AP   |  AR   |         Details and Download         |\n| :--------: | :--------: | :---: | :---: | :----------------------------------: |\n| HRNet-w32  |  256x192   | 0.323 | 0.366 |  [hrnet_aic.md](./aic/hrnet_aic.md)  |\n| ResNet-101 |  256x192   | 0.294 | 0.337 | [resnet_aic.md](./aic/resnet_aic.md) |\n\n### JHMDB Dataset\n\n|   Model   | Input Size | PCK(norm. by person size) | PCK (norm. by torso size) |            Details and Download            |\n| :-------: | :--------: | :-----------------------: | :-----------------------: | :----------------------------------------: |\n| ResNet-50 |  256x256   |           96.0            |           80.1            | [resnet_jhmdb.md](./jhmdb/resnet_jhmdb.md) |\n|    CPM    |  368x368   |           89.8            |           65.7            |    [cpm_jhmdb.md](./jhmdb/cpm_jhmdb.md)    |\n\n### PoseTrack2018 Dataset\n\nResults on PoseTrack2018 val with ground-truth bounding boxes.\n\n|   Model   | Input Size |  AP  |                     Details and Download                     |\n| :-------: | :--------: | :--: | :----------------------------------------------------------: |\n| HRNet-w48 |  256x192   | 84.6 |  [hrnet_posetrack18.md](./posetrack18/hrnet_posetrack18.md)  |\n| HRNet-w32 |  256x192   | 83.4 |  [hrnet_posetrack18.md](./posetrack18/hrnet_posetrack18.md)  |\n| ResNet-50 |  256x192   | 81.2 | [resnet_posetrack18.md](./posetrack18/resnet_posetrack18.md) |\n\n### Human-Art Dataset\n\nResults on Human-Art validation dataset with detector having human AP of 56.2 on Human-Art validation dataset\n\n|   Model   | Input Size |  AP   |  AR   |                 Details and Download                  |\n| :-------: | :--------: | :---: | :---: | :---------------------------------------------------: |\n| ViTPose-s |  256x192   | 0.381 | 0.448 | [vitpose_humanart.md](./humanart/vitpose_humanart.md) |\n| ViTPose-b |  256x192   | 0.410 | 0.475 | [vitpose_humanart.md](./humanart/vitpose_humanart.md) |\n\nResults on Human-Art validation dataset with ground-truth bounding-box\n\n|   Model   | Input Size |  AP   |  AR   |                 Details and Download                  |\n| :-------: | :--------: | :---: | :---: | :---------------------------------------------------: |\n| ViTPose-s |  256x192   | 0.738 | 0.768 | [vitpose_humanart.md](./humanart/vitpose_humanart.md) |\n| ViTPose-b |  256x192   | 0.759 | 0.790 | [vitpose_humanart.md](./humanart/vitpose_humanart.md) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/aic/hrnet_aic.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n\nResults on AIC val set with ground-truth bounding boxes\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/aic/td-hm_hrnet-w32_8xb64-210e_aic-256x192.py) |  256x192   | 0.323 |      0.761      |      0.218      | 0.366 |      0.789      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192-30a4e465_20200826.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192_20200826.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/aic/hrnet_aic.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/aic/td-hm_hrnet-w32_8xb64-210e_aic-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture:\n    - HRNet\n    Training Data: AI Challenger\n  Name: td-hm_hrnet-w32_8xb64-210e_aic-256x192\n  Results:\n  - Dataset: AI Challenger\n    Metrics:\n      AP: 0.323\n      AP@0.5: 0.761\n      AP@0.75: 0.218\n      AR: 0.366\n      AR@0.5: 0.789\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_aic_256x192-30a4e465_20200826.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/aic/resnet_aic.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n\nResults on AIC val set with ground-truth bounding boxes\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_101](/configs/body_2d_keypoint/topdown_heatmap/aic/td-hm_res101_8xb64-210e_aic-256x192.py) |  256x192   | 0.294 |      0.736      |      0.172      | 0.337 |      0.762      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res101_aic_256x192-79b35445_20200826.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res101_aic_256x192_20200826.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/aic/resnet_aic.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/aic/td-hm_res101_8xb64-210e_aic-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: AI Challenger\n  Name: td-hm_res101_8xb64-210e_aic-256x192\n  Results:\n  - Dataset: AI Challenger\n    Metrics:\n      AP: 0.294\n      AP@0.5: 0.736\n      AP@0.75: 0.172\n      AR: 0.337\n      AR@0.5: 0.762\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res101_aic_256x192-79b35445_20200826.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/aic/td-hm_hrnet-w32_8xb64-210e_aic-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=14,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AicDataset'\ndata_mode = 'topdown'\ndata_root = 'data/aic/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/aic_train.json',\n        data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                         'keypoint_train_images_20170902/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/aic_val.json',\n        data_prefix=dict(img='ai_challenger_keypoint_validation_20170911/'\n                         'keypoint_validation_images_20170911/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/aic_val.json',\n    use_area=False)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/aic/td-hm_res101_8xb64-210e_aic-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=14,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AicDataset'\ndata_mode = 'topdown'\ndata_root = 'data/aic/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/aic_train.json',\n        data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                         'keypoint_train_images_20170902/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/aic_val.json',\n        data_prefix=dict(img='ai_challenger_keypoint_validation_20170911/'\n                         'keypoint_validation_images_20170911/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/aic_val.json',\n    use_area=False)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/alexnet_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://proceedings.neurips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf\">AlexNet (NeurIPS'2012)</a></summary>\n\n```bibtex\n@inproceedings{krizhevsky2012imagenet,\n  title={Imagenet classification with deep convolutional neural networks},\n  author={Krizhevsky, Alex and Sutskever, Ilya and Hinton, Geoffrey E},\n  booktitle={Advances in neural information processing systems},\n  pages={1097--1105},\n  year={2012}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_alexnet](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_alexnet_8xb64-210e_coco-256x192.py) |  256x192   | 0.448 |      0.767      |      0.461      | 0.521 |      0.829      | [ckpt](https://download.openmmlab.com/mmpose/top_down/alexnet/alexnet_coco_256x192-a7b1fd15_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/alexnet/alexnet_coco_256x192_20200727.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/alexnet_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_alexnet_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - AlexNet\n    Training Data: COCO\n  Name: td-hm_alexnet_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.448\n      AP@0.5: 0.767\n      AP@0.75: 0.461\n      AR: 0.521\n      AR@0.5: 0.829\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/alexnet/alexnet_coco_256x192-a7b1fd15_20200727.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cpm_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Wei_Convolutional_Pose_Machines_CVPR_2016_paper.html\">CPM (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{wei2016convolutional,\n  title={Convolutional pose machines},\n  author={Wei, Shih-En and Ramakrishna, Varun and Kanade, Takeo and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={4724--4732},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [cpm](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192.py) |  256x192   | 0.627 |      0.862      |      0.709      | 0.689 |      0.906      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192-0e978875_20220920.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192_20220920.log) |\n| [cpm](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288.py) |  384x288   | 0.652 |      0.865      |      0.730      | 0.710 |      0.907      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288-165487b8_20221011.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288_20221011.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cpm_coco.yml",
    "content": "Collections:\n- Name: CPM\n  Paper:\n    Title: Convolutional pose machines\n    URL: http://openaccess.thecvf.com/content_cvpr_2016/html/Wei_Convolutional_Pose_Machines_CVPR_2016_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/cpm.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192.py\n  In Collection: CPM\n  Metadata:\n    Architecture: &id001\n    - CPM\n    Training Data: COCO\n  Name: td-hm_cpm_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.627\n      AP@0.5: 0.862\n      AP@0.75: 0.709\n      AR: 0.689\n      AR@0.5: 0.906\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192-0e978875_20220920.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288.py\n  In Collection: CPM\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_cpm_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.652\n      AP@0.5: 0.865\n      AP@0.75: 0.730\n      AR: 0.710\n      AR@0.5: 0.907\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288-165487b8_20221011.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-l_udp_8xb256-210e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# keypoint mappings\nkeypoint_mapping_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nkeypoint_mapping_aic = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n    (12, 17),\n    (13, 18),\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=19,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        output_keypoint_indices=[\n            target for _, target in keypoint_mapping_coco\n        ]))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[\n            dict(\n                type='KeypointConverter',\n                num_keypoints=19,\n                mapping=keypoint_mapping_coco)\n        ],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,\n            mapping=keypoint_mapping_aic)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-l_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-m_udp_8xb256-210e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# keypoint mappings\nkeypoint_mapping_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nkeypoint_mapping_aic = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n    (12, 17),\n    (13, 18),\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=19,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        output_keypoint_indices=[\n            target for _, target in keypoint_mapping_coco\n        ]))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[\n            dict(\n                type='KeypointConverter',\n                num_keypoints=19,\n                mapping=keypoint_mapping_coco)\n        ],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,\n            mapping=keypoint_mapping_aic)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-m_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-s_udp_8xb256-210e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.0),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# keypoint mappings\nkeypoint_mapping_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nkeypoint_mapping_aic = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n    (12, 17),\n    (13, 18),\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-s_imagenet_600e-ea671761.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=19,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        output_keypoint_indices=[\n            target for _, target in keypoint_mapping_coco\n        ]))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[\n            dict(\n                type='KeypointConverter',\n                num_keypoints=19,\n                mapping=keypoint_mapping_coco)\n        ],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,\n            mapping=keypoint_mapping_aic)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-s_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-s_imagenet_600e-ea671761.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-tiny_udp_8xb256-210e_aic-coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.0),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# keypoint mappings\nkeypoint_mapping_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nkeypoint_mapping_aic = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n    (12, 17),\n    (13, 18),\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-tiny_imagenet_600e-3a2dd350.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=384,\n        out_channels=19,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        output_keypoint_indices=[\n            target for _, target in keypoint_mapping_coco\n        ]))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type='RepeatDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[\n            dict(\n                type='KeypointConverter',\n                num_keypoints=19,\n                mapping=keypoint_mapping_coco)\n        ],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,\n            mapping=keypoint_mapping_aic)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-tiny_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-tiny_imagenet_600e-3a2dd350.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=384,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext_udp_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_cspnext_t_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-tiny_udp_8xb256-210e_coco-256x192.py) |  256x192   | 0.665 |      0.874      |      0.723      | 0.723 |      0.917      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-coco_pt-in1k_210e-256x192-0908dd2d_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-coco_pt-in1k_210e-256x192-0908dd2d_20230123.json) |\n| [pose_cspnext_s_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-s_udp_8xb256-210e_coco-256x192.py) |  256x192   | 0.697 |      0.886      |      0.776      | 0.753 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-coco_pt-in1k_210e-256x192-92dbfc1d_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-coco_pt-in1k_210e-256x192-92dbfc1d_20230123.json) |\n| [pose_cspnext_m_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-m_udp_8xb256-210e_coco-256x192.py) |  256x192   | 0.732 |      0.896      |      0.806      | 0.785 |      0.937      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-coco_pt-in1k_210e-256x192-95f5967e_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-coco_pt-in1k_210e-256x192-95f5967e_20230123.json) |\n| [pose_cspnext_l_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-l_udp_8xb256-210e_coco-256x192.py) |  256x192   | 0.750 |      0.904      |      0.822      | 0.800 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-coco_pt-in1k_210e-256x192-661cdd8c_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-coco_pt-in1k_210e-256x192-661cdd8c_20230123.json) |\n| [pose_cspnext_t_udp_aic_coco](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-tiny_udp_8xb256-210e_aic-coco-256x192.py) |  256x192   | 0.655 |      0.884      |      0.731      | 0.689 |      0.890      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.json) |\n| [pose_cspnext_s_udp_aic_coco](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-s_udp_8xb256-210e_aic-coco-256x192.py) |  256x192   | 0.700 |      0.905      |      0.783      | 0.733 |      0.918      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.json) |\n| [pose_cspnext_m_udp_aic_coco](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-m_udp_8xb256-210e_aic-coco-256x192.py) |  256x192   | 0.748 |      0.925      |      0.818      | 0.777 |      0.933      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.json) |\n| [pose_cspnext_l_udp_aic_coco](/configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-l_udp_8xb256-210e_aic-coco-256x192.py) |  256x192   | 0.772 |      0.936      |      0.839      | 0.799 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.json) |\n\nNote that, UDP also adopts the unbiased encoding/decoding algorithm of [DARK](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#darkpose-cvpr-2020).\n\nFlip test and detector is not used in the result of aic-coco training.\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/cspnext_udp_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-tiny_udp_8xb256-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: &id001\n    - CSPNeXt\n    - UDP\n    Training Data: COCO\n  Name: cspnext-tiny_udp_8xb256-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.665\n      AP@0.5: 0.874\n      AP@0.75: 0.723\n      AR: 0.723\n      AR@0.5: 0.917\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-coco_pt-in1k_210e-256x192-0908dd2d_20230123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-s_udp_8xb256-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: cspnext-s_udp_8xb256-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.697\n      AP@0.5: 0.886\n      AP@0.75: 0.776\n      AR: 0.753\n      AR@0.5: 0.929\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-coco_pt-in1k_210e-256x192-92dbfc1d_20230123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-m_udp_8xb256-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: cspnext-m_udp_8xb256-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.732\n      AP@0.5: 0.896\n      AP@0.75: 0.806\n      AR: 0.785\n      AR@0.5: 0.937\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-coco_pt-in1k_210e-256x192-95f5967e_20230123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-l_udp_8xb256-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: cspnext-l_udp_8xb256-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.750\n      AP@0.5: 0.904\n      AP@0.75: 0.822\n      AR: 0.8\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-coco_pt-in1k_210e-256x192-661cdd8c_20230123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-tiny_udp_8xb256-210e_aic-coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data:\n    - COCO\n    - AIC\n  Name: cspnext-tiny_udp_8xb256-210e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.655\n      AP@0.5: 0.884\n      AP@0.75: 0.731\n      AR: 0.689\n      AR@0.5: 0.89\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-s_udp_8xb256-210e_aic-coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data:\n    - COCO\n    - AIC\n  Name: cspnext-s_udp_8xb256-210e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.7\n      AP@0.5: 0.905\n      AP@0.75: 0.783\n      AR: 0.733\n      AR@0.5: 0.918\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-m_udp_8xb256-210e_aic-coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data:\n    - COCO\n    - AIC\n  Name: cspnext-m_udp_8xb256-210e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.748\n      AP@0.5: 0.925\n      AP@0.75: 0.818\n      AR: 0.777\n      AR@0.5: 0.933\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/cspnext-l_udp_8xb256-210e_aic-coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data:\n    - COCO\n    - AIC\n  Name: cspnext-l_udp_8xb256-210e_aic-coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.772\n      AP@0.5: 0.936\n      AP@0.75: 0.839\n      AR: 0.799\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hourglass_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\">Hourglass (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{newell2016stacked,\n  title={Stacked hourglass networks for human pose estimation},\n  author={Newell, Alejandro and Yang, Kaiyu and Deng, Jia},\n  booktitle={European conference on computer vision},\n  pages={483--499},\n  year={2016},\n  organization={Springer}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hourglass_52](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hourglass52_8xb32-210e_coco-256x256.py) |  256x256   | 0.726 |      0.896      |      0.799      | 0.780 |      0.934      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_coco_256x256-4ec713ba_20200709.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_coco_256x256_20200709.log.json) |\n| [pose_hourglass_52](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hourglass52_8xb32-210e_coco-384x384.py) |  384x384   | 0.746 |      0.900      |      0.812      | 0.797 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_coco_384x384-be91ba2b_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_coco_384x384_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hourglass_coco.yml",
    "content": "Collections:\n- Name: Hourglass\n  Paper:\n    Title: Stacked hourglass networks for human pose estimation\n    URL: https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\n  README:  https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/hourglass.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hourglass52_8xb32-210e_coco-256x256.py\n  In Collection: Hourglass\n  Metadata:\n    Architecture: &id001\n    - Hourglass\n    Training Data: COCO\n  Name: td-hm_hourglass52_8xb32-210e_coco-256x256\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.726\n      AP@0.5: 0.896\n      AP@0.75: 0.799\n      AR: 0.780\n      AR@0.5: 0.934\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_coco_256x256-4ec713ba_20200709.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hourglass52_8xb32-210e_coco-384x384.py\n  In Collection: Hourglass\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hourglass52_8xb32-210e_coco-384x384\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.746\n      AP@0.5: 0.900\n      AP@0.75: 0.812\n      AR: 0.797\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_coco_384x384-be91ba2b_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrformer_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html\">HRFormer (NIPS'2021)</a></summary>\n\n```bibtex\n@article{yuan2021hrformer,\n  title={HRFormer: High-Resolution Vision Transformer for Dense Predict},\n  author={Yuan, Yuhui and Fu, Rao and Huang, Lang and Lin, Weihong and Zhang, Chao and Chen, Xilin and Wang, Jingdong},\n  journal={Advances in Neural Information Processing Systems},\n  volume={34},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrformer_small](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-small_8xb32-210e_coco-256x192.py) |  256x192   | 0.738 |      0.904      |      0.812      | 0.793 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_small_coco_256x192-5310d898_20220316.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_small_coco_256x192_20220316.log.json) |\n| [pose_hrformer_small](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-small_8xb32-210e_coco-384x288.py) |  384x288   | 0.757 |      0.905      |      0.824      | 0.807 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_small_coco_384x288-98d237ed_20220316.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_small_coco_384x288_20220316.log.json) |\n| [pose_hrformer_base](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-base_8xb32-210e_coco-256x192.py) |  256x192   | 0.754 |      0.906      |      0.827      | 0.807 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_base_coco_256x192-6f5f1169_20220316.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_base_coco_256x192_20220316.log.json) |\n| [pose_hrformer_base](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-base_8xb32-210e_coco-384x288.py) |  384x288   | 0.774 |      0.909      |      0.842      | 0.823 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_base_coco_384x288-ecf0758d_20220316.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_base_coco_384x288_20220316.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrformer_coco.yml",
    "content": "Collections:\n- Name: HRFormer\n  Paper:\n    Title: 'HRFormer: High-Resolution Vision Transformer for Dense Predict'\n    URL: https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/hrformer.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-small_8xb32-210e_coco-256x192.py\n  In Collection: HRFormer\n  Metadata:\n    Architecture: &id001\n    - HRFormer\n    Training Data: COCO\n  Name: td-hm_hrformer-small_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.738\n      AP@0.5: 0.904\n      AP@0.75: 0.812\n      AR: 0.793\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_small_coco_256x192-5310d898_20220316.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-small_8xb32-210e_coco-384x288.py\n  In Collection: HRFormer\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrformer-small_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.757\n      AP@0.5: 0.905\n      AP@0.75: 0.824\n      AR: 0.807\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_small_coco_384x288-98d237ed_20220316.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-base_8xb32-210e_coco-256x192.py\n  In Collection: HRFormer\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrformer-base_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.754\n      AP@0.5: 0.906\n      AP@0.75: 0.827\n      AR: 0.807\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_base_coco_256x192-6f5f1169_20220316.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-base_8xb32-210e_coco-384x288.py\n  In Collection: HRFormer\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrformer-base_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.774\n      AP@0.5: 0.909\n      AP@0.75: 0.842\n      AR: 0.823\n      AR@0.5: 0.945\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrformer/hrformer_base_coco_384x288-ecf0758d_20220316.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_augmentation_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.mdpi.com/649002\">Albumentations (Information'2020)</a></summary>\n\n```bibtex\n@article{buslaev2020albumentations,\n  title={Albumentations: fast and flexible image augmentations},\n  author={Buslaev, Alexander and Iglovikov, Vladimir I and Khvedchenya, Eugene and Parinov, Alex and Druzhinin, Mikhail and Kalinin, Alexandr A},\n  journal={Information},\n  volume={11},\n  number={2},\n  pages={125},\n  year={2020},\n  publisher={Multidisciplinary Digital Publishing Institute}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [coarsedropout](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_coarsedropout-8xb64-210e_coco-256x192.py) |  256x192   | 0.753 |      0.908      |      0.822      | 0.805 |      0.944      | [ckpt](https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_coarsedropout-0f16a0ce_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_coarsedropout_20210320.log.json) |\n| [gridmask](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_gridmask-8xb64-210e_coco-256x192.py) |  256x192   | 0.752 |      0.906      |      0.825      | 0.804 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_gridmask-868180df_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_gridmask_20210320.log.json) |\n| [photometric](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_photometric-8xb64-210e_coco-256x192.py) |  256x192   | 0.754 |      0.908      |      0.825      | 0.805 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_photometric-308cf591_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_photometric_20210320.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_augmentation_coco.yml",
    "content": "Collections:\n- Name: Albumentations\n  Paper:\n    Title: 'Albumentations: fast and flexible image augmentations'\n    URL: https://www.mdpi.com/649002\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/techniques/albumentations.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_coarsedropout-8xb64-210e_coco-256x192.py\n  In Collection: Albumentations\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_coarsedropout-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.753\n      AP@0.5: 0.908\n      AP@0.75: 0.822\n      AR: 0.805\n      AR@0.5: 0.944\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_coarsedropout-0f16a0ce_20210320.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_gridmask-8xb64-210e_coco-256x192.py\n  In Collection: Albumentations\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_gridmask-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.752\n      AP@0.5: 0.906\n      AP@0.75: 0.825\n      AR: 0.804\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_gridmask-868180df_20210320.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_photometric-8xb64-210e_coco-256x192.py\n  In Collection: Albumentations\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_photometric-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.754\n      AP@0.5: 0.908\n      AP@0.75: 0.825\n      AR: 0.805\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/augmentation/hrnet_w32_coco_256x192_photometric-308cf591_20210320.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) |  256x192   | 0.749 |      0.906      |      0.821      | 0.804 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220909.log) |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288.py) |  384x288   | 0.761 |      0.908      |      0.826      | 0.811 |      0.944      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288-ca5956af_20220909.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288_20220909.log) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py) |  256x192   | 0.756 |      0.908      |      0.826      | 0.809 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192_20220913.log) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288.py) |  384x288   | 0.767 |      0.911      |      0.832      | 0.817 |      0.947      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288-c161b7de_20220915.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288_20220915.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_coco.yml",
    "content": "Collections:\n- Name: HRNet\n  Paper:\n    Title: Deep high-resolution representation learning for human pose estimation\n    URL: http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/hrnet.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.746\n      AP@0.5: 0.904\n      AP@0.75: 0.819\n      AR: 0.799\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.76\n      AP@0.5: 0.906\n      AP@0.75: 0.83\n      AR: 0.81\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288-ca5956af_20220909.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w48_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.756\n      AP@0.5: 0.907\n      AP@0.75: 0.825\n      AR: 0.806\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w48_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.767\n      AP@0.5: 0.91\n      AP@0.75: 0.831\n      AR: 0.816\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288-c161b7de_20220915.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data:\n    - COCO\n    - AI Challenger\n  Name: td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.757\n      AP@0.5: 0.907\n      AP@0.75: 0.829\n      AR: 0.809\n      AR@0.5: 0.944\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge-b05435b9_20221025.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data:\n    - COCO\n    - AI Challenger\n  Name: td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.756\n      AP@0.5: 0.906\n      AP@0.75: 0.826\n      AR: 0.807\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine-4ce66880_20221026.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.749\n      AP@0.5: 0.907\n      AP@0.75: 0.822\n      AR: 0.802\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192-f1e84e3b_20220914.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_coco_aic.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n\nMMPose supports training model with combined datasets. [coco-aic-merge](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py) and [coco-aic-combine](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py) are two examples.\n\n- [coco-aic-merge](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py) leverages AIC data with partial keypoints as auxiliary data to train a COCO model\n- [coco-aic-combine](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py) constructs a combined dataset whose keypoints are the union of COCO and AIC keypoints to train a model that predicts keypoints of both datasets.\n\nEvaluation results on COCO val2017 of models trained with solely COCO dataset and combined dataset as shown below. These models are evaluated with detector having human AP of 56.4 on COCO val2017 dataset.\n\n| Train Set                                    | Arch           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                  ckpt                   |                  log                   |\n| :------------------------------------------- | :------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------: | :------------------------------------: |\n| [coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) | pose_hrnet_w32 |  256x192   | 0.749 |      0.906      |      0.821      | 0.804 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220909.log) |\n| [coco-aic-merge](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py) | pose_hrnet_w32 |  256x192   | 0.756 |      0.907      |      0.828      | 0.809 |      0.944      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge-a9ea6d77_20230818.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge_20230818.json) |\n| [coco-aic-combine](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py) | pose_hrnet_w32 |  256x192   | 0.755 |      0.904      |      0.825      | 0.807 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine-458125cc_20230818.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine_20230818.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_dark_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192.py) |  256x192   | 0.757 |      0.907      |      0.825      | 0.807 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192-0e00bf12_20220914.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192_20220914.log) |\n| [pose_hrnet_w32_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288.py) |  384x288   | 0.766 |      0.907      |      0.829      | 0.815 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288-9bab4c9b_20220917.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288_20220917.log) |\n| [pose_hrnet_w48_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192.py) |  256x192   | 0.764 |      0.907      |      0.831      | 0.814 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192-e1ebdd6f_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192_20220913.log) |\n| [pose_hrnet_w48_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288.py) |  384x288   | 0.772 |      0.911      |      0.833      | 0.821 |      0.948      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288-39c3c381_20220916.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288_20220916.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_dark_coco.yml",
    "content": "Collections:\n- Name: DarkPose\n  Paper:\n    Title: Distribution-aware coordinate representation for human pose estimation\n    URL: http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/techniques/dark.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    - DarkPose\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.757\n      AP@0.5: 0.907\n      AP@0.75: 0.825\n      AR: 0.807\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192-0e00bf12_20220914.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.766\n      AP@0.5: 0.907\n      AP@0.75: 0.829\n      AR: 0.815\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288-9bab4c9b_20220917.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.764\n      AP@0.5: 0.907\n      AP@0.75: 0.831\n      AR: 0.814\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192-e1ebdd6f_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.772\n      AP@0.5: 0.911\n      AP@0.75: 0.833\n      AR: 0.821\n      AR@0.5: 0.948\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288-39c3c381_20220916.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_fp16_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1710.03740\">FP16 (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{micikevicius2017mixed,\n  title={Mixed precision training},\n  author={Micikevicius, Paulius and Narang, Sharan and Alben, Jonah and Diamos, Gregory and Elsen, Erich and Garcia, David and Ginsburg, Boris and Houston, Michael and Kuchaiev, Oleksii and Venkatesh, Ganesh and others},\n  journal={arXiv preprint arXiv:1710.03740},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32_fp16](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192.py) |  256x192   | 0.749 |      0.907      |      0.822      | 0.802 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192-f1e84e3b_20220914.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192_20220914.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_udp_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192.py) |  256x192   | 0.762 |      0.907      |      0.829      | 0.810 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192-73ede547_20220914.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192_20220914.log) |\n| [pose_hrnet_w32_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288.py) |  384x288   | 0.768 |      0.909      |      0.832      | 0.815 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288-9a3f7c85_20220914.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288_20220914.log) |\n| [pose_hrnet_w48_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192.py) |  256x192   | 0.768 |      0.908      |      0.833      | 0.817 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192-3feaef8f_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192_20220913.log) |\n| [pose_hrnet_w48_udp](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288.py) |  384x288   | 0.773 |      0.911      |      0.836      | 0.821 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288-70d7ab01_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288_20220913.log) |\n| [pose_hrnet_w32_udp_regress](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192.py) |  256x192   | 0.759 |      0.907      |      0.827      | 0.813 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192-9c0b77b4_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192_20220226.log) |\n\nNote that, UDP also adopts the unbiased encoding/decoding algorithm of [DARK](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/techniques.html#darkpose-cvpr-2020).\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_udp_coco.yml",
    "content": "Collections:\n- Name: UDP\n  Paper:\n    Title: 'The Devil Is in the Details: Delving Into Unbiased Data Processing for\n      Human Pose Estimation'\n    URL: http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/techniques/udp.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    - UDP\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.762\n      AP@0.5: 0.907\n      AP@0.75: 0.829\n      AR: 0.810\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192-73ede547_20220914.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.768\n      AP@0.5: 0.909\n      AP@0.75: 0.832\n      AR: 0.815\n      AR@0.5: 0.945\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288-9a3f7c85_20220914.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.768\n      AP@0.5: 0.908\n      AP@0.75: 0.833\n      AR: 0.817\n      AR@0.5: 0.945\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192-3feaef8f_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.773\n      AP@0.5: 0.911\n      AP@0.75: 0.836\n      AR: 0.821\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288-70d7ab01_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.759\n      AP@0.5: 0.907\n      AP@0.75: 0.827\n      AR: 0.813\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192-9c0b77b4_20220926.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/litehrnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.06403\">LiteHRNet (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{Yulitehrnet21,\n  title={Lite-HRNet: A Lightweight High-Resolution Network},\n  author={Yu, Changqian and Xiao, Bin and Gao, Changxin and Yuan, Lu and Zhang, Lei and Sang, Nong and Wang, Jingdong},\n  booktitle={CVPR},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [LiteHRNet-18](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-18_8xb64-210e_coco-256x192.py) |  256x192   | 0.642 |      0.867      |      0.719      | 0.705 |      0.911      | [ckpt](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_coco_256x192-6bace359_20211230.pth) | [log](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_coco_256x192_20211230.log.json) |\n| [LiteHRNet-18](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-18_8xb32-210e_coco-384x288.py) |  384x288   | 0.676 |      0.876      |      0.746      | 0.735 |      0.919      | [ckpt](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_coco_384x288-8d4dac48_20211230.pth) | [log](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_coco_384x288_20211230.log.json) |\n| [LiteHRNet-30](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-30_8xb64-210e_coco-256x192.py) |  256x192   | 0.676 |      0.880      |      0.756      | 0.736 |      0.922      | [ckpt](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_coco_256x192-4176555b_20210626.pth) | [log](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_coco_256x192_20210626.log.json) |\n| [LiteHRNet-30](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-30_8xb32-210e_coco-384x288.py) |  384x288   | 0.700 |      0.883      |      0.776      | 0.758 |      0.926      | [ckpt](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_coco_384x288-a3aef5c4_20210626.pth) | [log](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_coco_384x288_20210626.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/litehrnet_coco.yml",
    "content": "Collections:\n- Name: LiteHRNet\n  Paper:\n    Title: 'Lite-HRNet: A Lightweight High-Resolution Network'\n    URL: https://arxiv.org/abs/2104.06403\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/litehrnet.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-18_8xb64-210e_coco-256x192.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture: &id001\n    - LiteHRNet\n    Training Data: COCO\n  Name: td-hm_litehrnet-18_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.642\n      AP@0.5: 0.867\n      AP@0.75: 0.719\n      AR: 0.705\n      AR@0.5: 0.911\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_coco_256x192-6bace359_20211230.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-18_8xb32-210e_coco-384x288.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_litehrnet-18_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.676\n      AP@0.5: 0.876\n      AP@0.75: 0.746\n      AR: 0.735\n      AR@0.5: 0.919\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_coco_384x288-8d4dac48_20211230.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-30_8xb64-210e_coco-256x192.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_litehrnet-30_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.676\n      AP@0.5: 0.88\n      AP@0.75: 0.756\n      AR: 0.736\n      AR@0.5: 0.922\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_coco_256x192-4176555b_20210626.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-30_8xb32-210e_coco-384x288.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_litehrnet-30_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.7\n      AP@0.5: 0.883\n      AP@0.75: 0.776\n      AR: 0.758\n      AR@0.5: 0.926\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_coco_384x288-a3aef5c4_20210626.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/mobilenetv2_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_mobilenetv2](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-256x192.py) |  256x192   | 0.648 |      0.874      |      0.725      | 0.709 |      0.918      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-256x192-55a04c35_20221016.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-256x192_20221016.log) |\n| [pose_mobilenetv2](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-384x288.py) |  384x288   | 0.677 |      0.882      |      0.746      | 0.734 |      0.920      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-384x288-d3ab1457_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-384x288_20221013.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/mobilenetv2_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - MobilenetV2\n    Training Data: COCO\n  Name: td-hm_mobilenetv2_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.648\n      AP@0.5: 0.874\n      AP@0.75: 0.725\n      AR: 0.709\n      AR@0.5: 0.918\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-256x192-55a04c35_20221016.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_mobilenetv2_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.677\n      AP@0.5: 0.882\n      AP@0.75: 0.746\n      AR: 0.734\n      AR@0.5: 0.920\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-384x288-d3ab1457_20221013.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/mspn_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1901.00148\">MSPN (ArXiv'2019)</a></summary>\n\n```bibtex\n@article{li2019rethinking,\n  title={Rethinking on Multi-Stage Networks for Human Pose Estimation},\n  author={Li, Wenbo and Wang, Zhicheng and Yin, Binyi and Peng, Qixiang and Du, Yuming and Xiao, Tianzi and Yu, Gang and Lu, Hongtao and Wei, Yichen and Sun, Jian},\n  journal={arXiv preprint arXiv:1901.00148},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [mspn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mspn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.723 |      0.895      |      0.794      | 0.788 |      0.934      | [ckpt](https://download.openmmlab.com/mmpose/top_down/mspn/mspn50_coco_256x192-8fbfb5d0_20201123.pth) | [log](https://download.openmmlab.com/mmpose/top_down/mspn/mspn50_coco_256x192_20201123.log.json) |\n| [2xmspn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xmspn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.754 |      0.903      |      0.826      | 0.816 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/top_down/mspn/2xmspn50_coco_256x192-c8765a5c_20201123.pth) | [log](https://download.openmmlab.com/mmpose/top_down/mspn/2xmspn50_coco_256x192_20201123.log.json) |\n| [3xmspn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xmspn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.758 |      0.904      |      0.830      | 0.821 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/mspn/3xmspn50_coco_256x192-e348f18e_20201123.pth) | [log](https://download.openmmlab.com/mmpose/top_down/mspn/3xmspn50_coco_256x192_20201123.log.json) |\n| [4xmspn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_4xmspn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.765 |      0.906      |      0.835      | 0.826 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/mspn/4xmspn50_coco_256x192-7b837afb_20201123.pth) | [log](https://download.openmmlab.com/mmpose/top_down/mspn/4xmspn50_coco_256x192_20201123.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/mspn_coco.yml",
    "content": "Collections:\n- Name: MSPN\n  Paper:\n    Title: Rethinking on Multi-Stage Networks for Human Pose Estimation\n    URL: https://arxiv.org/abs/1901.00148\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/mspn.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mspn50_8xb32-210e_coco-256x192.py\n  In Collection: MSPN\n  Metadata:\n    Architecture: &id001\n    - MSPN\n    Training Data: COCO\n  Name: td-hm_mspn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.723\n      AP@0.5: 0.895\n      AP@0.75: 0.794\n      AR: 0.788\n      AR@0.5: 0.934\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/mspn/mspn50_coco_256x192-8fbfb5d0_20201123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xmspn50_8xb32-210e_coco-256x192.py\n  In Collection: MSPN\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_2xmspn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.754\n      AP@0.5: 0.903\n      AP@0.75: 0.826\n      AR: 0.816\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/mspn/2xmspn50_coco_256x192-c8765a5c_20201123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xmspn50_8xb32-210e_coco-256x192.py\n  In Collection: MSPN\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_3xmspn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.758\n      AP@0.5: 0.904\n      AP@0.75: 0.83\n      AR: 0.821\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/mspn/3xmspn50_coco_256x192-e348f18e_20201123.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_4xmspn50_8xb32-210e_coco-256x192.py\n  In Collection: MSPN\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_4xmspn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.765\n      AP@0.5: 0.906\n      AP@0.75: 0.835\n      AR: 0.826\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/mspn/4xmspn50_coco_256x192-7b837afb_20201123.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/pvt_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2102.12122\">PVT (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{wang2021pyramid,\n  title={Pyramid vision transformer: A versatile backbone for dense prediction without convolutions},\n  author={Wang, Wenhai and Xie, Enze and Li, Xiang and Fan, Deng-Ping and Song, Kaitao and Liang, Ding and Lu, Tong and Luo, Ping and Shao, Ling},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={568--578},\n  year={2021}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2106.13797\">PVTV2 (CVMJ'2022)</a></summary>\n\n```bibtex\n@article{wang2022pvt,\n  title={PVT v2: Improved baselines with Pyramid Vision Transformer},\n  author={Wang, Wenhai and Xie, Enze and Li, Xiang and Fan, Deng-Ping and Song, Kaitao and Liang, Ding and Lu, Tong and Luo, Ping and Shao, Ling},\n  journal={Computational Visual Media},\n  pages={1--10},\n  year={2022},\n  publisher={Springer}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_pvt-s](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_pvt-s_8xb64-210e_coco-256x192.py) |  256x192   | 0.714 |      0.896      |      0.794      | 0.773 |      0.936      | [ckpt](https://download.openmmlab.com/mmpose/top_down/pvt/pvt_small_coco_256x192-4324a49d_20220501.pth) | [log](https://download.openmmlab.com/mmpose/top_down/pvt/pvt_small_coco_256x192_20220501.log.json) |\n| [pose_pvtv2-b2](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_pvtv2-b2_8xb64-210e_coco-256x192.py) |  256x192   | 0.737 |      0.905      |      0.812      | 0.791 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/top_down/pvt/pvtv2_b2_coco_256x192-b4212737_20220501.pth) | [log](https://download.openmmlab.com/mmpose/top_down/pvt/pvtv2_b2_coco_256x192_20220501.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/pvt_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_pvt-s_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - PVT\n    Training Data: COCO\n  Name: td-hm_pvt-s_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.714\n      AP@0.5: 0.896\n      AP@0.75: 0.794\n      AR: 0.773\n      AR@0.5: 0.936\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/pvt/pvt_small_coco_256x192-4324a49d_20220501.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_pvtv2-b2_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_pvtv2-b2_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.737\n      AP@0.5: 0.905\n      AP@0.75: 0.812\n      AR: 0.791\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/pvt/pvtv2_b2_coco_256x192-b4212737_20220501.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnest_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2004.08955\">ResNeSt (ArXiv'2020)</a></summary>\n\n```bibtex\n@article{zhang2020resnest,\n  title={ResNeSt: Split-Attention Networks},\n  author={Zhang, Hang and Wu, Chongruo and Zhang, Zhongyue and Zhu, Yi and Zhang, Zhi and Lin, Haibin and Sun, Yue and He, Tong and Muller, Jonas and Manmatha, R. and Li, Mu and Smola, Alexander},\n  journal={arXiv preprint arXiv:2004.08955},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnest_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest50_8xb64-210e_coco-256x192.py) |  256x192   | 0.720 |      0.899      |      0.800      | 0.775 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest50_coco_256x192-6e65eece_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest50_coco_256x192_20210320.log.json) |\n| [pose_resnest_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest50_8xb64-210e_coco-384x288.py) |  384x288   | 0.737 |      0.900      |      0.811      | 0.789 |      0.937      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest50_coco_384x288-dcd20436_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest50_coco_384x288_20210320.log.json) |\n| [pose_resnest_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest101_8xb64-210e_coco-256x192.py) |  256x192   | 0.725 |      0.900      |      0.807      | 0.781 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest101_coco_256x192-2ffcdc9d_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest101_coco_256x192_20210320.log.json) |\n| [pose_resnest_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest101_8xb32-210e_coco-384x288.py) |  384x288   | 0.745 |      0.905      |      0.818      | 0.798 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest101_coco_384x288-80660658_20210320.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest101_coco_384x288_20210320.log.json) |\n| [pose_resnest_200](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest200_8xb64-210e_coco-256x192.py) |  256x192   | 0.731 |      0.905      |      0.812      | 0.787 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest200_coco_256x192-db007a48_20210517.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest200_coco_256x192_20210517.log.json) |\n| [pose_resnest_200](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest200_8xb16-210e_coco-384x288.py) |  384x288   | 0.753 |      0.907      |      0.827      | 0.805 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest200_coco_384x288-b5bb76cb_20210517.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest200_coco_384x288_20210517.log.json) |\n| [pose_resnest_269](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest269_8xb32-210e_coco-256x192.py) |  256x192   | 0.737 |      0.907      |      0.819      | 0.792 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest269_coco_256x192-2a7882ac_20210517.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest269_coco_256x192_20210517.log.json) |\n| [pose_resnest_269](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest269_8xb16-210e_coco-384x288.py) |  384x288   | 0.754 |      0.908      |      0.828      | 0.805 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnest/resnest269_coco_384x288-b142b9fb_20210517.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnest/resnest269_coco_384x288_20210517.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnest_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest50_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNeSt\n    Training Data: COCO\n  Name: td-hm_resnest50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.720\n      AP@0.5: 0.899\n      AP@0.75: 0.8\n      AR: 0.775\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest50_coco_256x192-6e65eece_20210320.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest50_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest50_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.737\n      AP@0.5: 0.9\n      AP@0.75: 0.811\n      AR: 0.789\n      AR@0.5: 0.937\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest50_coco_384x288-dcd20436_20210320.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest101_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest101_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.725\n      AP@0.5: 0.9\n      AP@0.75: 0.807\n      AR: 0.781\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest101_coco_256x192-2ffcdc9d_20210320.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest101_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest101_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.745\n      AP@0.5: 0.905\n      AP@0.75: 0.818\n      AR: 0.798\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest101_coco_384x288-80660658_20210320.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest200_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest200_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.731\n      AP@0.5: 0.905\n      AP@0.75: 0.812\n      AR: 0.787\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest200_coco_256x192-db007a48_20210517.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest200_8xb16-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest200_8xb16-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.753\n      AP@0.5: 0.907\n      AP@0.75: 0.827\n      AR: 0.805\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest200_coco_384x288-b5bb76cb_20210517.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest269_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest269_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.737\n      AP@0.5: 0.907\n      AP@0.75: 0.819\n      AR: 0.792\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest269_coco_256x192-2a7882ac_20210517.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest269_8xb16-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnest269_8xb16-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.754\n      AP@0.5: 0.908\n      AP@0.75: 0.828\n      AR: 0.805\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnest/resnest269_coco_384x288-b142b9fb_20210517.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py) |  256x192   | 0.718 |      0.898      |      0.796      | 0.774 |      0.934      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192-04af38ce_20220923.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192_20220923.log) |\n| [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-384x288.py) |  384x288   | 0.731 |      0.900      |      0.799      | 0.782 |      0.937      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-384x288-7b8db90e_20220923.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-384x288_20220923.log) |\n| [pose_resnet_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192.py) |  256x192   | 0.728 |      0.904      |      0.809      | 0.783 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192-065d3625_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192_20220926.log) |\n| [pose_resnet_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb32-210e_coco-384x288.py) |  384x288   | 0.749 |      0.906      |      0.817      | 0.799 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192-065d3625_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192_20220926.log) |\n| [pose_resnet_152](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-256x192.py) |  256x192   | 0.736 |      0.904      |      0.818      | 0.791 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-256x192-0345f330_20220928.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-256x192_20220928.log) |\n| [pose_resnet_152](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-384x288.py) |  384x288   | 0.750 |      0.908      |      0.821      | 0.800 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-384x288-7fbb906f_20220927.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-384x288_20220927.log) |\n\nThe following model is equipped with a visibility prediction head and has been trained using COCO and AIC datasets.\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm-vis_res50_8xb64-210e_coco-aic-256x192-merge.py) |  256x192   | 0.729 |      0.900      |      0.807      | 0.783 |      0.938      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm-vis_res50_8xb64-210e_coco-aic-256x192-merge-21815b2c_20230726.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192_20220923.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnet_coco.yml",
    "content": "Collections:\n- Name: SimpleBaseline2D\n  Paper:\n    Title: Simple baselines for human pose estimation and tracking\n    URL: http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/simplebaseline2d.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: COCO\n  Name: td-hm_res50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.718\n      AP@0.5: 0.898\n      AP@0.75: 0.796\n      AR: 0.774\n      AR@0.5: 0.934\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192-04af38ce_20220923.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res50_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.731\n      AP@0.5: 0.9\n      AP@0.75: 0.799\n      AR: 0.782\n      AR@0.5: 0.937\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-384x288-7b8db90e_20220923.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res101_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.728\n      AP@0.5: 0.904\n      AP@0.75: 0.809\n      AR: 0.783\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192-065d3625_20220926.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res101_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.749\n      AP@0.5: 0.906\n      AP@0.75: 0.817\n      AR: 0.799\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192-065d3625_20220926.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res152_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.736\n      AP@0.5: 0.904\n      AP@0.75: 0.818\n      AR: 0.791\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-256x192-0345f330_20220928.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res152_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.75\n      AP@0.5: 0.908\n      AP@0.75: 0.821\n      AR: 0.8\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-384x288-7fbb906f_20220927.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_fp16-8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res50_fp16-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.716\n      AP@0.5: 0.898\n      AP@0.75: 0.798\n      AR: 0.772\n      AR@0.5: 0.937\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_fp16-8xb64-210e_coco-256x192-463da051_20220927.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnet_dark_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_50_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-256x192.py) |  256x192   | 0.724 |      0.897      |      0.797      | 0.777 |      0.934      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-256x192-c129dcb6_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-256x192_20220926.log) |\n| [pose_resnet_50_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-384x288.py) |  384x288   | 0.735 |      0.902      |      0.801      | 0.786 |      0.938      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-384x288-8b90b538_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-384x288_20220926.log) |\n| [pose_resnet_101_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-256x192.py) |  256x192   | 0.733 |      0.900      |      0.810      | 0.786 |      0.938      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-256x192-528ec248_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-256x192_20220926.log) |\n| [pose_resnet_101_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-384x288.py) |  384x288   | 0.749 |      0.905      |      0.818      | 0.799 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-384x288-487d40a4_20220926.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-384x288_20220926.log) |\n| [pose_resnet_152_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-256x192.py) |  256x192   | 0.743 |      0.906      |      0.819      | 0.796 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-256x192-f754df5f_20221031.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-256x192_20221031.log) |\n| [pose_resnet_152_dark](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-384x288.py) |  384x288   | 0.755 |      0.907      |      0.825      | 0.805 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-384x288-329f8454_20221031.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-384x288_20221031.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnet_dark_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-256x192.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    - DarkPose\n    Training Data: COCO\n  Name: td-hm_res50_dark-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.724\n      AP@0.5: 0.897\n      AP@0.75: 0.797\n      AR: 0.777\n      AR@0.5: 0.934\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-256x192-c129dcb6_20220926.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-384x288.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res50_dark-8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.735\n      AP@0.5: 0.902\n      AP@0.75: 0.801\n      AR: 0.786\n      AR@0.5: 0.938\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-384x288-8b90b538_20220926.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-256x192.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res101_dark-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.733\n      AP@0.5: 0.9\n      AP@0.75: 0.81\n      AR: 0.786\n      AR@0.5: 0.938\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-256x192-528ec248_20220926.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-384x288.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res101_dark-8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.749\n      AP@0.5: 0.905\n      AP@0.75: 0.818\n      AR: 0.799\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-384x288-487d40a4_20220926.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-256x192.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res152_dark-8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.743\n      AP@0.5: 0.906\n      AP@0.75: 0.819\n      AR: 0.796\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-256x192-f754df5f_20221031.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-384x288.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_res152_dark-8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.757\n      AP@0.5: 0.907\n      AP@0.75: 0.825\n      AR: 0.805\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-384x288-329f8454_20221031.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnet_fp16_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1710.03740\">FP16 (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{micikevicius2017mixed,\n  title={Mixed precision training},\n  author={Micikevicius, Paulius and Narang, Sharan and Alben, Jonah and Diamos, Gregory and Elsen, Erich and Garcia, David and Ginsburg, Boris and Houston, Michael and Kuchaiev, Oleksii and Venkatesh, Ganesh and others},\n  journal={arXiv preprint arXiv:1710.03740},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_50_fp16](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_fp16-8xb64-210e_coco-256x192.py) |  256x192   | 0.716 |      0.898      |      0.798      | 0.772 |      0.937      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_fp16-8xb64-210e_coco-256x192-463da051_20220927.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_fp16-8xb64-210e_coco-256x192_20220927.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnetv1d_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/He_Bag_of_Tricks_for_Image_Classification_with_Convolutional_Neural_Networks_CVPR_2019_paper.html\">ResNetV1D (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{he2019bag,\n  title={Bag of tricks for image classification with convolutional neural networks},\n  author={He, Tong and Zhang, Zhi and Zhang, Hang and Zhang, Zhongyue and Xie, Junyuan and Li, Mu},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={558--567},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnetv1d_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-256x192.py) |  256x192   | 0.722 |      0.897      |      0.796      | 0.777 |      0.936      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-256x192-27545d63_20221020.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-256x192_20221020.log) |\n| [pose_resnetv1d_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-384x288.py) |  384x288   | 0.730 |      0.899      |      0.800      | 0.782 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-384x288-0646b46e_20221020.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-384x288_20221020.log) |\n| [pose_resnetv1d_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb64-210e_coco-256x192.py) |  256x192   | 0.732 |      0.901      |      0.808      | 0.785 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb64-210e_coco-256x192-ee9e7212_20221021.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb64-210e_coco-256x192_20221021.log) |\n| [pose_resnetv1d_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb32-210e_coco-384x288.py) |  384x288   | 0.748 |      0.906      |      0.817      | 0.798 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb32-210e_coco-384x288-d0b5875f_20221028.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb32-210e_coco-384x288_20221028.log) |\n| [pose_resnetv1d_152](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb32-210e_coco-256x192.py) |  256x192   | 0.737 |      0.904      |      0.814      | 0.790 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb32-210e_coco-256x192-fd49f947_20221021.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb32-210e_coco-256x192_20221021.log) |\n| [pose_resnetv1d_152](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb48-210e_coco-384x288.py) |  384x288   | 0.751 |      0.907      |      0.821      | 0.801 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb48-210e_coco-384x288-b9a99602_20221022.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb48-210e_coco-384x288_20221022.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnetv1d_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNetV1D\n    Training Data: COCO\n  Name: td-hm_resnetv1d50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.722\n      AP@0.5: 0.897\n      AP@0.75: 0.796\n      AR: 0.777\n      AR@0.5: 0.936\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-256x192-27545d63_20221020.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnetv1d50_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.73\n      AP@0.5: 0.899\n      AP@0.75: 0.8\n      AR: 0.782\n      AR@0.5: 0.935\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-384x288-0646b46e_20221020.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnetv1d101_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.732\n      AP@0.5: 0.901\n      AP@0.75: 0.808\n      AR: 0.785\n      AR@0.5: 0.940\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb64-210e_coco-256x192-ee9e7212_20221021.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnetv1d101_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.748\n      AP@0.5: 0.906\n      AP@0.75: 0.817\n      AR: 0.798\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb32-210e_coco-384x288-d0b5875f_20221028.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnetv1d152_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.737\n      AP@0.5: 0.904\n      AP@0.75: 0.814\n      AR: 0.790\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb32-210e_coco-256x192-fd49f947_20221021.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb48-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnetv1d152_8xb48-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.751\n      AP@0.5: 0.907\n      AP@0.75: 0.821\n      AR: 0.801\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb48-210e_coco-384x288-b9a99602_20221022.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnext_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2017/html/Xie_Aggregated_Residual_Transformations_CVPR_2017_paper.html\">ResNext (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{xie2017aggregated,\n  title={Aggregated residual transformations for deep neural networks},\n  author={Xie, Saining and Girshick, Ross and Doll{\\'a}r, Piotr and Tu, Zhuowen and He, Kaiming},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1492--1500},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_resnext_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext50_8xb64-210e_coco-256x192.py) |  256x192   | 0.715 |      0.897      |      0.791      | 0.771 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext50_coco_256x192-dcff15f6_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext50_coco_256x192_20200727.log.json) |\n| [pose_resnext_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext50_8xb64-210e_coco-384x288.py) |  384x288   | 0.724 |      0.899      |      0.794      | 0.777 |      0.936      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext50_coco_384x288-412c848f_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext50_coco_384x288_20200727.log.json) |\n| [pose_resnext_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext101_8xb64-210e_coco-256x192.py) |  256x192   | 0.726 |      0.900      |      0.801      | 0.781 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext101_coco_256x192-c7eba365_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext101_coco_256x192_20200727.log.json) |\n| [pose_resnext_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext101_8xb32-210e_coco-384x288.py) |  384x288   | 0.744 |      0.903      |      0.815      | 0.794 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext101_coco_384x288-f5eabcd6_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext101_coco_384x288_20200727.log.json) |\n| [pose_resnext_152](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext152_8xb32-210e_coco-256x192.py) |  256x192   | 0.730 |      0.903      |      0.808      | 0.785 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_coco_256x192-102449aa_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_coco_256x192_20200727.log.json) |\n| [pose_resnext_152](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext152_8xb48-210e_coco-384x288.py) |  384x288   | 0.742 |      0.904      |      0.810      | 0.794 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_coco_384x288-806176df_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_coco_384x288_20200727.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/resnext_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext50_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNext\n    Training Data: COCO\n  Name: td-hm_resnext50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.715\n      AP@0.5: 0.897\n      AP@0.75: 0.791\n      AR: 0.771\n      AR@0.5: 0.935\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext50_coco_256x192-dcff15f6_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext50_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnext50_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.724\n      AP@0.5: 0.899\n      AP@0.75: 0.794\n      AR: 0.777\n      AR@0.5: 0.936\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext50_coco_384x288-412c848f_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext101_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnext101_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.726\n      AP@0.5: 0.9\n      AP@0.75: 0.801\n      AR: 0.781\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext101_coco_256x192-c7eba365_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext101_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnext101_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.744\n      AP@0.5: 0.903\n      AP@0.75: 0.815\n      AR: 0.794\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext101_coco_384x288-f5eabcd6_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext152_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnext152_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.73\n      AP@0.5: 0.903\n      AP@0.75: 0.808\n      AR: 0.785\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_coco_256x192-102449aa_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext152_8xb48-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_resnext152_8xb48-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.742\n      AP@0.5: 0.904\n      AP@0.75: 0.81\n      AR: 0.794\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_coco_384x288-806176df_20200727.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RSN (ECCV'2020)</a></summary>\n\n```bibtex\n@misc{cai2020learning,\n    title={Learning Delicate Local Representations for Multi-Person Pose Estimation},\n    author={Yuanhao Cai and Zhicheng Wang and Zhengxiong Luo and Binyi Yin and Angang Du and Haoqian Wang and Xinyu Zhou and Erjin Zhou and Xiangyu Zhang and Jian Sun},\n    year={2020},\n    eprint={2003.04030},\n    archivePrefix={arXiv},\n    primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [rsn_18](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192.py) |  256x192   | 0.704 |      0.887      |      0.781      | 0.773 |      0.927      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192-9049ed09_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192_20221013.log) |\n| [rsn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.724 |      0.894      |      0.799      | 0.790 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192-c35901d5_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192_20221013.log) |\n| [2xrsn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.748 |      0.900      |      0.821      | 0.810 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192-9ede341e_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192_20221013.log) |\n| [3xrsn_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192.py) |  256x192   | 0.750 |      0.900      |      0.824      | 0.814 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192-c3e3c4fe_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192_20221013.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.yml",
    "content": "Collections:\n- Name: RSN\n  Paper:\n    Title: Learning Delicate Local Representations for Multi-Person Pose Estimation\n    URL: https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/rsn.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192.py\n  In Collection: RSN\n  Metadata:\n    Architecture: &id001\n    - RSN\n    Training Data: COCO\n  Name: td-hm_rsn18_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.704\n      AP@0.5: 0.887\n      AP@0.75: 0.781\n      AR: 0.773\n      AR@0.5: 0.927\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192-9049ed09_20221013.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py\n  In Collection: RSN\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_rsn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.724\n      AP@0.5: 0.894\n      AP@0.75: 0.799\n      AR: 0.79\n      AR@0.5: 0.935\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192-c35901d5_20221013.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192.py\n  In Collection: RSN\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_2xrsn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.748\n      AP@0.5: 0.9\n      AP@0.75: 0.821\n      AR: 0.81\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192-9ede341e_20221013.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192.py\n  In Collection: RSN\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_3xrsn50_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.75\n      AP@0.5: 0.9\n      AP@0.75: 0.824\n      AR: 0.814\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192-c3e3c4fe_20221013.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/scnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Liu_Improving_Convolutional_Networks_With_Self-Calibrated_Convolutions_CVPR_2020_paper.html\">SCNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020improving,\n  title={Improving Convolutional Networks with Self-Calibrated Convolutions},\n  author={Liu, Jiang-Jiang and Hou, Qibin and Cheng, Ming-Ming and Wang, Changhu and Feng, Jiashi},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={10096--10105},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_scnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet50_8xb64-210e_coco-256x192.py) |  256x192   | 0.728 |      0.899      |      0.807      | 0.784 |      0.938      | [ckpt](https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_coco_256x192-6920f829_20200709.pth) | [log](https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_coco_256x192_20200709.log.json) |\n| [pose_scnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet50_8xb32-210e_coco-384x288.py) |  384x288   | 0.751 |      0.906      |      0.818      | 0.802 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_coco_384x288-9cacd0ea_20200709.pth) | [log](https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_coco_384x288_20200709.log.json) |\n| [pose_scnet_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet101_8xb32-210e_coco-256x192.py) |  256x192   | 0.733 |      0.902      |      0.811      | 0.789 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_coco_256x192-6d348ef9_20200709.pth) | [log](https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_coco_256x192_20200709.log.json) |\n| [pose_scnet_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet101_8xb48-210e_coco-384x288.py) |  384x288   | 0.752 |      0.906      |      0.823      | 0.804 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_coco_384x288-0b6e631b_20200709.pth) | [log](https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_coco_384x288_20200709.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/scnet_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet50_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SCNet\n    Training Data: COCO\n  Name: td-hm_scnet50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.728\n      AP@0.5: 0.899\n      AP@0.75: 0.807\n      AR: 0.784\n      AR@0.5: 0.938\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_coco_256x192-6920f829_20200709.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet50_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: topdown_heatmap_scnet50_coco_384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.751\n      AP@0.5: 0.906\n      AP@0.75: 0.818\n      AR: 0.802\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_coco_384x288-9cacd0ea_20200709.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet101_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_scnet101_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.733\n      AP@0.5: 0.902\n      AP@0.75: 0.811\n      AR: 0.789\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_coco_256x192-6d348ef9_20200709.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet101_8xb48-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_scnet101_8xb48-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.752\n      AP@0.5: 0.906\n      AP@0.75: 0.823\n      AR: 0.804\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_coco_384x288-0b6e631b_20200709.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/seresnet_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper\">SEResNet (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{hu2018squeeze,\n  title={Squeeze-and-excitation networks},\n  author={Hu, Jie and Shen, Li and Sun, Gang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={7132--7141},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_seresnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet50_8xb64-210e_coco-256x192.py) |  256x192   | 0.729 |      0.903      |      0.807      | 0.784 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_coco_256x192-25058b66_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_coco_256x192_20200727.log.json) |\n| [pose_seresnet_50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet50_8xb64-210e_coco-384x288.py) |  384x288   | 0.748 |      0.904      |      0.819      | 0.799 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_coco_384x288-bc0b7680_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_coco_384x288_20200727.log.json) |\n| [pose_seresnet_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet101_8xb64-210e_coco-256x192.py) |  256x192   | 0.734 |      0.905      |      0.814      | 0.790 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_coco_256x192-83f29c4d_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_coco_256x192_20200727.log.json) |\n| [pose_seresnet_101](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet101_8xb32-210e_coco-384x288.py) |  384x288   | 0.754 |      0.907      |      0.823      | 0.805 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_coco_384x288-48de1709_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_coco_384x288_20200727.log.json) |\n| [pose_seresnet_152\\*](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet152_8xb32-210e_coco-256x192.py) |  256x192   | 0.730 |      0.899      |      0.810      | 0.787 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_coco_256x192-1c628d79_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_coco_256x192_20200727.log.json) |\n| [pose_seresnet_152\\*](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet152_8xb48-210e_coco-384x288.py) |  384x288   | 0.753 |      0.906      |      0.824      | 0.806 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_coco_384x288-58b23ee8_20200727.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_coco_384x288_20200727.log.json) |\n\nNote that * means without imagenet pre-training.\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/seresnet_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet50_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SEResNet\n    Training Data: COCO\n  Name: td-hm_seresnet50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.729\n      AP@0.5: 0.903\n      AP@0.75: 0.807\n      AR: 0.784\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_coco_256x192-25058b66_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet50_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_seresnet50_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.748\n      AP@0.5: 0.904\n      AP@0.75: 0.819\n      AR: 0.799\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_coco_384x288-bc0b7680_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet101_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_seresnet101_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.734\n      AP@0.5: 0.905\n      AP@0.75: 0.814\n      AR: 0.79\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_coco_256x192-83f29c4d_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet101_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_seresnet101_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.754\n      AP@0.5: 0.907\n      AP@0.75: 0.823\n      AR: 0.805\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_coco_384x288-48de1709_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet152_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_seresnet152_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.73\n      AP@0.5: 0.899\n      AP@0.75: 0.81\n      AR: 0.787\n      AR@0.5: 0.939\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_coco_256x192-1c628d79_20200727.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet152_8xb48-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_seresnet152_8xb48-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.753\n      AP@0.5: 0.906\n      AP@0.75: 0.824\n      AR: 0.806\n      AR@0.5: 0.945\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_coco_384x288-58b23ee8_20200727.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/shufflenetv1_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Zhang_ShuffleNet_An_Extremely_CVPR_2018_paper.html\">ShufflenetV1 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{zhang2018shufflenet,\n  title={Shufflenet: An extremely efficient convolutional neural network for mobile devices},\n  author={Zhang, Xiangyu and Zhou, Xinyu and Lin, Mengxiao and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={6848--6856},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_shufflenetv1](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-256x192.py) |  256x192   | 0.587 |      0.849      |      0.654      | 0.654 |      0.896      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-256x192-7a7ea4f4_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-256x192_20221013.log) |\n| [pose_shufflenetv1](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-384x288.py) |  384x288   | 0.626 |      0.862      |      0.696      | 0.687 |      0.903      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-384x288-8342f8ba_20221013.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-384x288_20221013.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/shufflenetv1_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ShufflenetV1\n    Training Data: COCO\n  Name: td-hm_shufflenetv1_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.587\n      AP@0.5: 0.849\n      AP@0.75: 0.654\n      AR: 0.654\n      AR@0.5: 0.896\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-256x192-7a7ea4f4_20221013.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_shufflenetv1_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.626\n      AP@0.5: 0.862\n      AP@0.75: 0.696\n      AR: 0.687\n      AR@0.5: 0.903\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-384x288-8342f8ba_20221013.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/shufflenetv2_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Ningning_Light-weight_CNN_Architecture_ECCV_2018_paper.html\">ShufflenetV2 (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{ma2018shufflenet,\n  title={Shufflenet v2: Practical guidelines for efficient cnn architecture design},\n  author={Ma, Ningning and Zhang, Xiangyu and Zheng, Hai-Tao and Sun, Jian},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={116--131},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_shufflenetv2](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-256x192.py) |  256x192   | 0.602 |      0.857      |      0.672      | 0.668 |      0.902      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-256x192-51fb931e_20221014.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-256x192_20221014.log) |\n| [pose_shufflenetv2](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-384x288.py) |  384x288   | 0.638 |      0.866      |      0.707      | 0.699 |      0.910      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-384x288-d30ab55c_20221014.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-384x288_20221014.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/shufflenetv2_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ShufflenetV2\n    Training Data: COCO\n  Name: td-hm_shufflenetv2_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.602\n      AP@0.5: 0.857\n      AP@0.75: 0.672\n      AR: 0.668\n      AR@0.5: 0.902\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-256x192-51fb931e_20221014.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_shufflenetv2_8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.638\n      AP@0.5: 0.866\n      AP@0.75: 0.707\n      AR: 0.699\n      AR@0.5: 0.91\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-384x288-d30ab55c_20221014.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/swin_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2103.14030\">Swin (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{liu2021swin,\n  title={Swin transformer: Hierarchical vision transformer using shifted windows},\n  author={Liu, Ze and Lin, Yutong and Cao, Yue and Hu, Han and Wei, Yixuan and Zhang, Zheng and Lin, Stephen and Guo, Baining},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={10012--10022},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content_cvpr_2017/html/Lin_Feature_Pyramid_Networks_CVPR_2017_paper.html\">FPN (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{lin2017feature,\n  title={Feature pyramid networks for object detection},\n  author={Lin, Tsung-Yi and Doll{\\'a}r, Piotr and Girshick, Ross and He, Kaiming and Hariharan, Bharath and Belongie, Serge},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2117--2125},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_swin_t](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py) |  256x192   | 0.724 |      0.901      |      0.806      | 0.782 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/top_down/swin/swin_t_p4_w7_coco_256x192-eaefe010_20220503.pth) | [log](https://download.openmmlab.com/mmpose/top_down/swin/swin_t_p4_w7_coco_256x192_20220503.log.json) |\n| [pose_swin_b](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-b-p4-w7_8xb32-210e_coco-256x192.py) |  256x192   | 0.737 |      0.904      |      0.820      | 0.794 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_coco_256x192-7432be9e_20220705.pth) | [log](https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_coco_256x192_20220705.log.json) |\n| [pose_swin_b](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-b-p4-w7_8xb32-210e_coco-384x288.py) |  384x288   | 0.759 |      0.910      |      0.832      | 0.811 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_coco_384x288-3abf54f9_20220705.pth) | [log](https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_coco_384x288_20220705.log.json) |\n| [pose_swin_l](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192.py) |  256x192   | 0.743 |      0.906      |      0.821      | 0.798 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/top_down/swin/swin_l_p4_w7_coco_256x192-642a89db_20220705.pth) | [log](https://download.openmmlab.com/mmpose/top_down/swin/swin_l_p4_w7_coco_256x192_20220705.log.json) |\n| [pose_swin_l](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-l-p4-w7_8xb32-210e_coco-384x288.py) |  384x288   | 0.763 |      0.912      |      0.830      | 0.814 |      0.949      | [ckpt](https://download.openmmlab.com/mmpose/top_down/swin/swin_l_p4_w7_coco_384x288-c36b7845_20220705.pth) | [log](https://download.openmmlab.com/mmpose/top_down/swin/swin_l_p4_w7_coco_384x288_20220705.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/swin_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - Swin\n    Training Data: COCO\n  Name: td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.724\n      AP@0.5: 0.901\n      AP@0.75: 0.806\n      AR: 0.782\n      AR@0.5: 0.94\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/swin/swin_t_p4_w7_coco_256x192-eaefe010_20220503.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-b-p4-w7_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_swin-b-p4-w7_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.737\n      AP@0.5: 0.904\n      AP@0.75: 0.82\n      AR: 0.794\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_coco_256x192-7432be9e_20220705.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-b-p4-w7_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_swin-b-p4-w7_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.759\n      AP@0.5: 0.91\n      AP@0.75: 0.832\n      AR: 0.811\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_coco_384x288-3abf54f9_20220705.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.743\n      AP@0.5: 0.906\n      AP@0.75: 0.821\n      AR: 0.798\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/swin/swin_l_p4_w7_coco_256x192-642a89db_20220705.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-l-p4-w7_8xb32-210e_coco-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_swin-l-p4-w7_8xb32-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.763\n      AP@0.5: 0.912\n      AP@0.75: 0.83\n      AR: 0.814\n      AR@0.5: 0.949\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/swin/swin_l_p4_w7_coco_384x288-c36b7845_20220705.pth\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/swin_b_p4_w7_fpn_coco_256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: topdown_heatmap_swin_b_p4_w7_fpn_coco_256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.741\n      AP@0.5: 0.907\n      AP@0.75: 0.821\n      AR: 0.798\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/swin/swin_b_p4_w7_fpn_coco_256x192-a3b91c45_20220705.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm-vis_res50_8xb64-210e_coco-aic-256x192-merge.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='VisPredictHead',\n        loss=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            use_sigmoid=True,\n            loss_weight=1e-3,\n        ),\n        pose_cfg=dict(\n            type='HeatmapHead',\n            in_channels=2048,\n            out_channels=17,\n            loss=dict(type='KeypointMSELoss', use_target_weight=True),\n            decoder=codec)),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    data_mode=data_mode,\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    # score_mode='bbox',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xmspn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [15, 11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MSPN',\n        unit_channels=256,\n        num_stages=2,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        norm_cfg=dict(type='BN'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='torchvision://resnet50',\n        )),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=2,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3] + [1, 2, 3, 4],\n        loss=([\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ]) * 2,\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_2xrsn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [15, 11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='RSN',\n        unit_channels=256,\n        num_stages=2,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        num_steps=4,\n        norm_cfg=dict(type='BN'),\n    ),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=2,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3] + [1, 2, 3, 4],\n        loss=([\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ]) * 2,\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xmspn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [15, 11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MSPN',\n        unit_channels=256,\n        num_stages=3,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        norm_cfg=dict(type='BN'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='torchvision://resnet50',\n        )),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=3,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3] * 2 + [1, 2, 3, 4],\n        loss=([\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ]) * 3,\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_3xrsn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [15, 11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='RSN',\n        unit_channels=256,\n        num_stages=3,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        num_steps=4,\n        norm_cfg=dict(type='BN'),\n    ),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=3,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3] * 2 + [1, 2, 3, 4],\n        loss=([\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ]) * 3,\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_4xmspn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [15, 11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MSPN',\n        unit_channels=256,\n        num_stages=4,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        norm_cfg=dict(type='BN'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='torchvision://resnet50',\n        )),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=4,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3] * 3 + [1, 2, 3, 4],\n        loss=([\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ]) * 4,\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=12,\n        layer_decay_rate=0.75,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='base',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.3,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_base_20230913.pth'),\n    ),\n    neck=dict(type='FeatureMapProcessor', scale_factor=4.0, apply_relu=True),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        deconv_out_channels=[],\n        deconv_kernel_sizes=[],\n        final_layer=dict(kernel_size=3, padding=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec,\n    ),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=12,\n        layer_decay_rate=0.75,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='base',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.3,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_base_20230913.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=32,\n        layer_decay_rate=0.85,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='huge',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.55,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_huge_20230913.pth'),\n    ),\n    neck=dict(type='FeatureMapProcessor', scale_factor=4.0, apply_relu=True),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=17,\n        deconv_out_channels=[],\n        deconv_kernel_sizes=[],\n        final_layer=dict(kernel_size=3, padding=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec,\n    ),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=32,\n        layer_decay_rate=0.85,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='huge',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.55,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_huge_20230913.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=24,\n        layer_decay_rate=0.8,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='large',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.5,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_large_20230913.pth'),\n    ),\n    neck=dict(type='FeatureMapProcessor', scale_factor=4.0, apply_relu=True),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        deconv_out_channels=[],\n        deconv_kernel_sizes=[],\n        final_layer=dict(kernel_size=3, padding=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec,\n    ),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=24,\n        layer_decay_rate=0.8,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='large',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.5,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_large_20230913.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=12,\n        layer_decay_rate=0.8,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch={\n            'embed_dims': 384,\n            'num_layers': 12,\n            'num_heads': 12,\n            'feedforward_channels': 384 * 4\n        },\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.1,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_small_20230913.pth'),\n    ),\n    neck=dict(type='FeatureMapProcessor', scale_factor=4.0, apply_relu=True),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=384,\n        out_channels=17,\n        deconv_out_channels=[],\n        deconv_kernel_sizes=[],\n        final_layer=dict(kernel_size=3, padding=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec,\n    ),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=12,\n        layer_decay_rate=0.8,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch={\n            'embed_dims': 384,\n            'num_layers': 12,\n            'num_heads': 12,\n            'feedforward_channels': 384 * 4\n        },\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.1,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_small_20230913.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=384,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_alexnet_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(40, 56), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='AlexNet', num_classes=-1),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=256,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(36, 48), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CPM',\n        in_channels=3,\n        out_channels=17,\n        feat_channels=128,\n        num_stages=6),\n    head=dict(\n        type='CPMHead',\n        in_channels=17,\n        out_channels=17,\n        num_stages=6,\n        deconv_out_channels=None,\n        final_layer=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_cpm_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(24, 32), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CPM',\n        in_channels=3,\n        out_channels=17,\n        feat_channels=128,\n        num_stages=6),\n    head=dict(\n        type='CPMHead',\n        in_channels=17,\n        out_channels=17,\n        num_stages=6,\n        deconv_out_channels=None,\n        final_layer=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hourglass52_8xb32-210e_coco-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HourglassNet',\n        num_stacks=1,\n    ),\n    head=dict(\n        type='CPMHead',\n        in_channels=256,\n        out_channels=17,\n        num_stages=1,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hourglass52_8xb32-210e_coco-384x384.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(384, 384), heatmap_size=(96, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HourglassNet',\n        num_stacks=1,\n    ),\n    head=dict(\n        type='CPMHead',\n        in_channels=256,\n        out_channels=17,\n        num_stages=1,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-base_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW',\n        lr=5e-4,\n        betas=(0.9, 0.999),\n        weight_decay=0.01,\n    ),\n    paramwise_cfg=dict(\n        custom_keys={'relative_position_bias_table': dict(decay_mult=0.)}))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRFormer',\n        in_channels=3,\n        norm_cfg=norm_cfg,\n        extra=dict(\n            drop_path_rate=0.2,\n            with_rpe=True,\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(2, ),\n                num_channels=(64, ),\n                num_heads=[2],\n                mlp_ratios=[4]),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2),\n                num_channels=(78, 156),\n                num_heads=[2, 4],\n                mlp_ratios=[4, 4],\n                window_sizes=[7, 7]),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2),\n                num_channels=(78, 156, 312),\n                num_heads=[2, 4, 8],\n                mlp_ratios=[4, 4, 4],\n                window_sizes=[7, 7, 7]),\n            stage4=dict(\n                num_modules=2,\n                num_branches=4,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2, 2),\n                num_channels=(78, 156, 312, 624),\n                num_heads=[2, 4, 8, 16],\n                mlp_ratios=[4, 4, 4, 4],\n                window_sizes=[7, 7, 7, 7])),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrformer_base-32815020_20220226.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=78,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-base_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW',\n        lr=5e-4,\n        betas=(0.9, 0.999),\n        weight_decay=0.01,\n    ),\n    paramwise_cfg=dict(\n        custom_keys={'relative_position_bias_table': dict(decay_mult=0.)}))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRFormer',\n        in_channels=3,\n        norm_cfg=norm_cfg,\n        extra=dict(\n            drop_path_rate=0.2,\n            with_rpe=True,\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(2, ),\n                num_channels=(64, ),\n                num_heads=[2],\n                mlp_ratios=[4]),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2),\n                num_channels=(78, 156),\n                num_heads=[2, 4],\n                mlp_ratios=[4, 4],\n                window_sizes=[7, 7]),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2),\n                num_channels=(78, 156, 312),\n                num_heads=[2, 4, 8],\n                mlp_ratios=[4, 4, 4],\n                window_sizes=[7, 7, 7]),\n            stage4=dict(\n                num_modules=2,\n                num_branches=4,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2, 2),\n                num_channels=(78, 156, 312, 624),\n                num_heads=[2, 4, 8, 16],\n                mlp_ratios=[4, 4, 4, 4],\n                window_sizes=[7, 7, 7, 7])),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrformer_base-32815020_20220226.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=78,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-small_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW',\n        lr=5e-4,\n        betas=(0.9, 0.999),\n        weight_decay=0.01,\n    ),\n    paramwise_cfg=dict(\n        custom_keys={'relative_position_bias_table': dict(decay_mult=0.)}))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRFormer',\n        in_channels=3,\n        norm_cfg=norm_cfg,\n        extra=dict(\n            drop_path_rate=0.1,\n            with_rpe=True,\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(2, ),\n                num_channels=(64, ),\n                num_heads=[2],\n                num_mlp_ratios=[4]),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2),\n                num_channels=(32, 64),\n                num_heads=[1, 2],\n                mlp_ratios=[4, 4],\n                window_sizes=[7, 7]),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2),\n                num_channels=(32, 64, 128),\n                num_heads=[1, 2, 4],\n                mlp_ratios=[4, 4, 4],\n                window_sizes=[7, 7, 7]),\n            stage4=dict(\n                num_modules=2,\n                num_branches=4,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2, 2),\n                num_channels=(32, 64, 128, 256),\n                num_heads=[1, 2, 4, 8],\n                mlp_ratios=[4, 4, 4, 4],\n                window_sizes=[7, 7, 7, 7])),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrformer_small-09516375_20220226.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrformer-small_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW',\n        lr=5e-4,\n        betas=(0.9, 0.999),\n        weight_decay=0.01,\n    ),\n    paramwise_cfg=dict(\n        custom_keys={'relative_position_bias_table': dict(decay_mult=0.)}))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRFormer',\n        in_channels=3,\n        norm_cfg=norm_cfg,\n        extra=dict(\n            drop_path_rate=0.1,\n            with_rpe=True,\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(2, ),\n                num_channels=(64, ),\n                num_heads=[2],\n                num_mlp_ratios=[4]),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2),\n                num_channels=(32, 64),\n                num_heads=[1, 2],\n                mlp_ratios=[4, 4],\n                window_sizes=[7, 7]),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2),\n                num_channels=(32, 64, 128),\n                num_heads=[1, 2, 4],\n                mlp_ratios=[4, 4, 4],\n                window_sizes=[7, 7, 7]),\n            stage4=dict(\n                num_modules=2,\n                num_branches=4,\n                block='HRFORMERBLOCK',\n                num_blocks=(2, 2, 2, 2),\n                num_channels=(32, 64, 128, 256),\n                num_heads=[1, 2, 4, 8],\n                mlp_ratios=[4, 4, 4, 4],\n                window_sizes=[7, 7, 7, 7])),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrformer_small-09516375_20220226.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=3))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# keypoint mappings\nkeypoint_mapping_coco = [\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nkeypoint_mapping_aic = [\n    (0, 6),\n    (1, 8),\n    (2, 10),\n    (3, 5),\n    (4, 7),\n    (5, 9),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 11),\n    (10, 13),\n    (11, 15),\n    (12, 17),\n    (13, 18),\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=19,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n        output_keypoint_indices=[\n            target for _, target in keypoint_mapping_coco\n        ]))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,\n            mapping=keypoint_mapping_coco)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    data_mode=data_mode,\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,\n            mapping=keypoint_mapping_aic)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    data_mode=data_mode,\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_coarsedropout-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'body_2d_keypoint/topdown_heatmap/coco/'\n            'td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(\n                type='CoarseDropout',\n                max_holes=8,\n                max_height=40,\n                max_width=40,\n                min_holes=1,\n                min_height=10,\n                min_width=10,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_dark-8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(288, 384),\n    heatmap_size=(72, 96),\n    sigma=3,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_fp16-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['./td-hm_hrnet-w32_8xb64-210e_coco-256x192.py']\n\n# fp16 settings\noptim_wrapper = dict(\n    type='AmpOptimWrapper',\n    loss_scale='dynamic',\n)\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_gridmask-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'body_2d_keypoint/topdown_heatmap/coco/'\n            'td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(\n                type='GridDropout',\n                unit_size_min=10,\n                unit_size_max=40,\n                random_offset=True,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_photometric-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'body_2d_keypoint/topdown_heatmap/coco/'\n            'td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_udp-regress-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    heatmap_type='combined')\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=3 * 17,\n        deconv_out_channels=None,\n        loss=dict(type='CombinedTargetMSELoss', use_target_weight=True),\n        decoder=codec),\n    train_cfg=dict(compute_acc=False),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='udp_combined',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_dark-8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(288, 384),\n    heatmap_size=(72, 96),\n    sigma=3,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-18_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(2, 4, 2),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-18_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(2, 4, 2),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-30_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(3, 8, 3),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_litehrnet-30_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(3, 8, 3),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='mmcls://mobilenet_v2',\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mobilenetv2_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='mmcls://mobilenet_v2',\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_mspn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MSPN',\n        unit_channels=256,\n        num_stages=1,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        norm_cfg=dict(type='BN'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='torchvision://resnet50',\n        )),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=1,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3],\n        loss=[\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ],\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_pvt-s_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='PyramidVisionTransformer',\n        num_layers=[3, 4, 6, 3],\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/whai362/PVT/'\n            'releases/download/v2/pvt_small.pth'),\n    ),\n    neck=dict(type='FeatureMapProcessor', select_index=3),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_pvtv2-b2_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='PyramidVisionTransformerV2',\n        embed_dims=64,\n        num_layers=[3, 4, 6, 3],\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/whai362/PVT/'\n            'releases/download/v2/pvt_v2_b2.pth'),\n    ),\n    neck=dict(type='FeatureMapProcessor', select_index=3),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res101_dark-8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(288, 384),\n    heatmap_size=(72, 96),\n    sigma=3,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res152_dark-8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(288, 384),\n    heatmap_size=(72, 96),\n    sigma=3,\n    unbiased=True,\n    blur_kernel_size=17)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_dark-8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(288, 384),\n    heatmap_size=(72, 96),\n    sigma=3,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_fp16-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['./td-hm_res50_8xb64-210e_coco-256x192.py']\n\n# fp16 settings\noptim_wrapper = dict(\n    type='AmpOptimWrapper',\n    loss_scale='dynamic',\n)\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest101_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest101_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest200_8xb16-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=128)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=200,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest200'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=16,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest200_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=200,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest200'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest269_8xb16-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=128)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=269,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest269'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=16,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest269_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=269,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest269'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnest50_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeSt',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnest50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet101_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d101_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet101_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet152_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d152_8xb48-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=384)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet152_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=48,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet50_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnetv1d50_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet50_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext101_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=101,\n        init_cfg=dict(\n            type='Pretrained', checkpoint='mmcls://resnext101_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext101_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=101,\n        init_cfg=dict(\n            type='Pretrained', checkpoint='mmcls://resnext101_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext152_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=152,\n        init_cfg=dict(\n            type='Pretrained', checkpoint='mmcls://resnext152_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext152_8xb48-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=384)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=152,\n        init_cfg=dict(\n            type='Pretrained', checkpoint='mmcls://resnext152_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=48,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnext50_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_resnext50_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnext50_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn18_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-2,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 190, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='RSN',\n        unit_channels=256,\n        num_stages=1,\n        num_units=4,\n        num_blocks=[2, 2, 2, 2],\n        num_steps=4,\n        norm_cfg=dict(type='BN'),\n    ),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=1,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3],\n        loss=[\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ],\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_rsn50_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\n# multiple kernel_sizes of heatmap gaussian for 'Megvii' approach.\nkernel_sizes = [11, 9, 7, 5]\ncodec = [\n    dict(\n        type='MegviiHeatmap',\n        input_size=(192, 256),\n        heatmap_size=(48, 64),\n        kernel_size=kernel_size) for kernel_size in kernel_sizes\n]\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='RSN',\n        unit_channels=256,\n        num_stages=1,\n        num_units=4,\n        num_blocks=[3, 4, 6, 3],\n        num_steps=4,\n        norm_cfg=dict(type='BN'),\n    ),\n    head=dict(\n        type='MSPNHead',\n        out_shape=(64, 48),\n        unit_channels=256,\n        out_channels=17,\n        num_stages=1,\n        num_units=4,\n        norm_cfg=dict(type='BN'),\n        # each sub list is for a stage\n        # and each element in each list is for a unit\n        level_indices=[0, 1, 2, 3],\n        loss=[\n            dict(\n                type='KeypointMSELoss',\n                use_target_weight=True,\n                loss_weight=0.25)\n        ] * 3 + [\n            dict(\n                type='KeypointOHKMMSELoss',\n                use_target_weight=True,\n                loss_weight=1.)\n        ],\n        decoder=codec[-1]),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='GenerateTarget', multilevel=True, encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec[0]['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    nms_mode='none')\ntest_evaluator = val_evaluator\n\n# fp16 settings\nfp16 = dict(loss_scale='dynamic')\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet101_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=101,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet101-94250a77.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=1,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet101_8xb48-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=101,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet101-94250a77.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=48,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet50_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet50-7ef0a199.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=1,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_scnet50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet50-7ef0a199.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet101_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://se-resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet101_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://se-resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet152_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=152,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet152_8xb48-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=384)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=152,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=48,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://se-resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_seresnet50_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://se-resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ShuffleNetV1',\n        groups=3,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://shufflenet_v1'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=960,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv1_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ShuffleNetV1',\n        groups=3,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://shufflenet_v1'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=960,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ShuffleNetV2',\n        widen_factor=1.0,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://shufflenet_v2'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_shufflenetv2_8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ShuffleNetV2',\n        widen_factor=1.0,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://shufflenet_v2'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-b-p4-w7_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SwinTransformer',\n        embed_dims=128,\n        depths=[2, 2, 18, 2],\n        num_heads=[4, 8, 16, 32],\n        window_size=7,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.3,\n        patch_norm=True,\n        out_indices=(3, ),\n        with_cp=False,\n        convert_weights=True,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/SwinTransformer/storage/releases/'\n            'download/v1.0.0/swin_base_patch4_window7_224_22k.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-b-p4-w7_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SwinTransformer',\n        embed_dims=128,\n        depths=[2, 2, 18, 2],\n        num_heads=[4, 8, 16, 32],\n        window_size=12,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.3,\n        patch_norm=True,\n        out_indices=(3, ),\n        with_cp=False,\n        convert_weights=True,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/SwinTransformer/storage/releases/'\n            'download/v1.0.0/swin_base_patch4_window12_384_22k.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-l-p4-w7_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW',\n        lr=5e-4,\n        betas=(0.9, 0.999),\n        weight_decay=0.01,\n    ),\n    paramwise_cfg=dict(\n        custom_keys={\n            'absolute_pos_embed': dict(decay_mult=0.),\n            'relative_position_bias_table': dict(decay_mult=0.),\n            'norm': dict(decay_mult=0.)\n        }))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SwinTransformer',\n        embed_dims=192,\n        depths=[2, 2, 18, 2],\n        num_heads=[6, 12, 24, 48],\n        window_size=7,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.5,\n        patch_norm=True,\n        out_indices=(3, ),\n        with_cp=False,\n        convert_weights=True,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/SwinTransformer/storage/releases/'\n            'download/v1.0.0/swin_base_patch4_window7_224_22k.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1536,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-l-p4-w7_8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW',\n        lr=5e-4,\n        betas=(0.9, 0.999),\n        weight_decay=0.01,\n    ),\n    paramwise_cfg=dict(\n        custom_keys={\n            'absolute_pos_embed': dict(decay_mult=0.),\n            'relative_position_bias_table': dict(decay_mult=0.),\n            'norm': dict(decay_mult=0.)\n        }))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SwinTransformer',\n        embed_dims=192,\n        depths=[2, 2, 18, 2],\n        num_heads=[6, 12, 24, 48],\n        window_size=7,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.5,\n        patch_norm=True,\n        out_indices=(3, ),\n        with_cp=False,\n        convert_weights=True,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/SwinTransformer/storage/releases/'\n            'download/v1.0.0/swin_base_patch4_window12_384_22k.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1536,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_swin-t-p4-w7_8xb32-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SwinTransformer',\n        embed_dims=96,\n        depths=[2, 2, 6, 2],\n        num_heads=[3, 6, 12, 24],\n        window_size=7,\n        mlp_ratio=4,\n        qkv_bias=True,\n        qk_scale=None,\n        drop_rate=0.,\n        attn_drop_rate=0.,\n        drop_path_rate=0.2,\n        patch_norm=True,\n        out_indices=(3, ),\n        with_cp=False,\n        convert_weights=True,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://github.com/SwinTransformer/storage/releases/'\n            'download/v1.0.0/swin_tiny_patch4_window7_224.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vgg16-bn_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='VGG',\n        depth=16,\n        norm_cfg=dict(type='BN'),\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://vgg16_bn'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-mbv3_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ViPNAS_MobileNetV3'),\n    head=dict(\n        type='ViPNASHead',\n        in_channels=160,\n        out_channels=17,\n        deconv_out_channels=(160, 160, 160),\n        deconv_num_groups=(160, 160, 160),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-res50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ViPNAS_ResNet', depth=50),\n    head=dict(\n        type='ViPNASHead',\n        in_channels=608,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/vgg_coco.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1409.1556\">VGG (ICLR'2015)</a></summary>\n\n```bibtex\n@article{simonyan2014very,\n  title={Very deep convolutional networks for large-scale image recognition},\n  author={Simonyan, Karen and Zisserman, Andrew},\n  journal={arXiv preprint arXiv:1409.1556},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [vgg](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vgg16-bn_8xb64-210e_coco-256x192.py) |  256x192   | 0.699 |      0.890      |      0.769      | 0.754 |      0.927      | [ckpt](https://download.openmmlab.com/mmpose/top_down/vgg/vgg16_bn_coco_256x192-7e7c58d6_20210517.pth) | [log](https://download.openmmlab.com/mmpose/top_down/vgg/vgg16_bn_coco_256x192_20210517.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/vgg_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vgg16-bn_8xb64-210e_coco-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - VGG\n    Training Data: COCO\n  Name: td-hm_vgg16-bn_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.699\n      AP@0.5: 0.89\n      AP@0.75: 0.769\n      AR: 0.754\n      AR@0.5: 0.927\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/vgg/vgg16_bn_coco_256x192-7e7c58d6_20210517.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/vipnas_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2105.10154\">ViPNAS (CVPR'2021)</a></summary>\n\n```bibtex\n@article{xu2021vipnas,\n  title={ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search},\n  author={Xu, Lumin and Guan, Yingda and Jin, Sheng and Liu, Wentao and Qian, Chen and Luo, Ping and Ouyang, Wanli and Wang, Xiaogang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [S-ViPNAS-MobileNetV3](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-mbv3_8xb64-210e_coco-256x192.py) |  256x192   | 0.700 |      0.887      |      0.783      | 0.758 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-mbv3_8xb64-210e_coco-256x192-e0987441_20221010.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-mbv3_8xb64-210e_coco-256x192_20221010.log) |\n| [S-ViPNAS-Res50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-res50_8xb64-210e_coco-256x192.py) |  256x192   | 0.711 |      0.894      |      0.787      | 0.769 |      0.934      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-res50_8xb64-210e_coco-256x192-35d4bff9_20220917.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-res50_8xb64-210e_coco-256x192_20220917.log) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/vipnas_coco.yml",
    "content": "Collections:\n- Name: ViPNAS\n  Paper:\n    Title: 'ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search'\n    URL: https://arxiv.org/abs/2105.10154\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/vipnas.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-mbv3_8xb64-210e_coco-256x192.py\n  In Collection: ViPNAS\n  Metadata:\n    Architecture: &id001\n    - ViPNAS\n    Training Data: COCO\n  Name: td-hm_vipnas-mbv3_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.7\n      AP@0.5: 0.887\n      AP@0.75: 0.783\n      AR: 0.758\n      AR@0.5: 0.929\n    Task: Body 2D Keypoint\n  Weights: (https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-mbv3_8xb64-210e_coco-256x192-e0987441_20221010.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-res50_8xb64-210e_coco-256x192.py\n  In Collection: ViPNAS\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-hm_vipnas-res50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.711\n      AP@0.5: 0.894\n      AP@0.75: 0.787\n      AR: 0.769\n      AR@0.5: 0.934\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_vipnas-res50_8xb64-210e_coco-256x192-35d4bff9_20220917.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/vitpose_coco.md",
    "content": "To utilize ViTPose, you'll need to have [MMPreTrain](https://github.com/open-mmlab/mmpretrain). To install the required version, run the following command:\n\n```shell\nmim install 'mmpretrain>=1.0.0'\n```\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.12484\">ViTPose (NeurIPS'2022)</a></summary>\n\n```bibtex\n@inproceedings{\n  xu2022vitpose,\n  title={Vi{TP}ose: Simple Vision Transformer Baselines for Human Pose Estimation},\n  author={Yufei Xu and Jing Zhang and Qiming Zhang and Dacheng Tao},\n  booktitle={Advances in Neural Information Processing Systems},\n  year={2022},\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ViTPose-S](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192.py) |  256x192   | 0.739 |      0.903      |      0.816      | 0.792 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.json) |\n| [ViTPose-B](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py) |  256x192   | 0.757 |      0.905      |      0.829      | 0.810 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.json) |\n| [ViTPose-L](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192.py) |  256x192   | 0.782 |      0.914      |      0.850      | 0.834 |      0.952      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.json) |\n| [ViTPose-H](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py) |  256x192   | 0.788 |      0.917      |      0.855      | 0.839 |      0.954      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.json) |\n| [ViTPose-H\\*](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py) |  256x192   | 0.790 |      0.916      |      0.857      | 0.840 |      0.953      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_3rdparty_coco-256x192-5b738c8e_20230314.pth) |                       -                       |\n\n*Models with * are converted from the [official repo](https://github.com/ViTAE-Transformer/ViTPose).  The config files of these models are only for validation.*\n\n> With simple decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ViTPose-S](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192.py) |  256x192   | 0.736 |      0.900      |      0.811      | 0.790 |      0.940      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192-4c101a76_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192-4c101a76_20230314.json) |\n| [ViTPose-B](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192.py) |  256x192   | 0.756 |      0.906      |      0.826      | 0.809 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192-0b8234ea_20230407.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192-0b8234ea_20230407.json) |\n| [ViTPose-L](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192.py) |  256x192   | 0.780 |      0.914      |      0.851      | 0.833 |      0.952      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192-3a7ee9e1_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192-3a7ee9e1_20230314.json) |\n| [ViTPose-H](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192.py) |  256x192   | 0.789 |      0.916      |      0.856      | 0.839 |      0.953      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192-ffd48c05_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192-ffd48c05_20230314.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/coco/vitpose_coco.yml",
    "content": "Collections:\n- Name: ViTPose\n  Paper:\n    Title: 'ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation'\n    URL: https://arxiv.org/abs/2204.12484\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/vitpose.md\n  Metadata:\n    Training Resources: 8x A100 GPUs\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: &id001\n    - ViTPose\n    - Classic Head\n    Model Size: Small\n    Training Data: COCO\n  Name: td-hm_ViTPose-small_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.739\n      AP@0.5: 0.903\n      AP@0.75: 0.816\n      AR: 0.792\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: *id001\n    Model Size: Base\n    Training Data: COCO\n  Name: td-hm_ViTPose-base_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.757\n      AP@0.5: 0.905\n      AP@0.75: 0.829\n      AR: 0.81\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: *id001\n    Model Size: Large\n    Training Data: COCO\n  Name: td-hm_ViTPose-large_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.782\n      AP@0.5: 0.914\n      AP@0.75: 0.850\n      AR: 0.834\n      AR@0.5: 0.952\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: *id001\n    Model Size: Huge\n    Training Data: COCO\n  Name: td-hm_ViTPose-huge_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.788\n      AP@0.5: 0.917\n      AP@0.75: 0.855\n      AR: 0.839\n      AR@0.5: 0.954\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Alias: vitpose-s\n  Metadata:\n    Architecture: &id002\n    - ViTPose\n    - Simple Head\n    Model Size: Small\n    Training Data: COCO\n  Name: td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.736\n      AP@0.5: 0.900\n      AP@0.75: 0.811\n      AR: 0.790\n      AR@0.5: 0.940\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192-4c101a76_20230314.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Alias:\n  - vitpose\n  - vitpose-b\n  Metadata:\n    Architecture: *id002\n    Model Size: Base\n    Training Data: COCO\n  Name: td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.756\n      AP@0.5: 0.906\n      AP@0.75: 0.826\n      AR: 0.809\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192-0b8234ea_20230407.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Alias: vitpose-l\n  Metadata:\n    Architecture: *id002\n    Model Size: Large\n    Training Data: COCO\n  Name: td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.780\n      AP@0.5: 0.914\n      AP@0.75: 0.851\n      AR: 0.833\n      AR@0.5: 0.952\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192-3a7ee9e1_20230314.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192.py\n  In Collection: ViTPose\n  Alias: vitpose-h\n  Metadata:\n    Architecture: *id002\n    Model Size: Huge\n    Training Data: COCO\n  Name: td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.789\n      AP@0.5: 0.916\n      AP@0.75: 0.856\n      AR: 0.839\n      AR@0.5: 0.953\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192-ffd48c05_20230314.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/cspnext-m_udp_8xb64-210e_crowpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=14,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='pose/CrowdPose/images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='crowdpose/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'crowdpose/annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/cspnext_udp_crowdpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\nResults on CrowdPose test with [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) human detector\n\n| Arch                                           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                      ckpt                      |                      log                      |\n| :--------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :--------------------------------------------: | :-------------------------------------------: |\n| [pose_cspnext_m](/configs/body_2d_keypoint/topdown_heatmap/crowdpose/cspnext-m_udp_8xb64-210e_crowpose-256x192.py) |  256x192   | 0.662 |      0.821      |      0.723      | 0.759  | 0.675  | 0.539  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-crowdpose_pt-in1k_210e-256x192-f591079f_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-crowdpose_pt-in1k_210e-256x192-f591079f_20230123.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/cspnext_udp_crowdpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/crowdpose/cspnext-m_udp_8xb64-210e_crowpose-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture:\n    - UDP\n    - CSPNeXt\n    Training Data: CrowdPose\n  Name: cspnext-m_udp_8xb64-210e_crowpose-256x192\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.662\n      AP (E): 0.759\n      AP (H): 0.539\n      AP (M): 0.675\n      AP@0.5: 0.821\n      AP@0.75: 0.723\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-crowdpose_pt-in1k_210e-256x192-f591079f_20230123.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/hrnet_crowdpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\nResults on CrowdPose test with [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) human detector\n\n| Arch                                           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                      ckpt                      |                      log                      |\n| :--------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :--------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_hrnet-w32_8xb64-210e_crowdpose-256x192.py) |  256x192   | 0.675 |      0.825      |      0.729      | 0.770  | 0.687  | 0.553  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_crowdpose_256x192-960be101_20201227.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_crowdpose_256x192_20201227.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/hrnet_crowdpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_hrnet-w32_8xb64-210e_crowdpose-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture:\n    - HRNet\n    Training Data: CrowdPose\n  Name: td-hm_hrnet-w32_8xb64-210e_crowdpose-256x192\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.675\n      AP (E): 0.77\n      AP (H): 0.553\n      AP (M): 0.687\n      AP@0.5: 0.825\n      AP@0.75: 0.729\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_crowdpose_256x192-960be101_20201227.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/resnet_crowdpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\nResults on CrowdPose test with [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) human detector\n\n| Arch                                           | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                      ckpt                      |                      log                      |\n| :--------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :--------------------------------------------: | :-------------------------------------------: |\n| [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res50_8xb64-210e_crowdpose-256x192.py) |  256x192   | 0.637 |      0.808      |      0.692      | 0.738  | 0.650  | 0.506  | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_crowdpose_256x192-c6a526b6_20201227.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_crowdpose_256x192_20201227.log.json) |\n| [pose_resnet_101](/configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res101_8xb64-210e_crowdpose-256x192.py) |  256x192   | 0.647 |      0.810      |      0.703      | 0.745  | 0.658  | 0.521  | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res101_crowdpose_256x192-8f5870f4_20201227.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res101_crowdpose_256x192_20201227.log.json) |\n| [pose_resnet_101](/configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res101_8xb64-210e_crowdpose-320x256.py) |  320x256   | 0.661 |      0.821      |      0.714      | 0.759  | 0.672  | 0.534  | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res101_crowdpose_320x256-c88c512a_20201227.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res101_crowdpose_320x256_20201227.log.json) |\n| [pose_resnet_152](/configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res152_8xb64-210e_crowdpose-256x192.py) |  256x192   | 0.656 |      0.818      |      0.712      | 0.754  | 0.666  | 0.533  | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res152_crowdpose_256x192-dbd49aba_20201227.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res152_crowdpose_256x192_20201227.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/resnet_crowdpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res50_8xb64-210e_crowdpose-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: CrowdPose\n  Name: td-hm_res50_8xb64-210e_crowdpose-256x192\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.637\n      AP (E): 0.738\n      AP (H): 0.506\n      AP (M): 0.65\n      AP@0.5: 0.808\n      AP@0.75: 0.692\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_crowdpose_256x192-c6a526b6_20201227.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res101_8xb64-210e_crowdpose-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: td-hm_res101_8xb64-210e_crowdpose-256x192\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.647\n      AP (E): 0.745\n      AP (H): 0.521\n      AP (M): 0.658\n      AP@0.5: 0.81\n      AP@0.75: 0.703\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res101_crowdpose_256x192-8f5870f4_20201227.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res101_8xb64-210e_crowdpose-320x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: td-hm_res101_8xb64-210e_crowdpose-320x256\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.661\n      AP (E): 0.759\n      AP (H): 0.534\n      AP (M): 0.672\n      AP@0.5: 0.821\n      AP@0.75: 0.714\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res101_crowdpose_320x256-c88c512a_20201227.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res152_8xb64-210e_crowdpose-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: CrowdPose\n  Name: td-hm_res152_8xb64-210e_crowdpose-256x192\n  Results:\n  - Dataset: CrowdPose\n    Metrics:\n      AP: 0.656\n      AP (E): 0.754\n      AP (H): 0.533\n      AP (M): 0.666\n      AP@0.5: 0.818\n      AP@0.75: 0.712\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res152_crowdpose_256x192-dbd49aba_20201227.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_hrnet-w32_8xb64-210e_crowdpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=14,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res101_8xb64-210e_crowdpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=14,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res101_8xb64-210e_crowdpose-320x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 320), heatmap_size=(64, 80), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=14,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res152_8xb64-210e_crowdpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=14,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/crowdpose/td-hm_res50_8xb64-210e_crowdpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='crowdpose/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=14,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CrowdPoseDataset'\ndata_mode = 'topdown'\ndata_root = 'data/crowdpose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_trainval.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mmpose_crowdpose_test.json',\n        bbox_file='data/crowdpose/annotations/det_for_crowd_test_0.1_0.5.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/mmpose_crowdpose_test.json',\n    use_area=False,\n    iou_type='keypoints_crowd',\n    prefix='crowdpose')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/exlpose/hrnet_exlpose.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://cg.postech.ac.kr/research/ExLPose/\">ExLPose (2023)</a></summary>\n\n```bibtex\n@inproceedings{ExLPose_2023_CVPR,\n title={Human Pose Estimation in Extremely Low-Light Conditions},\n author={Sohyun Lee, Jaesung Rim, Boseung Jeong, Geonu Kim, ByungJu Woo, Haechan Lee, Sunghyun Cho, Suha Kwak},\n booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n year={2023}\n}\n```\n\n</details>\n\nResults on ExLPose-LLA val set with ground-truth bounding boxes\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/exlpose/td-hm_hrnet-w32_8xb64-210e_exlpose-256x192.py) |  256x192   | 0.401 |      0.64       |      0.40       | 0.452 |      0.693      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/exlpose/td-hm_hrnet-w32_8xb64-210e_exlpose-ll-256x192.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/exlpose/td-hm_hrnet-w32_8xb64-210e_exlpose-ll-256x192.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/exlpose/hrnet_exlpose.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/exlpose/td-hm_hrnet-w32_8xb64-210e_exlpose-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture:\n    - HRNet\n    Training Data: ExLPose-LL\n  Name: td-hm_hrnet-w32_8xb64-210e_exlpose-256x192\n  Results:\n  - Dataset: ExLPose\n    Metrics:\n      AP: 0.401\n      AP@0.5: 0.64\n      AP@0.75: 0.40\n      AR: 0.452\n      AR@0.5: 0.693\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/exlpose/td-hm_hrnet-w32_8xb64-210e_exlpose-ll-256x192.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/exlpose/td-hm_hrnet-w32_8xb64-210e_exlpose-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=14,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'ExlposeDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ExLPose/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ExLPose/ExLPose_train_LL.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ExLPose/ExLPose_test_LL-A.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ExLPose/ExLPose_test_LL-A.json',\n    use_area=False)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/hrnet_humanart.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://idea-research.github.io/HumanArt/\">Human-Art (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ju2023humanart,\n    title={Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes},\n    author={Ju, Xuan and Zeng, Ailing and Jianan, Wang and Qiang, Xu and Lei, Zhang},\n    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR),\n    year={2023}}\n```\n\n</details>\n\nResults on Human-Art validation dataset with detector having human AP of 56.2 on Human-Art validation dataset\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32-coco](configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) |  256x192   | 0.252 |      0.397      |      0.255      | 0.321 |      0.485      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220909.log) |\n| [pose_hrnet_w32-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w32_8xb64-210e_humanart-256x192.py) |  256x192   | 0.399 |      0.545      |      0.420      | 0.466 |      0.613      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.json) |\n| [pose_hrnet_w48-coco](configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py) |  256x192   | 0.271 |      0.413      |      0.277      | 0.339 |      0.499      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192_20220913.log) |\n| [pose_hrnet_w48-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w48_8xb32-210e_humanart-256x192.py) |  256x192   | 0.417 |      0.553      |      0.442      | 0.481 |      0.617      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.json) |\n\nResults on Human-Art validation dataset with ground-truth bounding-box\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32-coco](configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) |  256x192   | 0.533 |      0.771      |      0.562      | 0.574 |      0.792      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220909.log) |\n| [pose_hrnet_w32-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w32_8xb64-210e_humanart-256x192.py) |  256x192   | 0.754 |      0.906      |      0.812      | 0.783 |      0.916      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.json) |\n| [pose_hrnet_w48-coco](configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py) |  256x192   | 0.557 |      0.782      |      0.593      | 0.595 |      0.804      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192_20220913.log) |\n| [pose_hrnet_w48-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w48_8xb32-210e_humanart-256x192.py) |  256x192   | 0.769 |      0.906      |      0.825      | 0.796 |      0.919      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.json) |\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [pose_hrnet_w32-coco](configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) |  256x192   | 0.749 |      0.906      |      0.821      | 0.804 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220909.log) |\n| [pose_hrnet_w32-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w32_8xb64-210e_humanart-256x192.py) |  256x192   | 0.741 |      0.902      |      0.814      | 0.795 |      0.941      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.json) |\n| [pose_hrnet_w48-coco](configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py) |  256x192   | 0.756 |      0.908      |      0.826      | 0.809 |      0.945      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192_20220913.log) |\n| [pose_hrnet_w48-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w48_8xb32-210e_humanart-256x192.py) |  256x192   | 0.751 |      0.905      |      0.822      | 0.805 |      0.943      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/hrnet_humanart.yml",
    "content": "Collections:\n- Name: HRNet\n  Paper:\n    Title: Deep high-resolution representation learning for human pose estimation\n    URL: http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/hrnet.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w32_8xb64-210e_humanart-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: &id002\n    - COCO\n    - Human-Art\n  Name: td-hm_hrnet-w32_8xb64-210e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.741\n      AP@0.5: 0.902\n      AP@0.75: 0.814\n      AR: 0.795\n      AR@0.5: 0.941\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.399\n      AP@0.5: 0.545\n      AP@0.75: 0.420\n      AR: 0.466\n      AR@0.5: 0.613\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.754\n      AP@0.5: 0.906\n      AP@0.75: 0.812\n      AR: 0.783\n      AR@0.5: 0.916\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w32_8xb64-210e_humanart-256x192-0773ef0b_20230614.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w48_8xb32-210e_humanart-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: td-hm_hrnet-w48_8xb32-210e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.751\n      AP@0.5: 0.905\n      AP@0.75: 0.822\n      AR: 0.805\n      AR@0.5: 0.943\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.417\n      AP@0.5: 0.553\n      AP@0.75: 0.442\n      AR: 0.481\n      AR@0.5: 0.617\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.769\n      AP@0.5: 0.906\n      AP@0.75: 0.825\n      AR: 0.796\n      AR@0.5: 0.919\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_hrnet-w48_8xb32-210e_humanart-256x192-05178983_20230614.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=12,\n        layer_decay_rate=0.75,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch='base',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.3,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_base.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/'\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=32,\n        layer_decay_rate=0.85,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmcls.VisionTransformer',\n        arch='huge',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.55,\n        with_cls_token=False,\n        output_cls_token=False,\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_huge.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/'\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-large_8xb64-210e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=24,\n        layer_decay_rate=0.8,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmcls.VisionTransformer',\n        arch='large',\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.5,\n        with_cls_token=False,\n        output_cls_token=False,\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_large.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/'\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-small_8xb64-210e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\ncustom_imports = dict(\n    imports=['mmpose.engine.optim_wrappers.layer_decay_optim_wrapper'],\n    allow_failed_imports=False)\n\noptim_wrapper = dict(\n    optimizer=dict(\n        type='AdamW', lr=5e-4, betas=(0.9, 0.999), weight_decay=0.1),\n    paramwise_cfg=dict(\n        num_layers=12,\n        layer_decay_rate=0.8,\n        custom_keys={\n            'bias': dict(decay_multi=0.0),\n            'pos_embed': dict(decay_mult=0.0),\n            'relative_position_bias_table': dict(decay_mult=0.0),\n            'norm': dict(decay_mult=0.0),\n        },\n    ),\n    constructor='LayerDecayOptimWrapperConstructor',\n    clip_grad=dict(max_norm=1., norm_type=2),\n)\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='mmpretrain.VisionTransformer',\n        arch={\n            'embed_dims': 384,\n            'num_layers': 12,\n            'num_heads': 12,\n            'feedforward_channels': 384 * 4\n        },\n        img_size=(256, 192),\n        patch_size=16,\n        qkv_bias=True,\n        drop_path_rate=0.1,\n        with_cls_token=False,\n        out_type='featmap',\n        patch_cfg=dict(padding=2),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'v1/pretrained_models/mae_pretrain_vit_small.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=384,\n        out_channels=17,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndata_root = 'data/'\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w32_8xb64-210e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_hrnet-w48_8xb32-210e_humanart-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'HumanArtDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='HumanArt/annotations/validation_humanart.json',\n        bbox_file=f'{data_root}HumanArt/person_detection_results/'\n        'HumanArt_validation_detections_AP_H_56_person.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/vitpose_humanart.md",
    "content": "To utilize ViTPose, you'll need to have [MMPreTrain](https://github.com/open-mmlab/mmpretrain). To install the required version, run the following command:\n\n```shell\nmim install 'mmpretrain>=1.0.0'\n```\n\n<!-- [BACKBONE] -->\n\n<details>\n\n<summary  align=\"right\"><a  href=\"https://arxiv.org/abs/2204.12484\">ViTPose (NeurIPS'2022)</a></summary>\n\n```bibtex\n@inproceedings{\n  xu2022vitpose,\n  title={Vi{TP}ose: Simple Vision Transformer Baselines for Human Pose Estimation},\n  author={Yufei Xu and Jing Zhang and Qiming Zhang and Dacheng Tao},\n  booktitle={Advances in Neural Information Processing Systems},\n  year={2022},\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<details>\n<summary align=\"right\"><a href=\"https://idea-research.github.io/HumanArt/\">Human-Art (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ju2023humanart,\n    title={Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes},\n    author={Ju, Xuan and Zeng, Ailing and Jianan, Wang and Qiang, Xu and Lei, Zhang},\n    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR),\n    year={2023}}\n```\n\n</details>\n\nResults on Human-Art validation dataset with detector having human AP of 56.2 on Human-Art validation dataset\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ViTPose-S-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192.py) |  256x192   | 0.228 |      0.371      |      0.229      | 0.298 |      0.467      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.json) |\n| [ViTPose-S-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-small_8xb64-210e_humanart-256x192.py) |  256x192   | 0.381 |      0.532      |      0.405      | 0.448 |      0.602      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.json) |\n| [ViTPose-B-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py) |  256x192   | 0.270 |      0.423      |      0.272      | 0.340 |      0.510      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.json) |\n| [ViTPose-B-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py) |  256x192   | 0.410 |      0.549      |      0.434      | 0.475 |      0.615      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.json) |\n| [ViTPose-L-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py) |  256x192   | 0.342 |      0.498      |      0.357      | 0.413 |      0.577      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.json) |\n| [ViTPose-L-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py) |  256x192   | 0.459 |      0.592      |      0.487      | 0.525 |      0.656      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.json) |\n| [ViTPose-H-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py) |  256x192   | 0.377 |      0.541      |      0.391      | 0.447 |      0.615      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.json) |\n| [ViTPose-H-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192.py) |  256x192   | 0.468 |      0.594      |      0.498      | 0.534 |      0.655      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.json) |\n\nResults on Human-Art validation dataset with ground-truth bounding-box\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ViTPose-S-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192.py) |  256x192   | 0.507 |      0.758      |      0.531      | 0.551 |      0.780      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.json) |\n| [ViTPose-S-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-small_8xb64-210e_humanart-256x192.py) |  256x192   | 0.738 |      0.905      |      0.802      | 0.768 |      0.911      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.json) |\n| [ViTPose-B-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py) |  256x192   | 0.555 |      0.782      |      0.590      | 0.599 |      0.809      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.json) |\n| [ViTPose-B-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py) |  256x192   | 0.759 |      0.905      |      0.823      | 0.790 |      0.917      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.json) |\n| [ViTPose-L-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py) |  256x192   | 0.637 |      0.838      |      0.689      | 0.677 |      0.859      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.json) |\n| [ViTPose-L-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py) |  256x192   | 0.789 |      0.916      |      0.845      | 0.819 |      0.929      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.json) |\n| [ViTPose-H-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py) |  256x192   | 0.665 |      0.860      |      0.715      | 0.701 |      0.871      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.json) |\n| [ViTPose-H-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192.py) |  256x192   | 0.800 |      0.926      |      0.855      | 0.828 |      0.933      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.json) |\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n> With classic decoder\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [ViTPose-S-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192.py) |  256x192   | 0.739 |      0.903      |      0.816      | 0.792 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-small_8xb64-210e_coco-256x192-62d7a712_20230314.json) |\n| [ViTPose-S-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-small_8xb64-210e_humanart-256x192.py) |  256x192   | 0.737 |      0.902      |      0.811      | 0.792 |      0.942      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.json) |\n| [ViTPose-B-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192.py) |  256x192   | 0.757 |      0.905      |      0.829      | 0.810 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-base_8xb64-210e_coco-256x192-216eae50_20230314.json) |\n| [ViTPose-B-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py) |  256x192   | 0.758 |      0.906      |      0.829      | 0.812 |      0.946      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.json) |\n| [ViTPose-L-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192.py) |  256x192   | 0.782 |      0.914      |      0.850      | 0.834 |      0.952      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-large_8xb64-210e_coco-256x192-53609f55_20230314.json) |\n| [ViTPose-L-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py) |  256x192   | 0.782 |      0.914      |      0.849      | 0.835 |      0.953      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.json) |\n| [ViTPose-H-coco](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192.py) |  256x192   | 0.788 |      0.917      |      0.855      | 0.839 |      0.954      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_ViTPose-huge_8xb64-210e_coco-256x192-e32adcd4_20230314.json) |\n| [ViTPose-H-humanart-coco](configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192.py) |  256x192   | 0.788 |      0.914      |      0.853      | 0.841 |      0.956      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/humanart/vitpose_humanart.yml",
    "content": "Collections:\n- Name: ViTPose\n  Paper:\n    Title: 'ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation'\n    URL: https://arxiv.org/abs/2204.12484\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/vitpose.md\n  Metadata:\n    Training Resources: 8x A100 GPUs\nModels:\n- Config: configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-small_8xb64-210e_humanart-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: &id001\n    - ViTPose\n    - Classic Head\n    Model Size: Small\n    Training Data: &id002\n    - COCO\n    - Human-Art\n  Name: td-hm_ViTPose-small_8xb64-210e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.737\n      AP@0.5: 0.902\n      AP@0.75: 0.811\n      AR: 0.792\n      AR@0.5: 0.942\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.381\n      AP@0.5: 0.532\n      AP@0.75: 0.405\n      AR: 0.448\n      AR@0.5: 0.602\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.738\n      AP@0.5: 0.905\n      AP@0.75: 0.802\n      AR: 0.768\n      AR@0.5: 0.911\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-small_8xb64-210e_humanart-256x192-5cbe2bfc_20230611.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-base_8xb64-210e_humanart-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: *id001\n    Model Size: Base\n    Training Data: *id002\n  Name: td-hm_ViTPose-base_8xb64-210e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.758\n      AP@0.5: 0.906\n      AP@0.75: 0.829\n      AR: 0.812\n      AR@0.5: 0.946\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.410\n      AP@0.5: 0.549\n      AP@0.75: 0.434\n      AR: 0.475\n      AR@0.5: 0.615\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.759\n      AP@0.5: 0.905\n      AP@0.75: 0.823\n      AR: 0.790\n      AR@0.5: 0.917\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-base_8xb64-210e_humanart-256x192-b417f546_20230611.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-large_8xb64-210e_humanart-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: *id001\n    Model Size: Large\n    Training Data: *id002\n  Name: td-hm_ViTPose-large_8xb64-210e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.782\n      AP@0.5: 0.914\n      AP@0.75: 0.849\n      AR: 0.835\n      AR@0.5: 0.953\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.459\n      AP@0.5: 0.592\n      AP@0.75: 0.487\n      AR: 0.525\n      AR@0.5: 0.656\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.789\n      AP@0.5: 0.916\n      AP@0.75: 0.845\n      AR: 0.819\n      AR@0.5: 0.929\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-large_8xb64-210e_humanart-256x192-9aba9345_20230614.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/humanart/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192.py\n  In Collection: ViTPose\n  Metadata:\n    Architecture: *id001\n    Model Size: Huge\n    Training Data: *id002\n  Name: td-hm_ViTPose-huge_8xb64-210e_humanart-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.788\n      AP@0.5: 0.914\n      AP@0.75: 0.853\n      AR: 0.841\n      AR@0.5: 0.956\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art\n    Metrics:\n      AP: 0.468\n      AP@0.5: 0.594\n      AP@0.75: 0.498\n      AR: 0.534\n      AR@0.5: 0.655\n    Task: Body 2D Keypoint\n  - Dataset: Human-Art(GT)\n    Metrics:\n      AP: 0.800\n      AP@0.5: 0.926\n      AP@0.75: 0.855\n      AR: 0.828\n      AR@0.5: 0.933\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/human_art/td-hm_ViTPose-huge_8xb64-210e_humanart-256x192-603bb573_20230612.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/cpm_jhmdb.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Wei_Convolutional_Pose_Machines_CVPR_2016_paper.html\">CPM (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{wei2016convolutional,\n  title={Convolutional pose machines},\n  author={Wei, Shih-En and Ramakrishna, Varun and Kanade, Takeo and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={4724--4732},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2013/html/Jhuang_Towards_Understanding_Action_2013_ICCV_paper.html\">JHMDB (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{Jhuang:ICCV:2013,\n  title = {Towards understanding action recognition},\n  author = {H. Jhuang and J. Gall and S. Zuffi and C. Schmid and M. J. Black},\n  booktitle = {International Conf. on Computer Vision (ICCV)},\n  month = Dec,\n  pages = {3192-3199},\n  year = {2013}\n}\n```\n\n</details>\n\nResults on Sub-JHMDB dataset\n\nThe models are pre-trained on MPII dataset only. NO test-time augmentation (multi-scale /rotation testing) is used.\n\n- Normalized by Person Size\n\n| Split   |                        Arch                        | Input Size | Head | Sho  | Elb  | Wri  | Hip  | Knee | Ank  | Mean |                        ckpt                         |                        log                         |\n| :------ | :------------------------------------------------: | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :-------------------------------------------------: | :------------------------------------------------: |\n| Sub1    | [cpm](/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368.py) |  368x368   | 96.1 | 91.9 | 81.0 | 78.9 | 96.6 | 90.8 | 87.3 | 89.5 | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub1_368x368-2d2585c9_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub1_368x368_20201122.log.json) |\n| Sub2    | [cpm](/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368.py) |  368x368   | 98.1 | 93.6 | 77.1 | 70.9 | 94.0 | 89.1 | 84.7 | 87.4 | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub2_368x368-fc742f1f_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub2_368x368_20201122.log.json) |\n| Sub3    | [cpm](/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368.py) |  368x368   | 97.9 | 94.9 | 87.3 | 84.0 | 98.6 | 94.4 | 86.2 | 92.4 | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub3_368x368-49337155_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub3_368x368_20201122.log.json) |\n| Average |                        cpm                         |  368x368   | 97.4 | 93.5 | 81.5 | 77.9 | 96.4 | 91.4 | 86.1 | 89.8 |                          -                          |                         -                          |\n\n- Normalized by Torso Size\n\n| Split   |                        Arch                        | Input Size | Head | Sho  | Elb  | Wri  | Hip  | Knee | Ank  | Mean |                        ckpt                         |                        log                         |\n| :------ | :------------------------------------------------: | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :-------------------------------------------------: | :------------------------------------------------: |\n| Sub1    | [cpm](/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368.py) |  368x368   | 89.0 | 63.0 | 54.0 | 54.9 | 68.2 | 63.1 | 61.2 | 66.0 | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub1_368x368-2d2585c9_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub1_368x368_20201122.log.json) |\n| Sub2    | [cpm](/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368.py) |  368x368   | 90.3 | 57.9 | 46.8 | 44.3 | 60.8 | 58.2 | 62.4 | 61.1 | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub2_368x368-fc742f1f_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub2_368x368_20201122.log.json) |\n| Sub3    | [cpm](/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368.py) |  368x368   | 91.0 | 72.6 | 59.9 | 54.0 | 73.2 | 68.5 | 65.8 | 70.3 | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub3_368x368-49337155_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub3_368x368_20201122.log.json) |\n| Average |                        cpm                         |  368x368   | 90.1 | 64.5 | 53.6 | 51.1 | 67.4 | 63.3 | 63.1 | 65.7 |                          -                          |                         -                          |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/cpm_jhmdb.yml",
    "content": "Models:\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture: &id001\n    - CPM\n    Training Data: JHMDB\n  Name: td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 87.3\n      Elb: 81\n      Head: 96.1\n      Hip: 96.6\n      Knee: 90.8\n      Mean: 89.5\n      Sho: 91.9\n      Wri: 78.9\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub1_368x368-2d2585c9_20201122.pth\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 84.7\n      Elb: 77.1\n      Head: 98.1\n      Hip: 94.0\n      Knee: 89.1\n      Mean: 87.4\n      Sho: 93.6\n      Wri: 70.9\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub2_368x368-fc742f1f_20201122.pth\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 86.2\n      Elb: 87.3\n      Head: 97.9\n      Hip: 98.6\n      Knee: 94.4\n      Mean: 92.4\n      Sho: 94.9\n      Wri: 84.0\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub3_368x368-49337155_20201122.pth\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 61.2\n      Elb: 54.0\n      Head: 89.0\n      Hip: 68.2\n      Knee: 63.1\n      Mean: 66.0\n      Sho: 63.0\n      Wri: 54.9\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub1_368x368-2d2585c9_20201122.pth\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 62.4\n      Elb: 46.8\n      Head: 90.3\n      Hip: 60.8\n      Knee: 58.2\n      Mean: 61.1\n      Sho: 57.9\n      Wri: 44.3\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub2_368x368-fc742f1f_20201122.pth\n- Config: configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 65.8\n      Elb: 59.9\n      Head: 91.0\n      Hip: 73.2\n      Knee: 68.5\n      Mean: 70.3\n      Sho: 72.6\n      Wri: 54.0\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_jhmdb_sub3_368x368-49337155_20201122.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/resnet_jhmdb.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2013/html/Jhuang_Towards_Understanding_Action_2013_ICCV_paper.html\">JHMDB (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{Jhuang:ICCV:2013,\n  title = {Towards understanding action recognition},\n  author = {H. Jhuang and J. Gall and S. Zuffi and C. Schmid and M. J. Black},\n  booktitle = {International Conf. on Computer Vision (ICCV)},\n  month = Dec,\n  pages = {3192-3199},\n  year = {2013}\n}\n```\n\n</details>\n\nResults on Sub-JHMDB dataset\n\nThe models are pre-trained on MPII dataset only. *NO* test-time augmentation (multi-scale /rotation testing) is used.\n\n- Normalized by Person Size\n\n| Split   |                        Arch                        | Input Size | Head | Sho  | Elb  | Wri  | Hip  | Knee | Ank  | Mean |                        ckpt                         |                        log                         |\n| :------ | :------------------------------------------------: | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :-------------------------------------------------: | :------------------------------------------------: |\n| Sub1    | [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub1-256x256.py) |  256x256   | 99.1 | 98.0 | 93.8 | 91.3 | 99.4 | 96.5 | 92.8 | 96.1 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub1_256x256-932cb3b4_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub1_256x256_20201122.log.json) |\n| Sub2    | [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub2-256x256.py) |  256x256   | 99.3 | 97.1 | 90.6 | 87.0 | 98.9 | 96.3 | 94.1 | 95.0 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub2_256x256-83d606f7_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub2_256x256_20201122.log.json) |\n| Sub3    | [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub3-256x256.py) |  256x256   | 99.0 | 97.9 | 94.0 | 91.6 | 99.7 | 98.0 | 94.7 | 96.7 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub3_256x256-c4ec1a0b_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub3_256x256_20201122.log.json) |\n| Average |                   pose_resnet_50                   |  256x256   | 99.2 | 97.7 | 92.8 | 90.0 | 99.3 | 96.9 | 93.9 | 96.0 |                          -                          |                         -                          |\n| Sub1    | [pose_resnet_50 (2 Deconv.)](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256.py) |  256x256   | 99.1 | 98.5 | 94.6 | 92.0 | 99.4 | 94.6 | 92.5 | 96.1 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub1_256x256-f0574a52_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub1_256x256_20201122.log.json) |\n| Sub2    | [pose_resnet_50 (2 Deconv.)](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256.py) |  256x256   | 99.3 | 97.8 | 91.0 | 87.0 | 99.1 | 96.5 | 93.8 | 95.2 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub2_256x256-f63af0ff_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub2_256x256_20201122.log.json) |\n| Sub3    | [pose_resnet_50 (2 Deconv.)](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256.py) |  256x256   | 98.8 | 98.4 | 94.3 | 92.1 | 99.8 | 97.5 | 93.8 | 96.7 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub3_256x256-c4bc2ddb_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub3_256x256_20201122.log.json) |\n| Average |             pose_resnet_50 (2 Deconv.)             |  256x256   | 99.1 | 98.2 | 93.3 | 90.4 | 99.4 | 96.2 | 93.4 | 96.0 |                          -                          |                         -                          |\n\n- Normalized by Torso Size\n\n| Split   |                        Arch                        | Input Size | Head | Sho  | Elb  | Wri  | Hip  | Knee | Ank  | Mean |                        ckpt                         |                        log                         |\n| :------ | :------------------------------------------------: | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :-------------------------------------------------: | :------------------------------------------------: |\n| Sub1    | [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub1-256x256.py) |  256x256   | 93.3 | 83.2 | 74.4 | 72.7 | 85.0 | 81.2 | 78.9 | 81.9 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub1_256x256-932cb3b4_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub1_256x256_20201122.log.json) |\n| Sub2    | [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub2-256x256.py) |  256x256   | 94.1 | 74.9 | 64.5 | 62.5 | 77.9 | 71.9 | 78.6 | 75.5 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub2_256x256-83d606f7_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub2_256x256_20201122.log.json) |\n| Sub3    | [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub3-256x256.py) |  256x256   | 97.0 | 82.2 | 74.9 | 70.7 | 84.7 | 83.7 | 84.2 | 82.9 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub3_256x256-c4ec1a0b_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub3_256x256_20201122.log.json) |\n| Average |                   pose_resnet_50                   |  256x256   | 94.8 | 80.1 | 71.3 | 68.6 | 82.5 | 78.9 | 80.6 | 80.1 |                          -                          |                         -                          |\n| Sub1    | [pose_resnet_50 (2 Deconv.)](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256.py) |  256x256   | 92.4 | 80.6 | 73.2 | 70.5 | 82.3 | 75.4 | 75.0 | 79.2 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub1_256x256-f0574a52_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub1_256x256_20201122.log.json) |\n| Sub2    | [pose_resnet_50 (2 Deconv.)](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256.py) |  256x256   | 93.4 | 73.6 | 63.8 | 60.5 | 75.1 | 68.4 | 75.5 | 73.7 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub2_256x256-f63af0ff_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub2_256x256_20201122.log.json) |\n| Sub3    | [pose_resnet_50 (2 Deconv.)](/configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256.py) |  256x256   | 96.1 | 81.2 | 72.6 | 67.9 | 83.6 | 80.9 | 81.5 | 81.2 | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub3_256x256-c4bc2ddb_20201122.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub3_256x256_20201122.log.json) |\n| Average |             pose_resnet_50 (2 Deconv.)             |  256x256   | 94.0 | 78.5 | 69.9 | 66.3 | 80.3 | 74.9 | 77.3 | 78.0 |                          -                          |                         -                          |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/resnet_jhmdb.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub1-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: JHMDB\n  Name: td-hm_res50_8xb64-20e_jhmdb-sub1-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 92.8\n      Elb: 93.8\n      Head: 99.1\n      Hip: 99.4\n      Knee: 96.5\n      Mean: 96.1\n      Sho: 98.0\n      Wri: 91.3\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub1_256x256-932cb3b4_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub2-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50_8xb64-20e_jhmdb-sub2-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 94.1\n      Elb: 90.6\n      Head: 99.3\n      Hip: 98.9\n      Knee: 96.3\n      Mean: 95.0\n      Sho: 97.1\n      Wri: 87.0\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub2_256x256-83d606f7_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub3-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50_8xb64-20e_jhmdb-sub3-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 94.7\n      Elb: 94.0\n      Head: 99.0\n      Hip: 99.7\n      Knee: 98.0\n      Mean: 96.7\n      Sho: 97.9\n      Wri: 91.6\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub3_256x256-c4ec1a0b_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 92.5\n      Elb: 94.6\n      Head: 99.1\n      Hip: 99.4\n      Knee: 94.6\n      Mean: 96.1\n      Sho: 98.5\n      Wri: 92.0\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub1_256x256-f0574a52_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 93.8\n      Elb: 91.0\n      Head: 99.3\n      Hip: 99.1\n      Knee: 96.5\n      Mean: 95.2\n      Sho: 97.8\n      Wri: 87.0\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub2_256x256-f63af0ff_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 93.8\n      Elb: 94.3\n      Head: 98.8\n      Hip: 99.8\n      Knee: 97.5\n      Mean: 96.7\n      Sho: 98.4\n      Wri: 92.1\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub3_256x256-c4bc2ddb_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub1-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50_8xb64-20e_jhmdb-sub1-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 78.9\n      Elb: 74.4\n      Head: 93.3\n      Hip: 85.0\n      Knee: 81.2\n      Mean: 81.9\n      Sho: 83.2\n      Wri: 72.7\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub1_256x256-932cb3b4_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub2-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50_8xb64-20e_jhmdb-sub2-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 78.6\n      Elb: 64.5\n      Head: 94.1\n      Hip: 77.9\n      Knee: 71.9\n      Mean: 75.5\n      Sho: 74.9\n      Wri: 62.5\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub2_256x256-83d606f7_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub3-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50_8xb64-20e_jhmdb-sub3-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 84.2\n      Elb: 74.9\n      Head: 97.0\n      Hip: 84.7\n      Knee: 83.7\n      Mean: 82.9\n      Sho: 82.2\n      Wri: 70.7\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_jhmdb_sub3_256x256-c4ec1a0b_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 75.0\n      Elb: 73.2\n      Head: 92.4\n      Hip: 82.3\n      Knee: 75.4\n      Mean: 79.2\n      Sho: 80.6\n      Wri: 70.5\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub1_256x256-f0574a52_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 75.5\n      Elb: 63.8\n      Head: 93.4\n      Hip: 75.1\n      Knee: 68.4\n      Mean: 73.7\n      Sho: 73.6\n      Wri: 60.5\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub2_256x256-f63af0ff_20201122.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: JHMDB\n  Name: td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256\n  Results:\n  - Dataset: JHMDB\n    Metrics:\n      Ank: 81.5\n      Elb: 72.6\n      Head: 96.1\n      Hip: 83.6\n      Knee: 80.9\n      Mean: 81.2\n      Sho: 81.2\n      Wri: 67.9\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_2deconv_jhmdb_sub3_256x256-c4bc2ddb_20201122.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub1-368x368.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=40, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=40,\n        milestones=[20, 30],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(368, 368), heatmap_size=(46, 46), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CPM',\n        in_channels=3,\n        out_channels=15,\n        feat_channels=128,\n        num_stages=6),\n    head=dict(\n        type='CPMHead',\n        in_channels=15,\n        out_channels=15,\n        num_stages=6,\n        deconv_out_channels=None,\n        final_layer=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub1_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub1_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub2-368x368.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=40, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=40,\n        milestones=[20, 30],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(368, 368), heatmap_size=(46, 46), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CPM',\n        in_channels=3,\n        out_channels=15,\n        feat_channels=128,\n        num_stages=6),\n    head=dict(\n        type='CPMHead',\n        in_channels=15,\n        out_channels=15,\n        num_stages=6,\n        deconv_out_channels=None,\n        final_layer=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub2_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub2_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_cpm_8xb32-40e_jhmdb-sub3-368x368.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=40, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=40,\n        milestones=[20, 30],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(368, 368), heatmap_size=(46, 46), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CPM',\n        in_channels=3,\n        out_channels=15,\n        feat_channels=128,\n        num_stages=6),\n    head=dict(\n        type='CPMHead',\n        in_channels=15,\n        out_channels=15,\n        num_stages=6,\n        deconv_out_channels=None,\n        final_layer=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub3_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub3_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub1-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=40, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=40,\n        milestones=[20, 30],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(32, 32), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ResNet', depth=50),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=15,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth'  # noqa: E501\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub1_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub1_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub2-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=40, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=40,\n        milestones=[20, 30],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(32, 32), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ResNet', depth=50),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=15,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth'  # noqa: E501\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub2_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub2_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50-2deconv_8xb64-40e_jhmdb-sub3-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=40, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=40,\n        milestones=[20, 30],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(32, 32), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ResNet', depth=50),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=15,\n        deconv_out_channels=(256, 256),\n        deconv_kernel_sizes=(4, 4),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth'  # noqa: E501\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub3_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub3_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub1-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[8, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ResNet', depth=50),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=15,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth'  # noqa: E501\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub1_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub1_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub2-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[8, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ResNet', depth=50),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=15,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth'  # noqa: E501\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub2_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub2_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/jhmdb/td-hm_res50_8xb64-20e_jhmdb-sub3-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[8, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ResNet', depth=50),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=15,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth'  # noqa: E501\n\n# base dataset settings\ndataset_type = 'JhmdbDataset'\ndata_mode = 'topdown'\ndata_root = 'data/jhmdb/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub3_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/Sub3_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='JhmdbPCKAccuracy', thr=0.2, norm_item=['bbox', 'torso']),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/cpm_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Wei_Convolutional_Pose_Machines_CVPR_2016_paper.html\">CPM (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{wei2016convolutional,\n  title={Convolutional pose machines},\n  author={Wei, Shih-En and Ramakrishna, Varun and Kanade, Takeo and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={4724--4732},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [cpm](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_cpm_8xb64-210e_mpii-368x368.py) |  368x368   | 0.876 |  0.285   | [ckpt](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_mpii_368x368-116e62b8_20200822.pth) | [log](https://download.openmmlab.com/mmpose/top_down/cpm/cpm_mpii_368x368_20200822.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/cpm_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_cpm_8xb64-210e_mpii-368x368.py\n  In Collection: CPM\n  Metadata:\n    Architecture:\n    - CPM\n    Training Data: MPII\n  Name: td-hm_cpm_8xb64-210e_mpii-368x368\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.876\n      Mean@0.1: 0.285\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/cpm/cpm_mpii_368x368-116e62b8_20200822.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/cspnext-m_udp_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/pose/MPI/',\n#         f'{data_root}': 's3://openmmlab/datasets/pose/MPI/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='PCK', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/cspnext_udp_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/mpii/cspnext-m_udp_8xb64-210e_mpii-256x256.py) |  256x256   | 0.902 |  0.303   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-mpii_pt-in1k_210e-256x256-68d0402f_20230208.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-mpii_pt-in1k_210e-256x256-68d0402f_20230208.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/cspnext_udp_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/cspnext-m_udp_8xb64-210e_mpii-256x256.py\n  In Collection: UDP\n  Metadata:\n    Architecture:\n    - UDP\n    - CSPNeXt\n    Training Data: MPII\n  Name: cspnext-m_udp_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.902\n      Mean@0.1: 0.303\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-mpii_pt-in1k_210e-256x256-68d0402f_20230208.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/hourglass_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\">Hourglass (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{newell2016stacked,\n  title={Stacked hourglass networks for human pose estimation},\n  author={Newell, Alejandro and Yang, Kaiyu and Deng, Jia},\n  booktitle={European conference on computer vision},\n  pages={483--499},\n  year={2016},\n  organization={Springer}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_hourglass_52](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hourglass52_8xb64-210e_mpii-256x256.py) |  256x256   | 0.889 |  0.317   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256-ae358435_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256_20200812.log.json) |\n| [pose_hourglass_52](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hourglass52_8xb32-210e_mpii-384x384.py) |  384x384   | 0.894 |  0.367   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384-04090bc3_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/hourglass_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hourglass52_8xb64-210e_mpii-256x256.py\n  In Collection: Hourglass\n  Metadata:\n    Architecture: &id001\n    - Hourglass\n    Training Data: MPII\n  Name: td-hm_hourglass52_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.889\n      Mean@0.1: 0.317\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_mpii_256x256-ae358435_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hourglass52_8xb32-210e_mpii-384x384.py\n  In Collection: Hourglass\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_hourglass52_8xb32-210e_mpii-384x384\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.894\n      Mean@0.1: 0.367\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hourglass/hourglass52_mpii_384x384-04090bc3_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/hrnet_dark_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_hrnet_w32_dark](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w32_dark-8xb64-210e_mpii-256x256.py) |  256x256   | 0.904 |  0.354   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256_dark-f1601c5b_20200927.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256_dark_20200927.log.json) |\n| [pose_hrnet_w48_dark](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w48_dark-8xb64-210e_mpii-256x256.py) |  256x256   | 0.905 |  0.360   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256_dark-0decd39f_20200927.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256_dark_20200927.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/hrnet_dark_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w32_dark-8xb64-210e_mpii-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    - DarkPose\n    Training Data: MPII\n  Name: td-hm_hrnet-w32_dark-8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.904\n      Mean@0.1: 0.354\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256_dark-f1601c5b_20200927.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w48_dark-8xb64-210e_mpii-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_hrnet-w48_dark-8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.905\n      Mean@0.1: 0.36\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256_dark-0decd39f_20200927.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/hrnet_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w32_8xb64-210e_mpii-256x256.py) |  256x256   | 0.900 |  0.334   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256-6c4f923f_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256_20200812.log.json) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w48_8xb64-210e_mpii-256x256.py) |  256x256   | 0.901 |  0.337   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256-92cab7bd_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/hrnet_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w32_8xb64-210e_mpii-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: MPII\n  Name: td-hm_hrnet-w32_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.9\n      Mean@0.1: 0.334\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_mpii_256x256-6c4f923f_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w48_8xb64-210e_mpii-256x256.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_hrnet-w48_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.901\n      Mean@0.1: 0.337\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_mpii_256x256-92cab7bd_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/litehrnet_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.06403\">LiteHRNet (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{Yulitehrnet21,\n  title={Lite-HRNet: A Lightweight High-Resolution Network},\n  author={Yu, Changqian and Xiao, Bin and Gao, Changxin and Yuan, Lu and Zhang, Lei and Sang, Nong and Wang, Jingdong},\n  booktitle={CVPR},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [LiteHRNet-18](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_litehrnet-18_8xb64-210e_mpii-256x256.py) |  256x256   | 0.859 |  0.260   | [ckpt](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_mpii_256x256-cabd7984_20210623.pth) | [log](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_mpii_256x256_20210623.log.json) |\n| [LiteHRNet-30](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_litehrnet-30_8xb64-210e_mpii-256x256.py) |  256x256   | 0.869 |  0.271   | [ckpt](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_mpii_256x256-faae8bd8_20210622.pth) | [log](https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_mpii_256x256_20210622.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/litehrnet_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_litehrnet-18_8xb64-210e_mpii-256x256.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture: &id001\n    - LiteHRNet\n    Training Data: MPII\n  Name: td-hm_litehrnet-18_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.859\n      Mean@0.1: 0.26\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet18_mpii_256x256-cabd7984_20210623.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_litehrnet-30_8xb64-210e_mpii-256x256.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_litehrnet-30_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.869\n      Mean@0.1: 0.271\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/litehrnet/litehrnet30_mpii_256x256-faae8bd8_20210622.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/mobilenetv2_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_mobilenetv2](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_mobilenetv2_8xb64-210e_mpii-256x256.py) |  256x256   | 0.854 |  0.234   | [ckpt](https://download.openmmlab.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256-e068afa7_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/mobilenetv2_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_mobilenetv2_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - MobilenetV2\n    Training Data: MPII\n  Name: td-hm_mobilenetv2_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.854\n      Mean@0.1: 0.234\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/mobilenetv2/mobilenetv2_mpii_256x256-e068afa7_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/resnet_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res50_8xb64-210e_mpii-256x256.py) |  256x256   | 0.882 |  0.286   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256_20200812.log.json) |\n| [pose_resnet_101](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res101_8xb64-210e_mpii-256x256.py) |  256x256   | 0.888 |  0.290   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res101_mpii_256x256-416f5d71_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res101_mpii_256x256_20200812.log.json) |\n| [pose_resnet_152](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res152_8xb32-210e_mpii-256x256.py) |  256x256   | 0.889 |  0.303   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res152_mpii_256x256-3ecba29d_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res152_mpii_256x256_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/resnet_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res50_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: MPII\n  Name: td-hm_res50_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.882\n      Mean@0.1: 0.286\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_mpii_256x256-418ffc88_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res101_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_res101_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.888\n      Mean@0.1: 0.29\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res101_mpii_256x256-416f5d71_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res152_8xb32-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_res152_8xb32-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.889\n      Mean@0.1: 0.303\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res152_mpii_256x256-3ecba29d_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/resnetv1d_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/He_Bag_of_Tricks_for_Image_Classification_with_Convolutional_Neural_Networks_CVPR_2019_paper.html\">ResNetV1D (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{he2019bag,\n  title={Bag of tricks for image classification with convolutional neural networks},\n  author={He, Tong and Zhang, Zhi and Zhang, Hang and Zhang, Zhongyue and Xie, Junyuan and Li, Mu},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={558--567},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_resnetv1d_50](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d50_8xb64-210e_mpii-256x256.py) |  256x256   | 0.881 |  0.290   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256-2337a92e_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256_20200812.log.json) |\n| [pose_resnetv1d_101](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d101_8xb64-210e_mpii-256x256.py) |  256x256   | 0.883 |  0.295   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256-2851d710_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256_20200812.log.json) |\n| [pose_resnetv1d_152](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d152_8xb64-210e_mpii-256x256.py) |  256x256   | 0.888 |  0.300   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256-8b10a87c_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/resnetv1d_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d50_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNetV1D\n    Training Data: MPII\n  Name: td-hm_resnetv1d50_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.881\n      Mean@0.1: 0.29\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d50_mpii_256x256-2337a92e_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d101_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_resnetv1d101_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.883\n      Mean@0.1: 0.295\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d101_mpii_256x256-2851d710_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d152_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_resnetv1d152_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.888\n      Mean@0.1: 0.3\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnetv1d/resnetv1d152_mpii_256x256-8b10a87c_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/resnext_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2017/html/Xie_Aggregated_Residual_Transformations_CVPR_2017_paper.html\">ResNext (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{xie2017aggregated,\n  title={Aggregated residual transformations for deep neural networks},\n  author={Xie, Saining and Girshick, Ross and Doll{\\'a}r, Piotr and Tu, Zhuowen and He, Kaiming},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1492--1500},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_resnext_152](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnext152_8xb32-210e_mpii-256x256.py) |  256x256   | 0.887 |  0.294   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_mpii_256x256-df302719_20200927.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_mpii_256x256_20200927.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/resnext_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnext152_8xb32-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNext\n    Training Data: MPII\n  Name: td-hm_resnext152_8xb32-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.887\n      Mean@0.1: 0.294\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnext/resnext152_mpii_256x256-df302719_20200927.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/scnet_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Liu_Improving_Convolutional_Networks_With_Self-Calibrated_Convolutions_CVPR_2020_paper.html\">SCNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020improving,\n  title={Improving Convolutional Networks with Self-Calibrated Convolutions},\n  author={Liu, Jiang-Jiang and Hou, Qibin and Cheng, Ming-Ming and Wang, Changhu and Feng, Jiashi},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={10096--10105},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_scnet_50](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_scnet50_8xb64-210e_mpii-256x256.py) |  256x256   | 0.888 |  0.290   | [ckpt](https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_mpii_256x256-a54b6af5_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_mpii_256x256_20200812.log.json) |\n| [pose_scnet_101](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_scnet101_8xb64-210e_mpii-256x256.py) |  256x256   | 0.887 |  0.293   | [ckpt](https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_mpii_256x256-b4c2d184_20200812.pth) | [log](https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_mpii_256x256_20200812.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/scnet_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_scnet50_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - SCNet\n    Training Data: MPII\n  Name: td-hm_scnet50_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.888\n      Mean@0.1: 0.29\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/scnet/scnet50_mpii_256x256-a54b6af5_20200812.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_scnet101_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_scnet101_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.887\n      Mean@0.1: 0.293\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/scnet/scnet101_mpii_256x256-b4c2d184_20200812.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/seresnet_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper\">SEResNet (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{hu2018squeeze,\n  title={Squeeze-and-excitation networks},\n  author={Hu, Jie and Shen, Li and Sun, Gang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={7132--7141},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_seresnet_50](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet50_8xb64-210e_mpii-256x256.py) |  256x256   | 0.884 |  0.292   | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_mpii_256x256-1bb21f79_20200927.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_mpii_256x256_20200927.log.json) |\n| [pose_seresnet_101](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet101_8xb64-210e_mpii-256x256.py) |  256x256   | 0.884 |  0.295   | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_mpii_256x256-0ba14ff5_20200927.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_mpii_256x256_20200927.log.json) |\n| [pose_seresnet_152\\*](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet152_8xb32-210e_mpii-256x256.py) |  256x256   | 0.884 |  0.287   | [ckpt](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_mpii_256x256-6ea1e774_20200927.pth) | [log](https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_mpii_256x256_20200927.log.json) |\n\nNote that * means without imagenet pre-training.\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/seresnet_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet50_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - SEResNet\n    Training Data: MPII\n  Name: td-hm_seresnet50_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.884\n      Mean@0.1: 0.292\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet50_mpii_256x256-1bb21f79_20200927.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet101_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_seresnet101_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.884\n      Mean@0.1: 0.295\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet101_mpii_256x256-0ba14ff5_20200927.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet152_8xb32-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-hm_seresnet152_8xb32-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.884\n      Mean@0.1: 0.287\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/seresnet/seresnet152_mpii_256x256-6ea1e774_20200927.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/shufflenetv1_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Zhang_ShuffleNet_An_Extremely_CVPR_2018_paper.html\">ShufflenetV1 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{zhang2018shufflenet,\n  title={Shufflenet: An extremely efficient convolutional neural network for mobile devices},\n  author={Zhang, Xiangyu and Zhou, Xinyu and Lin, Mengxiao and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={6848--6856},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_shufflenetv1](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_shufflenetv1_8xb64-210e_mpii-256x256.py) |  256x256   | 0.824 |  0.195   | [ckpt](https://download.openmmlab.com/mmpose/top_down/shufflenetv1/shufflenetv1_mpii_256x256-dcc1c896_20200925.pth) | [log](https://download.openmmlab.com/mmpose/top_down/shufflenetv1/shufflenetv1_mpii_256x256_20200925.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/shufflenetv1_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_shufflenetv1_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ShufflenetV1\n    Training Data: MPII\n  Name: td-hm_shufflenetv1_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.824\n      Mean@0.1: 0.195\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/shufflenetv1/shufflenetv1_mpii_256x256-dcc1c896_20200925.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/shufflenetv2_mpii.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Ningning_Light-weight_CNN_Architecture_ECCV_2018_paper.html\">ShufflenetV2 (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{ma2018shufflenet,\n  title={Shufflenet v2: Practical guidelines for efficient cnn architecture design},\n  author={Ma, Ningning and Zhang, Xiangyu and Zheng, Hai-Tao and Sun, Jian},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={116--131},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [pose_shufflenetv2](/configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_shufflenetv2_8xb64-210e_mpii-256x256.py) |  256x256   | 0.828 |  0.205   | [ckpt](https://download.openmmlab.com/mmpose/top_down/shufflenetv2/shufflenetv2_mpii_256x256-4fb9df2d_20200925.pth) | [log](https://download.openmmlab.com/mmpose/top_down/shufflenetv2/shufflenetv2_mpii_256x256_20200925.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/shufflenetv2_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_shufflenetv2_8xb64-210e_mpii-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ShufflenetV2\n    Training Data: MPII\n  Name: td-hm_shufflenetv2_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.828\n      Mean@0.1: 0.205\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/shufflenetv2/shufflenetv2_mpii_256x256-4fb9df2d_20200925.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_cpm_8xb64-210e_mpii-368x368.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(368, 368), heatmap_size=(46, 46), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CPM',\n        in_channels=3,\n        out_channels=16,\n        feat_channels=128,\n        num_stages=6),\n    head=dict(\n        type='CPMHead',\n        in_channels=16,\n        out_channels=16,\n        num_stages=6,\n        deconv_out_channels=None,\n        final_layer=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hourglass52_8xb32-210e_mpii-384x384.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(384, 384), heatmap_size=(96, 96), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HourglassNet',\n        num_stacks=1,\n    ),\n    head=dict(\n        type='CPMHead',\n        in_channels=256,\n        out_channels=16,\n        num_stages=1,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hourglass52_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HourglassNet',\n        num_stacks=1,\n    ),\n    head=dict(\n        type='CPMHead',\n        in_channels=256,\n        out_channels=16,\n        num_stages=1,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w32_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=16,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=16,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w32_dark-8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=16,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w48_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=16,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_hrnet-w48_dark-8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=16,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_litehrnet-18_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(2, 4, 2),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=16,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_litehrnet-30_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(3, 8, 3),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=16,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_mobilenetv2_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://mobilenet_v2'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res101_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res152_8xb32-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_res50_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d101_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet101_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d152_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet152_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnetv1d50_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNetV1d',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://resnet50_v1d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_resnext152_8xb32-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNeXt',\n        depth=152,\n        init_cfg=dict(\n            type='Pretrained', checkpoint='mmcls://resnext152_32x4d'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_scnet101_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=101,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet101-94250a77.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_scnet50_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet50-7ef0a199.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet101_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://se-resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet152_8xb32-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=152,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_seresnet50_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SEResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://se-resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_shufflenetv1_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ShuffleNetV1',\n        groups=3,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://shufflenet_v1'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=960,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/mpii/td-hm_shufflenetv2_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ShuffleNetV2',\n        widen_factor=1.0,\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://shufflenet_v2'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=16,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file='data/mpii/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/hrnet_posetrack18.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Andriluka_PoseTrack_A_Benchmark_CVPR_2018_paper.html\">PoseTrack18 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{andriluka2018posetrack,\n  title={Posetrack: A benchmark for human pose estimation and tracking},\n  author={Andriluka, Mykhaylo and Iqbal, Umar and Insafutdinov, Eldar and Pishchulin, Leonid and Milan, Anton and Gall, Juergen and Schiele, Bernt},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={5167--5176},\n  year={2018}\n}\n```\n\n</details>\n\nResults on PoseTrack2018 val with ground-truth bounding boxes\n\n| Arch                                                 | Input Size | Head | Shou | Elb  | Wri  | Hip  | Knee | Ankl | Total |                         ckpt                          |                         log                          |\n| :--------------------------------------------------- | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :---: | :---------------------------------------------------: | :--------------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192.py) |  256x192   | 86.2 | 89.0 | 84.5 | 79.2 | 82.3 | 82.5 | 78.7 | 83.4  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_256x192-1ee951c4_20201028.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_256x192_20201028.log.json) |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288.py) |  384x288   | 87.1 | 89.0 | 85.1 | 80.2 | 80.6 | 82.8 | 79.6 | 83.7  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_384x288-806f00a3_20211130.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_384x288_20211130.log.json) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192.py) |  256x192   | 88.3 | 90.2 | 86.0 | 81.0 | 80.7 | 83.3 | 80.6 | 84.6  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_256x192-b5d9b3f1_20211130.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_256x192_20211130.log.json) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288.py) |  384x288   | 87.8 | 90.0 | 86.2 | 81.3 | 81.0 | 83.4 | 80.9 | 84.6  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_384x288-5fd6d3ff_20211130.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_384x288_20211130.log.json) |\n\nThe models are first pre-trained on COCO dataset, and then fine-tuned on PoseTrack18.\n\nResults on PoseTrack2018 val with [MMDetection](https://github.com/open-mmlab/mmdetection) pre-trained [Cascade R-CNN](https://download.openmmlab.com/mmdetection/v2.0/cascade_rcnn/cascade_rcnn_x101_64x4d_fpn_20e_coco/cascade_rcnn_x101_64x4d_fpn_20e_coco_20200509_224357-051557b1.pth) (X-101-64x4d-FPN) human detector\n\n| Arch                                                 | Input Size | Head | Shou | Elb  | Wri  | Hip  | Knee | Ankl | Total |                         ckpt                          |                         log                          |\n| :--------------------------------------------------- | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :---: | :---------------------------------------------------: | :--------------------------------------------------: |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192.py) |  256x192   | 78.0 | 82.9 | 79.5 | 73.8 | 76.9 | 76.6 | 70.2 | 76.9  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_256x192-1ee951c4_20201028.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_256x192_20201028.log.json) |\n| [pose_hrnet_w32](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288.py) |  384x288   | 79.9 | 83.6 | 80.4 | 74.5 | 74.8 | 76.1 | 70.5 | 77.3  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_384x288-806f00a3_20211130.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_384x288_20211130.log.json) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192.py) |  256x192   | 80.1 | 83.4 | 80.6 | 74.8 | 74.3 | 76.8 | 70.5 | 77.4  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_256x192-b5d9b3f1_20211130.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_256x192_20211130.log.json) |\n| [pose_hrnet_w48](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288.py) |  384x288   | 80.2 | 83.8 | 80.9 | 75.2 | 74.7 | 76.7 | 71.7 | 77.8  | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_384x288-5fd6d3ff_20211130.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_384x288_20211130.log.json) |\n\nThe models are first pre-trained on COCO dataset, and then fine-tuned on PoseTrack18.\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/hrnet_posetrack18.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 78.7\n      Elb: 84.5\n      Head: 86.2\n      Hip: 82.3\n      Knee: 82.5\n      Shou: 89\n      Total: 83.4\n      Wri: 79.2\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_256x192-1ee951c4_20201028.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 79.6\n      Elb: 84.5\n      Head: 87.1\n      Hip: 80.6\n      Knee: 82.8\n      Shou: 89\n      Total: 83.7\n      Wri: 80.2\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_384x288-806f00a3_20211130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 79.6\n      Elb: 85.1\n      Head: 88.3\n      Hip: 80.6\n      Knee: 82.8\n      Shou: 90.2\n      Total: 84.6\n      Wri: 81\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_256x192-b5d9b3f1_20211130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 80.6\n      Elb: 86.2\n      Head: 87.8\n      Hip: 81\n      Knee: 83.4\n      Shou: 90\n      Total: 84.6\n      Wri: 81.3\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_384x288-5fd6d3ff_20211130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 70.2\n      Elb: 79.5\n      Head: 78.0\n      Hip: 76.9\n      Knee: 76.6\n      Shou: 82.9\n      Total: 76.9\n      Wri: 73.8\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_256x192-1ee951c4_20201028.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 70.5\n      Elb: 80.4\n      Head: 79.9\n      Hip: 74.8\n      Knee: 76.1\n      Shou: 83.6\n      Total: 77.3\n      Wri: 74.5\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_posetrack18_384x288-806f00a3_20211130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 70.4\n      Elb: 80.6\n      Head: 80.1\n      Hip: 74.3\n      Knee: 76.8\n      Shou: 83.4\n      Total: 77.4\n      Wri: 74.8\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_256x192-b5d9b3f1_20211130.pth\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: PoseTrack18\n  Name: td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 71.7\n      Elb: 80.9\n      Head: 80.2\n      Hip: 74.7\n      Knee: 76.7\n      Shou: 83.8\n      Total: 77.8\n      Wri: 75.2\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_posetrack18_384x288-5fd6d3ff_20211130.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/resnet_posetrack18.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Andriluka_PoseTrack_A_Benchmark_CVPR_2018_paper.html\">PoseTrack18 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{andriluka2018posetrack,\n  title={Posetrack: A benchmark for human pose estimation and tracking},\n  author={Andriluka, Mykhaylo and Iqbal, Umar and Insafutdinov, Eldar and Pishchulin, Leonid and Milan, Anton and Gall, Juergen and Schiele, Bernt},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={5167--5176},\n  year={2018}\n}\n```\n\n</details>\n\nResults on PoseTrack2018 val with ground-truth bounding boxes\n\n| Arch                                                 | Input Size | Head | Shou | Elb  | Wri  | Hip  | Knee | Ankl | Total |                         ckpt                          |                         log                          |\n| :--------------------------------------------------- | :--------: | :--: | :--: | :--: | :--: | :--: | :--: | :--: | :---: | :---------------------------------------------------: | :--------------------------------------------------: |\n| [pose_resnet_50](/configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_res50_8xb64-20e_posetrack18-256x192.py) |  256x192   | 86.5 | 87.7 | 82.5 | 75.8 | 80.1 | 78.8 | 74.2 | 81.2  | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_posetrack18_256x192-a62807c7_20201028.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_posetrack18_256x192_20201028.log.json) |\n\nThe models are first pre-trained on COCO dataset, and then fine-tuned on PoseTrack18.\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/resnet_posetrack18.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_res50_8xb64-20e_posetrack18-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: PoseTrack18\n  Name: td-hm_res50_8xb64-20e_posetrack18-256x192\n  Results:\n  - Dataset: PoseTrack18\n    Metrics:\n      Ankl: 74.2\n      Elb: 82.5\n      Head: 86.5\n      Hip: 80.1\n      Knee: 78.8\n      Shou: 87.7\n      Total: 81.2\n      Wri: 75.8\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_posetrack18_256x192-a62807c7_20201028.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[10, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='posetrack18/Total AP', rule='greater', interval=1))\n\n# load from the pretrained model\nload_from = 'https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth'  # noqa: E501\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'PoseTrack18Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/posetrack18/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_val.json',\n        # comment `bbox_file` and '`filter_cfg` if use gt bbox for evaluation\n        bbox_file='data/posetrack18/annotations/'\n        'posetrack18_val_human_detections.json',\n        filter_cfg=dict(bbox_score_thr=0.4),\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='PoseTrack18Metric',\n    ann_file=data_root + 'annotations/posetrack18_val.json',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w32_8xb64-20e_posetrack18-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[10, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='posetrack18/Total AP', rule='greater', interval=1))\n\n# load from the pretrained model\nload_from = 'https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-384x288-ca5956af_20220909.pth'  # noqa: E501\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'PoseTrack18Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/posetrack18/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_val.json',\n        # comment `bbox_file` and '`filter_cfg` if use gt bbox for evaluation\n        bbox_file='data/posetrack18/annotations/'\n        'posetrack18_val_human_detections.json',\n        filter_cfg=dict(bbox_score_thr=0.4),\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='PoseTrack18Metric',\n    ann_file=data_root + 'annotations/posetrack18_val.json',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[10, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='posetrack18/Total AP', rule='greater', interval=1))\n\n# load from the pretrained model\nload_from = 'https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth'  # noqa: E501\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'PoseTrack18Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/posetrack18/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_val.json',\n        # comment `bbox_file` and '`filter_cfg` if use gt bbox for evaluation\n        bbox_file='data/posetrack18/annotations/'\n        'posetrack18_val_human_detections.json',\n        filter_cfg=dict(bbox_score_thr=0.4),\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='PoseTrack18Metric',\n    ann_file=data_root + 'annotations/posetrack18_val.json',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_hrnet-w48_8xb64-20e_posetrack18-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[10, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='posetrack18/Total AP', rule='greater', interval=1))\n\n# load from the pretrained model\nload_from = 'https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-384x288-c161b7de_20220915.pth'  # noqa: E501\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'PoseTrack18Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/posetrack18/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_val.json',\n        # comment `bbox_file` and '`filter_cfg` if use gt bbox for evaluation\n        bbox_file='data/posetrack18/annotations/'\n        'posetrack18_val_human_detections.json',\n        filter_cfg=dict(bbox_score_thr=0.4),\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='PoseTrack18Metric',\n    ann_file=data_root + 'annotations/posetrack18_val.json',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_heatmap/posetrack18/td-hm_res50_8xb64-20e_posetrack18-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[10, 15],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='posetrack18/Total AP', rule='greater', interval=1))\n\n# load from the pretrained model\nload_from = 'https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_256x192-ec54d7f3_20200709.pth'  # noqa: E501\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'PoseTrack18Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/posetrack18/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/posetrack18_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='PoseTrack18Metric',\n    ann_file=data_root + 'annotations/posetrack18_val.json',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/README.md",
    "content": "# Top-down regression-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. At the 2nd stage, regression based methods directly regress the keypoint coordinates given the features extracted from the bounding box area, following the paradigm introduced in [Deeppose: Human pose estimation via deep neural networks](http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515040-a82a8a29-d6bc-42f1-a2ab-7dfa610ce363.png\">\n</div>\n\n## Results and Models\n\n### COCO Dataset\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n|      Model       | Input Size |  AP   |  AR   |                   Details and Download                    |\n| :--------------: | :--------: | :---: | :---: | :-------------------------------------------------------: |\n|  ResNet-152+RLE  |  256x192   | 0.731 | 0.805 |      [resnet_rle_coco.md](./coco/resnet_rle_coco.md)      |\n|  ResNet-101+RLE  |  256x192   | 0.722 | 0.768 |      [resnet_rle_coco.md](./coco/resnet_rle_coco.md)      |\n|  ResNet-50+RLE   |  256x192   | 0.706 | 0.768 |      [resnet_rle_coco.md](./coco/resnet_rle_coco.md)      |\n| MobileNet-v2+RLE |  256x192   | 0.593 | 0.644 | [mobilenetv2_rle_coco.md](./coco/mobilenetv2_rle_coco.md) |\n|    ResNet-152    |  256x192   | 0.584 | 0.688 |          [resnet_coco.md](./coco/resnet_coco.md)          |\n|    ResNet-101    |  256x192   | 0.562 | 0.670 |          [resnet_coco.md](./coco/resnet_coco.md)          |\n|    ResNet-50     |  256x192   | 0.528 | 0.639 |          [resnet_coco.md](./coco/resnet_coco.md)          |\n\n### MPII Dataset\n\n|     Model     | Input Size | PCKh@0.5 | PCKh@0.1 |              Details and Download               |\n| :-----------: | :--------: | :------: | :------: | :---------------------------------------------: |\n| ResNet-50+RLE |  256x256   |  0.861   |  0.277   | [resnet_rle_mpii.md](./mpii/resnet_rle_mpii.md) |\n|  ResNet-152   |  256x256   |  0.850   |  0.208   |     [resnet_mpii.md](./mpii/resnet_mpii.md)     |\n|  ResNet-101   |  256x256   |  0.841   |  0.200   |     [resnet_mpii.md](./mpii/resnet_mpii.md)     |\n|   ResNet-50   |  256x256   |  0.826   |  0.180   |     [resnet_mpii.md](./mpii/resnet_mpii.md)     |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/mobilenetv2_rle_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.11291\">RLE (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{li2021human,\n  title={Human pose regression with residual log-likelihood estimation},\n  author={Li, Jiefeng and Bian, Siyuan and Zeng, Ailing and Wang, Can and Pang, Bo and Liu, Wentao and Lu, Cewu},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={11025--11034},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [deeppose_mobilenetv2_rle_pretrained](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192.py) |  256x192   | 0.593 |      0.836      |      0.660      | 0.644 |      0.877      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192-39b73bd5_20220922.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192-39b73bd5_20220922.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/mobilenetv2_rle_coco.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192.py\n  In Collection: RLE\n  Metadata:\n    Architecture: &id001\n    - DeepPose\n    - RLE\n    - MobileNet\n    Training Data: COCO\n  Name: td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.593\n      AP@0.5: 0.836\n      AP@0.75: 0.66\n      AR: 0.644\n      AR@0.5: 0.877\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192-39b73bd5_20220922.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/resnet_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [deeppose_resnet_50](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192.py) |  256x192   | 0.541 |      0.824      |      0.601      | 0.649 |      0.893      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192-72ef04f3_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192-72ef04f3_20220913.log.json) |\n| [deeppose_resnet_101](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res101_8xb64-210e_coco-256x192.py) |  256x192   | 0.562 |      0.831      |      0.629      | 0.670 |      0.900      | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_coco_256x192-2f247111_20210205.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_coco_256x192_20210205.log.json) |\n| [deeppose_resnet_152](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_8xb64-210e_coco-256x192.py) |  256x192   | 0.584 |      0.842      |      0.659      | 0.688 |      0.907      | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_256x192-7df89a88_20210205.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_256x192_20210205.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/resnet_coco.yml",
    "content": "Collections:\n- Name: DeepPose\n  Paper:\n    Title: \"Deeppose: Human pose estimation via deep neural networks\"\n    URL: http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/deeppose.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture: &id001\n    - DeepPose\n    - ResNet\n    Training Data: COCO\n  Name: td-reg_res50_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.541\n      AP@0.5: 0.824\n      AP@0.75: 0.601\n      AR: 0.649\n      AR@0.5: 0.893\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192-72ef04f3_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res101_8xb64-210e_coco-256x192.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-reg_res101_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.562\n      AP@0.5: 0.831\n      AP@0.75: 0.629\n      AR: 0.67\n      AR@0.5: 0.9\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_coco_256x192-2f247111_20210205.pth\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_8xb64-210e_coco-256x192.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-reg_res152_8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.584\n      AP@0.5: 0.842\n      AP@0.75: 0.659\n      AR: 0.688\n      AR@0.5: 0.907\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_256x192-7df89a88_20210205.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/resnet_rle_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.11291\">RLE (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{li2021human,\n  title={Human pose regression with residual log-likelihood estimation},\n  author={Li, Jiefeng and Bian, Siyuan and Zeng, Ailing and Wang, Can and Pang, Bo and Liu, Wentao and Lu, Cewu},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={11025--11034},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [deeppose_resnet_50_rle](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py) |  256x192   | 0.706 |      0.888      |      0.776      | 0.753 |      0.924      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192-d37efd64_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192-d37efd64_20220913.log.json) |\n| [deeppose_resnet_50_rle_pretrained](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192.py) |  256x192   | 0.719 |      0.891      |      0.788      | 0.764 |      0.925      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192-2cb494ee_20220913.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192-2cb494ee_20220913.log.json) |\n| [deeppose_resnet_101_rle](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res101_rle-8xb64-210e_coco-256x192.py) |  256x192   | 0.722 |      0.894      |      0.794      | 0.768 |      0.930      | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_coco_256x192_rle-16c3d461_20220615.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_coco_256x192_rle_20220615.log.json) |\n| [deeppose_resnet_152_rle](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_rle-8xb64-210e_coco-256x192.py) |  256x192   | 0.731 |      0.897      |      0.805      | 0.777 |      0.933      | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_256x192_rle-c05bdccf_20220615.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_256x192_rle_20220615.log.json) |\n| [deeppose_resnet_152_rle](/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_rle-8xb64-210e_coco-384x288.py) |  384x288   | 0.749 |      0.901      |      0.815      | 0.793 |      0.935      | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_384x288_rle-b77c4c37_20220624.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_384x288_rle_20220624.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/resnet_rle_coco.yml",
    "content": "Collections:\n- Name: RLE\n  Paper:\n    Title: Human pose regression with residual log-likelihood estimation\n    URL: https://arxiv.org/abs/2107.11291\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/techniques/rle.md\nModels:\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py\n  In Collection: RLE\n  Metadata:\n    Architecture: &id001\n    - DeepPose\n    - RLE\n    - ResNet\n    Training Data: COCO\n  Name: td-reg_res50_rle-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.706\n      AP@0.5: 0.888\n      AP@0.75: 0.776\n      AR: 0.753\n      AR@0.5: 0.924\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192-d37efd64_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192.py\n  In Collection: RLE\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.719\n      AP@0.5: 0.891\n      AP@0.75: 0.788\n      AR: 0.764\n      AR@0.5: 0.925\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192-2cb494ee_20220913.pth\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res101_rle-8xb64-210e_coco-256x192.py\n  In Collection: RLE\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-reg_res101_rle-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.722\n      AP@0.5: 0.894\n      AP@0.75: 0.794\n      AR: 0.768\n      AR@0.5: 0.93\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_coco_256x192_rle-16c3d461_20220615.pth\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_rle-8xb64-210e_coco-256x192.py\n  In Collection: RLE\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-reg_res152_rle-8xb64-210e_coco-256x192\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.731\n      AP@0.5: 0.897\n      AP@0.75: 0.805\n      AR: 0.777\n      AR@0.5: 0.933\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_256x192_rle-c05bdccf_20220615.pth\n- Config: configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_rle-8xb64-210e_coco-384x288.py\n  In Collection: RLE\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: td-reg_res152_rle-8xb64-210e_coco-384x288\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.749\n      AP@0.5: 0.901\n      AP@0.75: 0.815\n      AR: 0.793\n      AR@0.5: 0.935\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_coco_384x288_rle-b77c4c37_20220624.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_mobilenetv2_rle-pretrained-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/top_down/'\n            'mobilenetv2/mobilenetv2_coco_256x192-d1e58e7b_20200727.pth')),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=1280,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ),\n)\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json',\n    score_mode='bbox_rle')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res101_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res101_rle-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json',\n    score_mode='bbox_rle')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_rle-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json',\n    score_mode='bbox_rle')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res152_rle-8xb64-210e_coco-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(288, 384))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json',\n    score_mode='bbox_rle')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json',\n    score_mode='bbox_rle')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-pretrained-8xb64-210e_coco-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=train_cfg['max_epochs'],\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/td-hm_res50_8xb64-210e_coco-256x192.pth'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=f'{data_root}annotations/person_keypoints_val2017.json',\n    score_mode='bbox_rle')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/resnet_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [deeppose_resnet_50](/configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res50_8xb64-210e_mpii-256x256.py) |  256x256   | 0.826 |  0.180   | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_mpii_256x256-c63cd0b6_20210203.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_mpii_256x256_20210203.log.json) |\n| [deeppose_resnet_101](/configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res101_8xb64-210e_mpii-256x256.py) |  256x256   | 0.841 |  0.200   | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_mpii_256x256-87516a90_20210205.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_mpii_256x256_20210205.log.json) |\n| [deeppose_resnet_152](/configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res152_8xb64-210e_mpii-256x256.py) |  256x256   | 0.850 |  0.208   | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_mpii_256x256-15f5e6f9_20210205.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_mpii_256x256_20210205.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/resnet_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res50_8xb64-210e_mpii-256x256.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture: &id001\n    - DeepPose\n    - ResNet\n    Training Data: MPII\n  Name: td-reg_res50_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.826\n      Mean@0.1: 0.18\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_mpii_256x256-c63cd0b6_20210203.pth\n- Config: configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res101_8xb64-210e_mpii-256x256.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-reg_res101_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.841\n      Mean@0.1: 0.2\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res101_mpii_256x256-87516a90_20210205.pth\n- Config: configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res152_8xb64-210e_mpii-256x256.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture: *id001\n    Training Data: MPII\n  Name: td-reg_res152_8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.85\n      Mean@0.1: 0.208\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res152_mpii_256x256-15f5e6f9_20210205.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/resnet_rle_mpii.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.11291\">RLE (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{li2021human,\n  title={Human pose regression with residual log-likelihood estimation},\n  author={Li, Jiefeng and Bian, Siyuan and Zeng, Ailing and Wang, Can and Pang, Bo and Liu, Wentao and Lu, Cewu},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={11025--11034},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nResults on MPII val set\n\n| Arch                                                        | Input Size | Mean  | Mean@0.1 |                            ckpt                             |                             log                             |\n| :---------------------------------------------------------- | :--------: | :---: | :------: | :---------------------------------------------------------: | :---------------------------------------------------------: |\n| [deeppose_resnet_50_rle](/configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res50_rle-8xb64-210e_mpii-256x256.py) |  256x256   | 0.861 |  0.277   | [ckpt](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_mpii_256x256_rle-5f92a619_20220504.pth) | [log](https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_mpii_256x256_rle_20220504.log.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/resnet_rle_mpii.yml",
    "content": "Models:\n- Config: configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res50_rle-8xb64-210e_mpii-256x256.py\n  In Collection: RLE\n  Metadata:\n    Architecture:\n    - DeepPose\n    - RLE\n    - ResNet\n    Training Data: MPII\n  Name: td-reg_res50_rle-8xb64-210e_mpii-256x256\n  Results:\n  - Dataset: MPII\n    Metrics:\n      Mean: 0.861\n      Mean@0.1: 0.277\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_mpii_256x256_rle-5f92a619_20220504.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res101_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=16,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res152_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=16,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\nfile_client_args = dict(backend='disk')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', file_client_args=file_client_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', file_client_args=file_client_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res50_8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=16,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/topdown_regression/mpii/td-reg_res50_rle-8xb64-210e_mpii-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=16,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'MpiiDataset'\ndata_mode = 'topdown'\ndata_root = 'data/mpii/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform', shift_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/mpii_val.json',\n        headbox_file=f'{data_root}/annotations/mpii_gt_val.mat',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='PCK', rule='greater'))\n\n# evaluators\nval_evaluator = dict(type='MpiiPCKAccuracy')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/README.md",
    "content": "# YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.06806\">YOLO-Pose (CVPRW'2022)</a></summary>\n\n```bibtex\n@inproceedings{maji2022yolo,\n  title={Yolo-pose: Enhancing yolo for multi person pose estimation using object keypoint similarity loss},\n  author={Maji, Debapriya and Nagori, Soyeb and Mathew, Manu and Poddar, Deepak},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={2637--2646},\n  year={2022}\n}\n```\n\n</details>\n\nYOLO-Pose is a bottom-up pose estimation approach that simultaneously detects all person instances and regresses keypoint locations in a single pass.\n\nWe implement **YOLOX-Pose** based on the **YOLOX** object detection framework and inherits the benefits of unified pose estimation and object detection from YOLO-pose. To predict keypoint locations more accurately, separate branches with adaptive convolutions are used to regress the offsets for different joints. This allows optimizing the feature extraction for each keypoint.\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_coco.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.06806\">YOLO-Pose (CVPRW'2022)</a></summary>\n\n```bibtex\n@inproceedings{maji2022yolo,\n  title={Yolo-pose: Enhancing yolo for multi person pose estimation using object keypoint similarity loss},\n  author={Maji, Debapriya and Nagori, Soyeb and Mathew, Manu and Poddar, Deepak},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={2637--2646},\n  year={2022}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.08430\">YOLOX</a></summary>\n\n```bibtex\n@article{ge2021yolox,\n  title={Yolox: Exceeding yolo series in 2021},\n  author={Ge, Zheng and Liu, Songtao and Wang, Feng and Li, Zeming and Sun, Jian},\n  journal={arXiv preprint arXiv:2107.08430},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nResults on COCO val2017\n\n| Arch                                          | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                     ckpt                      |                      log                      |\n| :-------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :-------------------------------------------: | :-------------------------------------------: |\n| [yoloxpose_tiny](/configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_tiny_4xb64-300e_coco-416.py) |  416x416   | 0.526 |      0.793      |      0.556      | 0.571 |      0.833      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_tiny_4xb64-300e_coco-416-76eb44ca_20230829.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_tiny_4xb64-300e_coco-416-20230829.json) |\n| [yoloxpose_s](/configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_s_8xb32-300e_coco-640.py) |  640x640   | 0.641 |      0.872      |      0.702      | 0.682 |      0.902      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_s_8xb32-300e_coco-640-56c79c1f_20230829.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_s_8xb32-300e_coco-640-20230829.json) |\n| [yoloxpose_m](/configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_m_8xb32-300e_coco-640.py) |  640x640   | 0.695 |      0.899      |      0.766      | 0.733 |      0.926      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_m_8xb32-300e_coco-640-84e9a538_20230829.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_m_8xb32-300e_coco-640-20230829.json) |\n| [yoloxpose_l](/configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_l_8xb32-300e_coco-640.py) |  640x640   | 0.712 |      0.901      |      0.782      | 0.749 |      0.926      | [ckpt](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_l_8xb32-300e_coco-640-de0f8dee_20230829.pth) | [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_l_8xb32-300e_coco-640-20230829.json) |\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_coco.yml",
    "content": "Collections:\n- Name: YOLOXPose\n  Paper:\n    Title: 'YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss'\n    URL: https://arxiv.org/abs/2204.06806\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/algorithms/yolopose.md\nModels:\n- Config: configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_tiny_4xb64-300e_coco-416.py\n  In Collection: YOLOXPose\n  Metadata:\n    Architecture: &id001\n    - YOLOXPose\n    Training Data: COCO\n  Name: yoloxpose_tiny_4xb64-300e_coco-416\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.526\n      AP@0.5: 0.793\n      AP@0.75: 0.556\n      AR: 0.571\n      AR@0.5: 0.833\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_tiny_4xb64-300e_coco-416-76eb44ca_20230829.pth\n- Config: configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_s_8xb32-300e_coco-640.py\n  In Collection: YOLOXPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: yoloxpose_s_8xb32-300e_coco-640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.641\n      AP@0.5: 0.872\n      AP@0.75: 0.702\n      AR: 0.682\n      AR@0.5: 0.902\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_s_8xb32-300e_coco-640-56c79c1f_20230829.pth\n- Config: configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_m_8xb32-300e_coco-640.py\n  In Collection: YOLOXPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: yoloxpose_m_8xb32-300e_coco-640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.695\n      AP@0.5: 0.899\n      AP@0.75: 0.766\n      AR: 0.733\n      AR@0.5: 0.926\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_m_8xb32-300e_coco-640-84e9a538_20230829.pth\n- Config: configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_l_8xb32-300e_coco-640.py\n  In Collection: YOLOXPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO\n  Name: yoloxpose_l_8xb32-300e_coco-640\n  Results:\n  - Dataset: COCO\n    Metrics:\n      AP: 0.712\n      AP@0.5: 0.901\n      AP@0.75: 0.782\n      AR: 0.749\n      AR@0.5: 0.926\n    Task: Body 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/yolox_pose/yoloxpose_l_8xb32-300e_coco-640-de0f8dee_20230829.pth\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_l_8xb32-300e_coco-640.py",
    "content": "_base_ = './yoloxpose_s_8xb32-300e_coco-640.py'\n\nwiden_factor = 1\ndeepen_factor = 1\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v2.0/yolox/yolox_' \\\n    'l_8x8_300e_coco/yolox_l_8x8_300e_coco_20211126_140236-d3bd2b23.pth'\n\n# model settings\nmodel = dict(\n    backbone=dict(\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        init_cfg=dict(checkpoint=checkpoint),\n    ),\n    neck=dict(\n        in_channels=[256, 512, 1024], out_channels=256, num_csp_blocks=3),\n    head=dict(head_module_cfg=dict(widen_factor=widen_factor)))\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_m_8xb32-300e_coco-640.py",
    "content": "_base_ = './yoloxpose_s_8xb32-300e_coco-640.py'\n\nwiden_factor = 0.75\ndeepen_factor = 0.67\ncheckpoint = 'https://download.openmmlab.com/mmpose/v1/pretrained_models/' \\\n             'yolox_m_8x8_300e_coco_20230829.pth'\n\n# model settings\nmodel = dict(\n    backbone=dict(\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        init_cfg=dict(checkpoint=checkpoint),\n    ),\n    neck=dict(in_channels=[192, 384, 768], out_channels=192, num_csp_blocks=2),\n    head=dict(head_module_cfg=dict(widen_factor=widen_factor)))\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_s_8xb32-300e_coco-640.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(\n    _delete_=True,\n    type='EpochBasedTrainLoop',\n    max_epochs=300,\n    val_interval=10,\n    dynamic_intervals=[(280, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n\ndefault_hooks = dict(\n    checkpoint=dict(type='CheckpointHook', interval=10, max_keep_ckpts=3))\n\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=0.004, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0,\n        bias_decay_mult=0,\n        bypass_duplicate=True,\n    ),\n    clip_grad=dict(max_norm=0.1, norm_type=2))\n\nparam_scheduler = [\n    dict(\n        type='QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0002,\n        begin=5,\n        T_max=280,\n        end=280,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=280, end=300),\n]\n\n# model\nwiden_factor = 0.5\ndeepen_factor = 0.33\n\nmodel = dict(\n    type='BottomupPoseEstimator',\n    init_cfg=dict(\n        type='Kaiming',\n        layer='Conv2d',\n        a=2.23606797749979,\n        distribution='uniform',\n        mode='fan_in',\n        nonlinearity='leaky_relu'),\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        pad_size_divisor=32,\n        mean=[0, 0, 0],\n        std=[1, 1, 1],\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1),\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmdetection/v2.0/'\n            'yolox/yolox_s_8x8_300e_coco/yolox_s_8x8_300e_coco_'\n            '20211121_095711-4592a793.pth',\n            prefix='backbone.',\n        )),\n    neck=dict(\n        type='YOLOXPAFPN',\n        in_channels=[128, 256, 512],\n        out_channels=128,\n        num_csp_blocks=1,\n        use_depthwise=False,\n        upsample_cfg=dict(scale_factor=2, mode='nearest'),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish')),\n    head=dict(\n        type='YOLOXPoseHead',\n        num_keypoints=17,\n        featmap_strides=(8, 16, 32),\n        head_module_cfg=dict(\n            num_classes=1,\n            in_channels=256,\n            feat_channels=256,\n            widen_factor=widen_factor,\n            stacked_convs=2,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='Swish')),\n        prior_generator=dict(\n            type='MlvlPointGenerator', offset=0, strides=[8, 16, 32]),\n        assigner=dict(type='SimOTAAssigner', dynamic_k_indicator='oks'),\n        overlaps_power=0.5,\n        loss_cls=dict(type='BCELoss', reduction='sum', loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_obj=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_oks=dict(\n            type='OKSLoss',\n            reduction='none',\n            metainfo='configs/_base_/datasets/coco.py',\n            norm_target_weight=True,\n            loss_weight=30.0),\n        loss_vis=dict(\n            type='BCELoss',\n            use_target_weight=True,\n            reduction='mean',\n            loss_weight=1.0),\n        loss_bbox_aux=dict(type='L1Loss', reduction='sum', loss_weight=1.0),\n    ),\n    test_cfg=dict(\n        score_thr=0.01,\n        nms_thr=0.65,\n    ))\n\n# data\ninput_size = (640, 640)\ncodec = dict(type='YOLOXPoseAnnotationProcessor', input_size=input_size)\n\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=(640, 640),\n        shift_prob=0,\n        rotate_prob=0,\n        scale_prob=0,\n        scale_type='long',\n        pad_val=(114, 114, 114),\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs'),\n]\n\ndata_mode = 'bottomup'\ndata_root = 'data/'\n\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    filter_cfg=dict(filter_empty_gt=False, min_size=32),\n    ann_file='coco/annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='coco/train2017/'),\n    pipeline=train_pipeline_stage1,\n)\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dataset_coco)\n\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json',\n    score_mode='bbox',\n    nms_mode='none',\n)\ntest_evaluator = val_evaluator\n\ncustom_hooks = [\n    dict(\n        type='YOLOXPoseModeSwitchHook',\n        num_last_epochs=20,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49),\n]\n"
  },
  {
    "path": "configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_tiny_4xb64-300e_coco-416.py",
    "content": "_base_ = './yoloxpose_s_8xb32-300e_coco-640.py'\n\n# model settings\nwiden_factor = 0.375\ndeepen_factor = 0.33\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v2.0/yolox/yolox_' \\\n    'tiny_8x8_300e_coco/yolox_tiny_8x8_300e_coco_20211124_171234-b4047906.pth'\n\nmodel = dict(\n    data_preprocessor=dict(batch_augments=[\n        dict(\n            type='BatchSyncRandomResize',\n            random_size_range=(320, 640),\n            size_divisor=32,\n            interval=1),\n    ]),\n    backbone=dict(\n        deepen_factor=deepen_factor,\n        widen_factor=widen_factor,\n        init_cfg=dict(checkpoint=checkpoint),\n    ),\n    neck=dict(\n        in_channels=[96, 192, 384],\n        out_channels=96,\n    ),\n    head=dict(head_module_cfg=dict(widen_factor=widen_factor), ))\n\n# dataset settings\ntrain_pipeline_stage1 = [\n    dict(type='LoadImage', backend_args=None),\n    dict(\n        type='Mosaic',\n        img_scale=_base_.input_size,\n        pad_val=114.0,\n        pre_transform=[dict(type='LoadImage', backend_args=None)]),\n    dict(\n        type='BottomupRandomAffine',\n        input_size=_base_.input_size,\n        shift_factor=0.1,\n        rotate_factor=10,\n        scale_factor=(0.75, 1.0),\n        pad_val=114,\n        distribution='uniform',\n        transform_mode='perspective',\n        bbox_keep_corner=False,\n        clip_border=True,\n    ),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip'),\n    dict(type='FilterAnnotations', by_kpt=True, by_box=True, keep_empty=False),\n    dict(type='GenerateTarget', encoder=_base_.codec),\n    dict(\n        type='PackPoseInputs',\n        extra_mapping_labels={\n            'bbox': 'bboxes',\n            'bbox_labels': 'labels',\n            'keypoints': 'keypoints',\n            'keypoints_visible': 'keypoints_visible',\n            'area': 'areas'\n        }),\n]\ntrain_dataloader = dict(\n    batch_size=64, dataset=dict(pipeline=train_pipeline_stage1))\n\ninput_size = (416, 416)\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(\n        type='BottomupResize', input_size=input_size, pad_val=(114, 114, 114)),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'input_size', 'input_center', 'input_scale'))\n]\n\nval_dataloader = dict(dataset=dict(pipeline=val_pipeline, ))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "configs/body_3d_keypoint/README.md",
    "content": "# Human Body 3D Pose Estimation\n\n3D pose estimation is the detection and analysis of X, Y, Z coordinates of human body joints from RGB images. For single-person 3D pose estimation from a monocular camera, existing works can be classified into three categories: (1) from 2D poses to 3D poses (2D-to-3D pose lifting) (2) jointly learning 2D and 3D poses, and (3) directly regressing 3D poses from images.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/3d_body_keypoint.md) to prepare data.\n\n## Demo\n\nPlease follow [Demo](/demo/docs/en/3d_human_pose_demo.md) to run demos.\n\n<img src=\"https://user-images.githubusercontent.com/15977946/118820606-02df2000-b8e9-11eb-9984-b9228101e780.gif\" width=\"600px\" alt><br>\n"
  },
  {
    "path": "configs/body_3d_keypoint/image_pose_lift/README.md",
    "content": "# A simple yet effective baseline for 3d human pose estimation\n\nSimple 3D baseline proposes to break down the task of 3d human pose estimation into 2 stages: (1) Image → 2D pose (2) 2D pose → 3D pose.\n\nThe authors find that \"lifting\" ground truth 2D joint locations to 3D space is a task that can be solved with a low error rate. Based on the success of 2d human pose estimation, it directly \"lifts\" 2d joint locations to 3d space.\n\n## Results and Models\n\n### Human3.6m Dataset\n\n| Arch                                        | MPJPE | P-MPJPE |                    ckpt                     |                     log                     |                    Details and Download                     |\n| :------------------------------------------ | :---: | :-----: | :-----------------------------------------: | :-----------------------------------------: | :---------------------------------------------------------: |\n| [SimpleBaseline3D](/configs/body_3d_keypoint/image_pose_lift/h36m/image-pose-lift_tcn_8xb64-200e_h36m.py) | 43.4  |  34.3   | [ckpt](https://download.openmmlab.com/mmpose/body3d/simple_baseline/simple3Dbaseline_h36m-f0ad73a4_20210419.pth) | [log](https://download.openmmlab.com/mmpose/body3d/simple_baseline/20210415_065056.log.json) | [simplebaseline3d_h36m.md](./h36m/simplebaseline3d_h36m.md) |\n"
  },
  {
    "path": "configs/body_3d_keypoint/image_pose_lift/h36m/image-pose-lift_tcn_8xb64-200e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=200, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=1e-3))\n\n# learning policy\nparam_scheduler = [\n    dict(type='StepLR', step_size=100000, gamma=0.96, end=80, by_epoch=False)\n]\n\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1))\n\n# codec settings\n# 3D keypoint normalization parameters\n# From file: '{data_root}/annotation_body3d/fps50/joint3d_rel_stats.pkl'\ntarget_mean = [[-2.55652589e-04, -7.11960570e-03, -9.81433052e-04],\n               [-5.65463051e-03, 3.19636009e-01, 7.19329269e-02],\n               [-1.01705840e-02, 6.91147892e-01, 1.55352986e-01],\n               [2.55651315e-04, 7.11954606e-03, 9.81423866e-04],\n               [-5.09729780e-03, 3.27040413e-01, 7.22258095e-02],\n               [-9.99656606e-03, 7.08277383e-01, 1.58016408e-01],\n               [2.90583676e-03, -2.11363307e-01, -4.74210915e-02],\n               [5.67537804e-03, -4.35088906e-01, -9.76974016e-02],\n               [5.93884964e-03, -4.91891970e-01, -1.10666618e-01],\n               [7.37352083e-03, -5.83948619e-01, -1.31171400e-01],\n               [5.41920653e-03, -3.83931702e-01, -8.68145417e-02],\n               [2.95964662e-03, -1.87567488e-01, -4.34536934e-02],\n               [1.26585822e-03, -1.20170579e-01, -2.82526049e-02],\n               [4.67186639e-03, -3.83644089e-01, -8.55125784e-02],\n               [1.67648571e-03, -1.97007177e-01, -4.31368364e-02],\n               [8.70569015e-04, -1.68664569e-01, -3.73902498e-02]],\ntarget_std = [[0.11072244, 0.02238818, 0.07246294],\n              [0.15856311, 0.18933832, 0.20880479],\n              [0.19179935, 0.24320062, 0.24756193],\n              [0.11072181, 0.02238805, 0.07246253],\n              [0.15880454, 0.19977188, 0.2147063],\n              [0.18001944, 0.25052739, 0.24853247],\n              [0.05210694, 0.05211406, 0.06908241],\n              [0.09515367, 0.10133032, 0.12899733],\n              [0.11742458, 0.12648469, 0.16465091],\n              [0.12360297, 0.13085539, 0.16433336],\n              [0.14602232, 0.09707956, 0.13952731],\n              [0.24347532, 0.12982249, 0.20230181],\n              [0.2446877, 0.21501816, 0.23938235],\n              [0.13876084, 0.1008926, 0.1424411],\n              [0.23687529, 0.14491219, 0.20980829],\n              [0.24400695, 0.23975028, 0.25520584]]\n# 2D keypoint normalization parameters\n# From file: '{data_root}/annotation_body3d/fps50/joint2d_stats.pkl'\nkeypoints_mean = [[532.08351635, 419.74137558], [531.80953144, 418.2607141],\n                  [530.68456967, 493.54259285], [529.36968722, 575.96448516],\n                  [532.29767646, 421.28483336], [531.93946631, 494.72186795],\n                  [529.71984447, 578.96110365], [532.93699382, 370.65225054],\n                  [534.1101856, 317.90342311], [534.55416813, 304.24143901],\n                  [534.86955004, 282.31030885], [534.11308566, 330.11296796],\n                  [533.53637525, 376.2742511], [533.49380107, 391.72324565],\n                  [533.52579142, 330.09494668], [532.50804964, 374.190479],\n                  [532.72786934, 380.61615716]],\nkeypoints_std = [[107.73640054, 63.35908715], [119.00836213, 64.1215443],\n                 [119.12412107, 50.53806215], [120.61688045, 56.38444891],\n                 [101.95735275, 62.89636486], [106.24832897, 48.41178119],\n                 [108.46734966, 54.58177071], [109.07369806, 68.70443672],\n                 [111.20130351, 74.87287863], [111.63203838, 77.80542514],\n                 [113.22330788, 79.90670556], [105.7145833, 73.27049436],\n                 [107.05804267, 73.93175781], [107.97449418, 83.30391802],\n                 [121.60675105, 74.25691526], [134.34378973, 77.48125087],\n                 [131.79990652, 89.86721124]]\ncodec = dict(\n    type='ImagePoseLifting',\n    num_keypoints=17,\n    root_index=0,\n    remove_root=True,\n    target_mean=target_mean,\n    target_std=target_std,\n    keypoints_mean=keypoints_mean,\n    keypoints_std=keypoints_std)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=2,\n        kernel_sizes=(1, 1, 1),\n        dropout=0.5,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=16,\n        loss=dict(type='MSELoss'),\n        decoder=codec,\n    ))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root', 'target_root_index', 'target_mean',\n                   'target_std'))\n]\nval_pipeline = train_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=1,\n        causal=True,\n        keypoint_2d_src='gt',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=1,\n        causal=True,\n        keypoint_2d_src='gt',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/image_pose_lift/h36m/simplebaseline3d_h36m.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2017/html/Martinez_A_Simple_yet_ICCV_2017_paper.html\">SimpleBaseline3D (ICCV'2017)</a></summary>\n\n```bibtex\n@inproceedings{martinez_2017_3dbaseline,\n  title={A simple yet effective baseline for 3d human pose estimation},\n  author={Martinez, Julieta and Hossain, Rayat and Romero, Javier and Little, James J.},\n  booktitle={ICCV},\n  year={2017}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\nResults on Human3.6M dataset with ground truth 2D detections\n\n| Arch                                                            | MPJPE | P-MPJPE |                              ckpt                               |                              log                               |\n| :-------------------------------------------------------------- | :---: | :-----: | :-------------------------------------------------------------: | :------------------------------------------------------------: |\n| [SimpleBaseline3D<sup>1</sup>](/configs/body_3d_keypoint/image_pose_lift/h36m/image-pose-lift_tcn_8xb64-200e_h36m.py) | 43.4  |  34.3   | [ckpt](https://download.openmmlab.com/mmpose/body3d/simple_baseline/simple3Dbaseline_h36m-f0ad73a4_20210419.pth) | [log](https://download.openmmlab.com/mmpose/body3d/simple_baseline/20210415_065056.log.json) |\n\n<sup>1</sup> Differing from the original paper, we didn't apply the `max-norm constraint` because we found this led to a better convergence and performance.\n"
  },
  {
    "path": "configs/body_3d_keypoint/image_pose_lift/h36m/simplebaseline3d_h36m.yml",
    "content": "Collections:\n- Name: SimpleBaseline3D\n  Paper:\n    Title: A simple yet effective baseline for 3d human pose estimation\n    URL: http://openaccess.thecvf.com/content_iccv_2017/html/Martinez_A_Simple_yet_ICCV_2017_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/en/papers/algorithms/simplebaseline3d.md\nModels:\n- Config: configs/body_3d_keypoint/image_pose_lift/h36m/image-pose-lift_tcn_8xb64-200e_h36m.py\n  In Collection: SimpleBaseline3D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline3D\n    Training Data: Human3.6M\n  Name: image-pose-lift_tcn_8xb64-200e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 43.4\n      P-MPJPE: 34.3\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/simple_baseline/simple3Dbaseline_h36m-f0ad73a4_20210419.pth\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/README.md",
    "content": "# MotionBERT: A Unified Perspective on Learning Human Motion Representations\n\nMotionbert proposes a pretraining stage in which a motion encoder is trained to recover the underlying 3D motion from noisy partial 2D observations. The motion representations acquired in this way incorporate geometric, kinematic, and physical knowledge about human motion, which can be easily transferred to multiple downstream tasks.\n\n## Results and Models\n\n### Human3.6m Dataset\n\n| Arch                                                                  | MPJPE | P-MPJPE |                                 ckpt                                  | log |              Details and Download               |\n| :-------------------------------------------------------------------- | :---: | :-----: | :-------------------------------------------------------------------: | :-: | :---------------------------------------------: |\n| [MotionBERT\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m.py) | 35.3  |  27.7   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_h36m-f554954f_20230531.pth) |  /  | [motionbert_h36m.md](./h36m/motionbert_h36m.md) |\n| [MotionBERT-finetuned\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m.py) | 27.5  |  21.6   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth) |  /  | [motionbert_h36m.md](./h36m/motionbert_h36m.md) |\n\n### Human3.6m Dataset from official repo <sup>1</sup>\n\n| Arch                                                           | MPJPE | Average MPJPE | P-MPJPE |                              ckpt                               | log |              Details and Download               |\n| :------------------------------------------------------------- | :---: | :-----------: | :-----: | :-------------------------------------------------------------: | :-: | :---------------------------------------------: |\n| [MotionBERT\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m-original.py) | 39.8  |     39.2      |  33.4   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_h36m-f554954f_20230531.pth) |  /  | [motionbert_h36m.md](./h36m/motionbert_h36m.md) |\n| [MotionBERT-finetuned\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m-original.py) | 37.7  |     37.2      |  32.2   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth) |  /  | [motionbert_h36m.md](./h36m/motionbert_h36m.md) |\n\n<sup>1</sup> Please refer to the [doc](./h36m/motionbert_h36m.md) for more details.\n\n*Models with * are converted from the official repo. The config files of these models are only for validation. We don't ensure these config files' training accuracy and welcome you to contribute your reproduction results.*\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m-original.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=240, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(type='AdamW', lr=0.0002, weight_decay=0.01))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.99, end=120, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ntrain_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, mode='train')\nval_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, rootrel=True)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='DSTFormer',\n        in_channels=3,\n        feat_size=512,\n        depth=5,\n        num_heads=8,\n        mlp_ratio=2,\n        seq_len=243,\n        att_fuse=True,\n    ),\n    head=dict(\n        type='MotionRegressionHead',\n        in_channels=512,\n        out_channels=3,\n        embedding_size=512,\n        loss=dict(type='MPJPEVelocityJointLoss'),\n        decoder=val_codec,\n    ),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='GenerateTarget', encoder=train_codec),\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(center_mode='static', center_x=0.),\n        target_flip_cfg=dict(center_mode='static', center_x=0.),\n        flip_label=True),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=val_codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train_original.npz',\n        seq_len=1,\n        multiple_target=243,\n        multiple_target_step=81,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\n\nval_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test_original.npz',\n        factor_file='annotation_body3d/fps50/h36m_factors.npy',\n        seq_len=1,\n        seq_step=1,\n        multiple_target=243,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nskip_list = [\n    'S9_Greet', 'S9_SittingDown', 'S9_Wait_1', 'S9_Greeting', 'S9_Waiting_1'\n]\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe', skip_list=skip_list),\n    dict(type='MPJPE', mode='p-mpjpe', skip_list=skip_list)\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=240, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(type='AdamW', lr=0.0002, weight_decay=0.01))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.99, end=120, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ntrain_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, mode='train')\nval_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, rootrel=True)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='DSTFormer',\n        in_channels=3,\n        feat_size=512,\n        depth=5,\n        num_heads=8,\n        mlp_ratio=2,\n        seq_len=243,\n        att_fuse=True,\n    ),\n    head=dict(\n        type='MotionRegressionHead',\n        in_channels=512,\n        out_channels=3,\n        embedding_size=512,\n        loss=dict(type='MPJPEVelocityJointLoss'),\n        decoder=val_codec,\n    ),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='GenerateTarget', encoder=train_codec),\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(center_mode='static', center_x=0.),\n        target_flip_cfg=dict(center_mode='static', center_x=0.),\n        flip_label=True),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=val_codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=1,\n        multiple_target=243,\n        multiple_target_step=81,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\n\nval_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=1,\n        seq_step=1,\n        multiple_target=243,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nskip_list = [\n    'S9_Greet', 'S9_SittingDown', 'S9_Wait_1', 'S9_Greeting', 'S9_Waiting_1'\n]\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe', skip_list=skip_list),\n    dict(type='MPJPE', mode='p-mpjpe', skip_list=skip_list)\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m-original.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=120, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(type='AdamW', lr=0.0002, weight_decay=0.01))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.99, end=60, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ntrain_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, mode='train')\nval_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, rootrel=True)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='DSTFormer',\n        in_channels=3,\n        feat_size=512,\n        depth=5,\n        num_heads=8,\n        mlp_ratio=2,\n        seq_len=243,\n        att_fuse=True,\n    ),\n    head=dict(\n        type='MotionRegressionHead',\n        in_channels=512,\n        out_channels=3,\n        embedding_size=512,\n        loss=dict(type='MPJPEVelocityJointLoss'),\n        decoder=val_codec,\n    ),\n    test_cfg=dict(flip_test=True),\n    init_cfg=dict(\n        type='Pretrained',\n        checkpoint='https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/'\n        'pose_lift/h36m/motionbert_pretrain_h36m-29ffebf5_20230719.pth'),\n)\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='GenerateTarget', encoder=train_codec),\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(center_mode='static', center_x=0.),\n        target_flip_cfg=dict(center_mode='static', center_x=0.),\n        flip_label=True),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=val_codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train_original.npz',\n        seq_len=1,\n        multiple_target=243,\n        multiple_target_step=81,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\n\nval_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test_original.npz',\n        factor_file='annotation_body3d/fps50/h36m_factors.npy',\n        seq_len=1,\n        seq_step=1,\n        multiple_target=243,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nskip_list = [\n    'S9_Greet', 'S9_SittingDown', 'S9_Wait_1', 'S9_Greeting', 'S9_Waiting_1'\n]\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe', skip_list=skip_list),\n    dict(type='MPJPE', mode='p-mpjpe', skip_list=skip_list)\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=120, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(type='AdamW', lr=0.0002, weight_decay=0.01))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.99, end=60, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ntrain_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, mode='train')\nval_codec = dict(\n    type='MotionBERTLabel', num_keypoints=17, concat_vis=True, rootrel=True)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='DSTFormer',\n        in_channels=3,\n        feat_size=512,\n        depth=5,\n        num_heads=8,\n        mlp_ratio=2,\n        seq_len=243,\n        att_fuse=True,\n    ),\n    head=dict(\n        type='MotionRegressionHead',\n        in_channels=512,\n        out_channels=3,\n        embedding_size=512,\n        loss=dict(type='MPJPEVelocityJointLoss'),\n        decoder=val_codec,\n    ),\n    test_cfg=dict(flip_test=True),\n    init_cfg=dict(\n        type='Pretrained',\n        checkpoint='https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/'\n        'pose_lift/h36m/motionbert_pretrain_h36m-29ffebf5_20230719.pth'),\n)\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='GenerateTarget', encoder=train_codec),\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(center_mode='static', center_x=0.),\n        target_flip_cfg=dict(center_mode='static', center_x=0.),\n        flip_label=True),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=val_codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'factor', 'camera_param'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=1,\n        multiple_target=243,\n        multiple_target_step=81,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\n\nval_dataloader = dict(\n    batch_size=32,\n    prefetch_factor=4,\n    pin_memory=True,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=1,\n        seq_step=1,\n        multiple_target=243,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nskip_list = [\n    'S9_Greet', 'S9_SittingDown', 'S9_Wait_1', 'S9_Greeting', 'S9_Waiting_1'\n]\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe', skip_list=skip_list),\n    dict(type='MPJPE', mode='p-mpjpe', skip_list=skip_list)\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/h36m/motionbert_h36m.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2210.06551\">MotionBERT (2022)</a></summary>\n\n```bibtex\n @misc{Zhu_Ma_Liu_Liu_Wu_Wang_2022,\n title={Learning Human Motion Representations: A Unified Perspective},\n author={Zhu, Wentao and Ma, Xiaoxuan and Liu, Zhaoyang and Liu, Libin and Wu, Wayne and Wang, Yizhou},\n year={2022},\n month={Oct},\n language={en-US}\n }\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\nauthor = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu, Cristian},\ntitle = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\njournal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\npublisher = {IEEE Computer Society},\nvolume = {36},\nnumber = {7},\npages = {1325-1339},\nmonth = {jul},\nyear = {2014}\n}\n```\n\n</details>\n\nResults on Human3.6M dataset with ground truth 2D detections\n\n| Arch                                                                                    | MPJPE | average MPJPE | P-MPJPE |                                           ckpt                                           |\n| :-------------------------------------------------------------------------------------- | :---: | :-----------: | :-----: | :--------------------------------------------------------------------------------------: |\n| [MotionBERT\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m.py) | 34.5  |     34.6      |  27.1   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_h36m-f554954f_20230531.pth) |\n| [MotionBERT-finetuned\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m.py) | 26.9  |     26.8      |  21.0   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth) |\n\nResults on Human3.6M dataset converted from the [official repo](https://github.com/Walter0807/MotionBERT)<sup>1</sup> with ground truth 2D detections\n\n| Arch                                                                                   | MPJPE | average MPJPE | P-MPJPE |                                          ckpt                                          | log |\n| :------------------------------------------------------------------------------------- | :---: | :-----------: | :-----: | :------------------------------------------------------------------------------------: | :-: |\n| [MotionBERT\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m-original.py) | 39.8  |     39.2      |  33.4   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_h36m-f554954f_20230531.pth) |  /  |\n| [MotionBERT-finetuned\\*](/configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m-original.py) | 37.7  |     37.2      |  32.2   | [ckpt](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth) |  /  |\n\n<sup>1</sup> By default, we test models with [Human 3.6m dataset](/docs/en/dataset_zoo/3d_body_keypoint.md#human3-6m) processed by MMPose. The official repo's dataset includes more data and applies a different pre-processing technique. To achieve the same result with the official repo, please download the [test annotation file](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/h36m_test_original.npz), [train annotation file](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/h36m_train_original.npz) and [factors](https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/h36m_factors.npy) under `$MMPOSE/data/h36m/annotation_body3d/fps50` and test with the configs we provided.\n\n*Models with * are converted from the [official repo](https://github.com/Walter0807/MotionBERT). The config files of these models are only for validation. We don't ensure these config files' training accuracy and welcome you to contribute your reproduction results.*\n"
  },
  {
    "path": "configs/body_3d_keypoint/motionbert/h36m/motionbert_h36m.yml",
    "content": "Collections:\n- Name: MotionBERT\n  Paper:\n    Title: \"Learning Human Motion Representations: A Unified Perspective\"\n    URL: https://arxiv.org/abs/2210.06551\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/en/papers/algorithms/motionbert.md\nModels:\n- Config: configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-243frm_8xb32-240e_h36m.py\n  In Collection: MotionBERT\n  Metadata:\n    Architecture: &id001\n    - MotionBERT\n    Training Data: Human3.6M (MotionBERT)\n  Name: motionbert_dstformer-243frm_8xb32-240e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 34.5\n      P-MPJPE: 27.1\n    Task: Body 3D Keypoint\n  - Dataset: Human3.6M (MotionBERT)\n    Metrics:\n      MPJPE: 39.8\n      P-MPJPE: 33.4\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_h36m-f554954f_20230531.pth\n- Config: configs/body_3d_keypoint/motionbert/h36m/motionbert_dstformer-ft-243frm_8xb32-120e_h36m.py\n  In Collection: MotionBERT\n  Alias: human3d\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M (MotionBERT)\n  Name: motionbert_dstformer-ft-243frm_8xb32-120e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 26.9\n      P-MPJPE: 21.0\n    Task: Body 3D Keypoint\n  - Dataset: Human3.6M (MotionBERT)\n    Metrics:\n      MPJPE: 37.7\n      P-MPJPE: 32.2\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/README.md",
    "content": "# 3D human pose estimation in video with temporal convolutions and semi-supervised training\n\nBased on the success of 2d human pose estimation, it directly \"lifts\" a sequence of 2d keypoints to 3d keypoints.\n\n## Results and Models\n\n### Human3.6m Dataset\n\n| Arch                                          | MPJPE | P-MPJPE | N-MPJPE |                     ckpt                      |                     log                      |              Details and Download               |\n| :-------------------------------------------- | :---: | :-----: | :-----: | :-------------------------------------------: | :------------------------------------------: | :---------------------------------------------: |\n| [VideoPose3D-supervised-27frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-supv_8xb128-160e_h36m.py) | 40.1  |  30.1   |    /    | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_supervised-fe8fbba9_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_supervised_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n| [VideoPose3D-supervised-81frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-81frm-supv_8xb128-160e_h36m.py) | 39.1  |  29.3   |    /    | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_81frames_fullconv_supervised-1f2d1104_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_81frames_fullconv_supervised_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n| [VideoPose3D-supervised-243frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv_8xb128-160e_h36m.py) | 37.6  |  28.3   |    /    | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised-880bea25_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n| [VideoPose3D-supervised-CPN-1frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-1frm-supv-cpn-ft_8xb128-160e_h36m.py) | 53.0  |  41.3   |    /    | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_1frame_fullconv_supervised_cpn_ft-5c3afaed_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_1frame_fullconv_supervised_cpn_ft_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n| [VideoPose3D-supervised-CPN-243frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py) | 47.9  |  38.0   |    /    | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n| [VideoPose3D-semi-supervised-27frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv_8xb64-200e_h36m.py) | 57.2  |  42.4   |  54.2   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised-54aef83b_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n| [VideoPose3D-semi-supervised-CPN-27frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv-cpn-ft_8xb64-200e_h36m.py) | 67.3  |  50.4   |  63.6   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_cpn_ft-71be9cde_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_cpn_ft_20210527.log.json) | [videpose3d_h36m.md](./h36m/videpose3d_h36m.md) |\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-1frm-supv-cpn-ft_8xb128-160e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=160, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=1e-4))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.98, end=80, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=4,\n        kernel_sizes=(1, 1, 1, 1, 1),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(),\n        target_flip_cfg=dict(),\n    ),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=1,\n        causal=False,\n        pad_video_seq=False,\n        keypoint_2d_src='detection',\n        keypoint_2d_det_file='joint_2d_det_files/cpn_ft_h36m_dbb_train.npy',\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ),\n)\nval_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=1,\n        causal=False,\n        pad_video_seq=False,\n        keypoint_2d_src='detection',\n        keypoint_2d_det_file='joint_2d_det_files/cpn_ft_h36m_dbb_test.npy',\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=200, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=1e-4))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.98, end=200, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=4,\n        kernel_sizes=(3, 3, 3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(),\n        target_flip_cfg=dict(),\n    ),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=243,\n        causal=False,\n        pad_video_seq=True,\n        keypoint_2d_src='detection',\n        keypoint_2d_det_file='joint_2d_det_files/cpn_ft_h36m_dbb_train.npy',\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ),\n)\nval_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=243,\n        causal=False,\n        pad_video_seq=True,\n        keypoint_2d_src='detection',\n        keypoint_2d_det_file='joint_2d_det_files/cpn_ft_h36m_dbb_test.npy',\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv_8xb128-160e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=160, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=1e-3))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.975, end=80, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=4,\n        kernel_sizes=(3, 3, 3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(),\n        target_flip_cfg=dict(),\n    ),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=243,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ),\n)\nval_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=243,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv-cpn-ft_8xb64-200e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = None\n\n# optimizer\n\n# learning policy\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=2,\n        kernel_sizes=(3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ),\n    traj_backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=2,\n        kernel_sizes=(3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    traj_head=dict(\n        type='TrajectoryRegressionHead',\n        in_channels=1024,\n        num_joints=1,\n        loss=dict(type='MPJPELoss', use_target_weight=True),\n        decoder=codec,\n    ),\n    semi_loss=dict(\n        type='SemiSupervisionLoss',\n        joint_parents=[0, 0, 1, 2, 0, 4, 5, 0, 7, 8, 9, 8, 11, 12, 8, 14, 15],\n        warmup_iterations=1311376 // 64 // 8 * 5),\n)\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=27,\n        causal=False,\n        pad_video_seq=True,\n        keypoint_2d_src='detection',\n        keypoint_2d_det_file='joint_2d_det_files/cpn_ft_h36m_dbb_test.npy',\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe'),\n    dict(type='MPJPE', mode='n-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv_8xb64-200e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = None\n\n# optimizer\n\n# learning policy\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=2,\n        kernel_sizes=(3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ),\n    traj_backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=2,\n        kernel_sizes=(3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    traj_head=dict(\n        type='TrajectoryRegressionHead',\n        in_channels=1024,\n        num_joints=1,\n        loss=dict(type='MPJPELoss', use_target_weight=True),\n        decoder=codec,\n    ),\n    semi_loss=dict(\n        type='SemiSupervisionLoss',\n        joint_parents=[0, 0, 1, 2, 0, 4, 5, 0, 7, 8, 9, 8, 11, 12, 8, 14, 15],\n        warmup_iterations=1311376 // 64 // 8 * 5),\n)\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=27,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe'),\n    dict(type='MPJPE', mode='n-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-supv_8xb128-160e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=160, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=1e-3))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.975, end=80, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=2,\n        kernel_sizes=(3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(),\n        target_flip_cfg=dict(),\n    ),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=27,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ),\n)\nval_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=27,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-81frm-supv_8xb128-160e_h36m.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=160, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=1e-3))\n\n# learning policy\nparam_scheduler = [\n    dict(type='ExponentialLR', gamma=0.975, end=80, by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='VideoPoseLifting',\n    num_keypoints=17,\n    zero_center=True,\n    root_index=0,\n    remove_root=False)\n\n# model settings\nmodel = dict(\n    type='PoseLifter',\n    backbone=dict(\n        type='TCN',\n        in_channels=2 * 17,\n        stem_channels=1024,\n        num_blocks=3,\n        kernel_sizes=(3, 3, 3, 3),\n        dropout=0.25,\n        use_stride_conv=True,\n    ),\n    head=dict(\n        type='TemporalRegressionHead',\n        in_channels=1024,\n        num_joints=17,\n        loss=dict(type='MPJPELoss'),\n        decoder=codec,\n    ))\n\n# base dataset settings\ndataset_type = 'Human36mDataset'\ndata_root = 'data/h36m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(\n        type='RandomFlipAroundRoot',\n        keypoints_flip_cfg=dict(),\n        target_flip_cfg=dict(),\n    ),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\nval_pipeline = [\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'category_id', 'target_img_path', 'flip_indices',\n                   'target_root'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_train.npz',\n        seq_len=81,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ),\n)\nval_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotation_body3d/fps50/h36m_test.npz',\n        seq_len=81,\n        causal=False,\n        pad_video_seq=True,\n        camera_param_file='annotation_body3d/cameras.pkl',\n        data_root=data_root,\n        data_prefix=dict(img='images/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='MPJPE', mode='mpjpe'),\n    dict(type='MPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/videopose3d_h36m.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Pavllo_3D_Human_Pose_Estimation_in_Video_With_Temporal_Convolutions_and_CVPR_2019_paper.html\">VideoPose3D (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{pavllo20193d,\ntitle={3d human pose estimation in video with temporal convolutions and semi-supervised training},\nauthor={Pavllo, Dario and Feichtenhofer, Christoph and Grangier, David and Auli, Michael},\nbooktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\npages={7753--7762},\nyear={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\nauthor = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu, Cristian},\ntitle = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\njournal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\npublisher = {IEEE Computer Society},\nvolume = {36},\nnumber = {7},\npages = {1325-1339},\nmonth = {jul},\nyear = {2014}\n}\n```\n\n</details>\n\nTesting results on Human3.6M dataset with ground truth 2D detections, supervised training\n\n| Arch                                                       | Receptive Field | MPJPE | P-MPJPE |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :-------------: | :---: | :-----: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [VideoPose3D-supervised-27frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-supv_8xb128-160e_h36m.py) |       27        | 40.1  |  30.1   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_supervised-fe8fbba9_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_supervised_20210527.log.json) |\n| [VideoPose3D-supervised-81frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-81frm-supv_8xb128-160e_h36m.py) |       81        | 39.1  |  29.3   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_81frames_fullconv_supervised-1f2d1104_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_81frames_fullconv_supervised_20210527.log.json) |\n| [VideoPose3D-supervised-243frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv_8xb128-160e_h36m.py) |       243       | 37.6  |  28.3   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised-880bea25_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_20210527.log.json) |\n\nTesting results on Human3.6M dataset with CPN 2D detections<sup>1</sup>, supervised training\n\n| Arch                                                       | Receptive Field | MPJPE | P-MPJPE |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :-------------: | :---: | :-----: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [VideoPose3D-supervised-CPN-1frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-1frm-supv-cpn-ft_8xb128-160e_h36m.py) |        1        | 53.0  |  41.3   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_1frame_fullconv_supervised_cpn_ft-5c3afaed_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_1frame_fullconv_supervised_cpn_ft_20210527.log.json) |\n| [VideoPose3D-supervised-CPN-243frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py) |       243       | 47.9  |  38.0   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft_20210527.log.json) |\n\nTesting results on Human3.6M dataset with ground truth 2D detections, semi-supervised training\n\n| Training Data |                        Arch                         | Receptive Field | MPJPE | P-MPJPE | N-MPJPE |                        ckpt                         |                         log                         |\n| :------------ | :-------------------------------------------------: | :-------------: | :---: | :-----: | :-----: | :-------------------------------------------------: | :-------------------------------------------------: |\n| 10% S1        | [VideoPose3D-semi-supervised-27frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv_8xb64-200e_h36m.py) |       27        | 57.2  |  42.4   |  54.2   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised-54aef83b_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_20210527.log.json) |\n\nTesting results on Human3.6M dataset with CPN 2D detections<sup>1</sup>, semi-supervised training\n\n| Training Data |                        Arch                         | Receptive Field | MPJPE | P-MPJPE | N-MPJPE |                        ckpt                         |                         log                         |\n| :------------ | :-------------------------------------------------: | :-------------: | :---: | :-----: | :-----: | :-------------------------------------------------: | :-------------------------------------------------: |\n| 10% S1        | [VideoPose3D-semi-supervised-CPN-27frm](/configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv-cpn-ft_8xb64-200e_h36m.py) |       27        | 67.3  |  50.4   |  63.6   | [ckpt](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_cpn_ft-71be9cde_20210527.pth) | [log](https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_cpn_ft_20210527.log.json) |\n\n<sup>1</sup> CPN 2D detections are provided by [official repo](https://github.com/facebookresearch/VideoPose3D/blob/master/DATASETS.md). The reformatted version used in this repository can be downloaded from [train_detection](https://download.openmmlab.com/mmpose/body3d/videopose/cpn_ft_h36m_dbb_train.npy) and [test_detection](https://download.openmmlab.com/mmpose/body3d/videopose/cpn_ft_h36m_dbb_test.npy).\n"
  },
  {
    "path": "configs/body_3d_keypoint/video_pose_lift/h36m/videopose3d_h36m.yml",
    "content": "Collections:\n- Name: VideoPose3D\n  Paper:\n    Title: 3d human pose estimation in video with temporal convolutions and semi-supervised\n      training\n    URL: http://openaccess.thecvf.com/content_CVPR_2019/html/Pavllo_3D_Human_Pose_Estimation_in_Video_With_Temporal_Convolutions_and_CVPR_2019_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/en/papers/algorithms/videopose3d.md\nModels:\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-supv_8xb128-160e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: &id001\n    - VideoPose3D\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-27frm-supv_8xb128-160e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 40.0\n      P-MPJPE: 30.1\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_supervised-fe8fbba9_20210527.pth\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-81frm-supv_8xb128-160e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-81frm-supv_8xb128-160e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 38.9\n      P-MPJPE: 29.2\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_81frames_fullconv_supervised-1f2d1104_20210527.pth\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv_8xb128-160e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-243frm-supv_8xb128-160e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 37.6\n      P-MPJPE: 28.3\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised-880bea25_20210527.pth\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-1frm-supv-cpn-ft_8xb128-160e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-1frm-supv-cpn-ft_8xb128-160e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 52.9\n      P-MPJPE: 41.3\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_1frame_fullconv_supervised_cpn_ft-5c3afaed_20210527.pth\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 47.9\n      P-MPJPE: 38.0\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv_8xb64-200e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-27frm-semi-supv_8xb64-200e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 58.1\n      N-MPJPE: 54.7\n      P-MPJPE: 42.8\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised-54aef83b_20210527.pth\n- Config: configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-27frm-semi-supv-cpn-ft_8xb64-200e_h36m.py\n  In Collection: VideoPose3D\n  Metadata:\n    Architecture: *id001\n    Training Data: Human3.6M\n  Name: video-pose-lift_tcn-27frm-semi-supv-cpn-ft_8xb64-200e_h36m\n  Results:\n  - Dataset: Human3.6M\n    Metrics:\n      MPJPE: 67.4\n      N-MPJPE: 63.2\n      P-MPJPE: 50.1\n    Task: Body 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_27frames_fullconv_semi-supervised_cpn_ft-71be9cde_20210527.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/README.md",
    "content": "# 2D Face Landmark Detection\n\n2D face landmark detection (also referred to as face alignment) is defined as the task of detecting the face keypoints from an input image.\n\nNormally, the input images are cropped face images, where the face locates at the center;\nor the rough location (or the bounding box) of the hand is provided.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_face_keypoint.md) to prepare data.\n\n## Demo\n\nPlease follow [Demo](/demo/docs/en/2d_face_demo.md) to run demos.\n\n<img src=\"https://user-images.githubusercontent.com/11788150/109144943-ccd44900-779c-11eb-9e9d-8682e7629654.gif\" width=\"600px\" alt><br>\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/README.md",
    "content": "# RTMPose\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency.\nIn order to bridge this gap, we empirically study five aspects that affect the performance of multi-person pose estimation algorithms: paradigm, backbone network, localization algorithm, training strategy, and deployment inference, and present a high-performance real-time multi-person pose estimation framework, **RTMPose**, based on MMPose.\nOur RTMPose-m achieves **75.8% AP** on COCO with **90+ FPS** on an Intel i7-11700 CPU and **430+ FPS** on an NVIDIA GTX 1660 Ti GPU, and RTMPose-l achieves **67.0% AP** on COCO-WholeBody with **130+ FPS**, outperforming existing open-source libraries.\nTo further evaluate RTMPose's capability in critical real-time applications, we also report the performance after deploying on the mobile device.\n\n## Results and Models\n\n### COCO-WholeBody-Face Dataset\n\nResults on COCO-WholeBody-Face val set\n\n|   Model   | Input Size |  NME   |                                  Details and Download                                  |\n| :-------: | :--------: | :----: | :------------------------------------------------------------------------------------: |\n| RTMPose-m |  256x256   | 0.0466 | [rtmpose_coco_wholebody_face.md](./coco_wholebody_face/rtmpose_coco_wholebody_face.md) |\n\n### WFLW  Dataset\n\nResults on WFLW  dataset\n\n|   Model   | Input Size | NME  |           Details and Download            |\n| :-------: | :--------: | :--: | :---------------------------------------: |\n| RTMPose-m |  256x256   | 4.01 | [rtmpose_wflw.md](./wflw/rtmpose_wflw.md) |\n\n### LaPa Dataset\n\nResults on LaPa dataset\n\n|   Model   | Input Size | NME  |           Details and Download            |\n| :-------: | :--------: | :--: | :---------------------------------------: |\n| RTMPose-m |  256x256   | 1.29 | [rtmpose_lapa.md](./lapa/rtmpose_lapa.md) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/coco_wholebody_face/rtmpose-m_8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 60\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=68,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=1, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/coco_wholebody_face/rtmpose_coco_wholebody_face.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_rtmpose_m](/configs/face_2d_keypoint/rtmpose/coco_wholebody_face/rtmpose-m_8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0466 | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody-face_pt-aic-coco_60e-256x256-62026ef2_20230228.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody-face_pt-aic-coco_60e-256x256-62026ef2_20230228.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/coco_wholebody_face/rtmpose_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/rtmpose/coco_wholebody_face/rtmpose-m_8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: COCO-WholeBody-Face\n  Name: rtmpose-m_8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0466\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody-face_pt-aic-coco_60e-256x256-62026ef2_20230228.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# lapa coco wflw 300w cofw halpe\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.005,\n        begin=30,\n        end=max_epochs,\n        T_max=max_epochs - 30,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=106,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# train dataset\ndataset_lapa = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[],\n)\n\nkpt_68_to_106 = [\n    #\n    (0, 0),\n    (1, 2),\n    (2, 4),\n    (3, 6),\n    (4, 8),\n    (5, 10),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 18),\n    (10, 20),\n    (11, 22),\n    (12, 24),\n    (13, 26),\n    (14, 28),\n    (15, 30),\n    (16, 32),\n    #\n    (17, 33),\n    (18, 34),\n    (19, 35),\n    (20, 36),\n    (21, 37),\n    #\n    (22, 42),\n    (23, 43),\n    (24, 44),\n    (25, 45),\n    (26, 46),\n    #\n    (27, 51),\n    (28, 52),\n    (29, 53),\n    (30, 54),\n    #\n    (31, 58),\n    (32, 59),\n    (33, 60),\n    (34, 61),\n    (35, 62),\n    #\n    (36, 66),\n    (39, 70),\n    #\n    ((37, 38), 68),\n    ((40, 41), 72),\n    #\n    (42, 75),\n    (45, 79),\n    #\n    ((43, 44), 77),\n    ((46, 47), 81),\n    #\n    (48, 84),\n    (49, 85),\n    (50, 86),\n    (51, 87),\n    (52, 88),\n    (53, 89),\n    (54, 90),\n    (55, 91),\n    (56, 92),\n    (57, 93),\n    (58, 94),\n    (59, 95),\n    (60, 96),\n    (61, 97),\n    (62, 98),\n    (63, 99),\n    (64, 100),\n    (65, 101),\n    (66, 102),\n    (67, 103)\n]\n\nmapping_halpe = [\n    #\n    (26, 0),\n    (27, 2),\n    (28, 4),\n    (29, 6),\n    (30, 8),\n    (31, 10),\n    (32, 12),\n    (33, 14),\n    (34, 16),\n    (35, 18),\n    (36, 20),\n    (37, 22),\n    (38, 24),\n    (39, 26),\n    (40, 28),\n    (41, 30),\n    (42, 32),\n    #\n    (43, 33),\n    (44, 34),\n    (45, 35),\n    (46, 36),\n    (47, 37),\n    #\n    (48, 42),\n    (49, 43),\n    (50, 44),\n    (51, 45),\n    (52, 46),\n    #\n    (53, 51),\n    (54, 52),\n    (55, 53),\n    (56, 54),\n    #\n    (57, 58),\n    (58, 59),\n    (59, 60),\n    (60, 61),\n    (61, 62),\n    #\n    (62, 66),\n    (65, 70),\n    #\n    ((63, 64), 68),\n    ((66, 67), 72),\n    #\n    (68, 75),\n    (71, 79),\n    #\n    ((69, 70), 77),\n    ((72, 73), 81),\n    #\n    (74, 84),\n    (75, 85),\n    (76, 86),\n    (77, 87),\n    (78, 88),\n    (79, 89),\n    (80, 90),\n    (81, 91),\n    (82, 92),\n    (83, 93),\n    (84, 94),\n    (85, 95),\n    (86, 96),\n    (87, 97),\n    (88, 98),\n    (89, 99),\n    (90, 100),\n    (91, 101),\n    (92, 102),\n    (93, 103)\n]\n\nmapping_wflw = [\n    #\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n    (17, 17),\n    (18, 18),\n    (19, 19),\n    (20, 20),\n    (21, 21),\n    (22, 22),\n    (23, 23),\n    (24, 24),\n    (25, 25),\n    (26, 26),\n    (27, 27),\n    (28, 28),\n    (29, 29),\n    (30, 30),\n    (31, 31),\n    (32, 32),\n    #\n    (33, 33),\n    (34, 34),\n    (35, 35),\n    (36, 36),\n    (37, 37),\n    (38, 38),\n    (39, 39),\n    (40, 40),\n    (41, 41),\n    #\n    (42, 42),\n    (43, 43),\n    (44, 44),\n    (45, 45),\n    (46, 46),\n    (47, 47),\n    (48, 48),\n    (49, 49),\n    (50, 50),\n    #\n    (51, 51),\n    (52, 52),\n    (53, 53),\n    (54, 54),\n    #\n    (55, 58),\n    (56, 59),\n    (57, 60),\n    (58, 61),\n    (59, 62),\n    #\n    (60, 66),\n    (61, 67),\n    (62, 68),\n    (63, 69),\n    (64, 70),\n    (65, 71),\n    (66, 72),\n    (67, 73),\n    #\n    (68, 75),\n    (69, 76),\n    (70, 77),\n    (71, 78),\n    (72, 79),\n    (73, 80),\n    (74, 81),\n    (75, 82),\n    #\n    (76, 84),\n    (77, 85),\n    (78, 86),\n    (79, 87),\n    (80, 88),\n    (81, 89),\n    (82, 90),\n    (83, 91),\n    (84, 92),\n    (85, 93),\n    (86, 94),\n    (87, 95),\n    (88, 96),\n    (89, 97),\n    (90, 98),\n    (91, 99),\n    (92, 100),\n    (93, 101),\n    (94, 102),\n    (95, 103),\n    #\n    (96, 104),\n    #\n    (97, 105)\n]\n\nmapping_cofw = [\n    #\n    (0, 33),\n    (2, 38),\n    (4, 35),\n    (5, 40),\n    #\n    (1, 46),\n    (3, 50),\n    (6, 44),\n    (7, 48),\n    #\n    (8, 60),\n    (10, 64),\n    (12, 62),\n    (13, 66),\n    #\n    (9, 72),\n    (11, 68),\n    (14, 70),\n    (15, 74),\n    #\n    (18, 57),\n    (19, 63),\n    (20, 54),\n    (21, 60),\n    #\n    (22, 84),\n    (23, 90),\n    (24, 87),\n    (25, 98),\n    (26, 102),\n    (27, 93),\n    #\n    (28, 16)\n]\ndataset_coco = dict(\n    type='CocoWholeBodyFaceDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_wflw)\n    ],\n)\n\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_cofw)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_133kpt.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_halpe)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/lapa.py'),\n        datasets=[\n            dataset_lapa, dataset_coco, dataset_wflw, dataset_300w,\n            dataset_cofw, dataset_halpe\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='LaPa/annotations/lapa_test.json',\n        data_prefix=dict(img='pose/LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# test dataset\nval_lapa = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_test.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[],\n)\n\nval_coco = dict(\n    type='CocoWholeBodyFaceDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\nval_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_test.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_wflw)\n    ],\n)\n\nval_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_test.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\nval_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_test.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_cofw)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_halpe)\n    ],\n)\n\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/lapa.py'),\n        datasets=[val_lapa, val_coco, val_wflw, val_300w, val_cofw, val_halpe],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=1, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/face6/rtmpose-s_8xb256-120e_face6-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# lapa coco wflw 300w cofw halpe\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.005,\n        begin=30,\n        end=max_epochs,\n        T_max=max_epochs - 30,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/cspnext-s_imagenet_600e-ea671761.pth')\n    ),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=106,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n# train dataset\ndataset_lapa = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[],\n)\n\nkpt_68_to_106 = [\n    #\n    (0, 0),\n    (1, 2),\n    (2, 4),\n    (3, 6),\n    (4, 8),\n    (5, 10),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 18),\n    (10, 20),\n    (11, 22),\n    (12, 24),\n    (13, 26),\n    (14, 28),\n    (15, 30),\n    (16, 32),\n    #\n    (17, 33),\n    (18, 34),\n    (19, 35),\n    (20, 36),\n    (21, 37),\n    #\n    (22, 42),\n    (23, 43),\n    (24, 44),\n    (25, 45),\n    (26, 46),\n    #\n    (27, 51),\n    (28, 52),\n    (29, 53),\n    (30, 54),\n    #\n    (31, 58),\n    (32, 59),\n    (33, 60),\n    (34, 61),\n    (35, 62),\n    #\n    (36, 66),\n    (39, 70),\n    #\n    ((37, 38), 68),\n    ((40, 41), 72),\n    #\n    (42, 75),\n    (45, 79),\n    #\n    ((43, 44), 77),\n    ((46, 47), 81),\n    #\n    (48, 84),\n    (49, 85),\n    (50, 86),\n    (51, 87),\n    (52, 88),\n    (53, 89),\n    (54, 90),\n    (55, 91),\n    (56, 92),\n    (57, 93),\n    (58, 94),\n    (59, 95),\n    (60, 96),\n    (61, 97),\n    (62, 98),\n    (63, 99),\n    (64, 100),\n    (65, 101),\n    (66, 102),\n    (67, 103)\n]\n\nmapping_halpe = [\n    #\n    (26, 0),\n    (27, 2),\n    (28, 4),\n    (29, 6),\n    (30, 8),\n    (31, 10),\n    (32, 12),\n    (33, 14),\n    (34, 16),\n    (35, 18),\n    (36, 20),\n    (37, 22),\n    (38, 24),\n    (39, 26),\n    (40, 28),\n    (41, 30),\n    (42, 32),\n    #\n    (43, 33),\n    (44, 34),\n    (45, 35),\n    (46, 36),\n    (47, 37),\n    #\n    (48, 42),\n    (49, 43),\n    (50, 44),\n    (51, 45),\n    (52, 46),\n    #\n    (53, 51),\n    (54, 52),\n    (55, 53),\n    (56, 54),\n    #\n    (57, 58),\n    (58, 59),\n    (59, 60),\n    (60, 61),\n    (61, 62),\n    #\n    (62, 66),\n    (65, 70),\n    #\n    ((63, 64), 68),\n    ((66, 67), 72),\n    #\n    (68, 75),\n    (71, 79),\n    #\n    ((69, 70), 77),\n    ((72, 73), 81),\n    #\n    (74, 84),\n    (75, 85),\n    (76, 86),\n    (77, 87),\n    (78, 88),\n    (79, 89),\n    (80, 90),\n    (81, 91),\n    (82, 92),\n    (83, 93),\n    (84, 94),\n    (85, 95),\n    (86, 96),\n    (87, 97),\n    (88, 98),\n    (89, 99),\n    (90, 100),\n    (91, 101),\n    (92, 102),\n    (93, 103)\n]\n\nmapping_wflw = [\n    #\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n    (17, 17),\n    (18, 18),\n    (19, 19),\n    (20, 20),\n    (21, 21),\n    (22, 22),\n    (23, 23),\n    (24, 24),\n    (25, 25),\n    (26, 26),\n    (27, 27),\n    (28, 28),\n    (29, 29),\n    (30, 30),\n    (31, 31),\n    (32, 32),\n    #\n    (33, 33),\n    (34, 34),\n    (35, 35),\n    (36, 36),\n    (37, 37),\n    (38, 38),\n    (39, 39),\n    (40, 40),\n    (41, 41),\n    #\n    (42, 42),\n    (43, 43),\n    (44, 44),\n    (45, 45),\n    (46, 46),\n    (47, 47),\n    (48, 48),\n    (49, 49),\n    (50, 50),\n    #\n    (51, 51),\n    (52, 52),\n    (53, 53),\n    (54, 54),\n    #\n    (55, 58),\n    (56, 59),\n    (57, 60),\n    (58, 61),\n    (59, 62),\n    #\n    (60, 66),\n    (61, 67),\n    (62, 68),\n    (63, 69),\n    (64, 70),\n    (65, 71),\n    (66, 72),\n    (67, 73),\n    #\n    (68, 75),\n    (69, 76),\n    (70, 77),\n    (71, 78),\n    (72, 79),\n    (73, 80),\n    (74, 81),\n    (75, 82),\n    #\n    (76, 84),\n    (77, 85),\n    (78, 86),\n    (79, 87),\n    (80, 88),\n    (81, 89),\n    (82, 90),\n    (83, 91),\n    (84, 92),\n    (85, 93),\n    (86, 94),\n    (87, 95),\n    (88, 96),\n    (89, 97),\n    (90, 98),\n    (91, 99),\n    (92, 100),\n    (93, 101),\n    (94, 102),\n    (95, 103),\n    #\n    (96, 104),\n    #\n    (97, 105)\n]\n\nmapping_cofw = [\n    #\n    (0, 33),\n    (2, 38),\n    (4, 35),\n    (5, 40),\n    #\n    (1, 46),\n    (3, 50),\n    (6, 44),\n    (7, 48),\n    #\n    (8, 60),\n    (10, 64),\n    (12, 62),\n    (13, 66),\n    #\n    (9, 72),\n    (11, 68),\n    (14, 70),\n    (15, 74),\n    #\n    (18, 57),\n    (19, 63),\n    (20, 54),\n    (21, 60),\n    #\n    (22, 84),\n    (23, 90),\n    (24, 87),\n    (25, 98),\n    (26, 102),\n    (27, 93),\n    #\n    (28, 16)\n]\ndataset_coco = dict(\n    type='CocoWholeBodyFaceDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_wflw)\n    ],\n)\n\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_cofw)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_133kpt.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_halpe)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/lapa.py'),\n        datasets=[\n            dataset_lapa, dataset_coco, dataset_wflw, dataset_300w,\n            dataset_cofw, dataset_halpe\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='LaPa/annotations/lapa_test.json',\n        data_prefix=dict(img='pose/LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# test dataset\nval_lapa = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_test.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[],\n)\n\nval_coco = dict(\n    type='CocoWholeBodyFaceDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\nval_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_test.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_wflw)\n    ],\n)\n\nval_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_test.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\nval_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_test.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_cofw)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_halpe)\n    ],\n)\n\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/lapa.py'),\n        datasets=[val_lapa, val_coco, val_wflw, val_300w, val_cofw, val_halpe],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=1, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/face6/rtmpose-t_8xb256-120e_face6-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# lapa coco wflw 300w cofw halpe\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.005,\n        begin=30,\n        end=max_epochs,\n        T_max=90,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/cspnext-tiny_imagenet_600e-3a2dd350.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=106,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n# train dataset\ndataset_lapa = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[],\n)\n\nkpt_68_to_106 = [\n    #\n    (0, 0),\n    (1, 2),\n    (2, 4),\n    (3, 6),\n    (4, 8),\n    (5, 10),\n    (6, 12),\n    (7, 14),\n    (8, 16),\n    (9, 18),\n    (10, 20),\n    (11, 22),\n    (12, 24),\n    (13, 26),\n    (14, 28),\n    (15, 30),\n    (16, 32),\n    #\n    (17, 33),\n    (18, 34),\n    (19, 35),\n    (20, 36),\n    (21, 37),\n    #\n    (22, 42),\n    (23, 43),\n    (24, 44),\n    (25, 45),\n    (26, 46),\n    #\n    (27, 51),\n    (28, 52),\n    (29, 53),\n    (30, 54),\n    #\n    (31, 58),\n    (32, 59),\n    (33, 60),\n    (34, 61),\n    (35, 62),\n    #\n    (36, 66),\n    (39, 70),\n    #\n    ((37, 38), 68),\n    ((40, 41), 72),\n    #\n    (42, 75),\n    (45, 79),\n    #\n    ((43, 44), 77),\n    ((46, 47), 81),\n    #\n    (48, 84),\n    (49, 85),\n    (50, 86),\n    (51, 87),\n    (52, 88),\n    (53, 89),\n    (54, 90),\n    (55, 91),\n    (56, 92),\n    (57, 93),\n    (58, 94),\n    (59, 95),\n    (60, 96),\n    (61, 97),\n    (62, 98),\n    (63, 99),\n    (64, 100),\n    (65, 101),\n    (66, 102),\n    (67, 103)\n]\n\nmapping_halpe = [\n    #\n    (26, 0),\n    (27, 2),\n    (28, 4),\n    (29, 6),\n    (30, 8),\n    (31, 10),\n    (32, 12),\n    (33, 14),\n    (34, 16),\n    (35, 18),\n    (36, 20),\n    (37, 22),\n    (38, 24),\n    (39, 26),\n    (40, 28),\n    (41, 30),\n    (42, 32),\n    #\n    (43, 33),\n    (44, 34),\n    (45, 35),\n    (46, 36),\n    (47, 37),\n    #\n    (48, 42),\n    (49, 43),\n    (50, 44),\n    (51, 45),\n    (52, 46),\n    #\n    (53, 51),\n    (54, 52),\n    (55, 53),\n    (56, 54),\n    #\n    (57, 58),\n    (58, 59),\n    (59, 60),\n    (60, 61),\n    (61, 62),\n    #\n    (62, 66),\n    (65, 70),\n    #\n    ((63, 64), 68),\n    ((66, 67), 72),\n    #\n    (68, 75),\n    (71, 79),\n    #\n    ((69, 70), 77),\n    ((72, 73), 81),\n    #\n    (74, 84),\n    (75, 85),\n    (76, 86),\n    (77, 87),\n    (78, 88),\n    (79, 89),\n    (80, 90),\n    (81, 91),\n    (82, 92),\n    (83, 93),\n    (84, 94),\n    (85, 95),\n    (86, 96),\n    (87, 97),\n    (88, 98),\n    (89, 99),\n    (90, 100),\n    (91, 101),\n    (92, 102),\n    (93, 103)\n]\n\nmapping_wflw = [\n    #\n    (0, 0),\n    (1, 1),\n    (2, 2),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n    (17, 17),\n    (18, 18),\n    (19, 19),\n    (20, 20),\n    (21, 21),\n    (22, 22),\n    (23, 23),\n    (24, 24),\n    (25, 25),\n    (26, 26),\n    (27, 27),\n    (28, 28),\n    (29, 29),\n    (30, 30),\n    (31, 31),\n    (32, 32),\n    #\n    (33, 33),\n    (34, 34),\n    (35, 35),\n    (36, 36),\n    (37, 37),\n    (38, 38),\n    (39, 39),\n    (40, 40),\n    (41, 41),\n    #\n    (42, 42),\n    (43, 43),\n    (44, 44),\n    (45, 45),\n    (46, 46),\n    (47, 47),\n    (48, 48),\n    (49, 49),\n    (50, 50),\n    #\n    (51, 51),\n    (52, 52),\n    (53, 53),\n    (54, 54),\n    #\n    (55, 58),\n    (56, 59),\n    (57, 60),\n    (58, 61),\n    (59, 62),\n    #\n    (60, 66),\n    (61, 67),\n    (62, 68),\n    (63, 69),\n    (64, 70),\n    (65, 71),\n    (66, 72),\n    (67, 73),\n    #\n    (68, 75),\n    (69, 76),\n    (70, 77),\n    (71, 78),\n    (72, 79),\n    (73, 80),\n    (74, 81),\n    (75, 82),\n    #\n    (76, 84),\n    (77, 85),\n    (78, 86),\n    (79, 87),\n    (80, 88),\n    (81, 89),\n    (82, 90),\n    (83, 91),\n    (84, 92),\n    (85, 93),\n    (86, 94),\n    (87, 95),\n    (88, 96),\n    (89, 97),\n    (90, 98),\n    (91, 99),\n    (92, 100),\n    (93, 101),\n    (94, 102),\n    (95, 103),\n    #\n    (96, 104),\n    #\n    (97, 105)\n]\n\nmapping_cofw = [\n    #\n    (0, 33),\n    (2, 38),\n    (4, 35),\n    (5, 40),\n    #\n    (1, 46),\n    (3, 50),\n    (6, 44),\n    (7, 48),\n    #\n    (8, 60),\n    (10, 64),\n    (12, 62),\n    (13, 66),\n    #\n    (9, 72),\n    (11, 68),\n    (14, 70),\n    (15, 74),\n    #\n    (18, 57),\n    (19, 63),\n    (20, 54),\n    (21, 60),\n    #\n    (22, 84),\n    (23, 90),\n    (24, 87),\n    (25, 98),\n    (26, 102),\n    (27, 93),\n    #\n    (28, 16)\n]\ndataset_coco = dict(\n    type='CocoWholeBodyFaceDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_wflw)\n    ],\n)\n\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_cofw)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_133kpt.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_halpe)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/lapa.py'),\n        datasets=[\n            dataset_lapa, dataset_coco, dataset_wflw, dataset_300w,\n            dataset_cofw, dataset_halpe\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='LaPa/annotations/lapa_test.json',\n        data_prefix=dict(img='pose/LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# test dataset\nval_lapa = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_test.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[],\n)\n\nval_coco = dict(\n    type='CocoWholeBodyFaceDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\nval_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_test.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_wflw)\n    ],\n)\n\nval_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_test.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=kpt_68_to_106)\n    ],\n)\n\nval_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_test.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_cofw)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter', num_keypoints=106, mapping=mapping_halpe)\n    ],\n)\n\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/lapa.py'),\n        datasets=[val_lapa, val_coco, val_wflw, val_300w, val_cofw, val_halpe],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=1, interval=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/face6/rtmpose_face6.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n- Results on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset.\n- `Face6` and `*` denote model trained on 6 public datasets:\n  - [COCO-Wholebody-Face](https://github.com/jin-s13/COCO-WholeBody/)\n  - [WFLW](https://wywu.github.io/projects/LAB/WFLW.html)\n  - [300W](https://ibug.doc.ic.ac.uk/resources/300-W/)\n  - [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/)\n  - [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/)\n  - [LaPa](https://github.com/JDAI-CV/lapa-dataset)\n\n|                                    Config                                    | Input Size | NME<sup><br>(LaPa) | FLOPS<sup><br>(G) |                                    Download                                     |\n| :--------------------------------------------------------------------------: | :--------: | :----------------: | :---------------: | :-----------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/face_2d_keypoint/rtmpose-t_8xb256-120e_face6-256x256.py) |  256x256   |        1.67        |       0.652       | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-face6_pt-in1k_120e-256x256-df79d9a5_20230529.pth) |\n| [RTMPose-s\\*](./rtmpose/face_2d_keypoint/rtmpose-s_8xb256-120e_face6-256x256.py) |  256x256   |        1.59        |       1.119       | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-face6_pt-in1k_120e-256x256-d779fdef_20230529.pth) |\n| [RTMPose-m\\*](./rtmpose/face_2d_keypoint/rtmpose-m_8xb256-120e_face6-256x256.py) |  256x256   |        1.44        |       2.852       | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/face6/rtmpose_face6.yml",
    "content": "Collections:\n- Name: RTMPose\n  Paper:\n    Title: \"RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\"\n    URL: https://arxiv.org/abs/2303.07399\n  README: https://github.com/open-mmlab/mmpose/blob/main/projects/rtmpose/README.md\nModels:\n- Config: configs/face_2d_keypoint/rtmpose/face6/rtmpose-t_8xb256-120e_face6-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: &id002\n    - COCO-Wholebody-Face\n    - WFLW\n    - 300W\n    - COFW\n    - Halpe\n    - LaPa\n  Name: rtmpose-t_8xb256-120e_face6-256x256\n  Results:\n  - Dataset: Face6\n    Metrics:\n      NME: 1.67\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-face6_pt-in1k_120e-256x256-df79d9a5_20230529.pth\n- Config: configs/face_2d_keypoint/rtmpose/face6/rtmpose-s_8xb256-120e_face6-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-s_8xb256-120e_face6-256x256\n  Results:\n  - Dataset: Face6\n    Metrics:\n      NME: 1.59\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-face6_pt-in1k_120e-256x256-d779fdef_20230529.pth\n- Config: configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: *id002\n  Name: rtmpose-m_8xb256-120e_face6-256x256\n  Alias: face\n  Results:\n  - Dataset: Face6\n    Metrics:\n      NME: 1.44\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/lapa/rtmpose-m_8xb64-120e_lapa-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=106,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/LaPa/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/pose/LaPa/',\n#         f'{data_root}': 's3://openmmlab/datasets/pose/LaPa/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=1, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/lapa/rtmpose_lapa.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://aaai.org/ojs/index.php/AAAI/article/view/6832/6686\">LaPa (AAAI'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020new,\n  title={A New Dataset and Boundary-Attention Semantic Segmentation for Face Parsing.},\n  author={Liu, Yinglu and Shi, Hailin and Shen, Hao and Si, Yue and Wang, Xiaobo and Mei, Tao},\n  booktitle={AAAI},\n  pages={11637--11644},\n  year={2020}\n}\n```\n\n</details>\n\nResults on LaPa val set\n\n| Arch                                                           | Input Size | NME  |                              ckpt                              |                              log                               |\n| :------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :------------------------------------------------------------: |\n| [pose_rtmpose_m](/configs/face_2d_keypoint/rtmpose/lapa/rtmpose-m_8xb64-120e_lapa-256x256.py) |  256x256   | 1.29 | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-lapa_pt-aic-coco_120e-256x256-762b1ae2_20230422.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-lapa_pt-aic-coco_120e-256x256-762b1ae2_20230422.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/lapa/rtmpose_lapa.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/rtmpose/lapa/rtmpose-m_8xb64-120e_lapa-256x256.py\n  In Collection: RTMPose\n  Alias: face\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: LaPa\n  Name: rtmpose-m_8xb64-120e_lapa-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME: 1.29\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-lapa_pt-aic-coco_120e-256x256-762b1ae2_20230422.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/wflw/rtmpose-m_8xb64-60e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 60\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=98,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/pose/WFLW/',\n#         f'{data_root}': 's3://openmmlab/datasets/pose/WFLW/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=1, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/wflw/rtmpose_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train.\n\n| Arch                                                           | Input Size | NME  |                              ckpt                              |                              log                               |\n| :------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :------------------------------------------------------------: |\n| [pose_rtmpose_m](/configs/face_2d_keypoint/rtmpose/wflw/rtmpose-m_8xb64-60e_wflw-256x256.py) |  256x256   | 4.01 | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-wflw_pt-aic-coco_60e-256x256-dc1dcdcf_20230228.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-wflw_pt-aic-coco_60e-256x256-dc1dcdcf_20230228.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/rtmpose/wflw/rtmpose_wflw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/rtmpose/wflw/rtmpose-m_8xb64-60e_wflw-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: WFLW\n  Name: rtmpose-m_8xb64-60e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME: 4.01\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-wflw_pt-aic-coco_60e-256x256-dc1dcdcf_20230228.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/300w/hrnetv2_300w.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.sciencedirect.com/science/article/pii/S0262885616000147\">300W (IMAVIS'2016)</a></summary>\n\n```bibtex\n@article{sagonas2016300,\n  title={300 faces in-the-wild challenge: Database and results},\n  author={Sagonas, Christos and Antonakos, Epameinondas and Tzimiropoulos, Georgios and Zafeiriou, Stefanos and Pantic, Maja},\n  journal={Image and vision computing},\n  volume={47},\n  pages={3--18},\n  year={2016},\n  publisher={Elsevier}\n}\n```\n\n</details>\n\nResults on 300W dataset\n\nThe model is trained on 300W train.\n\n| Arch                               | Input Size | NME<sub>*common*</sub> | NME<sub>*challenge*</sub> | NME<sub>*full*</sub> | NME<sub>*test*</sub> |                ckpt                 |                log                 |\n| :--------------------------------- | :--------: | :--------------------: | :-----------------------: | :------------------: | :------------------: | :---------------------------------: | :--------------------------------: |\n| [pose_hrnetv2_w18](/configs/face_2d_keypoint/topdown_heatmap/300w/td-hm_hrnetv2-w18_8xb64-60e_300w-256x256.py) |  256x256   |          2.92          |           5.64            |         3.45         |         4.10         | [ckpt](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_300w_256x256-eea53406_20211019.pth) | [log](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_300w_256x256_20211019.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/300w/hrnetv2_300w.yml",
    "content": "Collections:\n- Name: HRNetv2\n  Paper:\n    Title: Deep High-Resolution Representation Learning for Visual Recognition\n    URL: https://ieeexplore.ieee.org/abstract/document/9052469/\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/hrnetv2.md\nModels:\n- Config: configs/face_2d_keypoint/topdown_heatmap/300w/td-hm_hrnetv2-w18_8xb64-60e_300w-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: 300W\n  Name: td-hm_hrnetv2-w18_8xb64-60e_300w-256x256\n  Results:\n  - Dataset: 300W\n    Metrics:\n      NME challenge: 5.64\n      NME common: 2.92\n      NME full: 3.45\n      NME test: 4.1\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_300w_256x256-eea53406_20211019.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/300w/td-hm_hrnetv2-w18_8xb64-60e_300w-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=1.5)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=68,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Face300WDataset'\ndata_mode = 'topdown'\ndata_root = 'data/300w/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_300w_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_300w_valid.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/300wlp/hrnetv2_300wlp.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://www.cbsr.ia.ac.cn/users/xiangyuzhu/projects/3DDFA/main.htm\">300WLP (IEEE'2017)</a></summary>\n\n```bibtex\n@article{zhu2017face,\n  title={Face alignment in full pose range: A 3d total solution},\n  author={Zhu, Xiangyu and Liu, Xiaoming and Lei, Zhen and Li, Stan Z},\n  journal={IEEE transactions on pattern analysis and machine intelligence},\n  year={2017},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on 300W-LP dataset\n\nThe model is trained on 300W-LP train.\n\n| Arch                                               | Input Size | NME<sub>*full*</sub> | NME<sub>*test*</sub> |                        ckpt                        |                        log                         |\n| :------------------------------------------------- | :--------: | :------------------: | :------------------: | :------------------------------------------------: | :------------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/face_2d_keypoint/topdown_heatmap/300wlp/td-hm_hrnetv2-w18_8xb64-60e_300wlp-256x256.py) |  256x256   |        0.0413        |       0.04125        | [ckpt](https://download.openmmlab.com/mmpose/v1/face_2d_keypoint/topdown_heatmap/300wlp/hrnetv2_w18_300wlp_256x256-fb433d21_20230922.pth) | [log](https://download.openmmlab.com/mmpose/v1/face_2d_keypoint/topdown_heatmap/300wlp/hrnetv2_w18_300wlp_256x256-fb433d21_20230922.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/300wlp/hrnetv2_300wlp.yml",
    "content": "Collections:\n- Name: HRNetv2\n  Paper:\n    Title: Deep High-Resolution Representation Learning for Visual Recognition\n    URL: https://ieeexplore.ieee.org/abstract/document/9052469/\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/hrnetv2.md\nModels:\n- Config: configs/face_2d_keypoint/topdown_heatmap/300wlp/td-hm_hrnetv2-w18_8xb64-60e_300wlp-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: 300W-LP\n  Name: td-hm_hrnetv2-w18_8xb64-60e_300wlp-256x256\n  Results:\n  - Dataset: 300W-LP\n    Metrics:\n      NME full: 0.0413\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/face_2d_keypoint/topdown_heatmap/300wlp/hrnetv2_w18_300wlp_256x256-fb433d21_20230922.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/300wlp/td-hm_hrnetv2-w18_8xb64-60e_300wlp-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=1.5)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=68,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Face300WLPDataset'\ndata_mode = 'topdown'\ndata_root = 'data/300wlp/'\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=2,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_300wlp_train.json',\n        data_prefix=dict(img='train/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_300wlp_valid.json',\n        data_prefix=dict(img='val/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/README.md",
    "content": "# Top-down heatmap-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. Instead of estimating keypoint coordinates directly, the pose estimator will produce heatmaps which represent the likelihood of being a keypoint, following the paradigm introduced in [Simple Baselines for Human Pose Estimation and Tracking](http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\" height=400>\n</div>\n\n## Results and Models\n\n### 300W Dataset\n\nResults on 300W dataset\n\n|    Model    | Input Size | NME<sub>*common*</sub> | NME<sub>*challenge*</sub> | NME<sub>*full*</sub> | NME<sub>*test*</sub> |           Details and Download            |\n| :---------: | :--------: | :--------------------: | :-----------------------: | :------------------: | :------------------: | :---------------------------------------: |\n| HRNetv2-w18 |  256x256   |          2.92          |           5.64            |         3.45         |         4.10         | [hrnetv2_300w.md](./300w/hrnetv2_300w.md) |\n\n### AFLW Dataset\n\nResults on AFLW dataset\n\n|      Model       | Input Size | NME<sub>*full*</sub> | NME<sub>*frontal*</sub> |                Details and Download                 |\n| :--------------: | :--------: | :------------------: | :---------------------: | :-------------------------------------------------: |\n| HRNetv2-w18+Dark |  256x256   |         1.35         |          1.19           | [hrnetv2_dark_aflw.md](./aflw/hrnetv2_dark_aflw.md) |\n|   HRNetv2-w18    |  256x256   |         1.41         |          1.27           |      [hrnetv2_aflw.md](./aflw/hrnetv2_aflw.md)      |\n\n### COCO-WholeBody-Face Dataset\n\nResults on COCO-WholeBody-Face val set\n\n|      Model       | Input Size |  NME   |                                       Details and Download                                       |\n| :--------------: | :--------: | :----: | :----------------------------------------------------------------------------------------------: |\n| HRNetv2-w18+Dark |  256x256   | 0.0513 | [hrnetv2_dark_coco_wholebody_face.md](./coco_wholebody_face/hrnetv2_dark_coco_wholebody_face.md) |\n|     SCNet-50     |  256x256   | 0.0567 |        [scnet_coco_wholebody_face.md](./coco_wholebody_face/scnet_coco_wholebody_face.md)        |\n|   HRNetv2-w18    |  256x256   | 0.0569 |      [hrnetv2_coco_wholebody_face.md](./coco_wholebody_face/hrnetv2_coco_wholebody_face.md)      |\n|    ResNet-50     |  256x256   | 0.0582 |       [resnet_coco_wholebody_face.md](./coco_wholebody_face/resnet_coco_wholebody_face.md)       |\n|   HourglassNet   |  256x256   | 0.0587 |    [hourglass_coco_wholebody_face.md](./coco_wholebody_face/hourglass_coco_wholebody_face.md)    |\n|   MobileNet-v2   |  256x256   | 0.0611 |  [mobilenetv2_coco_wholebody_face.md](./coco_wholebody_face/mobilenetv2_coco_wholebody_face.md)  |\n\n### COFW Dataset\n\nResults on COFW dataset\n\n|    Model    | Input Size | NME  |           Details and Download            |\n| :---------: | :--------: | :--: | :---------------------------------------: |\n| HRNetv2-w18 |  256x256   | 3.48 | [hrnetv2_cofw.md](./cofw/hrnetv2_cofw.md) |\n\n### WFLW  Dataset\n\nResults on WFLW  dataset\n\n|  Model  | Input Size | NME<sub>*test*</sub> | NME<sub>*pose*</sub> | NME<sub>*illumination*</sub> | NME<sub>*occlusion*</sub> | NME<sub>*blur*</sub> | NME<sub>*makeup*</sub> | NME<sub>*expression*</sub> |  Details and Download  |\n| :-----: | :--------: | :------------------: | :------------------: | :--------------------------: | :-----------------------: | :------------------: | :--------------------: | :------------------------: | :--------------------: |\n| HRNetv2-w18+Dark |  256x256   |         3.98         |         6.98         |             3.96             |           4.78            |         4.56         |          3.89          |            4.29            | [hrnetv2_dark_wflw.md](./wflw/hrnetv2_dark_wflw.md) |\n| HRNetv2-w18+AWing |  256x256   |         4.02         |         6.94         |             3.97             |           4.78            |         4.59         |          3.87          |            4.28            | [hrnetv2_awing_wflw.md](./wflw/hrnetv2_awing_wflw.md) |\n| HRNetv2-w18 |  256x256   |         4.06         |         6.97         |             3.99             |           4.83            |         4.58         |          3.94          |            4.33            | [hrnetv2_wflw.md](./wflw/hrnetv2_wflw.md) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/aflw/hrnetv2_aflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6130513/\">AFLW (ICCVW'2011)</a></summary>\n\n```bibtex\n@inproceedings{koestinger2011annotated,\n  title={Annotated facial landmarks in the wild: A large-scale, real-world database for facial landmark localization},\n  author={Koestinger, Martin and Wohlhart, Paul and Roth, Peter M and Bischof, Horst},\n  booktitle={2011 IEEE international conference on computer vision workshops (ICCV workshops)},\n  pages={2144--2151},\n  year={2011},\n  organization={IEEE}\n}\n```\n\n</details>\n\nResults on AFLW dataset\n\nThe model is trained on AFLW train and evaluated on AFLW full and frontal.\n\n| Arch                                              | Input Size | NME<sub>*full*</sub> | NME<sub>*frontal*</sub> |                       ckpt                        |                        log                        |\n| :------------------------------------------------ | :--------: | :------------------: | :---------------------: | :-----------------------------------------------: | :-----------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_8xb64-60e_aflw-256x256.py) |  256x256   |         1.41         |          1.27           | [ckpt](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth) | [log](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256_20210125.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/aflw/hrnetv2_aflw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_8xb64-60e_aflw-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: AFLW\n  Name: td-hm_hrnetv2-w18_8xb64-60e_aflw-256x256\n  Results:\n  - Dataset: AFLW\n    Metrics:\n      NME frontal: 1.27\n      NME full: 1.41\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/aflw/hrnetv2_dark_aflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6130513/\">AFLW (ICCVW'2011)</a></summary>\n\n```bibtex\n@inproceedings{koestinger2011annotated,\n  title={Annotated facial landmarks in the wild: A large-scale, real-world database for facial landmark localization},\n  author={Koestinger, Martin and Wohlhart, Paul and Roth, Peter M and Bischof, Horst},\n  booktitle={2011 IEEE international conference on computer vision workshops (ICCV workshops)},\n  pages={2144--2151},\n  year={2011},\n  organization={IEEE}\n}\n```\n\n</details>\n\nResults on AFLW dataset\n\nThe model is trained on AFLW train and evaluated on AFLW full and frontal.\n\n| Arch                                              | Input Size | NME<sub>*full*</sub> | NME<sub>*frontal*</sub> |                       ckpt                        |                        log                        |\n| :------------------------------------------------ | :--------: | :------------------: | :---------------------: | :-----------------------------------------------: | :-----------------------------------------------: |\n| [pose_hrnetv2_w18_dark](/configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_dark-8xb64-60e_aflw-256x256.py) |  256x256   |         1.35         |          1.19           | [ckpt](https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_aflw_256x256_dark-219606c0_20210125.pth) | [log](https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_aflw_256x256_dark_20210125.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/aflw/hrnetv2_dark_aflw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_dark-8xb64-60e_aflw-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - DarkPose\n    Training Data: AFLW\n  Name: td-hm_hrnetv2-w18_dark-8xb64-60e_aflw-256x256\n  Results:\n  - Dataset: AFLW\n    Metrics:\n      NME frontal: 1.19\n      NME full: 1.34\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_aflw_256x256_dark-219606c0_20210125.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_8xb64-60e_aflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=19,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/aflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_aflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_aflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME', norm_mode='use_norm_item', norm_item='bbox_size')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_dark-8xb64-60e_aflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=19,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'AFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/aflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_aflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_aflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME', norm_mode='use_norm_item', norm_item='bbox_size')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hourglass_coco_wholebody_face.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\">Hourglass (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{newell2016stacked,\n  title={Stacked hourglass networks for human pose estimation},\n  author={Newell, Alejandro and Yang, Kaiyu and Deng, Jia},\n  booktitle={European conference on computer vision},\n  pages={483--499},\n  year={2016},\n  organization={Springer}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_hourglass_52](/configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0587 | [ckpt](https://download.openmmlab.com/mmpose/face/hourglass/hourglass52_coco_wholebody_face_256x256-6994cf2e_20210909.pth) | [log](https://download.openmmlab.com/mmpose/face/hourglass/hourglass52_coco_wholebody_face_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hourglass_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: Hourglass\n  Metadata:\n    Architecture:\n    - Hourglass\n    Training Data: COCO-WholeBody-Face\n  Name: td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0587\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hourglass/hourglass52_coco_wholebody_face_256x256-6994cf2e_20210909.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hrnetv2_coco_wholebody_face.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0569 | [ckpt](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_coco_wholebody_face_256x256-c1ca469b_20210909.pth) | [log](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_coco_wholebody_face_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hrnetv2_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: COCO-WholeBody-Face\n  Name: td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0569\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_coco_wholebody_face_256x256-c1ca469b_20210909.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hrnetv2_dark_coco_wholebody_face.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_hrnetv2_w18_dark](/configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_dark-8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0513 | [ckpt](https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_coco_wholebody_face_256x256_dark-3d9a334e_20210909.pth) | [log](https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_coco_wholebody_face_256x256_dark_20210909.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hrnetv2_dark_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_dark-8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - DarkPose\n    Training Data: COCO-WholeBody-Face\n  Name: td-hm_hrnetv2-w18_dark-8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0513\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_coco_wholebody_face_256x256_dark-3d9a334e_20210909.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/mobilenetv2_coco_wholebody_face.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_mobilenetv2](/configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_mobilenetv2_8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0611 | [ckpt](https://download.openmmlab.com/mmpose/face/mobilenetv2/mobilenetv2_coco_wholebody_face_256x256-4a3f096e_20210909.pth) | [log](https://download.openmmlab.com/mmpose/face/mobilenetv2/mobilenetv2_coco_wholebody_face_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/mobilenetv2_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_mobilenetv2_8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - MobilenetV2\n    Training Data: COCO-WholeBody-Face\n  Name: td-hm_mobilenetv2_8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0611\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/mobilenetv2/mobilenetv2_coco_wholebody_face_256x256-4a3f096e_20210909.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/resnet_coco_wholebody_face.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_res50](/configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_res50_8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0582 | [ckpt](https://download.openmmlab.com/mmpose/face/resnet/res50_coco_wholebody_face_256x256-5128edf5_20210909.pth) | [log](https://download.openmmlab.com/mmpose/face/resnet/res50_coco_wholebody_face_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/resnet_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_res50_8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: COCO-WholeBody-Face\n  Name: td-hm_res50_8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0582\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/resnet/res50_coco_wholebody_face_256x256-5128edf5_20210909.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/scnet_coco_wholebody_face.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Liu_Improving_Convolutional_Networks_With_Self-Calibrated_Convolutions_CVPR_2020_paper.html\">SCNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020improving,\n  title={Improving Convolutional Networks with Self-Calibrated Convolutions},\n  author={Liu, Jiang-Jiang and Hou, Qibin and Cheng, Ming-Ming and Wang, Changhu and Feng, Jiashi},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={10096--10105},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Face val set\n\n| Arch                                                          | Input Size |  NME   |                              ckpt                              |                              log                              |\n| :------------------------------------------------------------ | :--------: | :----: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [pose_scnet_50](/configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_scnet50_8xb32-60e_coco-wholebody-face-256x256.py) |  256x256   | 0.0567 | [ckpt](https://download.openmmlab.com/mmpose/face/scnet/scnet50_coco_wholebody_face_256x256-a0183f5f_20210909.pth) | [log](https://download.openmmlab.com/mmpose/face/scnet/scnet50_coco_wholebody_face_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/scnet_coco_wholebody_face.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_scnet50_8xb32-60e_coco-wholebody-face-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - SCNet\n    Training Data: COCO-WholeBody-Face\n  Name: td-hm_scnet50_8xb32-60e_coco-wholebody-face-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Face\n    Metrics:\n      NME: 0.0567\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/scnet/scnet50_coco_wholebody_face_256x256-a0183f5f_20210909.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hourglass52_8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HourglassNet',\n        num_stacks=1,\n    ),\n    head=dict(\n        type='CPMHead',\n        in_channels=256,\n        out_channels=68,\n        num_stages=1,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18')),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=68,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_hrnetv2-w18_dark-8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18')),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=68,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_mobilenetv2_8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://mobilenet_v2')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=68,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_res50_8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=68,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/td-hm_scnet50_8xb32-60e_coco-wholebody-face-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet50-7ef0a199.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=68,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyFaceDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/cofw/hrnetv2_cofw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2013/html/Burgos-Artizzu_Robust_Face_Landmark_2013_ICCV_paper.html\">COFW (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{burgos2013robust,\n  title={Robust face landmark estimation under occlusion},\n  author={Burgos-Artizzu, Xavier P and Perona, Pietro and Doll{\\'a}r, Piotr},\n  booktitle={Proceedings of the IEEE international conference on computer vision},\n  pages={1513--1520},\n  year={2013}\n}\n```\n\n</details>\n\nResults on COFW dataset\n\nThe model is trained on COFW train.\n\n| Arch                                                           | Input Size | NME  |                              ckpt                              |                              log                               |\n| :------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :------------------------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/face_2d_keypoint/topdown_heatmap/cofw/td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py) |  256x256   | 3.48 | [ckpt](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_cofw_256x256-49243ab8_20211019.pth) | [log](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_cofw_256x256_20211019.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/cofw/hrnetv2_cofw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/cofw/td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: COFW\n  Name: td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256\n  Results:\n  - Dataset: COFW\n    Metrics:\n      NME: 3.48\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_cofw_256x256-49243ab8_20211019.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/cofw/td-hm_hrnetv2-w18_8xb64-60e_cofw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=50,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=1.5)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=29,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'COFWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/cofw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/cofw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/cofw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_awing_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/1904.07399.pdf\">AdaptiveWingloss (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{wang2019adaptive,\n  title={Adaptive wing loss for robust face alignment via heatmap regression},\n  author={Wang, Xinyao and Bo, Liefeng and Fuxin, Li},\n  booktitle={Proceedings of the IEEE/CVF international conference on computer vision},\n  pages={6971--6981},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train.\n\n| Arch       | Input Size | NME<sub>*test*</sub> | NME<sub>*pose*</sub> | NME<sub>*illumination*</sub> | NME<sub>*occlusion*</sub> | NME<sub>*blur*</sub> | NME<sub>*makeup*</sub> | NME<sub>*expression*</sub> |    ckpt    |    log    |\n| :--------- | :--------: | :------------------: | :------------------: | :--------------------------: | :-----------------------: | :------------------: | :--------------------: | :------------------------: | :--------: | :-------: |\n| [pose_hrnetv2_w18_awing](/configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_awing-8xb64-60e_wflw-256x256.py) |  256x256   |         4.02         |         6.94         |             3.97             |           4.78            |         4.59         |          3.87          |            4.28            | [ckpt](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_wflw_256x256_awing-5af5055c_20211212.pth) | [log](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_wflw_256x256_awing_20211212.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_awing_wflw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_awing-8xb64-60e_wflw-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - AdaptiveWingloss\n    Training Data: WFLW\n  Name: td-hm_hrnetv2-w18_awing-8xb64-60e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME blur: 4.59\n      NME expression: 4.28\n      NME illumination: 3.97\n      NME makeup: 3.87\n      NME occlusion: 4.78\n      NME pose: 6.94\n      NME test: 4.02\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_wflw_256x256_awing-5af5055c_20211212.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_dark_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train.\n\n| Arch       | Input Size | NME<sub>*test*</sub> | NME<sub>*pose*</sub> | NME<sub>*illumination*</sub> | NME<sub>*occlusion*</sub> | NME<sub>*blur*</sub> | NME<sub>*makeup*</sub> | NME<sub>*expression*</sub> |    ckpt    |    log    |\n| :--------- | :--------: | :------------------: | :------------------: | :--------------------------: | :-----------------------: | :------------------: | :--------------------: | :------------------------: | :--------: | :-------: |\n| [pose_hrnetv2_w18_dark](/configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_dark-8xb64-60e_wflw-256x256.py) |  256x256   |         3.98         |         6.98         |             3.96             |           4.78            |         4.56         |          3.89          |            4.29            | [ckpt](https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_wflw_256x256_dark-3f8e0c2c_20210125.pth) | [log](https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_wflw_256x256_dark_20210125.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_dark_wflw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_dark-8xb64-60e_wflw-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - DarkPose\n    Training Data: WFLW\n  Name: td-hm_hrnetv2-w18_dark-8xb64-60e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME blur: 4.56\n      NME expression: 4.29\n      NME illumination: 3.96\n      NME makeup: 3.89\n      NME occlusion: 4.78\n      NME pose: 6.98\n      NME test: 3.98\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/darkpose/hrnetv2_w18_wflw_256x256_dark-3f8e0c2c_20210125.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train.\n\n| Arch       | Input Size | NME<sub>*test*</sub> | NME<sub>*pose*</sub> | NME<sub>*illumination*</sub> | NME<sub>*occlusion*</sub> | NME<sub>*blur*</sub> | NME<sub>*makeup*</sub> | NME<sub>*expression*</sub> |    ckpt    |    log    |\n| :--------- | :--------: | :------------------: | :------------------: | :--------------------------: | :-----------------------: | :------------------: | :--------------------: | :------------------------: | :--------: | :-------: |\n| [pose_hrnetv2_w18](/configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_8xb64-60e_wflw-256x256.py) |  256x256   |         4.06         |         6.97         |             3.99             |           4.83            |         4.58         |          3.94          |            4.33            | [ckpt](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_wflw_256x256-2bf032a6_20210125.pth) | [log](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_wflw_256x256_20210125.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_wflw.yml",
    "content": "Models:\n- Config: configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_8xb64-60e_wflw-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: WFLW\n  Name: td-hm_hrnetv2-w18_8xb64-60e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME blur: 4.58\n      NME expression: 4.33\n      NME illumination: 3.99\n      NME makeup: 3.94\n      NME occlusion: 4.83\n      NME pose: 6.97\n      NME test: 4.06\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_wflw_256x256-2bf032a6_20210125.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_8xb64-60e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=98,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_awing-8xb64-60e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=98,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='AdaptiveWingLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_heatmap/wflw/td-hm_hrnetv2-w18_dark-8xb64-60e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=60, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=60,\n        milestones=[40, 55],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=98,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0,\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/README.md",
    "content": "# Top-down regression-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. At the 2nd stage, regression based methods directly regress the keypoint coordinates given the features extracted from the bounding box area, following the paradigm introduced in [Deeppose: Human pose estimation via deep neural networks](http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515040-a82a8a29-d6bc-42f1-a2ab-7dfa610ce363.png\">\n</div>\n\n## Results and Models\n\n### WFLW Dataset\n\nResult on WFLW test set\n\n| Model                                                           | Input Size | NME  |                              ckpt                              |                              log                              |\n| :-------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [ResNet-50](/configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_8xb64-210e_wflw-256x256.py) |  256x256   | 4.88 | [ckpt](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256-92d0ba7f_20210303.pth) | [log](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_20210303.log.json) |\n| [ResNet-50+WingLoss](/configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py) |  256x256   | 4.67 | [ckpt](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_wingloss-f82a5e53_20210303.pth) | [log](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_wingloss_20210303.log.json) |\n| [ResNet-50+SoftWingLoss](/configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_softwingloss_8xb64-210e_wflw-256x256.py) |  256x256   | 4.44 | [ckpt](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_softwingloss-4d34f22a_20211212.pth) | [log](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_softwingloss_20211212.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/resnet_softwingloss_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/document/9442331/\">SoftWingloss (TIP'2021)</a></summary>\n\n```bibtex\n@article{lin2021structure,\n  title={Structure-Coherent Deep Feature Learning for Robust Face Alignment},\n  author={Lin, Chunze and Zhu, Beier and Wang, Quan and Liao, Renjie and Qian, Chen and Lu, Jiwen and Zhou, Jie},\n  journal={IEEE Transactions on Image Processing},\n  year={2021},\n  publisher={IEEE}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train set.\n\n| Model                                                           | Input Size | NME  |                              ckpt                              |                              log                              |\n| :-------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [ResNet-50+SoftWingLoss](/configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_softwingloss_8xb64-210e_wflw-256x256.py) |  256x256   | 4.44 | [ckpt](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_softwingloss-4d34f22a_20211212.pth) | [log](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_softwingloss_20211212.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/resnet_softwingloss_wflw.yml",
    "content": "Collections:\n- Name: SoftWingloss\n  Paper:\n    Title: Structure-Coherent Deep Feature Learning for Robust Face Alignment\n    URL: https://ieeexplore.ieee.org/document/9442331/\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/techniques/softwingloss.md\nModels:\n- Config: configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_softwingloss_8xb64-210e_wflw-256x256.py\n  In Collection: SoftWingloss\n  Metadata:\n    Architecture:\n    - DeepPose\n    - ResNet\n    - SoftWingloss\n    Training Data: WFLW\n  Name: td-reg_res50_softwingloss_8xb64-210e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME: 4.44\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_softwingloss-4d34f22a_20211212.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/resnet_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train set.\n\n| Model                                                           | Input Size | NME  |                              ckpt                              |                              log                              |\n| :-------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [ResNet-50](/configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_8xb64-210e_wflw-256x256.py) |  256x256   | 4.88 | [ckpt](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256-92d0ba7f_20210303.pth) | [log](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_20210303.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/resnet_wflw.yml",
    "content": "Collections:\n- Name: ResNet\n  Paper:\n    Title: Deep residual learning for image recognition\n    URL: http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/backbones/resnet.md\nModels:\n- Config: configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_8xb64-210e_wflw-256x256.py\n  In Collection: ResNet\n  Metadata:\n    Architecture:\n    - DeepPose\n    - ResNet\n    Training Data: WFLW\n  Name: td-reg_res50_8x64e-210e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME: 4.88\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256-92d0ba7f_20210303.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/resnet_wingloss_wflw.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Feng_Wing_Loss_for_CVPR_2018_paper.html\">Wingloss (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{feng2018wing,\n  title={Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks},\n  author={Feng, Zhen-Hua and Kittler, Josef and Awais, Muhammad and Huber, Patrik and Wu, Xiao-Jun},\n  booktitle={Computer Vision and Pattern Recognition (CVPR), 2018 IEEE Conference on},\n  year={2018},\n  pages ={2235-2245},\n  organization={IEEE}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\nResults on WFLW dataset\n\nThe model is trained on WFLW train set.\n\n| Model                                                           | Input Size | NME  |                              ckpt                              |                              log                              |\n| :-------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :-----------------------------------------------------------: |\n| [ResNet-50+WingLoss](/configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py) |  256x256   | 4.67 | [ckpt](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_wingloss-f82a5e53_20210303.pth) | [log](https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_wingloss_20210303.log.json) |\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/resnet_wingloss_wflw.yml",
    "content": "Collections:\n- Name: Wingloss\n  Paper:\n    Title: Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural\n      Networks\n    URL: http://openaccess.thecvf.com/content_cvpr_2018/html/Feng_Wing_Loss_for_CVPR_2018_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/main/docs/src/papers/techniques/wingloss.md\nModels:\n- Config: configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py\n  In Collection: Wingloss\n  Metadata:\n    Architecture:\n    - DeepPose\n    - ResNet\n    - WingLoss\n    Training Data: WFLW\n  Name: td-reg_res50_wingloss_8xb64-210e_wflw-256x256\n  Results:\n  - Dataset: WFLW\n    Metrics:\n      NME: 4.67\n    Task: Face 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/face/deeppose/deeppose_res50_wflw_256x256_wingloss-f82a5e53_20210303.pth\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_8xb64-210e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=98,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    train_cfg=dict(),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# dataloaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less'))\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_softwingloss_8xb64-210e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=98,\n        loss=dict(type='SoftWingLoss', use_target_weight=True),\n        decoder=codec),\n    train_cfg=dict(),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# dataloaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less'))\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/face_2d_keypoint/topdown_regression/wflw/td-reg_res50_wingloss_8xb64-210e_wflw-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=98,\n        loss=dict(type='WingLoss', use_target_weight=True),\n        decoder=codec),\n    train_cfg=dict(),\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# dataloaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less'))\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/README.md",
    "content": "# 2D Fashion Landmark Detection\n\n2D fashion landmark detection (also referred to as fashion alignment) aims to detect the key-point located at the functional region of clothes, for example the neckline and the cuff.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_fashion_landmark.md) to prepare data.\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/README.md",
    "content": "# Top-down heatmap-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. Instead of estimating keypoint coordinates directly, the pose estimator will produce heatmaps which represent the likelihood of being a keypoint, following the paradigm introduced in [Simple Baselines for Human Pose Estimation and Tracking](http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\" height=400>\n</div>\n\n## Results and Models\n\n### DeepFashion Dataset\n\nResults on DeepFashion dataset with ResNet backbones:\n\n|        Model        | Input Size | PCK@0.2 | AUC  | EPE  |                     Details and Download                     |\n| :-----------------: | :--------: | :-----: | :--: | :--: | :----------------------------------------------------------: |\n| HRNet-w48-UDP-Upper |  256x192   |  96.1   | 60.9 | 15.1 |  [hrnet_deepfashion.md](./deepfashion/hrnet_deepfashion.md)  |\n| HRNet-w48-UDP-Lower |  256x192   |  97.8   | 76.1 | 8.9  |  [hrnet_deepfashion.md](./deepfashion/hrnet_deepfashion.md)  |\n| HRNet-w48-UDP-Full  |  256x192   |  98.3   | 67.3 | 11.7 |  [hrnet_deepfashion.md](./deepfashion/hrnet_deepfashion.md)  |\n|   ResNet-50-Upper   |  256x192   |  95.4   | 57.8 | 16.8 | [resnet_deepfashion.md](./deepfashion/resnet_deepfashion.md) |\n|   ResNet-50-Lower   |  256x192   |  96.5   | 74.4 | 10.5 | [resnet_deepfashion.md](./deepfashion/resnet_deepfashion.md) |\n|   ResNet-50-Full    |  256x192   |  97.7   | 66.4 | 12.7 | [resnet_deepfashion.md](./deepfashion/resnet_deepfashion.md) |\n\n### DeepFashion2 Dataset\n\nResults on DeepFashion2 dataset\n\n|              Model              | Input Size | PCK@0.2 |  AUC  | EPE  |                     Details and Download                      |\n| :-----------------------------: | :--------: | :-----: | :---: | :--: | :-----------------------------------------------------------: |\n|  ResNet-50-Short-Sleeved-Shirt  |  256x192   |  0.988  | 0.703 | 10.2 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|  ResNet-50-Long-Sleeved-Shirt   |  256x192   |  0.973  | 0.587 | 16.6 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n| ResNet-50-Short-Sleeved-Outwear |  256x192   |  0.966  | 0.408 | 24.0 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n| ResNet-50-Long-Sleeved-Outwear  |  256x192   |  0.987  | 0.517 | 18.1 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|         ResNet-50-Vest          |  256x192   |  0.981  | 0.643 | 12.7 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|         ResNet-50-Sling         |  256x192   |  0.940  | 0.557 | 21.6 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|        ResNet-50-Shorts         |  256x192   |  0.975  | 0.682 | 12.4 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|       ResNet-50-Trousers        |  256x192   |  0.973  | 0.625 | 14.8 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|         ResNet-50-Skirt         |  256x192   |  0.952  | 0.653 | 16.6 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|  ResNet-50-Short-Sleeved-Dress  |  256x192   |  0.980  | 0.603 | 15.6 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|  ResNet-50-Long-Sleeved-Dress   |  256x192   |  0.976  | 0.518 | 20.1 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|      ResNet-50-Vest-Dress       |  256x192   |  0.980  | 0.600 | 16.0 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n|      ResNet-50-Sling-Dress      |  256x192   |  0.967  | 0.544 | 19.5 | [res50_deepfashion2.md](./deepfashion2/res50_deepfashion2.md) |\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/hrnet_deepfashion.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Liu_DeepFashion_Powering_Robust_CVPR_2016_paper.html\">DeepFashion (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuLQWTcvpr16DeepFashion,\n author = {Liu, Ziwei and Luo, Ping and Qiu, Shi and Wang, Xiaogang and Tang, Xiaoou},\n title = {DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations},\n booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n month = {June},\n year = {2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46475-6_15\">DeepFashion (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuYLWTeccv16FashionLandmark,\n author = {Liu, Ziwei and Yan, Sijie and Luo, Ping and Wang, Xiaogang and Tang, Xiaoou},\n title = {Fashion Landmark Detection in the Wild},\n booktitle = {European Conference on Computer Vision (ECCV)},\n month = {October},\n year = {2016}\n }\n```\n\n</details>\n\nResults on DeepFashion val set\n\n| Set   |                           Arch                            | Input Size | PCK@0.2 | AUC  | EPE  |                           ckpt                            |                           log                            |\n| :---- | :-------------------------------------------------------: | :--------: | :-----: | :--: | :--: | :-------------------------------------------------------: | :------------------------------------------------------: |\n| upper | [pose_hrnet_w48_udp](td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_uppder-256x192.py) |  256x192   |  96.1   | 60.9 | 15.1 | [ckpt](https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_upper-256x192-de7c0eb1_20230810.pth) | [log](https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_upper-256x192-de7c0eb1_20230810.log) |\n| lower | [pose_hrnet_w48_udp](td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192.py) |  256x192   |  97.8   | 76.1 | 8.9  | [ckpt](https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192-ddaf747d_20230810.pth) | [log](https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192-ddaf747d_20230810.log) |\n| full  | [pose_hrnet_w48_udp](td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192.py) |  256x192   |  98.3   | 67.3 | 11.7 | [ckpt](https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192-7ab504c7_20230810.pth) | [log](https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192-7ab504c7_20230810.log) |\n\nNote: Due to the time constraints, we have only trained resnet50 models. We warmly welcome any contributions if you can successfully reproduce the results from the paper!\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/hrnet_deepfashion.yml",
    "content": "Models:\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    - UDP\n    Training Data: DeepFashion\n  Name: td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192\n  Results:\n  - Dataset: DeepFashion\n    Metrics:\n      AUC: 76.1\n      EPE: 8.9\n      PCK@0.2: 97.8\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192-ddaf747d_20230810.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_upper-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion\n  Name: td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_upper-256x192\n  Results:\n  - Dataset: DeepFashion\n    Metrics:\n      AUC: 60.9\n      EPE: 15.1\n      PCK@0.2: 96.1\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_upper-256x192-de7c0eb1_20230810.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion\n  Name: td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192\n  Results:\n  - Dataset: DeepFashion\n    Metrics:\n      AUC: 67.3\n      EPE: 11.7\n      PCK@0.2: 98.3\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192-7ab504c7_20230810.pth\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/resnet_deepfashion.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Liu_DeepFashion_Powering_Robust_CVPR_2016_paper.html\">DeepFashion (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuLQWTcvpr16DeepFashion,\n author = {Liu, Ziwei and Luo, Ping and Qiu, Shi and Wang, Xiaogang and Tang, Xiaoou},\n title = {DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations},\n booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n month = {June},\n year = {2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46475-6_15\">DeepFashion (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuYLWTeccv16FashionLandmark,\n author = {Liu, Ziwei and Yan, Sijie and Luo, Ping and Wang, Xiaogang and Tang, Xiaoou},\n title = {Fashion Landmark Detection in the Wild},\n booktitle = {European Conference on Computer Vision (ECCV)},\n month = {October},\n year = {2016}\n }\n```\n\n</details>\n\nResults on DeepFashion val set\n\n| Set   |                           Arch                            | Input Size | PCK@0.2 | AUC  | EPE  |                           ckpt                            |                           log                            |\n| :---- | :-------------------------------------------------------: | :--------: | :-----: | :--: | :--: | :-------------------------------------------------------: | :------------------------------------------------------: |\n| upper | [pose_resnet_50](td-hm_res50_8xb64-210e_deepfashion_upper-256x192.py) |  256x192   |  95.4   | 57.8 | 16.8 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_upper_256x192-41794f03_20210124.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_upper_256x192_20210124.log.json) |\n| lower | [pose_resnet_50](td-hm_res50_8xb64-210e_deepfashion_lower-256x192.py) |  256x192   |  96.5   | 74.4 | 10.5 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_lower_256x192-1292a839_20210124.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_lower_256x192_20210124.log.json) |\n| full  | [pose_resnet_50](td-hm_res50_8xb64-210e_deepfashion_full-256x192.py) |  256x192   |  97.7   | 66.4 | 12.7 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_full_256x192-0dbd6e42_20210124.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_full_256x192_20210124.log.json) |\n\nNote: Due to the time constraints, we have only trained resnet50 models. We warmly welcome any contributions if you can successfully reproduce the results from the paper!\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/resnet_deepfashion.yml",
    "content": "Collections:\n- Name: SimpleBaseline2D\n  Paper:\n    Title: Simple baselines for human pose estimation and tracking\n    URL: http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\n  README: https://github.com/open-mmlab/mmpose/blob/master/docs/en/papers/algorithms/simplebaseline2d.md\nModels:\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res50_8xb64-210e_deepfashion_upper-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: DeepFashion\n  Name: td-hm_res50_8xb64-210e_deepfashion_upper-256x192\n  Results:\n  - Dataset: DeepFashion\n    Metrics:\n      AUC: 57.8\n      EPE: 16.8\n      PCK@0.2: 95.4\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_upper_256x192-41794f03_20210124.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res50_8xb64-210e_deepfashion_lower-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion\n  Name: td-hm_res50_8xb64-210e_deepfashion_lower-256x192\n  Results:\n  - Dataset: DeepFashion\n    Metrics:\n      AUC: 74.4\n      EPE: 96.5\n      PCK@0.2: 10.5\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_lower_256x192-1292a839_20210124.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res50_8xb64-210e_deepfashion_full-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion\n  Name: td-hm_res50_8xb64-210e_deepfashion_full-256x192\n  Results:\n  - Dataset: DeepFashion\n    Metrics:\n      AUC: 66.4\n      EPE: 12.7\n      PCK@0.2: 97.7\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion_full_256x192-0dbd6e42_20210124.pth\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w32_8xb64-210e_deepfashion_full-256x192.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=8,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashionDataset'\ndata_mode = 'topdown'\ndata_root = 'data/fld/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = val_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        subset='full',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_full_train.json',\n        data_prefix=dict(img='img/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='full',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_full_val.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='full',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_full_test.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w32_8xb64-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=4,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashionDataset'\ndata_mode = 'topdown'\ndata_root = 'data/fld/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = val_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        subset='lower',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_lower_train.json',\n        data_prefix=dict(img='img/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='lower',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_lower_val.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='lower',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_lower_test.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w32_8xb64-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=6,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashionDataset'\ndata_mode = 'topdown'\ndata_root = 'data/fld/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = val_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        subset='upper',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_upper_train.json',\n        data_prefix=dict(img='img/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='upper',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_upper_val.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='upper',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_upper_test.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w32_udp_8xb64-210e_deepfashion_full-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w32_8xb64-210e_deepfashion_full-256x192.py'\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=False))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w32_udp_8xb64-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w32_8xb64-210e_deepfashion_lower-256x192.py'\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=False))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w32_udp_8xb64-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w32_8xb64-210e_deepfashion_upper-256x192.py'\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=False))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_8xb32-210e_deepfashion_full-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w32_8xb64-210e_deepfashion_full-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\nmodel = dict(\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(in_channels=48))\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_8xb32-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w32_8xb64-210e_deepfashion_lower-256x192.py'  # noqa\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\nmodel = dict(\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(in_channels=48))\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_8xb32-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w32_8xb64-210e_deepfashion_upper-256x192.py'  # noqa\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\nmodel = dict(\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(in_channels=48))\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_full-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w48_8xb32-210e_deepfashion_full-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=False))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w48_8xb32-210e_deepfashion_lower-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=False))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_hrnet-w48_udp_8xb32-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = './td-hm_hrnet-w48_8xb32-210e_deepfashion_upper-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=False))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res101_8xb64-210e_deepfashion_full-256x192.py",
    "content": "_base_ = './td-hm_res50_8xb64-210e_deepfashion_full-256x192.py'\n\nmodel = dict(\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained',\n                      checkpoint='torchvision://resnet101')))\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res101_8xb64-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = './td-hm_res50_8xb64-210e_deepfashion_lower-256x192.py'\n\nmodel = dict(\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained',\n                      checkpoint='torchvision://resnet101')))\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res101_8xb64-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = './td-hm_res50_8xb64-210e_deepfashion_upper-256x192.py'\n\nmodel = dict(\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained',\n                      checkpoint='torchvision://resnet101')))\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res152_8xb32-210e_deepfashion_full-256x192.py",
    "content": "_base_ = './td-hm_res50_8xb64-210e_deepfashion_full-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\nmodel = dict(\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained',\n                      checkpoint='torchvision://resnet152')))\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res152_8xb32-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = './td-hm_res50_8xb64-210e_deepfashion_lower-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\nmodel = dict(\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained',\n                      checkpoint='torchvision://resnet152')))\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res152_8xb32-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = './td-hm_res50_8xb64-210e_deepfashion_upper-256x192.py'\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\nmodel = dict(\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained',\n                      checkpoint='torchvision://resnet152')))\n\ntrain_dataloader = dict(batch_size=32)\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res50_8xb64-210e_deepfashion_full-256x192.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=8,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashionDataset'\ndata_mode = 'topdown'\ndata_root = 'data/fld/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = val_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        subset='full',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_full_train.json',\n        data_prefix=dict(img='img/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='full',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_full_val.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='full',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_full_test.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res50_8xb64-210e_deepfashion_lower-256x192.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=64)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=4,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashionDataset'\ndata_mode = 'topdown'\ndata_root = 'data/fld/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = val_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        subset='lower',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_lower_train.json',\n        data_prefix=dict(img='img/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='lower',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_lower_val.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='lower',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_lower_test.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/td-hm_res50_8xb64-210e_deepfashion_upper-256x192.py",
    "content": "_base_ = '../../../_base_/default_runtime.py'\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=64)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=6,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashionDataset'\ndata_mode = 'topdown'\ndata_root = 'data/fld/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = val_pipeline\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        subset='upper',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_upper_train.json',\n        data_prefix=dict(img='img/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='upper',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_upper_val.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        subset='upper',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/fld_upper_test.json',\n        data_prefix=dict(img='img/'),\n        test_mode=True,\n        pipeline=test_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/res50_deepfashion2.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/1901.07973.pdf\">DeepFashion2 (CVPR'2019)</a></summary>\n\n```bibtex\n@article{DeepFashion2,\n  author = {Yuying Ge and Ruimao Zhang and Lingyun Wu and Xiaogang Wang and Xiaoou Tang and Ping Luo},\n  title={A Versatile Benchmark for Detection, Pose Estimation, Segmentation and Re-Identification of Clothing Images},\n  journal={CVPR},\n  year={2019}\n}\n```\n\n</details>\n\nResults on DeepFashion2 val set\n\n| Set                   |                        Arch                         | Input Size | PCK@0.2 |  AUC  | EPE  |                        ckpt                         |                         log                         |\n| :-------------------- | :-------------------------------------------------: | :--------: | :-----: | :---: | :--: | :-------------------------------------------------: | :-------------------------------------------------: |\n| short_sleeved_shirt   | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_6xb64-210e_deepfasion2-short-sleeved-shirt-256x192.py) |  256x192   |  0.988  | 0.703 | 10.2 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_shirt_256x192-21e1c5da_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_shirt_256x192_20221208.log.json) |\n| long_sleeved_shirt    | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-shirt-256x192.py) |  256x192   |  0.973  | 0.587 | 16.6 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_shirt_256x192-8679e7e3_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_shirt_256x192_20221208.log.json) |\n| short_sleeved_outwear | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-short-sleeved-outwear-256x192.py) |  256x192   |  0.966  | 0.408 | 24.0 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_outwear_256x192-a04c1298_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_outwear_256x192_20221208.log.json) |\n| long_sleeved_outwear  | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-outwear-256x192.py) |  256x192   |  0.987  | 0.517 | 18.1 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_outwear_256x192-31fbaecf_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_outwear_256x192_20221208.log.json) |\n| vest                  | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-vest-256x192.py) |  256x192   |  0.981  | 0.643 | 12.7 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_vest_256x192-4c48d05c_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_vest_256x192_20221208.log.json) |\n| sling                 | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-sling-256x192.py) |  256x192   |  0.940  | 0.557 | 21.6 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_sling_256x192-ebb2b736_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_sling_256x192_20221208.log.json) |\n| shorts                | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_3xb64-210e_deepfasion2-shorts-256x192.py) |  256x192   |  0.975  | 0.682 | 12.4 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_shorts_256x192-9ab23592_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_shorts_256x192_20221208.log.json) |\n| trousers              | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_2xb64-210e_deepfasion2-trousers-256x192.py) |  256x192   |  0.973  | 0.625 | 14.8 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_trousers_256x192-3e632257_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_trousers_256x192_20221208.log.json) |\n| skirt                 | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-skirt-256x192.py) |  256x192   |  0.952  | 0.653 | 16.6 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_skirt_256x192-09573469_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_skirt_256x192_20221208.log.json) |\n| short_sleeved_dress   | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-short-sleeved-dress-256x192.py) |  256x192   |  0.980  | 0.603 | 15.6 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_dress_256x192-1345b07a_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_dress_256x192_20221208.log.json) |\n| long_sleeved_dress    | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-long-sleeved-dress-256x192.py) |  256x192   |  0.976  | 0.518 | 20.1 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_dress_256x192-87bac74e_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_dress_256x192_20221208.log.json) |\n| vest_dress            | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-vest-dress-256x192.py) |  256x192   |  0.980  | 0.600 | 16.0 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_vest_dress_256x192-fb3fbd6f_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_vest_dress_256x192_20221208.log.json) |\n| sling_dress           | [pose_resnet_50](/configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-sling-dress-256x192.py) |  256x192   |  0.967  | 0.544 | 19.5 | [ckpt](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_sling_dress_256x192-8ebae0eb_20221208.pth) | [log](https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_sling_dress_256x192_20221208.log.json) |\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/res50_deepfasion2.yml",
    "content": "Models:\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_6xb64-210e_deepfasion2-short-sleeved-shirt-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: DeepFashion2\n  Name: td-hm_res50_6xb64-210e_deepfasion2-short-sleeved-shirt-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.703\n      EPE: 10.2\n      PCK@0.2: 0.988\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_shirt_256x192-21e1c5da_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-shirt-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-shirt-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.587\n      EPE: 16.5\n      PCK@0.2: 0.973\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_shirt_256x192-8679e7e3_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-short-sleeved-outwear-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_8xb64-210e_deepfasion2-short-sleeved-outwear-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.408\n      EPE: 24.0\n      PCK@0.2: 0.966\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_outwear_256x192-a04c1298_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-outwear-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-outwear-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.517\n      EPE: 18.1\n      PCK@0.2: 0.987\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_outwear_256x192-31fbaecf_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-vest-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_4xb64-210e_deepfasion2-vest-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.643\n      EPE: 12.7\n      PCK@0.2: 0.981\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_vest_256x192-4c48d05c_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-sling-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_4xb64-210e_deepfasion2-sling-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.557\n      EPE: 21.6\n      PCK@0.2: 0.94\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_sling_256x192-ebb2b736_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_3xb64-210e_deepfasion2-shorts-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_3xb64-210e_deepfasion2-shorts-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.682\n      EPE: 12.4\n      PCK@0.2: 0.975\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_shorts_256x192-9ab23592_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_2xb64-210e_deepfasion2-trousers-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_2xb64-210e_deepfasion2-trousers-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.625\n      EPE: 14.8\n      PCK@0.2: 0.973\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_trousers_256x192-3e632257_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-skirt-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_1xb64-210e_deepfasion2-skirt-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.653\n      EPE: 16.6\n      PCK@0.2: 0.952\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_skirt_256x192-09573469_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-short-sleeved-dress-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_4xb64-210e_deepfasion2-short-sleeved-dress-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.603\n      EPE: 15.6\n      PCK@0.2: 0.98\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_short_sleeved_dress_256x192-1345b07a_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-long-sleeved-dress-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_1xb64-210e_deepfasion2-long-sleeved-dress-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.518\n      EPE: 20.1\n      PCK@0.2: 0.976\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_long_sleeved_dress_256x192-87bac74e_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-vest-dress-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_1xb64-210e_deepfasion2-vest-dress-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.6\n      EPE: 16.0\n      PCK@0.2: 0.98\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_vest_dress_256x192-fb3fbd6f_20221208.pth\n- Config: configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-sling-dress-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: DeepFashion2\n  Name: td-hm_res50_4xb64-210e_deepfasion2-sling-dress-256x192\n  Results:\n  - Dataset: DeepFashion2\n    Metrics:\n      AUC: 0.544\n      EPE: 19.5\n      PCK@0.2: 0.967\n    Task: Fashion 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/fashion/resnet/res50_deepfashion2_sling_dress_256x192-8ebae0eb_20221208.pth\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-long-sleeved-dress-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=64)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_long_sleeved_dress_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_long_sleeved_dress_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-skirt-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=64)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_skirt_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_skirt_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_1xb64-210e_deepfasion2-vest-dress-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=64)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_vest_dress_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_vest_dress_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_2xb64-210e_deepfasion2-trousers-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=128)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_trousers_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_trousers_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_3xb64-210e_deepfasion2-shorts-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=192)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_shorts_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_shorts_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-short-sleeved-dress-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_short_sleeved_dress_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_short_sleeved_dress_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-sling-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_sling_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_sling_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-sling-dress-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_sling_dress_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_sling_dress_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_4xb64-210e_deepfasion2-vest-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_vest_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_vest_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_6xb64-210e_deepfasion2-short-sleeved-shirt-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=384)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_short_sleeved_shirt_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_short_sleeved_shirt_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-outwear-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_long_sleeved_outwear_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/'\n        'deepfashion2_long_sleeved_outwear_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-long-sleeved-shirt-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_long_sleeved_shirt_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/deepfashion2_long_sleeved_shirt_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/td-hm_res50_8xb64-210e_deepfasion2-short-sleeved-outwear-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    logger=dict(type='LoggerHook', interval=10),\n    checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=294,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'DeepFashion2Dataset'\ndata_mode = 'topdown'\ndata_root = 'data/deepfasion2/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='train/deepfashion2_short_sleeved_outwear_train.json',\n        data_prefix=dict(img='train/image/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='validation/'\n        'deepfashion2_short_sleeved_outwear_validation.json',\n        data_prefix=dict(img='validation/image/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/README.md",
    "content": "# 2D Hand Pose Estimation\n\n2D hand pose estimation is defined as the task of detecting the poses (or keypoints) of the hand from an input image.\n\nNormally, the input images are cropped hand images, where the hand locates at the center;\nor the rough location (or the bounding box) of the hand is provided.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_hand_keypoint.md) to prepare data.\n\n## Demo\n\nPlease follow [Demo](/demo/docs/en/2d_hand_demo.md) to run demos.\n\n<img src=\"https://user-images.githubusercontent.com/11788150/109098558-8c54db00-775c-11eb-8966-85df96b23dc5.gif\" width=\"600px\" alt><br>\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187664103-cfbe0c4e-5876-42f9-9023-5fb58ce00d7b.jpg\" height=\"500px\" alt><br>\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/README.md",
    "content": "# RTMPose\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency.\nIn order to bridge this gap, we empirically study five aspects that affect the performance of multi-person pose estimation algorithms: paradigm, backbone network, localization algorithm, training strategy, and deployment inference, and present a high-performance real-time multi-person pose estimation framework, **RTMPose**, based on MMPose.\nOur RTMPose-m achieves **75.8% AP** on COCO with **90+ FPS** on an Intel i7-11700 CPU and **430+ FPS** on an NVIDIA GTX 1660 Ti GPU, and RTMPose-l achieves **67.0% AP** on COCO-WholeBody with **130+ FPS**, outperforming existing open-source libraries.\nTo further evaluate RTMPose's capability in critical real-time applications, we also report the performance after deploying on the mobile device.\n\n## Results and Models\n\n### COCO-WholeBody-Hand Dataset\n\nResults on COCO-WholeBody-Hand val set\n\n|   Model   | Input Size | PCK@0.2 |  AUC  | EPE  |                                  Details and Download                                  |\n| :-------: | :--------: | :-----: | :---: | :--: | :------------------------------------------------------------------------------------: |\n| RTMPose-m |  256x256   |  0.815  | 0.837 | 4.51 | [rtmpose_coco_wholebody_hand.md](./coco_wholebody_hand/rtmpose_coco_wholebody_hand.md) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/coco_wholebody_hand/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=21,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5],\n        rotate_factor=180),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=180),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/coco_wholebody_hand/rtmpose_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [rtmpose_m](/configs/hand_2d_keypoint/rtmpose/coco_wholebody_hand/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.815  | 0.837 | 4.51 | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody-hand_pt-aic-coco_210e-256x256-99477206_20230228.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody-hand_pt-aic-coco_210e-256x256-99477206_20230228.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/coco_wholebody_hand/rtmpose_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/rtmpose/coco_wholebody_hand/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture:\n    - RTMPose\n    Training Data: COCO-WholeBody-Hand\n  Name: rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.815\n      EPE: 4.51\n      PCK@0.2: 0.837\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody-hand_pt-aic-coco_210e-256x256-99477206_20230228.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# coco-hand onehand10k freihand2d rhd2d halpehand\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 10\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(256, 256),\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=21,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5],\n        rotate_factor=180),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=180),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_onehand10k = dict(\n    type='OneHand10KDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='onehand10k/annotations/onehand10k_train.json',\n    data_prefix=dict(img='pose/OneHand10K/'),\n    pipeline=[],\n)\n\ndataset_freihand = dict(\n    type='FreiHandDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='freihand/annotations/freihand_train.json',\n    data_prefix=dict(img='pose/FreiHand/'),\n    pipeline=[],\n)\n\ndataset_rhd = dict(\n    type='Rhd2DDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='rhd/annotations/rhd_train.json',\n    data_prefix=dict(img='pose/RHD/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=21,\n            mapping=[\n                (0, 0),\n                (1, 4),\n                (2, 3),\n                (3, 2),\n                (4, 1),\n                (5, 8),\n                (6, 7),\n                (7, 6),\n                (8, 5),\n                (9, 12),\n                (10, 11),\n                (11, 10),\n                (12, 9),\n                (13, 16),\n                (14, 15),\n                (15, 14),\n                (16, 13),\n                (17, 20),\n                (18, 19),\n                (19, 18),\n                (20, 17),\n            ])\n    ],\n)\n\ndataset_halpehand = dict(\n    type='HalpeHandDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015/'),\n    pipeline=[],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(\n            from_file='configs/_base_/datasets/coco_wholebody_hand.py'),\n        datasets=[\n            dataset_coco, dataset_onehand10k, dataset_freihand, dataset_rhd,\n            dataset_halpehand\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# test datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\nval_onehand10k = dict(\n    type='OneHand10KDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='onehand10k/annotations/onehand10k_test.json',\n    data_prefix=dict(img='pose/OneHand10K/'),\n    pipeline=[],\n)\n\nval_freihand = dict(\n    type='FreiHandDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='freihand/annotations/freihand_test.json',\n    data_prefix=dict(img='pose/FreiHand/'),\n    pipeline=[],\n)\n\nval_rhd = dict(\n    type='Rhd2DDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='rhd/annotations/rhd_test.json',\n    data_prefix=dict(img='pose/RHD/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=21,\n            mapping=[\n                (0, 0),\n                (1, 4),\n                (2, 3),\n                (3, 2),\n                (4, 1),\n                (5, 8),\n                (6, 7),\n                (7, 6),\n                (8, 5),\n                (9, 12),\n                (10, 11),\n                (11, 10),\n                (12, 9),\n                (13, 16),\n                (14, 15),\n                (15, 14),\n                (16, 13),\n                (17, 20),\n                (18, 19),\n                (19, 18),\n                (20, 17),\n            ])\n    ],\n)\n\nval_halpehand = dict(\n    type='HalpeHandDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[],\n)\n\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(\n            from_file='configs/_base_/datasets/coco_wholebody_hand.py'),\n        datasets=[\n            val_coco, val_onehand10k, val_freihand, val_rhd, val_halpehand\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\nval_dataloader = test_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/hand5/rtmpose_hand5.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n- `Hand5` and `*` denote model trained on 5 public datasets:\n  - [COCO-Wholebody-Hand](https://github.com/jin-s13/COCO-WholeBody/)\n  - [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\n  - [FreiHand2d](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\n  - [RHD2d](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n\n|                  Config                   | Input Size | PCK@0.2<sup><br>(COCO-Wholebody-Hand) | PCK@0.2<sup><br>(Hand5) | AUC<sup><br>(Hand5) | EPE<sup><br>(Hand5) | FLOPS(G) |                  Download                   |\n| :---------------------------------------: | :--------: | :-----------------------------------: | :---------------------: | :-----------------: | :-----------------: | :------: | :-----------------------------------------: |\n| [RTMPose-m\\*<sup><br>(alpha version)](./rtmpose/hand_2d_keypoint/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |                 81.5                  |          96.4           |        83.9         |        5.06         |  2.581   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/rtmpose/hand5/rtmpose_hand5.yml",
    "content": "Collections:\n- Name: RTMPose\n  Paper:\n    Title: \"RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\"\n    URL: https://arxiv.org/abs/2303.07399\n  README: https://github.com/open-mmlab/mmpose/blob/main/projects/rtmpose/README.md\nModels:\n- Config: configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py\n  In Collection: RTMPose\n  Alias: hand\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: &id002\n    - COCO-Wholebody-Hand\n    - OneHand10K\n    - FreiHand2d\n    - RHD2d\n    - Halpe\n  Name: rtmpose-m_8xb256-210e_hand5-256x256\n  Results:\n  - Dataset: Hand5\n    Metrics:\n      PCK@0.2: 0.964\n      AUC: 0.839\n      EPE: 5.06\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/README.md",
    "content": "# Top-down heatmap-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. Instead of estimating keypoint coordinates directly, the pose estimator will produce heatmaps which represent the likelihood of being a keypoint, following the paradigm introduced in [Simple Baselines for Human Pose Estimation and Tracking](http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\" height=400>\n</div>\n\n## Results and Models\n\n### COCO-WholeBody-Hand Dataset\n\nResults on COCO-WholeBody-Hand val set\n\n|      Model       | Input Size | PCK@0.2 |  AUC  | EPE  |                                       Details and Download                                       |\n| :--------------: | :--------: | :-----: | :---: | :--: | :----------------------------------------------------------------------------------------------: |\n| HRNetv2-w18+Dark |  256x256   |  0.814  | 0.840 | 4.37 | [hrnetv2_dark_coco_wholebody_hand.md](./coco_wholebody_hand/hrnetv2_dark_coco_wholebody_hand.md) |\n|   HRNetv2-w18    |  256x256   |  0.813  | 0.840 | 4.39 |      [hrnetv2_coco_wholebody_hand.md](./coco_wholebody_hand/hrnetv2_coco_wholebody_hand.md)      |\n|   HourglassNet   |  256x256   |  0.804  | 0.835 | 4.54 |    [hourglass_coco_wholebody_hand.md](./coco_wholebody_hand/hourglass_coco_wholebody_hand.md)    |\n|     SCNet-50     |  256x256   |  0.803  | 0.834 | 4.55 |        [scnet_coco_wholebody_hand.md](./coco_wholebody_hand/scnet_coco_wholebody_hand.md)        |\n|    ResNet-50     |  256x256   |  0.800  | 0.833 | 4.64 |       [resnet_coco_wholebody_hand.md](./coco_wholebody_hand/resnet_coco_wholebody_hand.md)       |\n|   LiteHRNet-18   |  256x256   |  0.795  | 0.830 | 4.77 |    [litehrnet_coco_wholebody_hand.md](./coco_wholebody_hand/litehrnet_coco_wholebody_hand.md)    |\n|   MobileNet-v2   |  256x256   |  0.795  | 0.829 | 4.77 |  [mobilenetv2_coco_wholebody_hand.md](./coco_wholebody_hand/mobilenetv2_coco_wholebody_hand.md)  |\n\n### FreiHand Dataset\n\nResults on FreiHand val & test set\n\n|   Model   | Input Size | PCK@0.2 |  AUC  | EPE  |                   Details and Download                    |\n| :-------: | :--------: | :-----: | :---: | :--: | :-------------------------------------------------------: |\n| ResNet-50 |  224x224   |  0.999  | 0.868 | 3.27 | [resnet_freihand2d.md](./freihand2d/resnet_freihand2d.md) |\n\n### OneHand10K Dataset\n\nResults on OneHand10K val set\n\n|      Model       | Input Size | PCK@0.2 |  AUC  |  EPE  |                         Details and Download                          |\n| :--------------: | :--------: | :-----: | :---: | :---: | :-------------------------------------------------------------------: |\n| HRNetv2-w18+Dark |  256x256   |  0.990  | 0.572 | 23.96 | [hrnetv2_dark_onehand10k.md](./onehand10k/hrnetv2_dark_onehand10k.md) |\n| HRNetv2-w18+UDP  |  256x256   |  0.990  | 0.571 | 23.88 |  [hrnetv2_udp_onehand10k.md](./onehand10k/hrnetv2_udp_onehand10k.md)  |\n|   HRNetv2-w18    |  256x256   |  0.990  | 0.567 | 24.26 |      [hrnetv2_onehand10k.md](./onehand10k/hrnetv2_onehand10k.md)      |\n|    ResNet-50     |  256x256   |  0.989  | 0.555 | 25.16 |       [resnet_onehand10k.md](./onehand10k/resnet_onehand10k.md)       |\n|   MobileNet-v2   |  256x256   |  0.986  | 0.537 | 28.56 |  [mobilenetv2_onehand10k.md](./onehand10k/mobilenetv2_onehand10k.md)  |\n\n### RHD Dataset\n\nResults on RHD test set\n\n|      Model       | Input Size | PCK@0.2 |  AUC  | EPE  |                  Details and Download                  |\n| :--------------: | :--------: | :-----: | :---: | :--: | :----------------------------------------------------: |\n| HRNetv2-w18+Dark |  256x256   |  0.992  | 0.903 | 2.18 | [hrnetv2_dark_rhd2d.md](./rhd2d/hrnetv2_dark_rhd2d.md) |\n| HRNetv2-w18+UDP  |  256x256   |  0.992  | 0.902 | 2.19 |  [hrnetv2_udp_rhd2d.md](./rhd2d/hrnetv2_udp_rhd2d.md)  |\n|   HRNetv2-w18    |  256x256   |  0.992  | 0.902 | 2.21 |      [hrnetv2_rhd2d.md](./rhd2d/hrnetv2_rhd2d.md)      |\n|    ResNet-50     |  256x256   |  0.991  | 0.898 | 2.32 |       [resnet_rhd2d.md](./rhd2d/resnet_rhd2d.md)       |\n|   MobileNet-v2   |  256x256   |  0.985  | 0.883 | 2.79 |  [mobilenetv2_rhd2d.md](./rhd2d/mobilenetv2_rhd2d.md)  |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hourglass_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\">Hourglass (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{newell2016stacked,\n  title={Stacked hourglass networks for human pose estimation},\n  author={Newell, Alejandro and Yang, Kaiyu and Deng, Jia},\n  booktitle={European conference on computer vision},\n  pages={483--499},\n  year={2016},\n  organization={Springer}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_hourglass_52](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hourglass52_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.804  | 0.835 | 4.54 | [ckpt](https://download.openmmlab.com/mmpose/hand/hourglass/hourglass52_coco_wholebody_hand_256x256-7b05c6db_20210909.pth) | [log](https://download.openmmlab.com/mmpose/hand/hourglass/hourglass52_coco_wholebody_hand_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hourglass_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hourglass52_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: Hourglass\n  Metadata:\n    Architecture:\n    - Hourglass\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_hourglass52_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.835\n      EPE: 4.54\n      PCK@0.2: 0.804\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/hourglass/hourglass52_coco_wholebody_hand_256x256-7b05c6db_20210909.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hrnetv2_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hrnetv2-w18_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.813  | 0.840 | 4.39 | [ckpt](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_coco_wholebody_hand_256x256-1c028db7_20210908.pth) | [log](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_coco_wholebody_hand_256x256_20210908.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hrnetv2_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hrnetv2-w18_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_hrnetv2-w18_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.84\n      EPE: 4.39\n      PCK@0.2: 0.813\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_coco_wholebody_hand_256x256-1c028db7_20210908.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hrnetv2_dark_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_hrnetv2_w18_dark](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hrnetv2-w18_dark-8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.814  | 0.840 | 4.37 | [ckpt](https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_coco_wholebody_hand_256x256_dark-a9228c9c_20210908.pth) | [log](https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_coco_wholebody_hand_256x256_dark_20210908.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hrnetv2_dark_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hrnetv2-w18_dark-8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - DarkPose\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_hrnetv2-w18_dark-8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.84\n      EPE: 4.37\n      PCK@0.2: 0.814\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_coco_wholebody_hand_256x256_dark-a9228c9c_20210908.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/litehrnet_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.06403\">LiteHRNet (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{Yulitehrnet21,\n  title={Lite-HRNet: A Lightweight High-Resolution Network},\n  author={Yu, Changqian and Xiao, Bin and Gao, Changxin and Yuan, Lu and Zhang, Lei and Sang, Nong and Wang, Jingdong},\n  booktitle={CVPR},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [LiteHRNet-18](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_litehrnet-w18_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.795  | 0.830 | 4.77 | [ckpt](https://download.openmmlab.com/mmpose/hand/litehrnet/litehrnet_w18_coco_wholebody_hand_256x256-d6945e6a_20210908.pth) | [log](https://download.openmmlab.com/mmpose/hand/litehrnet/litehrnet_w18_coco_wholebody_hand_256x256_20210908.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/litehrnet_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_litehrnet-w18_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: LiteHRNet\n  Metadata:\n    Architecture:\n    - LiteHRNet\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_litehrnet-w18_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.83\n      EPE: 4.77\n      PCK@0.2: 0.795\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/litehrnet/litehrnet_w18_coco_wholebody_hand_256x256-d6945e6a_20210908.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/mobilenetv2_coco_wholebody_hand.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n|                            Arch                            | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------: | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_mobilenetv2](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_mobilenetv2_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.795  | 0.829 | 4.77 | [ckpt](https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_coco_wholebody_hand_256x256-06b8c877_20210909.pth) | [log](https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_coco_wholebody_hand_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/mobilenetv2_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_mobilenetv2_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - MobilenetV2\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_mobilenetv2_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.829\n      EPE: 4.77\n      PCK@0.2: 0.795\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_coco_wholebody_hand_256x256-06b8c877_20210909.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/resnet_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n|                            Arch                            | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------: | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_resnet_50](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_res50_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.800  | 0.833 | 4.64 | [ckpt](https://download.openmmlab.com/mmpose/hand/resnet/res50_coco_wholebody_hand_256x256-8dbc750c_20210908.pth) | [log](https://download.openmmlab.com/mmpose/hand/resnet/res50_coco_wholebody_hand_256x256_20210908.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/resnet_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_res50_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_res50_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.833\n      EPE: 4.64\n      PCK@0.2: 0.8\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/resnet/res50_coco_wholebody_hand_256x256-8dbc750c_20210908.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/scnet_coco_wholebody_hand.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Liu_Improving_Convolutional_Networks_With_Self-Calibrated_Convolutions_CVPR_2020_paper.html\">SCNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020improving,\n  title={Improving Convolutional Networks with Self-Calibrated Convolutions},\n  author={Liu, Jiang-Jiang and Hou, Qibin and Cheng, Ming-Ming and Wang, Changhu and Feng, Jiashi},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={10096--10105},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody-Hand val set\n\n|                            Arch                            | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------: | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_scnet_50](/configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_scnet50_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |  0.803  | 0.834 | 4.55 | [ckpt](https://download.openmmlab.com/mmpose/hand/scnet/scnet50_coco_wholebody_hand_256x256-e73414c7_20210909.pth) | [log](https://download.openmmlab.com/mmpose/hand/scnet/scnet50_coco_wholebody_hand_256x256_20210909.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/scnet_coco_wholebody_hand.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_scnet50_8xb32-210e_coco-wholebody-hand-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SCNet\n    Training Data: COCO-WholeBody-Hand\n  Name: td-hm_scnet50_8xb32-210e_coco-wholebody-hand-256x256\n  Results:\n  - Dataset: COCO-WholeBody-Hand\n    Metrics:\n      AUC: 0.834\n      EPE: 4.55\n      PCK@0.2: 0.803\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/scnet/scnet50_coco_wholebody_hand_256x256-e73414c7_20210909.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hourglass52_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HourglassNet',\n        num_stacks=1,\n    ),\n    head=dict(\n        type='CPMHead',\n        in_channels=256,\n        out_channels=21,\n        num_stages=1,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=180.0,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hrnetv2-w18_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18')),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_hrnetv2-w18_dark-8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18')),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_litehrnet-w18_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='LiteHRNet',\n        in_channels=3,\n        extra=dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(2, 4, 2),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True,\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=40,\n        out_channels=21,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_mobilenetv2_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(type='Pretrained', checkpoint='mmcls://mobilenet_v2')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_res50_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/td-hm_scnet50_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='SCNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/scnet50-7ef0a199.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/freihand2d/resnet_freihand2d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Zimmermann_FreiHAND_A_Dataset_for_Markerless_Capture_of_Hand_Pose_and_ICCV_2019_paper.html\">FreiHand (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{zimmermann2019freihand,\n  title={Freihand: A dataset for markerless capture of hand pose and shape from single rgb images},\n  author={Zimmermann, Christian and Ceylan, Duygu and Yang, Jimei and Russell, Bryan and Argus, Max and Brox, Thomas},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={813--822},\n  year={2019}\n}\n```\n\n</details>\n\nResults on FreiHand val & test set\n\n| Set  |                           Arch                            | Input Size | PCK@0.2 |  AUC  | EPE  |                           ckpt                            |                           log                            |\n| :--- | :-------------------------------------------------------: | :--------: | :-----: | :---: | :--: | :-------------------------------------------------------: | :------------------------------------------------------: |\n| test | [pose_resnet_50](/configs/hand_2d_keypoint/topdown_heatmap/freihand2d/td-hm_res50_8xb64-100e_freihand2d-224x224.py) |  224x224   |  0.999  | 0.868 | 3.27 | [ckpt](https://download.openmmlab.com/mmpose/hand/resnet/res50_freihand_224x224-ff0799bc_20200914.pth) | [log](https://download.openmmlab.com/mmpose/hand/resnet/res50_freihand_224x224_20200914.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/freihand2d/resnet_freihand2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/freihand2d/td-hm_res50_8xb64-100e_freihand2d-224x224.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: FreiHand\n  Name: td-hm_res50_8xb64-100e_freihand2d-224x224\n  Results:\n  - Dataset: FreiHand\n    Metrics:\n      AUC: 0.868\n      EPE: 3.27\n      PCK@0.2: 0.999\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/resnet/res50_freihand_224x224-ff0799bc_20200914.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/freihand2d/td-hm_res50_8xb64-100e_freihand2d-224x224.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=100, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=100,\n        milestones=[50, 70],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', interval=1))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(224, 224), heatmap_size=(56, 56), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'FreiHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/freihand/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.25,\n        rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=0.8),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/freihand_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/freihand_val.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/freihand_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_dark_onehand10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on OneHand10K val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  |  EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :---: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [pose_hrnetv2_w18_dark](/configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_dark-8xb64-210e_onehand10k-256x256.py) |  256x256   |  0.990  | 0.572 | 23.96 | [ckpt](https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_onehand10k_256x256_dark-a2f80c64_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_onehand10k_256x256_dark_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_dark_onehand10k.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_dark-8xb64-210e_onehand10k-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - DarkPose\n    Training Data: OneHand10K\n  Name: td-hm_hrnetv2-w18_dark-8xb64-210e_onehand10k-256x256\n  Results:\n  - Dataset: OneHand10K\n    Metrics:\n      AUC: 0.572\n      EPE: 23.96\n      PCK@0.2: 0.99\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_onehand10k_256x256_dark-a2f80c64_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_onehand10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on OneHand10K val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  |  EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :---: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256.py) |  256x256   |  0.990  | 0.567 | 24.26 | [ckpt](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_onehand10k_256x256-30bc9c6b_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_onehand10k_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_onehand10k.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: OneHand10K\n  Name: td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256\n  Results:\n  - Dataset: OneHand10K\n    Metrics:\n      AUC: 0.567\n      EPE: 24.26\n      PCK@0.2: 0.99\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_onehand10k_256x256-30bc9c6b_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_udp_onehand10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on OneHand10K val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  |  EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :---: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [pose_hrnetv2_w18_udp](/configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py) |  256x256   |  0.990  | 0.571 | 23.88 | [ckpt](https://download.openmmlab.com/mmpose/hand/udp/hrnetv2_w18_onehand10k_256x256_udp-0d1b515d_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/udp/hrnetv2_w18_onehand10k_256x256_udp_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_udp_onehand10k.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py\n  In Collection: UDP\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - UDP\n    Training Data: OneHand10K\n  Name: td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256\n  Results:\n  - Dataset: OneHand10K\n    Metrics:\n      AUC: 0.571\n      EPE: 23.88\n      PCK@0.2: 0.99\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/udp/hrnetv2_w18_onehand10k_256x256_udp-0d1b515d_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/mobilenetv2_onehand10k.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on OneHand10K val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  |  EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :---: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [pose_mobilenet_v2](/configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_mobilenetv2_8xb64-210e_onehand10k-256x256.py) |  256x256   |  0.986  | 0.537 | 28.56 | [ckpt](https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_onehand10k_256x256-f3a3d90e_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_onehand10k_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/mobilenetv2_onehand10k.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_mobilenetv2_8xb64-210e_onehand10k-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - MobilenetV2\n    Training Data: OneHand10K\n  Name: td-hm_mobilenetv2_8xb64-210e_onehand10k-256x256\n  Results:\n  - Dataset: OneHand10K\n    Metrics:\n      AUC: 0.537\n      EPE: 28.56\n      PCK@0.2: 0.986\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_onehand10k_256x256-f3a3d90e_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/resnet_onehand10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on OneHand10K val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  |  EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :---: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [pose_resnet_50](/configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_res50_8xb32-210e_onehand10k-256x256.py) |  256x256   |  0.989  | 0.555 | 25.16 | [ckpt](https://download.openmmlab.com/mmpose/hand/resnet/res50_onehand10k_256x256-739c8639_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/resnet/res50_onehand10k_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/resnet_onehand10k.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_res50_8xb32-210e_onehand10k-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: OneHand10K\n  Name: td-hm_res50_8xb32-210e_onehand10k-256x256\n  Results:\n  - Dataset: OneHand10K\n    Metrics:\n      AUC: 0.555\n      EPE: 25.16\n      PCK@0.2: 0.989\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/resnet/res50_onehand10k_256x256-739c8639_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='open-mmlab://msra/hrnetv2_w18',\n        )),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'OneHand10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/onehand10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_dark-8xb64-210e_onehand10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='open-mmlab://msra/hrnetv2_w18',\n        )),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'OneHand10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/onehand10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_udp-8xb64-210e_onehand10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='open-mmlab://msra/hrnetv2_w18',\n        )),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'OneHand10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/onehand10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_mobilenetv2_8xb64-210e_onehand10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='mmcls://mobilenet_v2',\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'OneHand10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/onehand10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_res50_8xb32-210e_onehand10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='torchvision://resnet50',\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'OneHand10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/onehand10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_dark_rhd2d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\nResults on RHD test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_hrnetv2_w18_dark](/configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_dark-8xb64-210e_rhd2d-256x256.py) |  256x256   |  0.992  | 0.903 | 2.18 | [ckpt](https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_rhd2d_256x256_dark-4df3a347_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_rhd2d_256x256_dark_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_dark_rhd2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_dark-8xb64-210e_rhd2d-256x256.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - DarkPose\n    Training Data: RHD\n  Name: td-hm_hrnetv2-w18_dark-8xb64-210e_rhd2d-256x256\n  Results:\n  - Dataset: RHD\n    Metrics:\n      AUC: 0.903\n      EPE: 2.18\n      PCK@0.2: 0.992\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/dark/hrnetv2_w18_rhd2d_256x256_dark-4df3a347_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_rhd2d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\nResults on RHD test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_hrnetv2_w18](/configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_8xb64-210e_rhd2d-256x256.py) |  256x256   |  0.992  | 0.902 | 2.21 | [ckpt](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_rhd2d_256x256-95b20dd8_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_rhd2d_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_rhd2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_8xb64-210e_rhd2d-256x256.py\n  In Collection: HRNetv2\n  Metadata:\n    Architecture:\n    - HRNetv2\n    Training Data: RHD\n  Name: td-hm_hrnetv2-w18_8xb64-210e_rhd2d-256x256\n  Results:\n  - Dataset: RHD\n    Metrics:\n      AUC: 0.902\n      EPE: 2.21\n      PCK@0.2: 0.992\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_rhd2d_256x256-95b20dd8_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_udp_rhd2d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\nResults on RHD test set\n\n| Arch                                                       | Input Size | PCKh@0.7 |  AUC  | EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :------: | :---: | :--: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [pose_hrnetv2_w18_udp](/configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_udp-8xb64-210e_rhd2d-256x256.py) |  256x256   |  0.992   | 0.902 | 2.19 | [ckpt](https://download.openmmlab.com/mmpose/hand/udp/hrnetv2_w18_rhd2d_256x256_udp-63ba6007_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/udp/hrnetv2_w18_rhd2d_256x256_udp_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_udp_rhd2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_udp-8xb64-210e_rhd2d-256x256.py\n  In Collection: UDP\n  Metadata:\n    Architecture:\n    - HRNetv2\n    - UDP\n    Training Data: RHD\n  Name: td-hm_hrnetv2-w18_udp-8xb64-210e_rhd2d-256x256\n  Results:\n  - Dataset: RHD\n    Metrics:\n      AUC: 0.902\n      EPE: 2.19\n      PCKh@0.7: 0.992\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/udp/hrnetv2_w18_rhd2d_256x256_udp-63ba6007_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/mobilenetv2_rhd2d.md",
    "content": "<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\nResults on RHD test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_mobilenet_v2](/configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_mobilenetv2_8xb64-210e_rhd2d-256x256.py) |  256x256   |  0.985  | 0.883 | 2.79 | [ckpt](https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_rhd2d_256x256-85fa02db_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_rhd2d_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/mobilenetv2_rhd2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_mobilenetv2_8xb64-210e_rhd2d-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - MobilenetV2\n    Training Data: RHD\n  Name: td-hm_mobilenetv2_8xb64-210e_rhd2d-256x256\n  Results:\n  - Dataset: RHD\n    Metrics:\n      AUC: 0.883\n      EPE: 2.79\n      PCK@0.2: 0.985\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/mobilenetv2/mobilenetv2_rhd2d_256x256-85fa02db_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/resnet_rhd2d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\nResults on RHD test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [pose_resnet50](/configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_res50_8xb64-210e_rhd2d-256x256.py) |  256x256   |  0.991  | 0.898 | 2.32 | [ckpt](https://download.openmmlab.com/mmpose/hand/resnet/res50_rhd2d_256x256-5dc7e4cc_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/resnet/res50_rhd2d_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/resnet_rhd2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_res50_8xb64-210e_rhd2d-256x256.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture:\n    - SimpleBaseline2D\n    - ResNet\n    Training Data: RHD\n  Name: td-hm_res50_8xb64-210e_rhd2d-256x256\n  Results:\n  - Dataset: RHD\n    Metrics:\n      AUC: 0.898\n      EPE: 2.32\n      PCK@0.2: 0.991\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/resnet/res50_rhd2d_256x256-5dc7e4cc_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_8xb64-210e_rhd2d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='open-mmlab://msra/hrnetv2_w18',\n        )),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Rhd2DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/rhd/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_dark-8xb64-210e_rhd2d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(256, 256),\n    heatmap_size=(64, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='open-mmlab://msra/hrnetv2_w18',\n        )),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Rhd2DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/rhd/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_hrnetv2-w18_udp-8xb64-210e_rhd2d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='open-mmlab://msra/hrnetv2_w18',\n        )),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=270,\n        out_channels=21,\n        deconv_out_channels=None,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'Rhd2DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/rhd/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_mobilenetv2_8xb64-210e_rhd2d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='MobileNetV2',\n        widen_factor=1.,\n        out_indices=(7, ),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='mmcls://mobilenet_v2',\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1280,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Rhd2DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/rhd/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_heatmap/rhd2d/td-hm_res50_8xb64-210e_rhd2d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='torchvision://resnet50',\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=21,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Rhd2DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/rhd/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/README.md",
    "content": "# Top-down regression-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. At the 2nd stage, regression based methods directly regress the keypoint coordinates given the features extracted from the bounding box area, following the paradigm introduced in [Deeppose: Human pose estimation via deep neural networks](http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515040-a82a8a29-d6bc-42f1-a2ab-7dfa610ce363.png\">\n</div>\n\n## Results and Models\n\n### OneHand10K Dataset\n\nResults on OneHand10K val set\n\n|   Model   | Input Size | PCK@0.2 |  AUC  |  EPE  |                   Details and Download                    |\n| :-------: | :--------: | :-----: | :---: | :---: | :-------------------------------------------------------: |\n| ResNet-50 |  256x256   |  0.990  | 0.485 | 34.21 | [resnet_onehand10k.md](./onehand10k/resnet_onehand10k.md) |\n\n### RHD Dataset\n\nResults on RHD test set\n\n|   Model   | Input Size | PCK@0.2 |  AUC  | EPE  |            Details and Download            |\n| :-------: | :--------: | :-----: | :---: | :--: | :----------------------------------------: |\n| ResNet-50 |  256x256   |  0.988  | 0.865 | 3.32 | [resnet_rhd2d.md](./rhd2d/resnet_rhd2d.md) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/onehand10k/resnet_onehand10k.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\nResults on OneHand10K val set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  |  EPE  |                            ckpt                            |                            log                            |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :---: | :--------------------------------------------------------: | :-------------------------------------------------------: |\n| [deeppose_resnet_50](/configs/hand_2d_keypoint/topdown_regression/onehand10k/td-reg_res50_8xb64-210e_onehand10k-256x256.py) |  256x256   |  0.990  | 0.485 | 34.21 | [ckpt](https://download.openmmlab.com/mmpose/hand/deeppose/deeppose_res50_onehand10k_256x256-cbddf43a_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/deeppose/deeppose_res50_onehand10k_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/onehand10k/resnet_onehand10k.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_regression/onehand10k/td-reg_res50_8xb64-210e_onehand10k-256x256.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture:\n    - DeepPose\n    - ResNet\n    Training Data: OneHand10K\n  Name: td-reg_res50_8xb64-210e_onehand10k-256x256\n  Results:\n  - Dataset: OneHand10K\n    Metrics:\n      AUC: 0.485\n      EPE: 34.21\n      PCK@0.2: 0.99\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/deeppose/deeppose_res50_onehand10k_256x256-cbddf43a_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/onehand10k/td-reg_res50_8xb64-210e_onehand10k-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=21,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'OneHand10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/onehand10k/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/onehand10k_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/rhd2d/resnet_rhd2d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\nResults on RHD test set\n\n| Arch                                                       | Input Size | PCK@0.2 |  AUC  | EPE  |                            ckpt                            |                            log                             |\n| :--------------------------------------------------------- | :--------: | :-----: | :---: | :--: | :--------------------------------------------------------: | :--------------------------------------------------------: |\n| [deeppose_resnet_50](/configs/hand_2d_keypoint/topdown_regression/rhd2d/td-reg_res50_8xb64-210e_rhd2d-256x256.py) |  256x256   |  0.988  | 0.865 | 3.32 | [ckpt](https://download.openmmlab.com/mmpose/hand/deeppose/deeppose_res50_rhd2d_256x256-37f1c4d3_20210330.pth) | [log](https://download.openmmlab.com/mmpose/hand/deeppose/deeppose_res50_rhd2d_256x256_20210330.log.json) |\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/rhd2d/resnet_rhd2d.yml",
    "content": "Models:\n- Config: configs/hand_2d_keypoint/topdown_regression/rhd2d/td-reg_res50_8xb64-210e_rhd2d-256x256.py\n  In Collection: DeepPose\n  Metadata:\n    Architecture:\n    - DeepPose\n    - ResNet\n    Training Data: RHD\n  Name: td-reg_res50_8xb64-210e_rhd2d-256x256\n  Results:\n  - Dataset: RHD\n    Metrics:\n      AUC: 0.865\n      EPE: 3.32\n      PCK@0.2: 0.988\n    Task: Hand 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand/deeppose/deeppose_res50_rhd2d_256x256-37f1c4d3_20210330.pth\n"
  },
  {
    "path": "configs/hand_2d_keypoint/topdown_regression/rhd2d/td-reg_res50_8xb64-210e_rhd2d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='AUC', rule='greater'))\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(256, 256))\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RegressionHead',\n        in_channels=2048,\n        num_joints=21,\n        loss=dict(type='SmoothL1Loss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'Rhd2DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/rhd/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='RandomBBoxTransform', rotate_factor=180,\n        scale_factor=(0.7, 1.3)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_train.json',\n        data_prefix=dict(img=''),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/rhd_test.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE'),\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_3d_keypoint/README.md",
    "content": "# 3D Hand Pose Estimation\n\n3D hand pose estimation is defined as the task of detecting the poses (or keypoints) of the hand from an input image.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/3d_hand_keypoint.md) to prepare data.\n"
  },
  {
    "path": "configs/hand_3d_keypoint/internet/README.md",
    "content": "# InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image\n\n## Results and Models\n\n### InterHand2.6m 3D Dataset\n\n| Arch                             |    Set    | MPJPE-single | MPJPE-interacting | MPJPE-all | MRRPE | APh  |               ckpt               |               log               |               Details and Download                |\n| :------------------------------- | :-------: | :----------: | :---------------: | :-------: | :---: | :--: | :------------------------------: | :-----------------------------: | :-----------------------------------------------: |\n| [InterNet_resnet_50](/configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py) | test(H+M) |     9.47     |       13.40       |   11.59   | 29.28 | 0.99 | [ckpt](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth) | [log](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256_20210702.log.json) | [internet_interhand3d.md](./interhand3d/internet_interhand3d.md) |\n| [InterNet_resnet_50](/configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py) |  val(M)   |    11.22     |       15.23       |   13.16   | 31.73 | 0.98 | [ckpt](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth) | [log](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256_20210702.log.json) | [internet_interhand3d.md](./interhand3d/internet_interhand3d.md) |\n"
  },
  {
    "path": "configs/hand_3d_keypoint/internet/interhand3d/internet_interhand3d.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterNet (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterHand2.6M (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\nResults on InterHand2.6M val & test set\n\n| Train Set | Set       |                    Arch                    | Input Size | MPJPE-single | MPJPE-interacting | MPJPE-all | MRRPE | APh  |                    ckpt                    |                    log                    |\n| :-------- | :-------- | :----------------------------------------: | :--------: | :----------: | :---------------: | :-------: | :---: | :--: | :----------------------------------------: | :---------------------------------------: |\n| All       | test(H+M) | [InterNet_resnet_50](/configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py) |  256x256   |     9.69     |       13.72       |   11.86   | 29.27 | 0.99 | [ckpt](https://download.openmmlab.com/mmpose/v1/hand_3d_keypoint/internet/interhand3d/internet_res50_interhand3d-d6ff20d6_20230913.pth) | [log](https://download.openmmlab.com/mmpose/v1/hand_3d_keypoint/internet/interhand3d/internet_res50_interhand3d-d6ff20d6_20230913.json) |\n| All       | val(M)    | [InterNet_resnet_50](/configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py) |  256x256   |    11.30     |       15.57       |   13.36   | 32.15 | 0.98 | [ckpt](https://download.openmmlab.com/mmpose/v1/hand_3d_keypoint/internet/interhand3d/internet_res50_interhand3d-d6ff20d6_20230913.pth) | [log](https://download.openmmlab.com/mmpose/v1/hand_3d_keypoint/internet/interhand3d/internet_res50_interhand3d-d6ff20d6_20230913.json) |\n| All       | test(H+M) | [InterNet_resnet_50\\*](/configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py) |  256x256   |     9.47     |       13.40       |   11.59   | 29.28 | 0.99 | [ckpt](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth) | [log](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256_20210702.log.json) |\n| All       | val(M)    | [InterNet_resnet_50\\*](/configs/hand/3d_kpt_sview_rgb_img/internet/interhand3d/res50_interhand3d_all_256x256.py) |  256x256   |    11.22     |       15.23       |   13.16   | 31.73 | 0.98 | [ckpt](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth) | [log](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256_20210702.log.json) |\n\n*Models with * are trained in [MMPose 0.x](https://github.com/open-mmlab/mmpose/tree/0.x). The checkpoints and logs are only for validation.*\n"
  },
  {
    "path": "configs/hand_3d_keypoint/internet/interhand3d/internet_interhand3d.yml",
    "content": "Collections:\n- Name: InterNet\n  Paper:\n    Title: 'InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation\n      from a Single RGB Image'\n    URL: https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\n  README: https://github.com/open-mmlab/mmpose/blob/master/docs/en/papers/algorithms/internet.md\nModels:\n- Config: configs/hand_3d_keypoint/internet/interhand3d/internet_res50_4xb16-20e_interhand3d-256x256.py\n  In Collection: InterNet\n  Alias: hand3d\n  Metadata:\n    Architecture: &id001\n    - InterNet\n    - ResNet\n    Training Data: InterHand2.6M\n  Name: internet_res50_4xb16-20e_interhand3d-256x256\n  Results:\n  - Dataset: InterHand2.6M (H+M)\n    Metrics:\n      APh: 0.99\n      MPJPE-all: 11.86\n      MPJPE-interacting: 13.72\n      MPJPE-single: 9.69\n      MRRPE: 29.27\n    Task: Hand 3D Keypoint\n  - Dataset: InterHand2.6M (M)\n    Metrics:\n      APh: 0.98\n      MPJPE-all: 13.36\n      MPJPE-interacting: 15.57\n      MPJPE-single: 11.30\n      MRRPE: 32.15\n    Task: Hand 3D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth\n"
  },
  {
    "path": "configs/hand_3d_keypoint/internet/interhand3d/internet_res50_4xb16-20e_interhand3d-256x256.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# visualization\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\ntrain_cfg = dict(max_epochs=20, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=0.0002))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=20,\n        milestones=[15, 17],\n        gamma=0.1,\n        by_epoch=True)\n]\n\nauto_scale_lr = dict(base_batch_size=128)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        interval=1,\n        save_best='MPJPE_all',\n        rule='less',\n        max_keep_ckpts=1),\n    logger=dict(type='LoggerHook', interval=20),\n)\n\n# codec settings\ncodec = dict(\n    type='Hand3DHeatmap',\n    image_size=[256, 256],\n    root_heatmap_size=64,\n    heatmap_size=[64, 64, 64],\n    sigma=2.5,\n    max_bound=255,\n    depth_size=64)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),\n    head=dict(\n        type='InternetHead',\n        keypoint_head_cfg=dict(\n            in_channels=2048,\n            out_channels=21 * 64,\n            depth_size=codec['depth_size'],\n            deconv_out_channels=(256, 256, 256),\n            deconv_kernel_sizes=(4, 4, 4),\n        ),\n        root_head_cfg=dict(\n            in_channels=2048,\n            heatmap_size=codec['root_heatmap_size'],\n            hidden_dims=(512, ),\n        ),\n        hand_type_head_cfg=dict(\n            in_channels=2048,\n            num_labels=2,\n            hidden_dims=(512, ),\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=False))\n\n# base dataset settings\ndataset_type = 'InterHand3DDataset'\ndata_mode = 'topdown'\ndata_root = 'data/interhand2.6m/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='HandRandomFlip', prob=0.5),\n    dict(type='RandomBBoxTransform', rotate_factor=90.0),\n    dict(type='TopdownAffine', input_size=codec['image_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'rotation', 'img_shape',\n                   'focal', 'principal_pt', 'input_size', 'input_center',\n                   'input_scale', 'hand_type', 'hand_type_valid', 'flip',\n                   'flip_indices', 'abs_depth'))\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['image_size']),\n    dict(\n        type='PackPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'rotation', 'img_shape',\n                   'focal', 'principal_pt', 'input_size', 'input_center',\n                   'input_scale', 'hand_type', 'hand_type_valid', 'flip',\n                   'flip_indices', 'abs_depth'))\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotations/all/InterHand2.6M_train_data.json',\n        camera_param_file='annotations/all/InterHand2.6M_train_camera.json',\n        joint_file='annotations/all/InterHand2.6M_train_joint_3d.json',\n        use_gt_root_depth=True,\n        rootnet_result_file=None,\n        data_mode=data_mode,\n        data_root=data_root,\n        data_prefix=dict(img='images/train/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=16,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotations/machine_annot/InterHand2.6M_val_data.json',\n        camera_param_file='annotations/machine_annot/'\n        'InterHand2.6M_val_camera.json',\n        joint_file='annotations/machine_annot/InterHand2.6M_val_joint_3d.json',\n        use_gt_root_depth=True,\n        rootnet_result_file=None,\n        data_mode=data_mode,\n        data_root=data_root,\n        data_prefix=dict(img='images/val/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\ntest_dataloader = dict(\n    batch_size=16,\n    num_workers=1,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        ann_file='annotations/all/'\n        'InterHand2.6M_test_data.json',\n        camera_param_file='annotations/all/'\n        'InterHand2.6M_test_camera.json',\n        joint_file='annotations/all/'\n        'InterHand2.6M_test_joint_3d.json',\n        use_gt_root_depth=True,\n        rootnet_result_file=None,\n        data_mode=data_mode,\n        data_root=data_root,\n        data_prefix=dict(img='images/test/'),\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\n# evaluators\nval_evaluator = [\n    dict(type='InterHandMetric', modes=['MPJPE', 'MRRPE', 'HandednessAcc'])\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/hand_gesture/README.md",
    "content": "# Gesture Recognition\n\nGesture recognition aims to recognize the hand gestures in the video, such as thumbs up.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_hand_gesture.md) to prepare data.\n\n## Demo\n\nPlease follow [Demo](/demo/docs/en/gesture_recognition_demo.md) to run the demo.\n\n<img src=\"https://user-images.githubusercontent.com/15977946/172213082-afb9d71a-f2df-4509-932c-e47dc61ec7d7.gif\" width=\"600px\" alt>\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/README.md",
    "content": "# 2D Human Whole-Body Pose Estimation\n\n2D human whole-body pose estimation aims to localize dense landmarks on the entire human body including face, hands, body, and feet.\n\nExisting approaches can be categorized into top-down and bottom-up approaches.\n\nTop-down methods divide the task into two stages: human detection and whole-body pose estimation. They perform human detection first, followed by single-person whole-body pose estimation given human bounding boxes.\n\nBottom-up approaches (e.g. AE) first detect all the whole-body keypoints and then group/associate them into person instances.\n\n## Data preparation\n\nPlease follow [DATA Preparation](/docs/en/dataset_zoo/2d_wholebody_keypoint.md) to prepare data.\n\n## Demo\n\nPlease follow [Demo](/demo/docs/en/2d_wholebody_pose_demo.md) to run demos.\n\n<img src=\"https://user-images.githubusercontent.com/9464825/95552839-00a61080-0a40-11eb-818c-b8dad7307217.gif\" width=\"600px\" alt><br>\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/README.md",
    "content": "# DWPose\n\nWhole-body pose estimation localizes the human body, hand, face, and foot keypoints in an image. This task is challenging due to multi-scale body parts, fine-grained localization for low-resolution regions, and data scarcity. Meanwhile, applying a highly efficient and accurate pose estimator to widely human-centric understanding and generation tasks is urgent. In this work, we present a two-stage pose **D**istillation for **W**hole-body **P**ose estimators, named **DWPose**, to improve their effectiveness and efficiency. The first-stage distillation designs a weight-decay strategy while utilizing a teacher's intermediate feature and final logits with both visible and invisible keypoints to supervise the student from scratch. The second stage distills the student model itself to further improve performance. Different from the previous self-knowledge distillation, this stage finetunes the student's head with only 20% training time as a plug-and-play training strategy. For data limitations, we explore the UBody dataset that contains diverse facial expressions and hand gestures for real-life applications. Comprehensive experiments show the superiority of our proposed simple yet effective methods. We achieve new state-of-the-art performance on COCO-WholeBody, significantly boosting the whole-body AP of RTMPose-l from 64.8% to 66.5%, even surpassing RTMPose-x teacher with 65.3% AP. We release a series of models with different sizes, from tiny to large, for satisfying various downstream tasks.\n\n## Results and Models\n\n### COCO-WholeBody Dataset\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n- DWPose Models are supported by [DWPose](https://github.com/IDEA-Research/DWPose)\n- Models are trained and distilled on the following datasets:\n  - [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/)\n  - [UBody](https://github.com/IDEA-Research/OSX)\n\n| Config       |    S1 Dis_config    |    S2 Dis_config    | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |    Download    |\n| :----------- | :-----------------: | :-----------------: | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :------------: |\n| [DWPose-t](../rtmpose/ubody/rtmpose-t_8xb64-270e_coco-ubody-wholebody-256x192.py) | [DW l-t](../dwpose/ubody/s1_dis/dwpose_l_dis_t_coco-ubody-256x192.py) | [DW t-t](../dwpose/ubody/s2_dis/dwpose_t-tt_coco-ubody-256x192.py) |  256x192   |   48.5   |   58.4   |        0.5        |                      -                      |                         -                          | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-ucoco_dw-ucoco_270e-256x192-dcf277bf_20230728.pth) |\n| [DWPose-s](../rtmpose/ubody/rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py) | [DW l-s](../dwpose/ubody/s1_dis/dwpose_l_dis_s_coco-ubody-256x192.py) | [DW s-s](../dwpose/ubody/s2_dis/dwpose_s-ss_coco-ubody-256x192.py) |  256x192   |   53.8   |   63.2   |        0.9        |                      -                      |                         -                          | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-ucoco_dw-ucoco_270e-256x192-3fd922c8_20230728.pth) |\n| [DWPose-m](../rtmpose/ubody/rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py) | [DW l-m](../dwpose/ubody/s1_dis/dwpose_l_dis_m_coco-ubody-256x192.py) | [DW m-m](../dwpose/ubody/s2_dis/dwpose_m-mm_coco-ubody-256x192.py) |  256x192   |   60.6   |   69.5   |       2.22        |                    13.50                    |                        4.00                        | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.pth) |\n| [DWPose-l](../rtmpose/ubody/rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py) | [DW x-l](../dwpose/ubody/s1_dis/dwpose_x_dis_l_coco-ubody-256x192.py) | [DW l-l](../dwpose/ubody/s2_dis/dwpose_l-ll_coco-ubody-256x192.py) |  256x192   |   63.1   |   71.7   |       4.52        |                    23.41                    |                        5.67                        | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth) |\n| [DWPose-l](../rtmpose/ubody/rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py) | [DW x-l](../dwpose/ubody/s1_dis/dwpose_x_dis_l_coco-ubody-384x288.py) | [DW l-l](../dwpose/ubody/s2_dis/dwpose_l-ll_coco-ubody-384x288.py) |  384x288   |   66.5   |   74.3   |       10.07       |                    44.58                    |                        7.68                        | [Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.pth) |\n\n## Train a model\n\n### Train DWPose with the first stage distillation\n\n```\nbash tools/dist_train.sh configs/wholebody_2d_keypoint/dwpose/ubody/s1_dis/rtmpose_x_dis_l_coco-ubody-384x288.py 8\n```\n\n### Tansfer the S1 distillation models into regular models\n\n```\n# first stage distillation\npython pth_transfer.py $dis_ckpt $new_pose_ckpt\n```\n\n⭐Before S2 distillation, you should add your model path into 'teacher_pretrained' of your S2 dis_config.\n\n### Train DWPose with the second stage distillation\n\n```\nbash tools/dist_train.sh configs/wholebody_2d_keypoint/dwpose/ubody/s2_dis/dwpose_l-ll_coco-ubody-384x288.py 8\n```\n\n### Tansfer the S2 distillation models into regular models\n\n```\n# second stage distillation\npython pth_transfer.py $dis_ckpt $new_pose_ckpt --two_dis\n```\n\n## Citation\n\n```\n@article{yang2023effective,\n  title={Effective Whole-body Pose Estimation with Two-stages Distillation},\n  author={Yang, Zhendong and Zeng, Ailing and Yuan, Chun and Li, Yu},\n  journal={arXiv preprint arXiv:2307.15880},\n  year={2023}\n}\n```\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/coco-wholebody/s1_dis/dwpose_l_dis_m_coco-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/coco-wholebody/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmpose/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-256x192-6f206314_20230124.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-l_8xb64-270e_coco-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-m_8xb64-270e_coco-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=768,\n                teacher_channels=1024,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/coco-wholebody/s1_dis/dwpose_x_dis_l_coco-384x288.py",
    "content": "_base_ = [\n    '../../../rtmpose/coco-wholebody/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmposev1/rtmpose-x_simcc-coco-wholebody_pt-body7_270e-384x288-401dfc90_20230629.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-x_8xb32-270e_coco-wholebody-384x288.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-l_8xb32-270e_coco-wholebody-384x288.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=1024,\n                teacher_channels=1280,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/coco-wholebody/s2_dis/dwpose_l-ll_coco-384x288.py",
    "content": "_base_ = [\n    '../../../rtmpose/coco-wholebody/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_x_dis_l_coco-384x288/dw-x-l_coco_384.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-l_8xb32-270e_coco-wholebody-384x288.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-l_8xb32-270e_coco-wholebody-384x288.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/coco-wholebody/s2_dis/dwpose_m-mm_coco-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/coco-wholebody/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_l_dis_m_coco-256x192/dw-l-m_coco_256.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-m_8xb64-270e_coco-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/'\n    'rtmpose-m_8xb64-270e_coco-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s1_dis/dwpose_l_dis_m_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmposev1/rtmpose-l_ucoco_256x192-95bb32f5_20230822.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=768,\n                teacher_channels=1024,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s1_dis/dwpose_l_dis_s_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmposev1/rtmpose-l_ucoco_256x192-95bb32f5_20230822.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=512,\n                teacher_channels=1024,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s1_dis/dwpose_l_dis_t_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmposev1/rtmpose-l_ucoco_256x192-95bb32f5_20230822.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-t_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=384,\n                teacher_channels=1024,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s1_dis/dwpose_x_dis_l_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmposev1/rtmpose-x_ucoco_256x192-05f5bcb7_20230822.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-x_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=1024,\n                teacher_channels=1280,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s1_dis/rtmpose_x_dis_l_coco-ubody-384x288.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = False\n\n# config settings\nfea = True\nlogit = True\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    teacher_pretrained='https://download.openmmlab.com/mmpose/v1/projects/'\n    'rtmposev1/rtmpose-x_ucoco_384x288-f5b50679_20230822.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-x_8xb32-270e_coco-ubody-wholebody-384x288.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='FeaLoss',\n                name='loss_fea',\n                use_this=fea,\n                student_channels=1024,\n                teacher_channels=1280,\n                alpha_fea=0.00007,\n            )\n        ]),\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=0.1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n)\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s2_dis/dwpose_l-ll_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_x_dis_l_coco-ubody-256x192/dw-x-l_ucoco_256.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s2_dis/dwpose_l-ll_coco-ubody-384x288.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_x_dis_l_coco-ubody-384x288/dw-x-l_ucoco_384.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s2_dis/dwpose_m-mm_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_l_dis_m_coco-ubody-256x192/dw-l-m_ucoco_256.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s2_dis/dwpose_s-ss_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_l_dis_s_coco-ubody-256x192/dw-l-s_ucoco_256.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/dwpose/ubody/s2_dis/dwpose_t-tt_coco-ubody-256x192.py",
    "content": "_base_ = [\n    '../../../rtmpose/ubody/rtmpose-t_8xb64-270e_coco-ubody-wholebody-256x192.py'  # noqa: E501\n]\n\n# model settings\nfind_unused_parameters = True\n\n# dis settings\nsecond_dis = True\n\n# config settings\nlogit = True\n\ntrain_cfg = dict(max_epochs=60, val_interval=10)\n\n# method details\nmodel = dict(\n    _delete_=True,\n    type='DWPoseDistiller',\n    two_dis=second_dis,\n    teacher_pretrained='work_dirs/'\n    'dwpose_l_dis_t_coco-ubody-256x192/dw-l-t_ucoco_256.pth',  # noqa: E501\n    teacher_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-t_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    student_cfg='configs/wholebody_2d_keypoint/rtmpose/ubody/'\n    'rtmpose-t_8xb64-270e_coco-ubody-wholebody-256x192.py',  # noqa: E501\n    distill_cfg=[\n        dict(methods=[\n            dict(\n                type='KDLoss',\n                name='loss_logit',\n                use_this=logit,\n                weight=1,\n            )\n        ]),\n    ],\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    train_cfg=train_cfg,\n)\n\noptim_wrapper = dict(clip_grad=dict(max_norm=1., norm_type=2))\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/README.md",
    "content": "# RTMPose\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency.\nIn order to bridge this gap, we empirically study five aspects that affect the performance of multi-person pose estimation algorithms: paradigm, backbone network, localization algorithm, training strategy, and deployment inference, and present a high-performance real-time multi-person pose estimation framework, **RTMPose**, based on MMPose.\nOur RTMPose-m achieves **75.8% AP** on COCO with **90+ FPS** on an Intel i7-11700 CPU and **430+ FPS** on an NVIDIA GTX 1660 Ti GPU, and RTMPose-l achieves **67.0% AP** on COCO-WholeBody with **130+ FPS**, outperforming existing open-source libraries.\nTo further evaluate RTMPose's capability in critical real-time applications, we also report the performance after deploying on the mobile device.\n\n## Results and Models\n\n### COCO-WholeBody Dataset\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n|   Model   | Input Size | Whole AP | Whole AR |                          Details and Download                           |\n| :-------: | :--------: | :------: | :------: | :---------------------------------------------------------------------: |\n| RTMPose-m |  256x192   |  0.582   |  0.674   | [rtmpose_coco-wholebody.md](./coco-wholebody/rtmpose_coco-wholebody.md) |\n| RTMPose-l |  256x192   |  0.611   |  0.700   | [rtmpose_coco-wholebody.md](./coco-wholebody/rtmpose_coco-wholebody.md) |\n| RTMPose-l |  384x288   |  0.648   |  0.730   | [rtmpose_coco-wholebody.md](./coco-wholebody/rtmpose_coco-wholebody.md) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-l_8xb1024-270e_cocktail14-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 1024\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=8192)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-l_8xb320-270e_cocktail14-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 320\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=2560)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False,\n    decode_visibility=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-m_8xb1024-270e_cocktail14-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 1024\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=8192)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[192, 384, 768],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-x_8xb320-270e_cocktail14-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 320\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=2560)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False,\n    decode_visibility=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-384x288-f5b50679_20230822.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-x_8xb704-270e_cocktail14-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 704\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=5632)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-256x192-05f5bcb7_20230822.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw_cocktail14.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n- `Cocktail14` denotes model trained on 14 public datasets:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n  - [COCO-Wholebody](https://github.com/jin-s13/COCO-WholeBody/)\n  - [UBody](https://github.com/IDEA-Research/OSX)\n  - [Human-Art](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#human-art-dataset)\n  - [WFLW](https://wywu.github.io/projects/LAB/WFLW.html)\n  - [300W](https://ibug.doc.ic.ac.uk/resources/300-W/)\n  - [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/)\n  - [LaPa](https://github.com/JDAI-CV/lapa-dataset)\n  - [InterHand](https://mks0601.github.io/InterHand2.6M/)\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                                      | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                            ckpt                            | log |\n| :-------------------------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------------------------: | :-: |\n| [rtmw-m](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-m_8xb1024-270e_cocktail14-256x192.py) |  256x192   |  0.676  |  0.747  |  0.671  |  0.794  |  0.783  |  0.854  |  0.491  |  0.604  |  0.582   |  0.673   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-l-m_simcc-cocktail14_270e-256x192-20231122.pth) |  -  |\n| [rtmw-l](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-l_8xb1024-270e_cocktail14-256x192.py) |  256x192   |  0.743  |  0.807  |  0.763  |  0.868  |  0.834  |  0.889  |  0.598  |  0.701  |  0.660   |  0.746   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-256x192-20231122.pth) |  -  |\n| [rtmw-x](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-x_8xb704-270e_cocktail14-256x192.py) |  256x192   |  0.746  |  0.808  |  0.770  |  0.869  |  0.844  |  0.896  |  0.610  |  0.710  |  0.672   |  0.752   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-256x192-13a2546d_20231208.pth) |  -  |\n| [rtmw-l](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-l_8xb320-270e_cocktail14-384x288.py) |  384x288   |  0.761  |  0.824  |  0.793  |  0.885  |  0.884  |  0.921  |  0.663  |  0.752  |  0.701   |  0.780   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-384x288-20231122.pth) |  -  |\n| [rtmw-x](/configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-x_8xb320-270e_cocktail14-384x288.py) |  384x288   |  0.763  |  0.826  |  0.796  |  0.888  |  0.884  |  0.923  |  0.664  |  0.755  |  0.702   |  0.781   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-384x288-f840f204_20231122.pth) |  -  |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw_cocktail14.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-m_8xb1024-270e_cocktail14-256x192.py\n  In Collection: RTMPose\n  Alias: wholebody\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: COCO-WholeBody\n  Name: rtmw-m_8xb1024-270e_cocktail14-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.676\n      Body AR: 0.747\n      Face AP: 0.783\n      Face AR: 0.854\n      Foot AP: 0.671\n      Foot AR: 0.794\n      Hand AP: 0.491\n      Hand AR: 0.604\n      Whole AP: 0.582\n      Whole AR: 0.673\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-l-m_simcc-cocktail14_270e-256x192-20231122.pth\n- Config: configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-l_8xb1024-270e_cocktail14-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: rtmw-l_8xb1024-270e_cocktail14-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.743\n      Body AR: 0.807\n      Face AP: 0.834\n      Face AR: 0.889\n      Foot AP: 0.763\n      Foot AR: 0.868\n      Hand AP: 0.598\n      Hand AR: 0.701\n      Whole AP: 0.660\n      Whole AR: 0.746\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-256x192-20231122.pth\n- Config: configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-x_8xb704-270e_cocktail14-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: rtmw-x_8xb704-270e_cocktail14-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.746\n      Body AR: 0.808\n      Face AP: 0.844\n      Face AR: 0.896\n      Foot AP: 0.770\n      Foot AR: 0.869\n      Hand AP: 0.610\n      Hand AR: 0.710\n      Whole AP: 0.672\n      Whole AR: 0.752\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-256x192-13a2546d_20231208.pth\n- Config: configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-l_8xb320-270e_cocktail14-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: rtmw-l_8xb320-270e_cocktail14-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.761\n      Body AR: 0.824\n      Face AP: 0.884\n      Face AR: 0.921\n      Foot AP: 0.793\n      Foot AR: 0.885\n      Hand AP: 0.663\n      Hand AR: 0.752\n      Whole AP: 0.701\n      Whole AR: 0.780\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-384x288-20231122.pth\n- Config: configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw-x_8xb320-270e_cocktail14-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: rtmw-x_8xb320-270e_cocktail14-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.763\n      Body AR: 0.826\n      Face AP: 0.884\n      Face AR: 0.923\n      Foot AP: 0.796\n      Foot AR: 0.888\n      Hand AP: 0.664\n      Hand AR: 0.755\n      Whole AP: 0.702\n      Whole AR: 0.781\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-384x288-f840f204_20231122.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(288, 384),\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-x_8xb32-270e_coco-wholebody-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 32\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (arXiv'2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [rtmpose-m](/configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |  0.673  |  0.750  |  0.615  |  0.752  |  0.813  |  0.871  |  0.475  |  0.589  |  0.582   |  0.674   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.json) |\n| [rtmpose-l](/configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |  0.695  |  0.769  |  0.658  |  0.785  |  0.833  |  0.887  |  0.519  |  0.628  |  0.611   |  0.700   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-256x192-6f206314_20230124.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-256x192-6f206314_20230124.json) |\n| [rtmpose-l](/configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |  0.712  |  0.781  |  0.693  |  0.811  |  0.882  |  0.919  |  0.579  |  0.677  |  0.648   |  0.730   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-384x288-eaeb96c8_20230125.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-384x288-eaeb96c8_20230125.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py\n  In Collection: RTMPose\n  Alias: wholebody\n  Metadata:\n    Architecture: &id001\n    - RTMPose\n    Training Data: COCO-WholeBody\n  Name: rtmpose-m_8xb64-270e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.673\n      Body AR: 0.750\n      Face AP: 0.813\n      Face AR: 0.871\n      Foot AP: 0.615\n      Foot AR: 0.752\n      Hand AP: 0.475\n      Hand AR: 0.589\n      Whole AP: 0.582\n      Whole AR: 0.674\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.pth\n- Config: configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: rtmpose-l_8xb64-270e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.695\n      Body AR: 0.769\n      Face AP: 0.833\n      Face AR: 0.887\n      Foot AP: 0.658\n      Foot AR: 0.785\n      Hand AP: 0.519\n      Hand AR: 0.628\n      Whole AP: 0.611\n      Whole AR: 0.700\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-256x192-6f206314_20230124.pth\n- Config: configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py\n  In Collection: RTMPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: rtmpose-l_8xb32-270e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.712\n      Body AR: 0.781\n      Face AP: 0.882\n      Face AR: 0.919\n      Foot AP: 0.693\n      Foot AR: 0.811\n      Hand AP: 0.579\n      Hand AR: 0.677\n      Whole AP: 0.648\n      Whole AR: 0.730\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-384x288-eaeb96c8_20230125.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-l_8xb32-270e_coco-ubody-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 32\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(288, 384),\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=(9, 12),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-l_8xb64-270e_coco-ubody-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-m_8xb64-270e_coco-ubody-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-s_8xb64-270e_coco-ubody-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-t_8xb64-270e_coco-ubody-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_8xb32-270e_coco-ubody-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 32\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_8xb64-270e_coco-ubody-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa: E501\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nbackend_args = dict(backend='local')\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/README.md",
    "content": "# Top-down heatmap-based pose estimation\n\nTop-down methods divide the task into two stages: object detection, followed by single-object pose estimation given object bounding boxes. Instead of estimating keypoint coordinates directly, the pose estimator will produce heatmaps which represent the likelihood of being a keypoint, following the paradigm introduced in [Simple Baselines for Human Pose Estimation and Tracking](http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html).\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\" height=400>\n</div>\n\n## Results and Models\n\n### COCO-WholeBody Dataset\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n|        Model        | Input Size | Whole AP | Whole AR |                              Details and Download                               |\n| :-----------------: | :--------: | :------: | :------: | :-----------------------------------------------------------------------------: |\n|   HRNet-w48+Dark+   |  384x288   |  0.661   |  0.743   |  [hrnet_dark_coco-wholebody.md](./coco-wholebody/hrnet_dark_coco-wholebody.md)  |\n|   HRNet-w32+Dark    |  256x192   |  0.582   |  0.671   |  [hrnet_dark_coco-wholebody.md](./coco-wholebody/hrnet_dark_coco-wholebody.md)  |\n|      HRNet-w48      |  256x192   |  0.579   |  0.681   |       [hrnet_coco-wholebody.md](./coco-wholebody/hrnet_coco-wholebody.md)       |\n|      CSPNeXt-m      |  256x192   |  0.567   |  0.641   | [cspnext_udp_coco-wholebody.md](./coco-wholebody/cspnext_udp_coco-wholebody.md) |\n|      HRNet-w32      |  256x192   |  0.549   |  0.646   |    [hrnet_ubody-coco-wholebody.md](./ubody2d/hrnet_ubody-coco-wholebody.md)     |\n|     ResNet-152      |  256x192   |  0.548   |  0.661   |      [resnet_coco-wholebody.md](./coco-wholebody/resnet_coco-wholebody.md)      |\n|      HRNet-w32      |  256x192   |  0.536   |  0.636   |       [hrnet_coco-wholebody.md](./coco-wholebody/hrnet_coco-wholebody.md)       |\n|     ResNet-101      |  256x192   |  0.531   |  0.645   |      [resnet_coco-wholebody.md](./coco-wholebody/resnet_coco-wholebody.md)      |\n| S-ViPNAS-Res50+Dark |  256x192   |  0.528   |  0.632   | [vipnas_dark_coco-wholebody.md](./coco-wholebody/vipnas_dark_coco-wholebody.md) |\n|      ResNet-50      |  256x192   |  0.521   |  0.633   |      [resnet_coco-wholebody.md](./coco-wholebody/resnet_coco-wholebody.md)      |\n|   S-ViPNAS-Res50    |  256x192   |  0.495   |  0.607   |      [vipnas_coco-wholebody.md](./coco-wholebody/vipnas_coco-wholebody.md)      |\n\n### UBody2D Dataset\n\nResult on UBody val set, computed with gt keypoints.\n\n|   Model   | Input Size | Whole AP | Whole AR |                           Details and Download                           |\n| :-------: | :--------: | :------: | :------: | :----------------------------------------------------------------------: |\n| HRNet-w32 |  256x192   |  0.690   |  0.729   | [hrnet_ubody-coco-wholebody.md](./ubody2d/hrnet_ubody-coco-wholebody.md) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext-l_udp_8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext-m_udp_8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext_udp_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2212.07784\">RTMDet (ArXiv 2022)</a></summary>\n\n```bibtex\n@misc{lyu2022rtmdet,\n      title={RTMDet: An Empirical Study of Designing Real-Time Object Detectors},\n      author={Chengqi Lyu and Wenwei Zhang and Haian Huang and Yue Zhou and Yudong Wang and Yanyi Liu and Shilong Zhang and Kai Chen},\n      year={2022},\n      eprint={2212.07784},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [pose_cspnext_m_udp](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext-m_udp_8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.687  |  0.735  |  0.680  |  0.763  |  0.697  |  0.755  |  0.460  |  0.543  |  0.567   |  0.641   | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-coco-wholebody_pt-in1k_210e-256x192-320fa258_20230123.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-coco-wholebody_pt-in1k_210e-256x192-320fa258_20230123.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext_udp_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext-m_udp_8xb64-210e_coco-wholebody-256x192.py\n  In Collection: UDP\n  Metadata:\n    Architecture: &id001\n    - UDP\n    - CSPNeXt\n    Training Data: COCO-WholeBody\n  Name: cspnext-m_udp_8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.687\n      Body AR: 0.735\n      Face AP: 0.697\n      Face AR: 0.755\n      Foot AP: 0.680\n      Foot AR: 0.763\n      Hand AP: 0.46\n      Hand AR: 0.567\n      Whole AP: 0.567\n      Whole AR: 0.641\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-coco-wholebody_pt-in1k_210e-256x192-320fa258_20230123.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/hrnet_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [pose_hrnet_w32](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.678  |  0.755  |  0.543  |  0.661  |  0.630  |  0.708  |  0.467  |  0.566  |  0.536   |  0.636   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_256x192-853765cd_20200918.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_256x192_20200918.log.json) |\n| [pose_hrnet_w32](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-384x288.py) |  384x288   |  0.700  |  0.772  |  0.585  |  0.691  |  0.726  |  0.783  |  0.515  |  0.603  |  0.586   |  0.673   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_384x288-78cacac3_20200922.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_384x288_20200922.log.json) |\n| [pose_hrnet_w48](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_8xb32-210e_coco-wholebody-256x192.py) |  256x192   |  0.701  |  0.776  |  0.675  |  0.787  |  0.656  |  0.743  |  0.535  |  0.639  |  0.579   |  0.681   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_256x192-643e18cb_20200922.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_256x192_20200922.log.json) |\n| [pose_hrnet_w48](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_8xb32-210e_coco-wholebody-384x288.py) |  384x288   |  0.722  |  0.791  |  0.696  |  0.801  |  0.776  |  0.834  |  0.587  |  0.678  |  0.632   |  0.717   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288-6e061c6a_20200922.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_20200922.log.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/hrnet_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: COCO-WholeBody\n  Name: td-hm_hrnet-w32_8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.678\n      Body AR: 0.755\n      Face AP: 0.630\n      Face AR: 0.708\n      Foot AP: 0.543\n      Foot AR: 0.661\n      Hand AP: 0.467\n      Hand AR: 0.566\n      Whole AP: 0.536\n      Whole AR: 0.636\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_256x192-853765cd_20200918.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_hrnet-w32_8xb64-210e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.700\n      Body AR: 0.772\n      Face AP: 0.726\n      Face AR: 0.783\n      Foot AP: 0.585\n      Foot AR: 0.691\n      Hand AP: 0.515\n      Hand AR: 0.603\n      Whole AP: 0.586\n      Whole AR: 0.673\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_384x288-78cacac3_20200922.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_8xb32-210e_coco-wholebody-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_hrnet-w48_8xb32-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.701\n      Body AR: 0.776\n      Face AP: 0.656\n      Face AR: 0.743\n      Foot AP: 0.675\n      Foot AR: 0.787\n      Hand AP: 0.535\n      Hand AR: 0.639\n      Whole AP: 0.579\n      Whole AR: 0.681\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_256x192-643e18cb_20200922.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_8xb32-210e_coco-wholebody-384x288.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_hrnet-w48_8xb32-210e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.722\n      Body AR: 0.791\n      Face AP: 0.776\n      Face AR: 0.834\n      Foot AP: 0.696\n      Foot AR: 0.801\n      Hand AP: 0.587\n      Hand AR: 0.678\n      Whole AP: 0.632\n      Whole AR: 0.717\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288-6e061c6a_20200922.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/hrnet_dark_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [pose_hrnet_w32_dark](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_dark-8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.693  |  0.764  |  0.564  |  0.674  |  0.737  |  0.809  |  0.503  |  0.602  |  0.582   |  0.671   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_256x192_dark-469327ef_20200922.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_256x192_dark_20200922.log.json) |\n| [pose_hrnet_w48_dark+](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py) |  384x288   |  0.742  |  0.807  |  0.707  |  0.806  |  0.841  |  0.892  |  0.602  |  0.694  |  0.661   |  0.743   | [ckpt](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth) | [log](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark_20200918.log.json) |\n\nNote: `+` means the model is first pre-trained on original COCO dataset, and then fine-tuned on COCO-WholeBody dataset. We find this will lead to better performance.\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/hrnet_dark_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_dark-8xb64-210e_coco-wholebody-256x192.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    - DarkPose\n    Training Data: COCO-WholeBody\n  Name: td-hm_hrnet-w32_dark-8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.693\n      Body AR: 0.764\n      Face AP: 0.737\n      Face AR: 0.809\n      Foot AP: 0.564\n      Foot AR: 0.674\n      Hand AP: 0.503\n      Hand AR: 0.602\n      Whole AP: 0.582\n      Whole AR: 0.671\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_wholebody_256x192_dark-469327ef_20200922.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py\n  In Collection: DarkPose\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.742\n      Body AR: 0.807\n      Face AP: 0.841\n      Face AR: 0.892\n      Foot AP: 0.707\n      Foot AR: 0.806\n      Hand AP: 0.602\n      Hand AR: 0.694\n      Whole AP: 0.661\n      Whole AR: 0.743\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/resnet_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [pose_resnet_50](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res50_8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.652  |  0.738  |  0.615  |  0.749  |  0.606  |  0.715  |  0.460  |  0.584  |  0.521   |  0.633   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_wholebody_256x192-9e37ed88_20201004.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_wholebody_256x192_20201004.log.json) |\n| [pose_resnet_50](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res50_8xb64-210e_coco-wholebody-384x288.py) |  384x288   |  0.666  |  0.747  |  0.634  |  0.763  |  0.731  |  0.811  |  0.536  |  0.646  |  0.574   |  0.670   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_wholebody_384x288-ce11e294_20201004.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_wholebody_384x288_20201004.log.json) |\n| [pose_resnet_101](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res101_8xb32-210e_coco-wholebody-256x192.py) |  256x192   |  0.669  |  0.753  |  0.637  |  0.766  |  0.611  |  0.722  |  0.463  |  0.589  |  0.531   |  0.645   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res101_coco_wholebody_256x192-7325f982_20201004.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res101_coco_wholebody_256x192_20201004.log.json) |\n| [pose_resnet_101](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res101_8xb32-210e_coco-wholebody-384x288.py) |  384x288   |  0.692  |  0.770  |  0.680  |  0.799  |  0.746  |  0.820  |  0.548  |  0.657  |  0.597   |  0.693   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res101_coco_wholebody_384x288-6c137b9a_20201004.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res101_coco_wholebody_384x288_20201004.log.json) |\n| [pose_resnet_152](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res152_8xb32-210e_coco-wholebody-256x192.py) |  256x192   |  0.682  |  0.764  |  0.661  |  0.787  |  0.623  |  0.728  |  0.481  |  0.607  |  0.548   |  0.661   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res152_coco_wholebody_256x192-5de8ae23_20201004.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res152_coco_wholebody_256x192_20201004.log.json) |\n| [pose_resnet_152](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res152_8xb32-210e_coco-wholebody-384x288.py) |  384x288   |  0.704  |  0.780  |  0.693  |  0.813  |  0.751  |  0.824  |  0.559  |  0.666  |  0.610   |  0.705   | [ckpt](https://download.openmmlab.com/mmpose/top_down/resnet/res152_coco_wholebody_384x288-eab8caa8_20201004.pth) | [log](https://download.openmmlab.com/mmpose/top_down/resnet/res152_coco_wholebody_384x288_20201004.log.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/resnet_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res50_8xb64-210e_coco-wholebody-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: &id001\n    - SimpleBaseline2D\n    Training Data: COCO-WholeBody\n  Name: td-hm_res50_8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.652\n      Body AR: 0.738\n      Face AP: 0.606\n      Face AR: 0.715\n      Foot AP: 0.615\n      Foot AR: 0.749\n      Hand AP: 0.46\n      Hand AR: 0.584\n      Whole AP: 0.521\n      Whole AR: 0.633\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_wholebody_256x192-9e37ed88_20201004.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res50_8xb64-210e_coco-wholebody-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_res50_8xb64-210e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.666\n      Body AR: 0.747\n      Face AP: 0.731\n      Face AR: 0.811\n      Foot AP: 0.634\n      Foot AR: 0.763\n      Hand AP: 0.536\n      Hand AR: 0.646\n      Whole AP: 0.574\n      Whole AR: 0.67\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res50_coco_wholebody_384x288-ce11e294_20201004.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res101_8xb32-210e_coco-wholebody-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_res101_8xb32-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.669\n      Body AR: 0.753\n      Face AP: 0.611\n      Face AR: 0.722\n      Foot AP: 0.637\n      Foot AR: 0.766\n      Hand AP: 0.463\n      Hand AR: 0.589\n      Whole AP: 0.531\n      Whole AR: 0.645\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res101_coco_wholebody_256x192-7325f982_20201004.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res101_8xb32-210e_coco-wholebody-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_res101_8xb32-210e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.692\n      Body AR: 0.77\n      Face AP: 0.746\n      Face AR: 0.82\n      Foot AP: 0.68\n      Foot AR: 0.799\n      Hand AP: 0.548\n      Hand AR: 0.657\n      Whole AP: 0.598\n      Whole AR: 0.691\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res101_coco_wholebody_384x288-6c137b9a_20201004.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res152_8xb32-210e_coco-wholebody-256x192.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_res152_8xb32-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.682\n      Body AR: 0.764\n      Face AP: 0.623\n      Face AR: 0.728\n      Foot AP: 0.661\n      Foot AR: 0.787\n      Hand AP: 0.481\n      Hand AR: 0.607\n      Whole AP: 0.548\n      Whole AR: 0.661\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res152_coco_wholebody_256x192-5de8ae23_20201004.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res152_8xb32-210e_coco-wholebody-384x288.py\n  In Collection: SimpleBaseline2D\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_res152_8xb32-210e_coco-wholebody-384x288\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.704\n      Body AR: 0.78\n      Face AP: 0.751\n      Face AR: 0.824\n      Foot AP: 0.693\n      Foot AR: 0.813\n      Hand AP: 0.559\n      Hand AR: 0.666\n      Whole AP: 0.61\n      Whole AR: 0.705\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/resnet/res152_coco_wholebody_384x288-eab8caa8_20201004.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w32_dark-8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_8xb32-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_8xb32-210e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(288, 384),\n    heatmap_size=(72, 96),\n    sigma=3,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=48,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res101_8xb32-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res101_8xb32-210e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=101,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet101'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res152_8xb32-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res152_8xb32-210e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=152,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet152'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res50_8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_res50_8xb64-210e_coco-wholebody-384x288.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=2048,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ViPNAS_MobileNetV3'),\n    head=dict(\n        type='ViPNASHead',\n        in_channels=160,\n        out_channels=133,\n        deconv_out_channels=(160, 160, 160),\n        deconv_num_groups=(160, 160, 160),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_dark-8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(type='ViPNAS_MobileNetV3'),\n    head=dict(\n        type='ViPNASHead',\n        in_channels=160,\n        out_channels=133,\n        deconv_out_channels=(160, 160, 160),\n        deconv_num_groups=(160, 160, 160),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ViPNAS_ResNet',\n        depth=50,\n    ),\n    head=dict(\n        type='ViPNASHead',\n        in_channels=608,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap',\n    input_size=(192, 256),\n    heatmap_size=(48, 64),\n    sigma=2,\n    unbiased=True)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ViPNAS_ResNet',\n        depth=50,\n    ),\n    head=dict(\n        type='ViPNASHead',\n        in_channels=608,\n        out_channels=133,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        rotate_factor=60,\n        scale_factor=(0.75, 1.25)),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/vipnas_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2105.10154\">ViPNAS (CVPR'2021)</a></summary>\n\n```bibtex\n@article{xu2021vipnas,\n  title={ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search},\n  author={Xu, Lumin and Guan, Yingda and Jin, Sheng and Liu, Wentao and Qian, Chen and Luo, Ping and Ouyang, Wanli and Wang, Xiaogang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [S-ViPNAS-MobileNetV3](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.619  |  0.700  |  0.477  |  0.608  |  0.585  |  0.689  |  0.386  |  0.505  |  0.473   |  0.578   | [ckpt](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_mbv3_coco_wholebody_256x192-0fee581a_20211205.pth) | [log](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_mbv3_coco_wholebody_256x192_20211205.log.json) |\n| [S-ViPNAS-Res50](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.643  |  0.726  |  0.553  |  0.694  |  0.587  |  0.698  |  0.410  |  0.529  |  0.495   |  0.607   | [ckpt](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192-49e1c3a4_20211112.pth) | [log](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_20211112.log.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/vipnas_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192.py\n  In Collection: ViPNAS\n  Metadata:\n    Architecture: &id001\n    - ViPNAS\n    Training Data: COCO-WholeBody\n  Name: td-hm_vipnas-mbv3_8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.619\n      Body AR: 0.7\n      Face AP: 0.585\n      Face AR: 0.689\n      Foot AP: 0.477\n      Foot AR: 0.608\n      Hand AP: 0.386\n      Hand AR: 0.505\n      Whole AP: 0.473\n      Whole AR: 0.578\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_mbv3_coco_wholebody_256x192-0fee581a_20211205.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_8xb64-210e_coco-wholebody-256x192.py\n  In Collection: ViPNAS\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_vipnas-res50_8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.643\n      Body AR: 0.726\n      Face AP: 0.587\n      Face AR: 0.698\n      Foot AP: 0.553\n      Foot AR: 0.694\n      Hand AP: 0.41\n      Hand AR: 0.529\n      Whole AP: 0.495\n      Whole AR: 0.607\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192-49e1c3a4_20211112.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/vipnas_dark_coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2105.10154\">ViPNAS (CVPR'2021)</a></summary>\n\n```bibtex\n@article{xu2021vipnas,\n  title={ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search},\n  author={Xu, Lumin and Guan, Yingda and Jin, Sheng and Liu, Wentao and Qian, Chen and Luo, Ping and Ouyang, Wanli and Wang, Xiaogang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  year={2021}\n}\n```\n\n</details>\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [S-ViPNAS-MobileNetV3_dark](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_dark-8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.632  |  0.710  |  0.530  |  0.660  |  0.672  |  0.771  |  0.404  |  0.519  |  0.508   |  0.607   | [ckpt](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_mbv3_coco_wholebody_256x192_dark-e2158108_20211205.pth) | [log](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_mbv3_coco_wholebody_256x192_dark_20211205.log.json) |\n| [S-ViPNAS-Res50_dark](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.650  |  0.732  |  0.550  |  0.686  |  0.684  |  0.783  |  0.437  |  0.554  |  0.528   |  0.632   | [ckpt](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth) | [log](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark_20211112.log.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/vipnas_dark_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-mbv3_dark-8xb64-210e_coco-wholebody-256x192.py\n  In Collection: ViPNAS\n  Metadata:\n    Architecture: &id001\n    - ViPNAS\n    - DarkPose\n    Training Data: COCO-WholeBody\n  Name: td-hm_vipnas-mbv3_dark-8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.632\n      Body AR: 0.71\n      Face AP: 0.672\n      Face AR: 0.771\n      Foot AP: 0.53\n      Foot AR: 0.66\n      Hand AP: 0.404\n      Hand AR: 0.519\n      Whole AP: 0.508\n      Whole AR: 0.607\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_mbv3_coco_wholebody_256x192_dark-e2158108_20211205.pth\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py\n  In Collection: ViPNAS\n  Metadata:\n    Architecture: *id001\n    Training Data: COCO-WholeBody\n  Name: td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.65\n      Body AR: 0.732\n      Face AP: 0.684\n      Face AR: 0.783\n      Foot AP: 0.55\n      Foot AR: 0.686\n      Hand AP: 0.437\n      Hand AR: 0.554\n      Whole AP: 0.528\n      Whole AR: 0.632\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/ubody2d/hrnet_coco-wholebody.yml",
    "content": "Models:\n- Config: configs/wholebody_2d_keypoint/topdown_heatmap/ubody2d/td-hm_hrnet-w32_8xb64-210e_ubody-256x192.py\n  In Collection: HRNet\n  Metadata:\n    Architecture: &id001\n    - HRNet\n    Training Data: UBody-COCO-WholeBody\n  Name: td-hm_hrnet-w32_8xb64-210e_ubody-256x192\n  Results:\n  - Dataset: COCO-WholeBody\n    Metrics:\n      Body AP: 0.678\n      Body AR: 0.755\n      Face AP: 0.630\n      Face AR: 0.708\n      Foot AP: 0.543\n      Foot AR: 0.661\n      Hand AP: 0.467\n      Hand AR: 0.566\n      Whole AP: 0.536\n      Whole AR: 0.636\n    Task: Wholebody 2D Keypoint\n  Weights: https://download.openmmlab.com/mmpose/v1/wholebody_2d_keypoint/ubody/td-hm_hrnet-w32_8xb64-210e_ubody-coco-256x192-7c227391_20230807.pth\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/ubody2d/hrnet_ubody-coco-wholebody.md",
    "content": "<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2303.16160\">UBody (CVPR'2023)</a></summary>\n\n```bibtex\n@article{lin2023one,\n  title={One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer},\n  author={Lin, Jing and Zeng, Ailing and Wang, Haoqian and Zhang, Lei and Li, Yu},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  year={2023},\n}\n```\n\n</details>\n\nResults on COCO-WholeBody v1.0 val with detector having human AP of 56.4 on COCO val2017 dataset\n\n| Arch                                    | Input Size | Body AP | Body AR | Foot AP | Foot AR | Face AP | Face AR | Hand AP | Hand AR | Whole AP | Whole AR |                   ckpt                   |                   log                   |\n| :-------------------------------------- | :--------: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :-----: | :------: | :------: | :--------------------------------------: | :-------------------------------------: |\n| [pose_hrnet_w32](/configs/wholebody_2d_keypoint/topdown_heatmap/ubody/td-hm_hrnet-w32_8xb64-210e_coco-wholebody-256x192.py) |  256x192   |  0.685  |  0.759  |  0.564  |  0.675  |  0.625  |  0.705  |  0.516  |  0.609  |  0.549   |  0.646   | [ckpt](https://download.openmmlab.com/mmpose/v1/wholebody_2d_keypoint/ubody/td-hm_hrnet-w32_8xb64-210e_ubody-coco-256x192-7c227391_20230807.pth) | [log](https://download.openmmlab.com/mmpose/v1/wholebody_2d_keypoint/ubody/td-hm_hrnet-w32_8xb64-210e_ubody-coco-256x192-7c227391_20230807.json) |\n"
  },
  {
    "path": "configs/wholebody_2d_keypoint/topdown_heatmap/ubody2d/td-hm_hrnet-w32_8xb64-210e_ubody-256x192.py",
    "content": "_base_ = ['../../../_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco-wholebody/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=133,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'UBody2dDataset'\ndata_mode = 'topdown'\ndata_root = 'data/UBody/'\n\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\ntrain_datasets = [\n    dict(\n        type='CocoWholeBodyDataset',\n        data_root='data/coco/',\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[])\n]\n\nfor scene in scenes:\n    train_dataset = dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='images/'),\n        pipeline=[],\n        sample_interval=10)\n    train_datasets.append(train_dataset)\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "dataset-index.yml",
    "content": "openxlab: true\ncoco2017:\n  dataset: OpenDataLab/COCO_2017\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_coco2017.sh\n\nmpii:\n  dataset: OpenDataLab/MPII_Human_Pose\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_mpii.sh\n\naic:\n  dataset: OpenDataLab/AI_Challenger\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_aic.sh\n\ncrowdpose:\n  dataset: OpenDataLab/CrowdPose\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_crowdpose.sh\n\nhalpe:\n  dataset: OpenDataLab/Halpe\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_halpe.sh\n\nlapa:\n  dataset: OpenDataLab/LaPa\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_lapa.sh\n\n300w:\n  dataset: OpenDataLab/300w\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_300w.sh\n\nwflw:\n  dataset: OpenDataLab/WFLW\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_wflw.sh\n\nonehand10k:\n  dataset: OpenDataLab/OneHand10K\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_onehand10k.sh\n\nfreihand:\n  dataset: OpenDataLab/FreiHAND\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_freihand.sh\n\nap10k:\n  dataset: OpenDataLab/AP-10K\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_ap10k.sh\n\nhagrid:\n  dataset: OpenDataLab/HaGRID\n  download_root: data\n  data_root: data/pose\n  script: tools/dataset_converters/scripts/preprocess_hagrid.sh\n"
  },
  {
    "path": "demo/MMPose_Tutorial.ipynb",
    "content": "{\n  \"cells\": [\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"F77yOqgkX8p4\"\n      },\n      \"source\": [\n        \"<a href=\\\"https://colab.research.google.com/github/open-mmlab/mmpose/blob/dev-1.x/demo/MMPose_Tutorial.ipynb\\\" target=\\\"_parent\\\"><img src=\\\"https://colab.research.google.com/assets/colab-badge.svg\\\" alt=\\\"Open In Colab\\\"/></a>\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"8xX3YewOtqV0\"\n      },\n      \"source\": [\n        \"# MMPose Tutorial\\n\",\n        \"\\n\",\n        \"Welcome to MMPose colab tutorial! In this tutorial, we will show you how to\\n\",\n        \"\\n\",\n        \"- install MMPose 1.x\\n\",\n        \"- perform inference with an MMPose model\\n\",\n        \"- train a new mmpose model with your own datasets\\n\",\n        \"\\n\",\n        \"Let's start!\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"bkw-kUD8t3t8\"\n      },\n      \"source\": [\n        \"## Install MMPose\\n\",\n        \"\\n\",\n        \"We recommend to use a conda environment to install mmpose and its dependencies. And compilers `nvcc` and `gcc` are required.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 1,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"0f_Ebb2otWtd\",\n        \"outputId\": \"8c16b8ae-b927-41d5-c49e-d61ba6798a2d\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"nvcc: NVIDIA (R) Cuda compiler driver\\n\",\n            \"Copyright (c) 2005-2022 NVIDIA Corporation\\n\",\n            \"Built on Wed_Sep_21_10:33:58_PDT_2022\\n\",\n            \"Cuda compilation tools, release 11.8, V11.8.89\\n\",\n            \"Build cuda_11.8.r11.8/compiler.31833905_0\\n\",\n            \"gcc (Ubuntu 9.4.0-1ubuntu1~20.04.1) 9.4.0\\n\",\n            \"Copyright (C) 2019 Free Software Foundation, Inc.\\n\",\n            \"This is free software; see the source for copying conditions.  There is NO\\n\",\n            \"warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.\\n\",\n            \"\\n\",\n            \"/usr/local/bin/python\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# check NVCC version\\n\",\n        \"!nvcc -V\\n\",\n        \"\\n\",\n        \"# check GCC version\\n\",\n        \"!gcc --version\\n\",\n        \"\\n\",\n        \"# check python in conda environment\\n\",\n        \"!which python\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 2,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"igSm4jhihE2M\",\n        \"outputId\": \"0d521640-a4d7-4264-889c-df862e9c332f\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Looking in indexes: https://download.pytorch.org/whl/cu118, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Requirement already satisfied: torch in /usr/local/lib/python3.9/dist-packages (2.0.0+cu118)\\n\",\n            \"Requirement already satisfied: torchvision in /usr/local/lib/python3.9/dist-packages (0.15.1+cu118)\\n\",\n            \"Requirement already satisfied: torchaudio in /usr/local/lib/python3.9/dist-packages (2.0.1+cu118)\\n\",\n            \"Requirement already satisfied: networkx in /usr/local/lib/python3.9/dist-packages (from torch) (3.1)\\n\",\n            \"Requirement already satisfied: filelock in /usr/local/lib/python3.9/dist-packages (from torch) (3.11.0)\\n\",\n            \"Requirement already satisfied: sympy in /usr/local/lib/python3.9/dist-packages (from torch) (1.11.1)\\n\",\n            \"Requirement already satisfied: triton==2.0.0 in /usr/local/lib/python3.9/dist-packages (from torch) (2.0.0)\\n\",\n            \"Requirement already satisfied: jinja2 in /usr/local/lib/python3.9/dist-packages (from torch) (3.1.2)\\n\",\n            \"Requirement already satisfied: typing-extensions in /usr/local/lib/python3.9/dist-packages (from torch) (4.5.0)\\n\",\n            \"Requirement already satisfied: cmake in /usr/local/lib/python3.9/dist-packages (from triton==2.0.0->torch) (3.25.2)\\n\",\n            \"Requirement already satisfied: lit in /usr/local/lib/python3.9/dist-packages (from triton==2.0.0->torch) (16.0.1)\\n\",\n            \"Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from torchvision) (1.22.4)\\n\",\n            \"Requirement already satisfied: requests in /usr/local/lib/python3.9/dist-packages (from torchvision) (2.27.1)\\n\",\n            \"Requirement already satisfied: pillow!=8.3.*,>=5.3.0 in /usr/local/lib/python3.9/dist-packages (from torchvision) (8.4.0)\\n\",\n            \"Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.9/dist-packages (from jinja2->torch) (2.1.2)\\n\",\n            \"Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision) (3.4)\\n\",\n            \"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision) (1.26.15)\\n\",\n            \"Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision) (2.0.12)\\n\",\n            \"Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision) (2022.12.7)\\n\",\n            \"Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.9/dist-packages (from sympy->torch) (1.3.0)\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# install dependencies: (if your colab has CUDA 11.8)\\n\",\n        \"%pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu118\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 3,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"MLcoZr3ot9iw\",\n        \"outputId\": \"70e5d18e-746c-41a3-a761-6303b79eaf02\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Collecting openmim\\n\",\n            \"  Downloading openmim-0.3.7-py2.py3-none-any.whl (51 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m51.3/51.3 kB\\u001b[0m \\u001b[31m1.3 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: tabulate in /usr/local/lib/python3.9/dist-packages (from openmim) (0.8.10)\\n\",\n            \"Requirement already satisfied: rich in /usr/local/lib/python3.9/dist-packages (from openmim) (13.3.3)\\n\",\n            \"Requirement already satisfied: pip>=19.3 in /usr/local/lib/python3.9/dist-packages (from openmim) (23.0.1)\\n\",\n            \"Collecting colorama\\n\",\n            \"  Downloading colorama-0.4.6-py2.py3-none-any.whl (25 kB)\\n\",\n            \"Collecting model-index\\n\",\n            \"  Downloading model_index-0.1.11-py3-none-any.whl (34 kB)\\n\",\n            \"Requirement already satisfied: pandas in /usr/local/lib/python3.9/dist-packages (from openmim) (1.5.3)\\n\",\n            \"Requirement already satisfied: requests in /usr/local/lib/python3.9/dist-packages (from openmim) (2.27.1)\\n\",\n            \"Requirement already satisfied: Click in /usr/local/lib/python3.9/dist-packages (from openmim) (8.1.3)\\n\",\n            \"Requirement already satisfied: markdown in /usr/local/lib/python3.9/dist-packages (from model-index->openmim) (3.4.3)\\n\",\n            \"Collecting ordered-set\\n\",\n            \"  Downloading ordered_set-4.1.0-py3-none-any.whl (7.6 kB)\\n\",\n            \"Requirement already satisfied: pyyaml in /usr/local/lib/python3.9/dist-packages (from model-index->openmim) (6.0)\\n\",\n            \"Requirement already satisfied: numpy>=1.20.3 in /usr/local/lib/python3.9/dist-packages (from pandas->openmim) (1.22.4)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.8.1 in /usr/local/lib/python3.9/dist-packages (from pandas->openmim) (2.8.2)\\n\",\n            \"Requirement already satisfied: pytz>=2020.1 in /usr/local/lib/python3.9/dist-packages (from pandas->openmim) (2022.7.1)\\n\",\n            \"Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.9/dist-packages (from requests->openmim) (2.0.12)\\n\",\n            \"Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/dist-packages (from requests->openmim) (2022.12.7)\\n\",\n            \"Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/dist-packages (from requests->openmim) (3.4)\\n\",\n            \"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/dist-packages (from requests->openmim) (1.26.15)\\n\",\n            \"Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.9/dist-packages (from rich->openmim) (2.14.0)\\n\",\n            \"Requirement already satisfied: markdown-it-py<3.0.0,>=2.2.0 in /usr/local/lib/python3.9/dist-packages (from rich->openmim) (2.2.0)\\n\",\n            \"Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.9/dist-packages (from markdown-it-py<3.0.0,>=2.2.0->rich->openmim) (0.1.2)\\n\",\n            \"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.9/dist-packages (from python-dateutil>=2.8.1->pandas->openmim) (1.16.0)\\n\",\n            \"Requirement already satisfied: importlib-metadata>=4.4 in /usr/local/lib/python3.9/dist-packages (from markdown->model-index->openmim) (6.2.0)\\n\",\n            \"Requirement already satisfied: zipp>=0.5 in /usr/local/lib/python3.9/dist-packages (from importlib-metadata>=4.4->markdown->model-index->openmim) (3.15.0)\\n\",\n            \"Installing collected packages: ordered-set, colorama, model-index, openmim\\n\",\n            \"Successfully installed colorama-0.4.6 model-index-0.1.11 openmim-0.3.7 ordered-set-4.1.0\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Looking in links: https://download.openmmlab.com/mmcv/dist/cu118/torch2.0.0/index.html\\n\",\n            \"Collecting mmengine\\n\",\n            \"  Downloading mmengine-0.7.2-py3-none-any.whl (366 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m366.9/366.9 kB\\u001b[0m \\u001b[31m14.0 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: rich in /usr/local/lib/python3.9/dist-packages (from mmengine) (13.3.3)\\n\",\n            \"Requirement already satisfied: matplotlib in /usr/local/lib/python3.9/dist-packages (from mmengine) (3.7.1)\\n\",\n            \"Requirement already satisfied: pyyaml in /usr/local/lib/python3.9/dist-packages (from mmengine) (6.0)\\n\",\n            \"Requirement already satisfied: opencv-python>=3 in /usr/local/lib/python3.9/dist-packages (from mmengine) (4.7.0.72)\\n\",\n            \"Collecting yapf\\n\",\n            \"  Downloading yapf-0.32.0-py2.py3-none-any.whl (190 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m190.2/190.2 kB\\u001b[0m \\u001b[31m17.6 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: termcolor in /usr/local/lib/python3.9/dist-packages (from mmengine) (2.2.0)\\n\",\n            \"Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from mmengine) (1.22.4)\\n\",\n            \"Collecting addict\\n\",\n            \"  Downloading addict-2.4.0-py3-none-any.whl (3.8 kB)\\n\",\n            \"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (1.4.4)\\n\",\n            \"Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (5.12.0)\\n\",\n            \"Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (23.0)\\n\",\n            \"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (0.11.0)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (2.8.2)\\n\",\n            \"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (4.39.3)\\n\",\n            \"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (3.0.9)\\n\",\n            \"Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (8.4.0)\\n\",\n            \"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine) (1.0.7)\\n\",\n            \"Requirement already satisfied: markdown-it-py<3.0.0,>=2.2.0 in /usr/local/lib/python3.9/dist-packages (from rich->mmengine) (2.2.0)\\n\",\n            \"Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.9/dist-packages (from rich->mmengine) (2.14.0)\\n\",\n            \"Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.9/dist-packages (from importlib-resources>=3.2.0->matplotlib->mmengine) (3.15.0)\\n\",\n            \"Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.9/dist-packages (from markdown-it-py<3.0.0,>=2.2.0->rich->mmengine) (0.1.2)\\n\",\n            \"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.9/dist-packages (from python-dateutil>=2.7->matplotlib->mmengine) (1.16.0)\\n\",\n            \"Installing collected packages: yapf, addict, mmengine\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"Successfully installed addict-2.4.0 mmengine-0.7.2 yapf-0.32.0\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Looking in links: https://download.openmmlab.com/mmcv/dist/cu118/torch2.0.0/index.html\\n\",\n            \"Collecting mmcv>=2.0.0rc1\\n\",\n            \"  Downloading https://download.openmmlab.com/mmcv/dist/cu118/torch2.0.0/mmcv-2.0.0-cp39-cp39-manylinux1_x86_64.whl (74.4 MB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m74.4/74.4 MB\\u001b[0m \\u001b[31m12.8 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: mmengine>=0.2.0 in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (0.7.2)\\n\",\n            \"Requirement already satisfied: yapf in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (0.32.0)\\n\",\n            \"Requirement already satisfied: packaging in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (23.0)\\n\",\n            \"Requirement already satisfied: addict in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (2.4.0)\\n\",\n            \"Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (1.22.4)\\n\",\n            \"Requirement already satisfied: pyyaml in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (6.0)\\n\",\n            \"Requirement already satisfied: opencv-python>=3 in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (4.7.0.72)\\n\",\n            \"Requirement already satisfied: Pillow in /usr/local/lib/python3.9/dist-packages (from mmcv>=2.0.0rc1) (8.4.0)\\n\",\n            \"Requirement already satisfied: matplotlib in /usr/local/lib/python3.9/dist-packages (from mmengine>=0.2.0->mmcv>=2.0.0rc1) (3.7.1)\\n\",\n            \"Requirement already satisfied: rich in /usr/local/lib/python3.9/dist-packages (from mmengine>=0.2.0->mmcv>=2.0.0rc1) (13.3.3)\\n\",\n            \"Requirement already satisfied: termcolor in /usr/local/lib/python3.9/dist-packages (from mmengine>=0.2.0->mmcv>=2.0.0rc1) (2.2.0)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (2.8.2)\\n\",\n            \"Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (5.12.0)\\n\",\n            \"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (0.11.0)\\n\",\n            \"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (4.39.3)\\n\",\n            \"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (3.0.9)\\n\",\n            \"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (1.4.4)\\n\",\n            \"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (1.0.7)\\n\",\n            \"Requirement already satisfied: markdown-it-py<3.0.0,>=2.2.0 in /usr/local/lib/python3.9/dist-packages (from rich->mmengine>=0.2.0->mmcv>=2.0.0rc1) (2.2.0)\\n\",\n            \"Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.9/dist-packages (from rich->mmengine>=0.2.0->mmcv>=2.0.0rc1) (2.14.0)\\n\",\n            \"Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.9/dist-packages (from importlib-resources>=3.2.0->matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (3.15.0)\\n\",\n            \"Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.9/dist-packages (from markdown-it-py<3.0.0,>=2.2.0->rich->mmengine>=0.2.0->mmcv>=2.0.0rc1) (0.1.2)\\n\",\n            \"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.9/dist-packages (from python-dateutil>=2.7->matplotlib->mmengine>=0.2.0->mmcv>=2.0.0rc1) (1.16.0)\\n\",\n            \"Installing collected packages: mmcv\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"Successfully installed mmcv-2.0.0\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Looking in links: https://download.openmmlab.com/mmcv/dist/cu118/torch2.0.0/index.html\\n\",\n            \"Collecting mmdet>=3.0.0rc0\\n\",\n            \"  Downloading mmdet-3.0.0-py3-none-any.whl (1.7 MB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m1.7/1.7 MB\\u001b[0m \\u001b[31m71.8 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: six in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (1.16.0)\\n\",\n            \"Collecting terminaltables\\n\",\n            \"  Downloading terminaltables-3.1.10-py2.py3-none-any.whl (15 kB)\\n\",\n            \"Requirement already satisfied: pycocotools in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (2.0.6)\\n\",\n            \"Requirement already satisfied: scipy in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (1.10.1)\\n\",\n            \"Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (1.22.4)\\n\",\n            \"Requirement already satisfied: matplotlib in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (3.7.1)\\n\",\n            \"Requirement already satisfied: shapely in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (2.0.1)\\n\",\n            \"Requirement already satisfied: mmengine<1.0.0,>=0.7.1 in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (0.7.2)\\n\",\n            \"Requirement already satisfied: mmcv<2.1.0,>=2.0.0rc4 in /usr/local/lib/python3.9/dist-packages (from mmdet>=3.0.0rc0) (2.0.0)\\n\",\n            \"Requirement already satisfied: pyyaml in /usr/local/lib/python3.9/dist-packages (from mmcv<2.1.0,>=2.0.0rc4->mmdet>=3.0.0rc0) (6.0)\\n\",\n            \"Requirement already satisfied: packaging in /usr/local/lib/python3.9/dist-packages (from mmcv<2.1.0,>=2.0.0rc4->mmdet>=3.0.0rc0) (23.0)\\n\",\n            \"Requirement already satisfied: opencv-python>=3 in /usr/local/lib/python3.9/dist-packages (from mmcv<2.1.0,>=2.0.0rc4->mmdet>=3.0.0rc0) (4.7.0.72)\\n\",\n            \"Requirement already satisfied: addict in /usr/local/lib/python3.9/dist-packages (from mmcv<2.1.0,>=2.0.0rc4->mmdet>=3.0.0rc0) (2.4.0)\\n\",\n            \"Requirement already satisfied: Pillow in /usr/local/lib/python3.9/dist-packages (from mmcv<2.1.0,>=2.0.0rc4->mmdet>=3.0.0rc0) (8.4.0)\\n\",\n            \"Requirement already satisfied: yapf in /usr/local/lib/python3.9/dist-packages (from mmcv<2.1.0,>=2.0.0rc4->mmdet>=3.0.0rc0) (0.32.0)\\n\",\n            \"Requirement already satisfied: termcolor in /usr/local/lib/python3.9/dist-packages (from mmengine<1.0.0,>=0.7.1->mmdet>=3.0.0rc0) (2.2.0)\\n\",\n            \"Requirement already satisfied: rich in /usr/local/lib/python3.9/dist-packages (from mmengine<1.0.0,>=0.7.1->mmdet>=3.0.0rc0) (13.3.3)\\n\",\n            \"Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (5.12.0)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (2.8.2)\\n\",\n            \"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (4.39.3)\\n\",\n            \"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (1.4.4)\\n\",\n            \"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (0.11.0)\\n\",\n            \"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (1.0.7)\\n\",\n            \"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmdet>=3.0.0rc0) (3.0.9)\\n\",\n            \"Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.9/dist-packages (from importlib-resources>=3.2.0->matplotlib->mmdet>=3.0.0rc0) (3.15.0)\\n\",\n            \"Requirement already satisfied: markdown-it-py<3.0.0,>=2.2.0 in /usr/local/lib/python3.9/dist-packages (from rich->mmengine<1.0.0,>=0.7.1->mmdet>=3.0.0rc0) (2.2.0)\\n\",\n            \"Requirement already satisfied: pygments<3.0.0,>=2.13.0 in /usr/local/lib/python3.9/dist-packages (from rich->mmengine<1.0.0,>=0.7.1->mmdet>=3.0.0rc0) (2.14.0)\\n\",\n            \"Requirement already satisfied: mdurl~=0.1 in /usr/local/lib/python3.9/dist-packages (from markdown-it-py<3.0.0,>=2.2.0->rich->mmengine<1.0.0,>=0.7.1->mmdet>=3.0.0rc0) (0.1.2)\\n\",\n            \"Installing collected packages: terminaltables, mmdet\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"  warnings.warn(\\n\",\n            \"Successfully installed mmdet-3.0.0 terminaltables-3.1.10\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# install MMEngine, MMCV and MMDetection using MIM\\n\",\n        \"%pip install -U openmim\\n\",\n        \"!mim install mmengine\\n\",\n        \"!mim install \\\"mmcv>=2.0.0\\\"\\n\",\n        \"!mim install \\\"mmdet>=3.0.0\\\"\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 4,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"42hRcloJhE2N\",\n        \"outputId\": \"9175e011-82c0-438d-f378-264e8467eb09\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Collecting git+https://github.com/jin-s13/xtcocoapi\\n\",\n            \"  Cloning https://github.com/jin-s13/xtcocoapi to /tmp/pip-req-build-6ts8xw10\\n\",\n            \"  Running command git clone --filter=blob:none --quiet https://github.com/jin-s13/xtcocoapi /tmp/pip-req-build-6ts8xw10\\n\",\n            \"  Resolved https://github.com/jin-s13/xtcocoapi to commit 86a60cab276e619dac5d22834a36dceaf7aa0a38\\n\",\n            \"  Preparing metadata (setup.py) ... \\u001b[?25l\\u001b[?25hdone\\n\",\n            \"Requirement already satisfied: setuptools>=18.0 in /usr/local/lib/python3.9/dist-packages (from xtcocotools==1.13) (67.6.1)\\n\",\n            \"Requirement already satisfied: cython>=0.27.3 in /usr/local/lib/python3.9/dist-packages (from xtcocotools==1.13) (0.29.34)\\n\",\n            \"Requirement already satisfied: matplotlib>=2.1.0 in /usr/local/lib/python3.9/dist-packages (from xtcocotools==1.13) (3.7.1)\\n\",\n            \"Requirement already satisfied: numpy>=1.20.0 in /usr/local/lib/python3.9/dist-packages (from xtcocotools==1.13) (1.22.4)\\n\",\n            \"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (1.4.4)\\n\",\n            \"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (4.39.3)\\n\",\n            \"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (1.0.7)\\n\",\n            \"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (0.11.0)\\n\",\n            \"Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (23.0)\\n\",\n            \"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (3.0.9)\\n\",\n            \"Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (5.12.0)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (2.8.2)\\n\",\n            \"Requirement already satisfied: pillow>=6.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib>=2.1.0->xtcocotools==1.13) (8.4.0)\\n\",\n            \"Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.9/dist-packages (from importlib-resources>=3.2.0->matplotlib>=2.1.0->xtcocotools==1.13) (3.15.0)\\n\",\n            \"Requirement already satisfied: six>=1.5 in /usr/local/lib/python3.9/dist-packages (from python-dateutil>=2.7->matplotlib>=2.1.0->xtcocotools==1.13) (1.16.0)\\n\",\n            \"Building wheels for collected packages: xtcocotools\\n\",\n            \"  Building wheel for xtcocotools (setup.py) ... \\u001b[?25l\\u001b[?25hdone\\n\",\n            \"  Created wheel for xtcocotools: filename=xtcocotools-1.13-cp39-cp39-linux_x86_64.whl size=402078 sha256=e6a1d4ea868ca2cbd8151f85509641b20b24745a9b8b353348ba8386c35ee6c6\\n\",\n            \"  Stored in directory: /tmp/pip-ephem-wheel-cache-a15wpqzs/wheels/3f/df/8b/d3eff2ded4b03a665d977a0baa328d9efa2f9ac9971929a222\\n\",\n            \"Successfully built xtcocotools\\n\",\n            \"Installing collected packages: xtcocotools\\n\",\n            \"Successfully installed xtcocotools-1.13\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# for better Colab compatibility, install xtcocotools from source\\n\",\n        \"%pip install git+https://github.com/jin-s13/xtcocoapi\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 5,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"lzuSKOjMvJZu\",\n        \"outputId\": \"d6a7a3f8-2d96-40a6-a7c4-65697e18ffc9\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Cloning into 'mmpose'...\\n\",\n            \"remote: Enumerating objects: 26225, done.\\u001b[K\\n\",\n            \"remote: Counting objects: 100% (97/97), done.\\u001b[K\\n\",\n            \"remote: Compressing objects: 100% (67/67), done.\\u001b[K\\n\",\n            \"remote: Total 26225 (delta 33), reused 67 (delta 28), pack-reused 26128\\u001b[K\\n\",\n            \"Receiving objects: 100% (26225/26225), 28.06 MiB | 13.36 MiB/s, done.\\n\",\n            \"Resolving deltas: 100% (18673/18673), done.\\n\",\n            \"/content/mmpose\\n\",\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from -r requirements/build.txt (line 2)) (1.22.4)\\n\",\n            \"Requirement already satisfied: torch>=1.6 in /usr/local/lib/python3.9/dist-packages (from -r requirements/build.txt (line 3)) (2.0.0+cu118)\\n\",\n            \"Collecting chumpy\\n\",\n            \"  Downloading chumpy-0.70.tar.gz (50 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m50.6/50.6 kB\\u001b[0m \\u001b[31m2.7 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25h  Preparing metadata (setup.py) ... \\u001b[?25l\\u001b[?25hdone\\n\",\n            \"Collecting json_tricks\\n\",\n            \"  Downloading json_tricks-3.16.1-py2.py3-none-any.whl (27 kB)\\n\",\n            \"Requirement already satisfied: matplotlib in /usr/local/lib/python3.9/dist-packages (from -r requirements/runtime.txt (line 3)) (3.7.1)\\n\",\n            \"Collecting munkres\\n\",\n            \"  Downloading munkres-1.1.4-py2.py3-none-any.whl (7.0 kB)\\n\",\n            \"Requirement already satisfied: opencv-python in /usr/local/lib/python3.9/dist-packages (from -r requirements/runtime.txt (line 6)) (4.7.0.72)\\n\",\n            \"Requirement already satisfied: pillow in /usr/local/lib/python3.9/dist-packages (from -r requirements/runtime.txt (line 7)) (8.4.0)\\n\",\n            \"Requirement already satisfied: scipy in /usr/local/lib/python3.9/dist-packages (from -r requirements/runtime.txt (line 8)) (1.10.1)\\n\",\n            \"Requirement already satisfied: torchvision in /usr/local/lib/python3.9/dist-packages (from -r requirements/runtime.txt (line 9)) (0.15.1+cu118)\\n\",\n            \"Requirement already satisfied: xtcocotools>=1.12 in /usr/local/lib/python3.9/dist-packages (from -r requirements/runtime.txt (line 10)) (1.13)\\n\",\n            \"Collecting coverage\\n\",\n            \"  Downloading coverage-7.2.3-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl (227 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m227.5/227.5 kB\\u001b[0m \\u001b[31m27.0 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hCollecting flake8\\n\",\n            \"  Downloading flake8-6.0.0-py2.py3-none-any.whl (57 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m57.8/57.8 kB\\u001b[0m \\u001b[31m6.8 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hCollecting interrogate\\n\",\n            \"  Downloading interrogate-1.5.0-py3-none-any.whl (45 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m45.3/45.3 kB\\u001b[0m \\u001b[31m5.0 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hCollecting isort==4.3.21\\n\",\n            \"  Downloading isort-4.3.21-py2.py3-none-any.whl (42 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m42.3/42.3 kB\\u001b[0m \\u001b[31m5.3 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hCollecting parameterized\\n\",\n            \"  Downloading parameterized-0.9.0-py2.py3-none-any.whl (20 kB)\\n\",\n            \"Requirement already satisfied: pytest in /usr/local/lib/python3.9/dist-packages (from -r requirements/tests.txt (line 6)) (7.2.2)\\n\",\n            \"Collecting pytest-runner\\n\",\n            \"  Downloading pytest_runner-6.0.0-py3-none-any.whl (7.2 kB)\\n\",\n            \"Collecting xdoctest>=0.10.0\\n\",\n            \"  Downloading xdoctest-1.1.1-py3-none-any.whl (137 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m137.6/137.6 kB\\u001b[0m \\u001b[31m14.7 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: yapf in /usr/local/lib/python3.9/dist-packages (from -r requirements/tests.txt (line 9)) (0.32.0)\\n\",\n            \"Requirement already satisfied: requests in /usr/local/lib/python3.9/dist-packages (from -r requirements/optional.txt (line 1)) (2.27.1)\\n\",\n            \"Requirement already satisfied: filelock in /usr/local/lib/python3.9/dist-packages (from torch>=1.6->-r requirements/build.txt (line 3)) (3.11.0)\\n\",\n            \"Requirement already satisfied: networkx in /usr/local/lib/python3.9/dist-packages (from torch>=1.6->-r requirements/build.txt (line 3)) (3.1)\\n\",\n            \"Requirement already satisfied: typing-extensions in /usr/local/lib/python3.9/dist-packages (from torch>=1.6->-r requirements/build.txt (line 3)) (4.5.0)\\n\",\n            \"Requirement already satisfied: jinja2 in /usr/local/lib/python3.9/dist-packages (from torch>=1.6->-r requirements/build.txt (line 3)) (3.1.2)\\n\",\n            \"Requirement already satisfied: triton==2.0.0 in /usr/local/lib/python3.9/dist-packages (from torch>=1.6->-r requirements/build.txt (line 3)) (2.0.0)\\n\",\n            \"Requirement already satisfied: sympy in /usr/local/lib/python3.9/dist-packages (from torch>=1.6->-r requirements/build.txt (line 3)) (1.11.1)\\n\",\n            \"Requirement already satisfied: cmake in /usr/local/lib/python3.9/dist-packages (from triton==2.0.0->torch>=1.6->-r requirements/build.txt (line 3)) (3.25.2)\\n\",\n            \"Requirement already satisfied: lit in /usr/local/lib/python3.9/dist-packages (from triton==2.0.0->torch>=1.6->-r requirements/build.txt (line 3)) (16.0.1)\\n\",\n            \"Requirement already satisfied: six>=1.11.0 in /usr/local/lib/python3.9/dist-packages (from chumpy->-r requirements/runtime.txt (line 1)) (1.16.0)\\n\",\n            \"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (4.39.3)\\n\",\n            \"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (3.0.9)\\n\",\n            \"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (1.4.4)\\n\",\n            \"Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (5.12.0)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (2.8.2)\\n\",\n            \"Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (23.0)\\n\",\n            \"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (1.0.7)\\n\",\n            \"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib->-r requirements/runtime.txt (line 3)) (0.11.0)\\n\",\n            \"Requirement already satisfied: setuptools>=18.0 in /usr/local/lib/python3.9/dist-packages (from xtcocotools>=1.12->-r requirements/runtime.txt (line 10)) (67.6.1)\\n\",\n            \"Requirement already satisfied: cython>=0.27.3 in /usr/local/lib/python3.9/dist-packages (from xtcocotools>=1.12->-r requirements/runtime.txt (line 10)) (0.29.34)\\n\",\n            \"Collecting pyflakes<3.1.0,>=3.0.0\\n\",\n            \"  Downloading pyflakes-3.0.1-py2.py3-none-any.whl (62 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m62.8/62.8 kB\\u001b[0m \\u001b[31m5.4 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hCollecting pycodestyle<2.11.0,>=2.10.0\\n\",\n            \"  Downloading pycodestyle-2.10.0-py2.py3-none-any.whl (41 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m41.3/41.3 kB\\u001b[0m \\u001b[31m4.8 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hCollecting mccabe<0.8.0,>=0.7.0\\n\",\n            \"  Downloading mccabe-0.7.0-py2.py3-none-any.whl (7.3 kB)\\n\",\n            \"Collecting py\\n\",\n            \"  Downloading py-1.11.0-py2.py3-none-any.whl (98 kB)\\n\",\n            \"\\u001b[2K     \\u001b[90m━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━\\u001b[0m \\u001b[32m98.7/98.7 kB\\u001b[0m \\u001b[31m11.5 MB/s\\u001b[0m eta \\u001b[36m0:00:00\\u001b[0m\\n\",\n            \"\\u001b[?25hRequirement already satisfied: colorama in /usr/local/lib/python3.9/dist-packages (from interrogate->-r requirements/tests.txt (line 3)) (0.4.6)\\n\",\n            \"Requirement already satisfied: toml in /usr/local/lib/python3.9/dist-packages (from interrogate->-r requirements/tests.txt (line 3)) (0.10.2)\\n\",\n            \"Requirement already satisfied: attrs in /usr/local/lib/python3.9/dist-packages (from interrogate->-r requirements/tests.txt (line 3)) (22.2.0)\\n\",\n            \"Requirement already satisfied: tabulate in /usr/local/lib/python3.9/dist-packages (from interrogate->-r requirements/tests.txt (line 3)) (0.8.10)\\n\",\n            \"Requirement already satisfied: click>=7.1 in /usr/local/lib/python3.9/dist-packages (from interrogate->-r requirements/tests.txt (line 3)) (8.1.3)\\n\",\n            \"Requirement already satisfied: tomli>=1.0.0 in /usr/local/lib/python3.9/dist-packages (from pytest->-r requirements/tests.txt (line 6)) (2.0.1)\\n\",\n            \"Requirement already satisfied: pluggy<2.0,>=0.12 in /usr/local/lib/python3.9/dist-packages (from pytest->-r requirements/tests.txt (line 6)) (1.0.0)\\n\",\n            \"Requirement already satisfied: iniconfig in /usr/local/lib/python3.9/dist-packages (from pytest->-r requirements/tests.txt (line 6)) (2.0.0)\\n\",\n            \"Requirement already satisfied: exceptiongroup>=1.0.0rc8 in /usr/local/lib/python3.9/dist-packages (from pytest->-r requirements/tests.txt (line 6)) (1.1.1)\\n\",\n            \"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/dist-packages (from requests->-r requirements/optional.txt (line 1)) (1.26.15)\\n\",\n            \"Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/dist-packages (from requests->-r requirements/optional.txt (line 1)) (2022.12.7)\\n\",\n            \"Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.9/dist-packages (from requests->-r requirements/optional.txt (line 1)) (2.0.12)\\n\",\n            \"Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/dist-packages (from requests->-r requirements/optional.txt (line 1)) (3.4)\\n\",\n            \"Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.9/dist-packages (from importlib-resources>=3.2.0->matplotlib->-r requirements/runtime.txt (line 3)) (3.15.0)\\n\",\n            \"Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.9/dist-packages (from jinja2->torch>=1.6->-r requirements/build.txt (line 3)) (2.1.2)\\n\",\n            \"Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.9/dist-packages (from sympy->torch>=1.6->-r requirements/build.txt (line 3)) (1.3.0)\\n\",\n            \"Building wheels for collected packages: chumpy\\n\",\n            \"  Building wheel for chumpy (setup.py) ... \\u001b[?25l\\u001b[?25hdone\\n\",\n            \"  Created wheel for chumpy: filename=chumpy-0.70-py3-none-any.whl size=58282 sha256=ccde33ce99f135241a3f9ed380871cf8e4a569053d21b0ceba97809ddf3b26c8\\n\",\n            \"  Stored in directory: /root/.cache/pip/wheels/71/b5/d3/bbff0d638d797944856371a4ee326f9ffb1829083a383bba77\\n\",\n            \"Successfully built chumpy\\n\",\n            \"Installing collected packages: munkres, json_tricks, xdoctest, pytest-runner, pyflakes, pycodestyle, py, parameterized, mccabe, isort, coverage, interrogate, flake8, chumpy\\n\",\n            \"Successfully installed chumpy-0.70 coverage-7.2.3 flake8-6.0.0 interrogate-1.5.0 isort-4.3.21 json_tricks-3.16.1 mccabe-0.7.0 munkres-1.1.4 parameterized-0.9.0 py-1.11.0 pycodestyle-2.10.0 pyflakes-3.0.1 pytest-runner-6.0.0 xdoctest-1.1.1\\n\",\n            \"Using pip 23.0.1 from /usr/local/lib/python3.9/dist-packages/pip (python 3.9)\\n\",\n            \"Looking in indexes: https://pypi.org/simple, https://us-python.pkg.dev/colab-wheels/public/simple/\\n\",\n            \"Obtaining file:///content/mmpose\\n\",\n            \"  Running command python setup.py egg_info\\n\",\n            \"  running egg_info\\n\",\n            \"  creating /tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info\\n\",\n            \"  writing /tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/PKG-INFO\\n\",\n            \"  writing dependency_links to /tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/dependency_links.txt\\n\",\n            \"  writing requirements to /tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/requires.txt\\n\",\n            \"  writing top-level names to /tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/top_level.txt\\n\",\n            \"  writing manifest file '/tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/SOURCES.txt'\\n\",\n            \"  reading manifest file '/tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/SOURCES.txt'\\n\",\n            \"  reading manifest template 'MANIFEST.in'\\n\",\n            \"  warning: no files found matching 'mmpose/.mim/model-index.yml'\\n\",\n            \"  warning: no files found matching '*.py' under directory 'mmpose/.mim/configs'\\n\",\n            \"  warning: no files found matching '*.yml' under directory 'mmpose/.mim/configs'\\n\",\n            \"  warning: no files found matching '*.py' under directory 'mmpose/.mim/tools'\\n\",\n            \"  warning: no files found matching '*.sh' under directory 'mmpose/.mim/tools'\\n\",\n            \"  warning: no files found matching '*.py' under directory 'mmpose/.mim/demo'\\n\",\n            \"  adding license file 'LICENSE'\\n\",\n            \"  writing manifest file '/tmp/pip-pip-egg-info-tatkegdw/mmpose.egg-info/SOURCES.txt'\\n\",\n            \"  Preparing metadata (setup.py) ... \\u001b[?25l\\u001b[?25hdone\\n\",\n            \"Requirement already satisfied: chumpy in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (0.70)\\n\",\n            \"Requirement already satisfied: json_tricks in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (3.16.1)\\n\",\n            \"Requirement already satisfied: matplotlib in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (3.7.1)\\n\",\n            \"Requirement already satisfied: munkres in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (1.1.4)\\n\",\n            \"Requirement already satisfied: numpy in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (1.22.4)\\n\",\n            \"Requirement already satisfied: opencv-python in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (4.7.0.72)\\n\",\n            \"Requirement already satisfied: pillow in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (8.4.0)\\n\",\n            \"Requirement already satisfied: scipy in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (1.10.1)\\n\",\n            \"Requirement already satisfied: torchvision in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (0.15.1+cu118)\\n\",\n            \"Requirement already satisfied: xtcocotools>=1.12 in /usr/local/lib/python3.9/dist-packages (from mmpose==1.0.0) (1.13)\\n\",\n            \"Requirement already satisfied: cython>=0.27.3 in /usr/local/lib/python3.9/dist-packages (from xtcocotools>=1.12->mmpose==1.0.0) (0.29.34)\\n\",\n            \"Requirement already satisfied: setuptools>=18.0 in /usr/local/lib/python3.9/dist-packages (from xtcocotools>=1.12->mmpose==1.0.0) (67.6.1)\\n\",\n            \"Requirement already satisfied: contourpy>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (1.0.7)\\n\",\n            \"Requirement already satisfied: cycler>=0.10 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (0.11.0)\\n\",\n            \"Requirement already satisfied: python-dateutil>=2.7 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (2.8.2)\\n\",\n            \"Requirement already satisfied: importlib-resources>=3.2.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (5.12.0)\\n\",\n            \"Requirement already satisfied: packaging>=20.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (23.0)\\n\",\n            \"Requirement already satisfied: fonttools>=4.22.0 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (4.39.3)\\n\",\n            \"Requirement already satisfied: kiwisolver>=1.0.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (1.4.4)\\n\",\n            \"Requirement already satisfied: pyparsing>=2.3.1 in /usr/local/lib/python3.9/dist-packages (from matplotlib->mmpose==1.0.0) (3.0.9)\\n\",\n            \"Requirement already satisfied: six>=1.11.0 in /usr/local/lib/python3.9/dist-packages (from chumpy->mmpose==1.0.0) (1.16.0)\\n\",\n            \"Requirement already satisfied: requests in /usr/local/lib/python3.9/dist-packages (from torchvision->mmpose==1.0.0) (2.27.1)\\n\",\n            \"Requirement already satisfied: torch==2.0.0 in /usr/local/lib/python3.9/dist-packages (from torchvision->mmpose==1.0.0) (2.0.0+cu118)\\n\",\n            \"Requirement already satisfied: filelock in /usr/local/lib/python3.9/dist-packages (from torch==2.0.0->torchvision->mmpose==1.0.0) (3.11.0)\\n\",\n            \"Requirement already satisfied: jinja2 in /usr/local/lib/python3.9/dist-packages (from torch==2.0.0->torchvision->mmpose==1.0.0) (3.1.2)\\n\",\n            \"Requirement already satisfied: networkx in /usr/local/lib/python3.9/dist-packages (from torch==2.0.0->torchvision->mmpose==1.0.0) (3.1)\\n\",\n            \"Requirement already satisfied: typing-extensions in /usr/local/lib/python3.9/dist-packages (from torch==2.0.0->torchvision->mmpose==1.0.0) (4.5.0)\\n\",\n            \"Requirement already satisfied: triton==2.0.0 in /usr/local/lib/python3.9/dist-packages (from torch==2.0.0->torchvision->mmpose==1.0.0) (2.0.0)\\n\",\n            \"Requirement already satisfied: sympy in /usr/local/lib/python3.9/dist-packages (from torch==2.0.0->torchvision->mmpose==1.0.0) (1.11.1)\\n\",\n            \"Requirement already satisfied: cmake in /usr/local/lib/python3.9/dist-packages (from triton==2.0.0->torch==2.0.0->torchvision->mmpose==1.0.0) (3.25.2)\\n\",\n            \"Requirement already satisfied: lit in /usr/local/lib/python3.9/dist-packages (from triton==2.0.0->torch==2.0.0->torchvision->mmpose==1.0.0) (16.0.1)\\n\",\n            \"Requirement already satisfied: zipp>=3.1.0 in /usr/local/lib/python3.9/dist-packages (from importlib-resources>=3.2.0->matplotlib->mmpose==1.0.0) (3.15.0)\\n\",\n            \"Requirement already satisfied: certifi>=2017.4.17 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision->mmpose==1.0.0) (2022.12.7)\\n\",\n            \"Requirement already satisfied: idna<4,>=2.5 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision->mmpose==1.0.0) (3.4)\\n\",\n            \"Requirement already satisfied: urllib3<1.27,>=1.21.1 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision->mmpose==1.0.0) (1.26.15)\\n\",\n            \"Requirement already satisfied: charset-normalizer~=2.0.0 in /usr/local/lib/python3.9/dist-packages (from requests->torchvision->mmpose==1.0.0) (2.0.12)\\n\",\n            \"Requirement already satisfied: MarkupSafe>=2.0 in /usr/local/lib/python3.9/dist-packages (from jinja2->torch==2.0.0->torchvision->mmpose==1.0.0) (2.1.2)\\n\",\n            \"Requirement already satisfied: mpmath>=0.19 in /usr/local/lib/python3.9/dist-packages (from sympy->torch==2.0.0->torchvision->mmpose==1.0.0) (1.3.0)\\n\",\n            \"Installing collected packages: mmpose\\n\",\n            \"  Running setup.py develop for mmpose\\n\",\n            \"    Running command python setup.py develop\\n\",\n            \"    running develop\\n\",\n            \"    /usr/local/lib/python3.9/dist-packages/setuptools/command/easy_install.py:144: EasyInstallDeprecationWarning: easy_install command is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"      warnings.warn(\\n\",\n            \"    /usr/local/lib/python3.9/dist-packages/setuptools/command/install.py:34: SetuptoolsDeprecationWarning: setup.py install is deprecated. Use build and pip and other standards-based tools.\\n\",\n            \"      warnings.warn(\\n\",\n            \"    running egg_info\\n\",\n            \"    creating mmpose.egg-info\\n\",\n            \"    writing mmpose.egg-info/PKG-INFO\\n\",\n            \"    writing dependency_links to mmpose.egg-info/dependency_links.txt\\n\",\n            \"    writing requirements to mmpose.egg-info/requires.txt\\n\",\n            \"    writing top-level names to mmpose.egg-info/top_level.txt\\n\",\n            \"    writing manifest file 'mmpose.egg-info/SOURCES.txt'\\n\",\n            \"    reading manifest file 'mmpose.egg-info/SOURCES.txt'\\n\",\n            \"    reading manifest template 'MANIFEST.in'\\n\",\n            \"    adding license file 'LICENSE'\\n\",\n            \"    writing manifest file 'mmpose.egg-info/SOURCES.txt'\\n\",\n            \"    running build_ext\\n\",\n            \"    Creating /usr/local/lib/python3.9/dist-packages/mmpose.egg-link (link to .)\\n\",\n            \"    Adding mmpose 1.0.0 to easy-install.pth file\\n\",\n            \"\\n\",\n            \"    Installed /content/mmpose\\n\",\n            \"Successfully installed mmpose-1.0.0\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"!git clone https://github.com/open-mmlab/mmpose.git\\n\",\n        \"# The master branch is version 1.x \\n\",\n        \"%cd mmpose\\n\",\n        \"%pip install -r requirements.txt\\n\",\n        \"%pip install -v -e .\\n\",\n        \"# \\\"-v\\\" means verbose, or more output\\n\",\n        \"# \\\"-e\\\" means installing a project in editable mode,\\n\",\n        \"# thus any local modifications made to the code will take effect without reinstallation.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 6,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"Miy2zVRcw6kL\",\n        \"outputId\": \"1cbae5a0-249a-4cb2-980a-7db592c759da\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"torch version: 2.0.0+cu118 True\\n\",\n            \"torchvision version: 0.15.1+cu118\\n\",\n            \"mmpose version: 1.0.0\\n\",\n            \"cuda version: 11.8\\n\",\n            \"compiler information: GCC 9.3\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# Check Pytorch installation\\n\",\n        \"import torch, torchvision\\n\",\n        \"\\n\",\n        \"print('torch version:', torch.__version__, torch.cuda.is_available())\\n\",\n        \"print('torchvision version:', torchvision.__version__)\\n\",\n        \"\\n\",\n        \"# Check MMPose installation\\n\",\n        \"import mmpose\\n\",\n        \"\\n\",\n        \"print('mmpose version:', mmpose.__version__)\\n\",\n        \"\\n\",\n        \"# Check mmcv installation\\n\",\n        \"from mmcv.ops import get_compiling_cuda_version, get_compiler_version\\n\",\n        \"\\n\",\n        \"print('cuda version:', get_compiling_cuda_version())\\n\",\n        \"print('compiler information:', get_compiler_version())\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"r2bf94XpyFnk\"\n      },\n      \"source\": [\n        \"## Inference with an MMPose model\\n\",\n        \"\\n\",\n        \"MMPose provides high-level APIs for model inference and training.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 7,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"JjTt4LZAx_lK\",\n        \"outputId\": \"485b62c4-226b-45fb-a864-99c2a029353c\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Loads checkpoint by http backend from path: https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth\\n\"\n          ]\n        },\n        {\n          \"name\": \"stderr\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Downloading: \\\"https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth\\\" to /root/.cache/torch/hub/checkpoints/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth\\n\"\n          ]\n        },\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Loads checkpoint by http backend from path: https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth\\n\"\n          ]\n        },\n        {\n          \"name\": \"stderr\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Downloading: \\\"https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth\\\" to /root/.cache/torch/hub/checkpoints/hrnet_w32_coco_256x192-c78dce93_20200708.pth\\n\"\n          ]\n        },\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"04/13 16:14:37 - mmengine - WARNING - `Visualizer` backend is not initialized because save_dir is None.\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"import mmcv\\n\",\n        \"from mmcv import imread\\n\",\n        \"import mmengine\\n\",\n        \"from mmengine.registry import init_default_scope\\n\",\n        \"import numpy as np\\n\",\n        \"\\n\",\n        \"from mmpose.apis import inference_topdown\\n\",\n        \"from mmpose.apis import init_model as init_pose_estimator\\n\",\n        \"from mmpose.evaluation.functional import nms\\n\",\n        \"from mmpose.registry import VISUALIZERS\\n\",\n        \"from mmpose.structures import merge_data_samples\\n\",\n        \"\\n\",\n        \"try:\\n\",\n        \"    from mmdet.apis import inference_detector, init_detector\\n\",\n        \"    has_mmdet = True\\n\",\n        \"except (ImportError, ModuleNotFoundError):\\n\",\n        \"    has_mmdet = False\\n\",\n        \"\\n\",\n        \"local_runtime = False\\n\",\n        \"\\n\",\n        \"try:\\n\",\n        \"    from google.colab.patches import cv2_imshow  # for image visualization in colab\\n\",\n        \"except:\\n\",\n        \"    local_runtime = True\\n\",\n        \"\\n\",\n        \"img = 'tests/data/coco/000000197388.jpg'\\n\",\n        \"pose_config = 'configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py'\\n\",\n        \"pose_checkpoint = 'https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth'\\n\",\n        \"det_config = 'demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py'\\n\",\n        \"det_checkpoint = 'https://download.openmmlab.com/mmdetection/v2.0/faster_rcnn/faster_rcnn_r50_fpn_1x_coco/faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'\\n\",\n        \"\\n\",\n        \"device = 'cuda:0'\\n\",\n        \"cfg_options = dict(model=dict(test_cfg=dict(output_heatmaps=True)))\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"# build detector\\n\",\n        \"detector = init_detector(\\n\",\n        \"    det_config,\\n\",\n        \"    det_checkpoint,\\n\",\n        \"    device=device\\n\",\n        \")\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"# build pose estimator\\n\",\n        \"pose_estimator = init_pose_estimator(\\n\",\n        \"    pose_config,\\n\",\n        \"    pose_checkpoint,\\n\",\n        \"    device=device,\\n\",\n        \"    cfg_options=cfg_options\\n\",\n        \")\\n\",\n        \"\\n\",\n        \"# init visualizer\\n\",\n        \"pose_estimator.cfg.visualizer.radius = 3\\n\",\n        \"pose_estimator.cfg.visualizer.line_width = 1\\n\",\n        \"visualizer = VISUALIZERS.build(pose_estimator.cfg.visualizer)\\n\",\n        \"# the dataset_meta is loaded from the checkpoint and\\n\",\n        \"# then pass to the model in init_pose_estimator\\n\",\n        \"visualizer.set_dataset_meta(pose_estimator.dataset_meta)\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 8,\n      \"metadata\": {\n        \"id\": \"tsSM0NRPEG1Z\"\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"\\n\",\n        \"def visualize_img(img_path, detector, pose_estimator, visualizer,\\n\",\n        \"                  show_interval, out_file):\\n\",\n        \"    \\\"\\\"\\\"Visualize predicted keypoints (and heatmaps) of one image.\\\"\\\"\\\"\\n\",\n        \"\\n\",\n        \"    # predict bbox\\n\",\n        \"    scope = detector.cfg.get('default_scope', 'mmdet')\\n\",\n        \"    if scope is not None:\\n\",\n        \"        init_default_scope(scope)\\n\",\n        \"    detect_result = inference_detector(detector, img_path)\\n\",\n        \"    pred_instance = detect_result.pred_instances.cpu().numpy()\\n\",\n        \"    bboxes = np.concatenate(\\n\",\n        \"        (pred_instance.bboxes, pred_instance.scores[:, None]), axis=1)\\n\",\n        \"    bboxes = bboxes[np.logical_and(pred_instance.labels == 0,\\n\",\n        \"                                   pred_instance.scores > 0.3)]\\n\",\n        \"    bboxes = bboxes[nms(bboxes, 0.3)][:, :4]\\n\",\n        \"\\n\",\n        \"    # predict keypoints\\n\",\n        \"    pose_results = inference_topdown(pose_estimator, img_path, bboxes)\\n\",\n        \"    data_samples = merge_data_samples(pose_results)\\n\",\n        \"\\n\",\n        \"    # show the results\\n\",\n        \"    img = mmcv.imread(img_path, channel_order='rgb')\\n\",\n        \"\\n\",\n        \"    visualizer.add_datasample(\\n\",\n        \"        'result',\\n\",\n        \"        img,\\n\",\n        \"        data_sample=data_samples,\\n\",\n        \"        draw_gt=False,\\n\",\n        \"        draw_heatmap=True,\\n\",\n        \"        draw_bbox=True,\\n\",\n        \"        show=False,\\n\",\n        \"        wait_time=show_interval,\\n\",\n        \"        out_file=out_file,\\n\",\n        \"        kpt_thr=0.3)\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 9,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"ogj5h9x-HiMA\",\n        \"outputId\": \"71452169-c16a-4a61-b558-f7518fcefaa0\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"04/13 16:15:22 - mmengine - WARNING - The current default scope \\\"mmpose\\\" is not \\\"mmdet\\\", `init_default_scope` will force set the currentdefault scope to \\\"mmdet\\\".\\n\",\n            \"04/13 16:15:29 - mmengine - WARNING - The current default scope \\\"mmdet\\\" is not \\\"mmpose\\\", `init_default_scope` will force set the currentdefault scope to \\\"mmpose\\\".\\n\"\n          ]\n        },\n        {\n          \"name\": \"stderr\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"/usr/local/lib/python3.9/dist-packages/mmengine/visualization/visualizer.py:664: UserWarning: Warning: The circle is out of bounds, the drawn circle may not be in the image\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/mmengine/visualization/visualizer.py:741: UserWarning: Warning: The bbox is out of bounds, the drawn bbox may not be in the image\\n\",\n            \"  warnings.warn(\\n\",\n            \"/usr/local/lib/python3.9/dist-packages/mmengine/visualization/visualizer.py:812: UserWarning: Warning: The polygon is out of bounds, the drawn polygon may not be in the image\\n\",\n            \"  warnings.warn(\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"visualize_img(\\n\",\n        \"    img,\\n\",\n        \"    detector,\\n\",\n        \"    pose_estimator,\\n\",\n        \"    visualizer,\\n\",\n        \"    show_interval=0,\\n\",\n        \"    out_file=None)\\n\",\n        \"\\n\",\n        \"vis_result = visualizer.get_image()\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": 10,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\",\n          \"height\": 801\n        },\n        \"id\": \"CEYxupWT3aJY\",\n        \"outputId\": \"05acd979-25b1-4b18-8738-d6b9edc6bfe1\"\n      },\n      \"outputs\": [\n        {\n          \"data\": {\n            \"image/png\": \"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\",\n            \"text/plain\": [\n              \"<PIL.Image.Image image mode=RGB size=640x784 at 0x7F06C5D2B8E0>\"\n            ]\n          },\n          \"metadata\": {},\n          \"output_type\": \"display_data\"\n        }\n      ],\n      \"source\": [\n        \"if local_runtime:\\n\",\n        \"    from IPython.display import Image, display\\n\",\n        \"    import tempfile\\n\",\n        \"    import os.path as osp\\n\",\n        \"    import cv2\\n\",\n        \"    with tempfile.TemporaryDirectory() as tmpdir:\\n\",\n        \"        file_name = osp.join(tmpdir, 'pose_results.png')\\n\",\n        \"        cv2.imwrite(file_name, vis_result[:,:,::-1])\\n\",\n        \"        display(Image(file_name))\\n\",\n        \"else:\\n\",\n        \"    cv2_imshow(vis_result[:,:,::-1]) #RGB2BGR to fit cv2\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"42HG6DSNI0Ke\"\n      },\n      \"source\": [\n        \"### Add a new dataset\\n\",\n        \"\\n\",\n        \"There are two methods to support a customized dataset in MMPose. The first one is to convert the data to a supported format (e.g. COCO) and use the corresponding dataset class (e.g. BaseCocoStyleDataset), as described in the [document](https://mmpose.readthedocs.io/en/1.x/user_guides/prepare_datasets.html). The second one is to add a new dataset class. In this tutorial, we give an example of the second method.\\n\",\n        \"\\n\",\n        \"We first download the demo dataset, which contains 100 samples (75 for training and 25 for validation) selected from COCO train2017 dataset. The annotations are stored in a different format from the original COCO format.\\n\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"qGzSb0Rm-p3V\",\n        \"outputId\": \"2e7ec2ba-88e1-490f-cd5a-66ef06ec3e52\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"/content/mmpose/data\\n\",\n            \"--2022-09-14 10:39:37--  https://download.openmmlab.com/mmpose/datasets/coco_tiny.tar\\n\",\n            \"Resolving download.openmmlab.com (download.openmmlab.com)... 47.89.140.71\\n\",\n            \"Connecting to download.openmmlab.com (download.openmmlab.com)|47.89.140.71|:443... connected.\\n\",\n            \"HTTP request sent, awaiting response... 200 OK\\n\",\n            \"Length: 16558080 (16M) [application/x-tar]\\n\",\n            \"Saving to: ‘coco_tiny.tar’\\n\",\n            \"\\n\",\n            \"coco_tiny.tar       100%[===================>]  15.79M  9.14MB/s    in 1.7s    \\n\",\n            \"\\n\",\n            \"2022-09-14 10:39:40 (9.14 MB/s) - ‘coco_tiny.tar’ saved [16558080/16558080]\\n\",\n            \"\\n\",\n            \"/content/mmpose\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# download dataset\\n\",\n        \"%mkdir data\\n\",\n        \"%cd data\\n\",\n        \"!wget https://download.openmmlab.com/mmpose/datasets/coco_tiny.tar\\n\",\n        \"!tar -xf coco_tiny.tar\\n\",\n        \"%cd ..\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"fL6S62JWJls0\",\n        \"outputId\": \"fe4cf7c9-5a8c-4542-f0b1-fe01908ca3e4\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"Reading package lists...\\n\",\n            \"Building dependency tree...\\n\",\n            \"Reading state information...\\n\",\n            \"The following package was automatically installed and is no longer required:\\n\",\n            \"  libnvidia-common-460\\n\",\n            \"Use 'apt autoremove' to remove it.\\n\",\n            \"The following NEW packages will be installed:\\n\",\n            \"  tree\\n\",\n            \"0 upgraded, 1 newly installed, 0 to remove and 32 not upgraded.\\n\",\n            \"Need to get 40.7 kB of archives.\\n\",\n            \"After this operation, 105 kB of additional disk space will be used.\\n\",\n            \"Get:1 http://archive.ubuntu.com/ubuntu bionic/universe amd64 tree amd64 1.7.0-5 [40.7 kB]\\n\",\n            \"Fetched 40.7 kB in 0s (161 kB/s)\\n\",\n            \"Selecting previously unselected package tree.\\n\",\n            \"(Reading database ... 155685 files and directories currently installed.)\\n\",\n            \"Preparing to unpack .../tree_1.7.0-5_amd64.deb ...\\n\",\n            \"Unpacking tree (1.7.0-5) ...\\n\",\n            \"Setting up tree (1.7.0-5) ...\\n\",\n            \"Processing triggers for man-db (2.8.3-2ubuntu0.1) ...\\n\",\n            \"data/coco_tiny\\n\",\n            \"├── images\\n\",\n            \"│   ├── 000000012754.jpg\\n\",\n            \"│   ├── 000000017741.jpg\\n\",\n            \"│   ├── 000000019157.jpg\\n\",\n            \"│   ├── 000000019523.jpg\\n\",\n            \"│   ├── 000000019608.jpg\\n\",\n            \"│   ├── 000000022816.jpg\\n\",\n            \"│   ├── 000000031092.jpg\\n\",\n            \"│   ├── 000000032124.jpg\\n\",\n            \"│   ├── 000000037209.jpg\\n\",\n            \"│   ├── 000000050713.jpg\\n\",\n            \"│   ├── 000000057703.jpg\\n\",\n            \"│   ├── 000000064909.jpg\\n\",\n            \"│   ├── 000000076942.jpg\\n\",\n            \"│   ├── 000000079754.jpg\\n\",\n            \"│   ├── 000000083935.jpg\\n\",\n            \"│   ├── 000000085316.jpg\\n\",\n            \"│   ├── 000000101013.jpg\\n\",\n            \"│   ├── 000000101172.jpg\\n\",\n            \"│   ├── 000000103134.jpg\\n\",\n            \"│   ├── 000000103163.jpg\\n\",\n            \"│   ├── 000000105647.jpg\\n\",\n            \"│   ├── 000000107960.jpg\\n\",\n            \"│   ├── 000000117891.jpg\\n\",\n            \"│   ├── 000000118181.jpg\\n\",\n            \"│   ├── 000000120021.jpg\\n\",\n            \"│   ├── 000000128119.jpg\\n\",\n            \"│   ├── 000000143908.jpg\\n\",\n            \"│   ├── 000000145025.jpg\\n\",\n            \"│   ├── 000000147386.jpg\\n\",\n            \"│   ├── 000000147979.jpg\\n\",\n            \"│   ├── 000000154222.jpg\\n\",\n            \"│   ├── 000000160190.jpg\\n\",\n            \"│   ├── 000000161112.jpg\\n\",\n            \"│   ├── 000000175737.jpg\\n\",\n            \"│   ├── 000000177069.jpg\\n\",\n            \"│   ├── 000000184659.jpg\\n\",\n            \"│   ├── 000000209468.jpg\\n\",\n            \"│   ├── 000000210060.jpg\\n\",\n            \"│   ├── 000000215867.jpg\\n\",\n            \"│   ├── 000000216861.jpg\\n\",\n            \"│   ├── 000000227224.jpg\\n\",\n            \"│   ├── 000000246265.jpg\\n\",\n            \"│   ├── 000000254919.jpg\\n\",\n            \"│   ├── 000000263687.jpg\\n\",\n            \"│   ├── 000000264628.jpg\\n\",\n            \"│   ├── 000000268927.jpg\\n\",\n            \"│   ├── 000000271177.jpg\\n\",\n            \"│   ├── 000000275219.jpg\\n\",\n            \"│   ├── 000000277542.jpg\\n\",\n            \"│   ├── 000000279140.jpg\\n\",\n            \"│   ├── 000000286813.jpg\\n\",\n            \"│   ├── 000000297980.jpg\\n\",\n            \"│   ├── 000000301641.jpg\\n\",\n            \"│   ├── 000000312341.jpg\\n\",\n            \"│   ├── 000000325768.jpg\\n\",\n            \"│   ├── 000000332221.jpg\\n\",\n            \"│   ├── 000000345071.jpg\\n\",\n            \"│   ├── 000000346965.jpg\\n\",\n            \"│   ├── 000000347836.jpg\\n\",\n            \"│   ├── 000000349437.jpg\\n\",\n            \"│   ├── 000000360735.jpg\\n\",\n            \"│   ├── 000000362343.jpg\\n\",\n            \"│   ├── 000000364079.jpg\\n\",\n            \"│   ├── 000000364113.jpg\\n\",\n            \"│   ├── 000000386279.jpg\\n\",\n            \"│   ├── 000000386968.jpg\\n\",\n            \"│   ├── 000000388619.jpg\\n\",\n            \"│   ├── 000000390137.jpg\\n\",\n            \"│   ├── 000000390241.jpg\\n\",\n            \"│   ├── 000000390298.jpg\\n\",\n            \"│   ├── 000000390348.jpg\\n\",\n            \"│   ├── 000000398606.jpg\\n\",\n            \"│   ├── 000000400456.jpg\\n\",\n            \"│   ├── 000000402514.jpg\\n\",\n            \"│   ├── 000000403255.jpg\\n\",\n            \"│   ├── 000000403432.jpg\\n\",\n            \"│   ├── 000000410350.jpg\\n\",\n            \"│   ├── 000000453065.jpg\\n\",\n            \"│   ├── 000000457254.jpg\\n\",\n            \"│   ├── 000000464153.jpg\\n\",\n            \"│   ├── 000000464515.jpg\\n\",\n            \"│   ├── 000000465418.jpg\\n\",\n            \"│   ├── 000000480591.jpg\\n\",\n            \"│   ├── 000000484279.jpg\\n\",\n            \"│   ├── 000000494014.jpg\\n\",\n            \"│   ├── 000000515289.jpg\\n\",\n            \"│   ├── 000000516805.jpg\\n\",\n            \"│   ├── 000000521994.jpg\\n\",\n            \"│   ├── 000000528962.jpg\\n\",\n            \"│   ├── 000000534736.jpg\\n\",\n            \"│   ├── 000000535588.jpg\\n\",\n            \"│   ├── 000000537548.jpg\\n\",\n            \"│   ├── 000000553698.jpg\\n\",\n            \"│   ├── 000000555622.jpg\\n\",\n            \"│   ├── 000000566456.jpg\\n\",\n            \"│   ├── 000000567171.jpg\\n\",\n            \"│   └── 000000568961.jpg\\n\",\n            \"├── train.json\\n\",\n            \"└── val.json\\n\",\n            \"\\n\",\n            \"1 directory, 99 files\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# check the directory structure\\n\",\n        \"!apt-get -q install tree\\n\",\n        \"!tree data/coco_tiny\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"Hl09rtA4Jn5b\",\n        \"outputId\": \"e94e84ea-7192-4d2f-9747-716931953d6d\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"<class 'list'> 75\\n\",\n            \"{'bbox': [267.03, 104.32, 229.19, 320],\\n\",\n            \" 'image_file': '000000537548.jpg',\\n\",\n            \" 'image_size': [640, 480],\\n\",\n            \" 'keypoints': [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 325, 160, 2, 398,\\n\",\n            \"               177, 2, 0, 0, 0, 437, 238, 2, 0, 0, 0, 477, 270, 2, 287, 255, 1,\\n\",\n            \"               339, 267, 2, 0, 0, 0, 423, 314, 2, 0, 0, 0, 355, 367, 2]}\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"# check the annotation format\\n\",\n        \"import json\\n\",\n        \"import pprint\\n\",\n        \"\\n\",\n        \"anns = json.load(open('data/coco_tiny/train.json'))\\n\",\n        \"\\n\",\n        \"print(type(anns), len(anns))\\n\",\n        \"pprint.pprint(anns[0], compact=True)\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"H-dMbjgnJzbH\"\n      },\n      \"source\": [\n        \"After downloading the data, we implement a new dataset class to load data samples for model training and validation. Assume that we are going to train a top-down pose estimation model, the new dataset class inherits `BaseCocoStyleDataset`.\\n\",\n        \"\\n\",\n        \"We have already implemented a `CocoDataset` so that we can take it as an example.\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"jCu4npV2rl_Q\"\n      },\n      \"source\": [\n        \"#### Note\\n\",\n        \"If you meet the following error:\\n\",\n        \"```shell\\n\",\n        \"AssertionError: class `PoseLocalVisualizer` in mmpose/visualization/local_visualizer.py: <class 'mmpose.visualization.local_visualizer.PoseLocalVisualizer'> instance named of visualizer has been created, the method `get_instance` should not access any other arguments\\n\",\n        \"```\\n\",\n        \"Please reboot your jupyter kernel and start running from here.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"id\": \"3I66Pi5Er94J\"\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"%cd mmpose\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"id\": \"rRNq50dytJki\"\n      },\n      \"outputs\": [],\n      \"source\": [\n        \"# Copyright (c) OpenMMLab. All rights reserved.\\n\",\n        \"import json\\n\",\n        \"import os.path as osp\\n\",\n        \"from typing import Callable, List, Optional, Sequence, Union\\n\",\n        \"\\n\",\n        \"import numpy as np\\n\",\n        \"from mmengine.utils import check_file_exist\\n\",\n        \"\\n\",\n        \"from mmpose.registry import DATASETS\\n\",\n        \"from mmpose.datasets.datasets.base import BaseCocoStyleDataset\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"@DATASETS.register_module()\\n\",\n        \"class TinyCocoDataset(BaseCocoStyleDataset):\\n\",\n        \"    METAINFO: dict = dict(from_file='configs/_base_/datasets/coco.py')\\n\",\n        \"\\n\",\n        \"    def _load_annotations(self) -> List[dict]:\\n\",\n        \"        \\\"\\\"\\\"Load data from annotations in MPII format.\\\"\\\"\\\"\\n\",\n        \"\\n\",\n        \"        check_file_exist(self.ann_file)\\n\",\n        \"        with open(self.ann_file) as anno_file:\\n\",\n        \"            anns = json.load(anno_file)\\n\",\n        \"\\n\",\n        \"        data_list = []\\n\",\n        \"        ann_id = 0\\n\",\n        \"\\n\",\n        \"        for idx, ann in enumerate(anns):\\n\",\n        \"            img_h, img_w = ann['image_size']\\n\",\n        \"\\n\",\n        \"            # get bbox in shape [1, 4], formatted as xywh\\n\",\n        \"            x, y, w, h = ann['bbox']\\n\",\n        \"            x1 = np.clip(x, 0, img_w - 1)\\n\",\n        \"            y1 = np.clip(y, 0, img_h - 1)\\n\",\n        \"            x2 = np.clip(x + w, 0, img_w - 1)\\n\",\n        \"            y2 = np.clip(y + h, 0, img_h - 1)\\n\",\n        \"\\n\",\n        \"            bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\\n\",\n        \"\\n\",\n        \"            # load keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\\n\",\n        \"            joints_3d = np.array(ann['keypoints']).reshape(1, -1, 3)\\n\",\n        \"            num_joints = joints_3d.shape[1]\\n\",\n        \"            keypoints = np.zeros((1, num_joints, 2), dtype=np.float32)\\n\",\n        \"            keypoints[:, :, :2] = joints_3d[:, :, :2]\\n\",\n        \"            keypoints_visible = np.minimum(1, joints_3d[:, :, 2:3])\\n\",\n        \"            keypoints_visible = keypoints_visible.reshape(1, -1)\\n\",\n        \"\\n\",\n        \"            data_info = {\\n\",\n        \"                'id': ann_id,\\n\",\n        \"                'img_id': int(ann['image_file'].split('.')[0]),\\n\",\n        \"                'img_path': osp.join(self.data_prefix['img'], ann['image_file']),\\n\",\n        \"                'bbox': bbox,\\n\",\n        \"                'bbox_score': np.ones(1, dtype=np.float32),\\n\",\n        \"                'keypoints': keypoints,\\n\",\n        \"                'keypoints_visible': keypoints_visible,\\n\",\n        \"            }\\n\",\n        \"\\n\",\n        \"            data_list.append(data_info)\\n\",\n        \"            ann_id = ann_id + 1\\n\",\n        \"\\n\",\n        \"        return data_list, None\\n\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"UmGitQZkUnom\"\n      },\n      \"source\": [\n        \"### Create a config file\\n\",\n        \"\\n\",\n        \"In the next step, we create a config file which configures the model, dataset and runtime settings. More information can be found at [Configs](https://mmpose.readthedocs.io/en/1.x/user_guides/configs.html). A common practice to create a config file is deriving from a existing one. In this tutorial, we load a config file that trains a HRNet on COCO dataset, and modify it to adapt to the COCOTiny dataset.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\"\n        },\n        \"id\": \"sMbVVHPXK87s\",\n        \"outputId\": \"a23a1ed9-a2ee-4a6a-93da-3c1968c8a2ec\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"default_scope = 'mmpose'\\n\",\n            \"default_hooks = dict(\\n\",\n            \"    timer=dict(type='IterTimerHook'),\\n\",\n            \"    logger=dict(type='LoggerHook', interval=50),\\n\",\n            \"    param_scheduler=dict(type='ParamSchedulerHook'),\\n\",\n            \"    checkpoint=dict(\\n\",\n            \"        type='CheckpointHook',\\n\",\n            \"        interval=1,\\n\",\n            \"        save_best='pck/PCK@0.05',\\n\",\n            \"        rule='greater',\\n\",\n            \"        max_keep_ckpts=1),\\n\",\n            \"    sampler_seed=dict(type='DistSamplerSeedHook'),\\n\",\n            \"    visualization=dict(type='PoseVisualizationHook', enable=False))\\n\",\n            \"custom_hooks = [dict(type='SyncBuffersHook')]\\n\",\n            \"env_cfg = dict(\\n\",\n            \"    cudnn_benchmark=False,\\n\",\n            \"    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\\n\",\n            \"    dist_cfg=dict(backend='nccl'))\\n\",\n            \"vis_backends = [dict(type='LocalVisBackend')]\\n\",\n            \"visualizer = dict(\\n\",\n            \"    type='PoseLocalVisualizer',\\n\",\n            \"    vis_backends=[dict(type='LocalVisBackend')],\\n\",\n            \"    name='visualizer')\\n\",\n            \"log_processor = dict(\\n\",\n            \"    type='LogProcessor', window_size=50, by_epoch=True, num_digits=6)\\n\",\n            \"log_level = 'INFO'\\n\",\n            \"load_from = None\\n\",\n            \"resume = False\\n\",\n            \"file_client_args = dict(backend='disk')\\n\",\n            \"train_cfg = dict(by_epoch=True, max_epochs=40, val_interval=1)\\n\",\n            \"val_cfg = dict()\\n\",\n            \"test_cfg = dict()\\n\",\n            \"optim_wrapper = dict(optimizer=dict(type='Adam', lr=0.0005))\\n\",\n            \"param_scheduler = [\\n\",\n            \"    dict(type='LinearLR', begin=0, end=10, start_factor=0.001, by_epoch=False),\\n\",\n            \"    dict(\\n\",\n            \"        type='MultiStepLR',\\n\",\n            \"        begin=0,\\n\",\n            \"        end=40,\\n\",\n            \"        milestones=[17, 35],\\n\",\n            \"        gamma=0.1,\\n\",\n            \"        by_epoch=True)\\n\",\n            \"]\\n\",\n            \"auto_scale_lr = dict(base_batch_size=512)\\n\",\n            \"codec = dict(\\n\",\n            \"    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\\n\",\n            \"model = dict(\\n\",\n            \"    type='TopdownPoseEstimator',\\n\",\n            \"    data_preprocessor=dict(\\n\",\n            \"        type='PoseDataPreprocessor',\\n\",\n            \"        mean=[123.675, 116.28, 103.53],\\n\",\n            \"        std=[58.395, 57.12, 57.375],\\n\",\n            \"        bgr_to_rgb=True),\\n\",\n            \"    backbone=dict(\\n\",\n            \"        type='HRNet',\\n\",\n            \"        in_channels=3,\\n\",\n            \"        extra=dict(\\n\",\n            \"            stage1=dict(\\n\",\n            \"                num_modules=1,\\n\",\n            \"                num_branches=1,\\n\",\n            \"                block='BOTTLENECK',\\n\",\n            \"                num_blocks=(4, ),\\n\",\n            \"                num_channels=(64, )),\\n\",\n            \"            stage2=dict(\\n\",\n            \"                num_modules=1,\\n\",\n            \"                num_branches=2,\\n\",\n            \"                block='BASIC',\\n\",\n            \"                num_blocks=(4, 4),\\n\",\n            \"                num_channels=(32, 64)),\\n\",\n            \"            stage3=dict(\\n\",\n            \"                num_modules=4,\\n\",\n            \"                num_branches=3,\\n\",\n            \"                block='BASIC',\\n\",\n            \"                num_blocks=(4, 4, 4),\\n\",\n            \"                num_channels=(32, 64, 128)),\\n\",\n            \"            stage4=dict(\\n\",\n            \"                num_modules=3,\\n\",\n            \"                num_branches=4,\\n\",\n            \"                block='BASIC',\\n\",\n            \"                num_blocks=(4, 4, 4, 4),\\n\",\n            \"                num_channels=(32, 64, 128, 256))),\\n\",\n            \"        init_cfg=dict(\\n\",\n            \"            type='Pretrained',\\n\",\n            \"            checkpoint=\\n\",\n            \"            'https://download.openmmlab.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth'\\n\",\n            \"        )),\\n\",\n            \"    head=dict(\\n\",\n            \"        type='HeatmapHead',\\n\",\n            \"        in_channels=32,\\n\",\n            \"        out_channels=17,\\n\",\n            \"        deconv_out_channels=None,\\n\",\n            \"        loss=dict(type='KeypointMSELoss', use_target_weight=True),\\n\",\n            \"        decoder=dict(\\n\",\n            \"            type='MSRAHeatmap',\\n\",\n            \"            input_size=(192, 256),\\n\",\n            \"            heatmap_size=(48, 64),\\n\",\n            \"            sigma=2)),\\n\",\n            \"    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))\\n\",\n            \"dataset_type = 'TinyCocoDataset'\\n\",\n            \"data_mode = 'topdown'\\n\",\n            \"data_root = 'data/coco_tiny'\\n\",\n            \"train_pipeline = [\\n\",\n            \"    dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"    dict(type='GetBBoxCenterScale'),\\n\",\n            \"    dict(type='RandomFlip', direction='horizontal'),\\n\",\n            \"    dict(type='RandomHalfBody'),\\n\",\n            \"    dict(type='RandomBBoxTransform'),\\n\",\n            \"    dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"    dict(\\n\",\n            \"        type='GenerateTarget',\\n\",\n            \"        target_type='heatmap',\\n\",\n            \"        encoder=dict(\\n\",\n            \"            type='MSRAHeatmap',\\n\",\n            \"            input_size=(192, 256),\\n\",\n            \"            heatmap_size=(48, 64),\\n\",\n            \"            sigma=2)),\\n\",\n            \"    dict(type='PackPoseInputs')\\n\",\n            \"]\\n\",\n            \"test_pipeline = [\\n\",\n            \"    dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"    dict(type='GetBBoxCenterScale'),\\n\",\n            \"    dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"    dict(type='PackPoseInputs')\\n\",\n            \"]\\n\",\n            \"train_dataloader = dict(\\n\",\n            \"    batch_size=16,\\n\",\n            \"    num_workers=2,\\n\",\n            \"    persistent_workers=True,\\n\",\n            \"    sampler=dict(type='DefaultSampler', shuffle=True),\\n\",\n            \"    dataset=dict(\\n\",\n            \"        type='TinyCocoDataset',\\n\",\n            \"        data_root='data/coco_tiny',\\n\",\n            \"        data_mode='topdown',\\n\",\n            \"        ann_file='train.json',\\n\",\n            \"        data_prefix=dict(img='images/'),\\n\",\n            \"        pipeline=[\\n\",\n            \"            dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"            dict(type='GetBBoxCenterScale'),\\n\",\n            \"            dict(type='RandomFlip', direction='horizontal'),\\n\",\n            \"            dict(type='RandomHalfBody'),\\n\",\n            \"            dict(type='RandomBBoxTransform'),\\n\",\n            \"            dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"            dict(\\n\",\n            \"                type='GenerateTarget',\\n\",\n            \"                target_type='heatmap',\\n\",\n            \"                encoder=dict(\\n\",\n            \"                    type='MSRAHeatmap',\\n\",\n            \"                    input_size=(192, 256),\\n\",\n            \"                    heatmap_size=(48, 64),\\n\",\n            \"                    sigma=2)),\\n\",\n            \"            dict(type='PackPoseInputs')\\n\",\n            \"        ]))\\n\",\n            \"val_dataloader = dict(\\n\",\n            \"    batch_size=16,\\n\",\n            \"    num_workers=2,\\n\",\n            \"    persistent_workers=True,\\n\",\n            \"    drop_last=False,\\n\",\n            \"    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\\n\",\n            \"    dataset=dict(\\n\",\n            \"        type='TinyCocoDataset',\\n\",\n            \"        data_root='data/coco_tiny',\\n\",\n            \"        data_mode='topdown',\\n\",\n            \"        ann_file='val.json',\\n\",\n            \"        bbox_file=None,\\n\",\n            \"        data_prefix=dict(img='images/'),\\n\",\n            \"        test_mode=True,\\n\",\n            \"        pipeline=[\\n\",\n            \"            dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"            dict(type='GetBBoxCenterScale'),\\n\",\n            \"            dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"            dict(type='PackPoseInputs')\\n\",\n            \"        ]))\\n\",\n            \"test_dataloader = dict(\\n\",\n            \"    batch_size=16,\\n\",\n            \"    num_workers=2,\\n\",\n            \"    persistent_workers=True,\\n\",\n            \"    drop_last=False,\\n\",\n            \"    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\\n\",\n            \"    dataset=dict(\\n\",\n            \"        type='TinyCocoDataset',\\n\",\n            \"        data_root='data/coco_tiny',\\n\",\n            \"        data_mode='topdown',\\n\",\n            \"        ann_file='val.json',\\n\",\n            \"        bbox_file=None,\\n\",\n            \"        data_prefix=dict(img='images/'),\\n\",\n            \"        test_mode=True,\\n\",\n            \"        pipeline=[\\n\",\n            \"            dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"            dict(type='GetBBoxCenterScale'),\\n\",\n            \"            dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"            dict(type='PackPoseInputs')\\n\",\n            \"        ]))\\n\",\n            \"val_evaluator = dict(type='PCKAccuracy')\\n\",\n            \"test_evaluator = dict(type='PCKAccuracy')\\n\",\n            \"work_dir = 'work_dirs/hrnet_w32_coco_tiny_256x192'\\n\",\n            \"randomness = dict(seed=0)\\n\",\n            \"\\n\"\n          ]\n        }\n      ],\n      \"source\": [\n        \"from mmengine import Config\\n\",\n        \"\\n\",\n        \"cfg = Config.fromfile(\\n\",\n        \"    './configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py'\\n\",\n        \")\\n\",\n        \"\\n\",\n        \"# set basic configs\\n\",\n        \"cfg.data_root = 'data/coco_tiny'\\n\",\n        \"cfg.work_dir = 'work_dirs/hrnet_w32_coco_tiny_256x192'\\n\",\n        \"cfg.randomness = dict(seed=0)\\n\",\n        \"\\n\",\n        \"# set log interval\\n\",\n        \"cfg.train_cfg.val_interval = 1\\n\",\n        \"\\n\",\n        \"# set num of epoch\\n\",\n        \"cfg.train_cfg.max_epochs = 40\\n\",\n        \"\\n\",\n        \"# set optimizer\\n\",\n        \"cfg.optim_wrapper = dict(optimizer=dict(\\n\",\n        \"    type='Adam',\\n\",\n        \"    lr=5e-4,\\n\",\n        \"))\\n\",\n        \"\\n\",\n        \"# set learning rate policy\\n\",\n        \"cfg.param_scheduler = [\\n\",\n        \"    dict(\\n\",\n        \"        type='LinearLR', begin=0, end=10, start_factor=0.001,\\n\",\n        \"        by_epoch=False),  # warm-up\\n\",\n        \"    dict(\\n\",\n        \"        type='MultiStepLR',\\n\",\n        \"        begin=0,\\n\",\n        \"        end=cfg.train_cfg.max_epochs,\\n\",\n        \"        milestones=[17, 35],\\n\",\n        \"        gamma=0.1,\\n\",\n        \"        by_epoch=True)\\n\",\n        \"]\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"# set batch size\\n\",\n        \"cfg.train_dataloader.batch_size = 16\\n\",\n        \"cfg.val_dataloader.batch_size = 16\\n\",\n        \"cfg.test_dataloader.batch_size = 16\\n\",\n        \"\\n\",\n        \"# set dataset configs\\n\",\n        \"cfg.dataset_type = 'TinyCocoDataset'\\n\",\n        \"cfg.train_dataloader.dataset.type = cfg.dataset_type\\n\",\n        \"cfg.train_dataloader.dataset.ann_file = 'train.json'\\n\",\n        \"cfg.train_dataloader.dataset.data_root = cfg.data_root\\n\",\n        \"cfg.train_dataloader.dataset.data_prefix = dict(img='images/')\\n\",\n        \"\\n\",\n        \"\\n\",\n        \"cfg.val_dataloader.dataset.type = cfg.dataset_type\\n\",\n        \"cfg.val_dataloader.dataset.bbox_file = None\\n\",\n        \"cfg.val_dataloader.dataset.ann_file = 'val.json'\\n\",\n        \"cfg.val_dataloader.dataset.data_root = cfg.data_root\\n\",\n        \"cfg.val_dataloader.dataset.data_prefix = dict(img='images/')\\n\",\n        \"\\n\",\n        \"cfg.test_dataloader.dataset.type = cfg.dataset_type\\n\",\n        \"cfg.test_dataloader.dataset.bbox_file = None\\n\",\n        \"cfg.test_dataloader.dataset.ann_file = 'val.json'\\n\",\n        \"cfg.test_dataloader.dataset.data_root = cfg.data_root\\n\",\n        \"cfg.test_dataloader.dataset.data_prefix = dict(img='images/')\\n\",\n        \"\\n\",\n        \"# set evaluator\\n\",\n        \"cfg.val_evaluator = dict(type='PCKAccuracy')\\n\",\n        \"cfg.test_evaluator = cfg.val_evaluator\\n\",\n        \"\\n\",\n        \"cfg.default_hooks.checkpoint.save_best = 'PCK'\\n\",\n        \"cfg.default_hooks.checkpoint.max_keep_ckpts = 1\\n\",\n        \"\\n\",\n        \"print(cfg.pretty_text)\\n\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"UlD8iDZehE2S\"\n      },\n      \"source\": [\n        \"or you can create a config file like follows:\\n\",\n        \"```Python3\\n\",\n        \"_base_ = ['../../../_base_/default_runtime.py']\\n\",\n        \"\\n\",\n        \"# runtime\\n\",\n        \"train_cfg = dict(max_epochs=40, val_interval=1)\\n\",\n        \"\\n\",\n        \"# optimizer\\n\",\n        \"optim_wrapper = dict(optimizer=dict(\\n\",\n        \"    type='Adam',\\n\",\n        \"    lr=5e-4,\\n\",\n        \"))\\n\",\n        \"\\n\",\n        \"# learning policy\\n\",\n        \"param_scheduler = [\\n\",\n        \"    dict(\\n\",\n        \"        type='LinearLR', begin=0, end=500, start_factor=0.001,\\n\",\n        \"        by_epoch=False),  # warm-up\\n\",\n        \"    dict(\\n\",\n        \"        type='MultiStepLR',\\n\",\n        \"        begin=0,\\n\",\n        \"        end=train_cfg.max_epochs,\\n\",\n        \"        milestones=[17, 35],\\n\",\n        \"        gamma=0.1,\\n\",\n        \"        by_epoch=True)\\n\",\n        \"]\\n\",\n        \"\\n\",\n        \"# automatically scaling LR based on the actual training batch size\\n\",\n        \"auto_scale_lr = dict(base_batch_size=512)\\n\",\n        \"\\n\",\n        \"# codec settings\\n\",\n        \"codec = dict(\\n\",\n        \"    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\\n\",\n        \"\\n\",\n        \"# model settings\\n\",\n        \"model = dict(\\n\",\n        \"    type='TopdownPoseEstimator',\\n\",\n        \"    data_preprocessor=dict(\\n\",\n        \"        type='PoseDataPreprocessor',\\n\",\n        \"        mean=[123.675, 116.28, 103.53],\\n\",\n        \"        std=[58.395, 57.12, 57.375],\\n\",\n        \"        bgr_to_rgb=True),\\n\",\n        \"    backbone=dict(\\n\",\n        \"        type='HRNet',\\n\",\n        \"        in_channels=3,\\n\",\n        \"        extra=dict(\\n\",\n        \"            stage1=dict(\\n\",\n        \"                num_modules=1,\\n\",\n        \"                num_branches=1,\\n\",\n        \"                block='BOTTLENECK',\\n\",\n        \"                num_blocks=(4, ),\\n\",\n        \"                num_channels=(64, )),\\n\",\n        \"            stage2=dict(\\n\",\n        \"                num_modules=1,\\n\",\n        \"                num_branches=2,\\n\",\n        \"                block='BASIC',\\n\",\n        \"                num_blocks=(4, 4),\\n\",\n        \"                num_channels=(32, 64)),\\n\",\n        \"            stage3=dict(\\n\",\n        \"                num_modules=4,\\n\",\n        \"                num_branches=3,\\n\",\n        \"                block='BASIC',\\n\",\n        \"                num_blocks=(4, 4, 4),\\n\",\n        \"                num_channels=(32, 64, 128)),\\n\",\n        \"            stage4=dict(\\n\",\n        \"                num_modules=3,\\n\",\n        \"                num_branches=4,\\n\",\n        \"                block='BASIC',\\n\",\n        \"                num_blocks=(4, 4, 4, 4),\\n\",\n        \"                num_channels=(32, 64, 128, 256))),\\n\",\n        \"        init_cfg=dict(\\n\",\n        \"            type='Pretrained',\\n\",\n        \"            checkpoint='https://download.openmmlab.com/mmpose/'\\n\",\n        \"            'pretrain_models/hrnet_w32-36af842e.pth'),\\n\",\n        \"    ),\\n\",\n        \"    head=dict(\\n\",\n        \"        type='HeatmapHead',\\n\",\n        \"        in_channels=32,\\n\",\n        \"        out_channels=17,\\n\",\n        \"        deconv_out_channels=None,\\n\",\n        \"        loss=dict(type='KeypointMSELoss', use_target_weight=True),\\n\",\n        \"        decoder=codec),\\n\",\n        \"    test_cfg=dict(\\n\",\n        \"        flip_test=True,\\n\",\n        \"        flip_mode='heatmap',\\n\",\n        \"        shift_heatmap=True,\\n\",\n        \"    ))\\n\",\n        \"\\n\",\n        \"# base dataset settings\\n\",\n        \"dataset_type = 'TinyCocoDataset'\\n\",\n        \"data_mode = 'topdown'\\n\",\n        \"data_root = 'data/coco_tiny'\\n\",\n        \"work_dir = 'work_dirs/hrnet_w32_coco_tiny_256x192'\\n\",\n        \"randomness = dict(seed=0)\\n\",\n        \"\\n\",\n        \"# pipelines\\n\",\n        \"train_pipeline = [\\n\",\n        \"    dict(type='LoadImage'),\\n\",\n        \"    dict(type='GetBBoxCenterScale'),\\n\",\n        \"    dict(type='RandomFlip', direction='horizontal'),\\n\",\n        \"    dict(type='RandomHalfBody'),\\n\",\n        \"    dict(type='RandomBBoxTransform'),\\n\",\n        \"    dict(type='TopdownAffine', input_size=codec['input_size']),\\n\",\n        \"    dict(type='GenerateTarget', target_type='heatmap', encoder=codec),\\n\",\n        \"    dict(type='PackPoseInputs')\\n\",\n        \"]\\n\",\n        \"test_pipeline = [\\n\",\n        \"    dict(type='LoadImage'),\\n\",\n        \"    dict(type='GetBBoxCenterScale'),\\n\",\n        \"    dict(type='TopdownAffine', input_size=codec['input_size']),\\n\",\n        \"    dict(type='PackPoseInputs')\\n\",\n        \"]\\n\",\n        \"\\n\",\n        \"# data loaders\\n\",\n        \"train_dataloader = dict(\\n\",\n        \"    batch_size=16,\\n\",\n        \"    num_workers=2,\\n\",\n        \"    persistent_workers=True,\\n\",\n        \"    sampler=dict(type='DefaultSampler', shuffle=True),\\n\",\n        \"    dataset=dict(\\n\",\n        \"        type=dataset_type,\\n\",\n        \"        data_root=data_root,\\n\",\n        \"        data_mode=data_mode,\\n\",\n        \"        ann_file='train.json',\\n\",\n        \"        data_prefix=dict(img='images/'),\\n\",\n        \"        pipeline=train_pipeline,\\n\",\n        \"    ))\\n\",\n        \"val_dataloader = dict(\\n\",\n        \"    batch_size=16,\\n\",\n        \"    num_workers=2,\\n\",\n        \"    persistent_workers=True,\\n\",\n        \"    drop_last=False,\\n\",\n        \"    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\\n\",\n        \"    dataset=dict(\\n\",\n        \"        type=dataset_type,\\n\",\n        \"        data_root=data_root,\\n\",\n        \"        data_mode=data_mode,\\n\",\n        \"        ann_file='val.json',\\n\",\n        \"        data_prefix=dict(img='images/'),\\n\",\n        \"        test_mode=True,\\n\",\n        \"        pipeline=test_pipeline,\\n\",\n        \"    ))\\n\",\n        \"test_dataloader = val_dataloader\\n\",\n        \"\\n\",\n        \"# evaluators\\n\",\n        \"val_evaluator = dict(\\n\",\n        \"    type='PCKAccuracy')\\n\",\n        \"test_evaluator = val_evaluator\\n\",\n        \"\\n\",\n        \"# hooks\\n\",\n        \"default_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\\n\",\n        \"```\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"ChVqB1oYncmo\"\n      },\n      \"source\": [\n        \"### Train and Evaluation\\n\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"colab\": {\n          \"base_uri\": \"https://localhost:8080/\",\n          \"height\": 1000,\n          \"referenced_widgets\": [\n            \"2a079d9c0b9845318e6c612ca9601b86\",\n            \"3554753622334094961a47daf9362c59\",\n            \"08e0412b8dd54d28a26c232e75ea6088\",\n            \"558a9420b0b34be2a2ca8a8b8af9cbfc\",\n            \"a9bd3e477f07449788f0e95e3cd13ddc\",\n            \"5b2ee1f3e78d4cd993009d04baf76b24\",\n            \"a3e5aa31c3f644b5a677ec49fe2e0832\",\n            \"d2ee56f920a245d9875de8e37596a5c8\",\n            \"b5f8c86d48a04afa997fc137e1acd716\",\n            \"1c1b09d91dec4e3dadefe953daf50745\",\n            \"6af448aebdb744b98a2807f66b1d6e5d\"\n          ]\n        },\n        \"id\": \"Ab3xsUdPlXuJ\",\n        \"outputId\": \"c07394b8-21f4-4766-af2b-87d2caa6e74c\"\n      },\n      \"outputs\": [\n        {\n          \"name\": \"stdout\",\n          \"output_type\": \"stream\",\n          \"text\": [\n            \"09/15 12:42:06 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"log_processor\\\" registry tree. As a workaround, the current \\\"log_processor\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:06 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - \\n\",\n            \"------------------------------------------------------------\\n\",\n            \"System environment:\\n\",\n            \"    sys.platform: linux\\n\",\n            \"    Python: 3.7.13 (default, Mar 29 2022, 02:18:16) [GCC 7.5.0]\\n\",\n            \"    CUDA available: True\\n\",\n            \"    numpy_random_seed: 0\\n\",\n            \"    GPU 0: NVIDIA GeForce GTX 1660 Ti\\n\",\n            \"    CUDA_HOME: /usr/local/cuda\\n\",\n            \"    NVCC: Cuda compilation tools, release 11.3, V11.3.109\\n\",\n            \"    GCC: gcc (Ubuntu 5.4.0-6ubuntu1~16.04.12) 5.4.0 20160609\\n\",\n            \"    PyTorch: 1.12.0+cu113\\n\",\n            \"    PyTorch compiling details: PyTorch built with:\\n\",\n            \"  - GCC 9.3\\n\",\n            \"  - C++ Version: 201402\\n\",\n            \"  - Intel(R) Math Kernel Library Version 2020.0.0 Product Build 20191122 for Intel(R) 64 architecture applications\\n\",\n            \"  - Intel(R) MKL-DNN v2.6.0 (Git Hash 52b5f107dd9cf10910aaa19cb47f3abf9b349815)\\n\",\n            \"  - OpenMP 201511 (a.k.a. OpenMP 4.5)\\n\",\n            \"  - LAPACK is enabled (usually provided by MKL)\\n\",\n            \"  - NNPACK is enabled\\n\",\n            \"  - CPU capability usage: AVX2\\n\",\n            \"  - CUDA Runtime 11.3\\n\",\n            \"  - NVCC architecture flags: -gencode;arch=compute_37,code=sm_37;-gencode;arch=compute_50,code=sm_50;-gencode;arch=compute_60,code=sm_60;-gencode;arch=compute_70,code=sm_70;-gencode;arch=compute_75,code=sm_75;-gencode;arch=compute_80,code=sm_80;-gencode;arch=compute_86,code=sm_86\\n\",\n            \"  - CuDNN 8.3.2  (built against CUDA 11.5)\\n\",\n            \"  - Magma 2.5.2\\n\",\n            \"  - Build settings: BLAS_INFO=mkl, BUILD_TYPE=Release, CUDA_VERSION=11.3, CUDNN_VERSION=8.3.2, CXX_COMPILER=/opt/rh/devtoolset-9/root/usr/bin/c++, CXX_FLAGS= -Wno-deprecated -fvisibility-inlines-hidden -DUSE_PTHREADPOOL -fopenmp -DNDEBUG -DUSE_KINETO -DUSE_FBGEMM -DUSE_QNNPACK -DUSE_PYTORCH_QNNPACK -DUSE_XNNPACK -DSYMBOLICATE_MOBILE_DEBUG_HANDLE -DEDGE_PROFILER_USE_KINETO -O2 -fPIC -Wno-narrowing -Wall -Wextra -Werror=return-type -Wno-missing-field-initializers -Wno-type-limits -Wno-array-bounds -Wno-unknown-pragmas -Wno-unused-parameter -Wno-unused-function -Wno-unused-result -Wno-unused-local-typedefs -Wno-strict-overflow -Wno-strict-aliasing -Wno-error=deprecated-declarations -Wno-stringop-overflow -Wno-psabi -Wno-error=pedantic -Wno-error=redundant-decls -Wno-error=old-style-cast -fdiagnostics-color=always -faligned-new -Wno-unused-but-set-variable -Wno-maybe-uninitialized -fno-math-errno -fno-trapping-math -Werror=format -Werror=cast-function-type -Wno-stringop-overflow, LAPACK_INFO=mkl, PERF_WITH_AVX=1, PERF_WITH_AVX2=1, PERF_WITH_AVX512=1, TORCH_VERSION=1.12.0, USE_CUDA=ON, USE_CUDNN=ON, USE_EXCEPTION_PTR=1, USE_GFLAGS=OFF, USE_GLOG=OFF, USE_MKL=ON, USE_MKLDNN=OFF, USE_MPI=OFF, USE_NCCL=ON, USE_NNPACK=ON, USE_OPENMP=ON, USE_ROCM=OFF, \\n\",\n            \"\\n\",\n            \"    TorchVision: 0.13.0+cu113\\n\",\n            \"    OpenCV: 4.6.0\\n\",\n            \"    MMEngine: 0.1.0\\n\",\n            \"\\n\",\n            \"Runtime environment:\\n\",\n            \"    cudnn_benchmark: False\\n\",\n            \"    mp_cfg: {'mp_start_method': 'fork', 'opencv_num_threads': 0}\\n\",\n            \"    dist_cfg: {'backend': 'nccl'}\\n\",\n            \"    seed: 0\\n\",\n            \"    Distributed launcher: none\\n\",\n            \"    Distributed training: False\\n\",\n            \"    GPU number: 1\\n\",\n            \"------------------------------------------------------------\\n\",\n            \"\\n\",\n            \"09/15 12:42:06 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Config:\\n\",\n            \"default_scope = 'mmpose'\\n\",\n            \"default_hooks = dict(\\n\",\n            \"    timer=dict(type='IterTimerHook'),\\n\",\n            \"    logger=dict(type='LoggerHook', interval=50),\\n\",\n            \"    param_scheduler=dict(type='ParamSchedulerHook'),\\n\",\n            \"    checkpoint=dict(\\n\",\n            \"        type='CheckpointHook',\\n\",\n            \"        interval=1,\\n\",\n            \"        save_best='pck/PCK@0.05',\\n\",\n            \"        rule='greater',\\n\",\n            \"        max_keep_ckpts=1),\\n\",\n            \"    sampler_seed=dict(type='DistSamplerSeedHook'),\\n\",\n            \"    visualization=dict(type='PoseVisualizationHook', enable=False))\\n\",\n            \"custom_hooks = [dict(type='SyncBuffersHook')]\\n\",\n            \"env_cfg = dict(\\n\",\n            \"    cudnn_benchmark=False,\\n\",\n            \"    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\\n\",\n            \"    dist_cfg=dict(backend='nccl'))\\n\",\n            \"vis_backends = [dict(type='LocalVisBackend')]\\n\",\n            \"visualizer = dict(\\n\",\n            \"    type='PoseLocalVisualizer',\\n\",\n            \"    vis_backends=[dict(type='LocalVisBackend')],\\n\",\n            \"    name='visualizer')\\n\",\n            \"log_processor = dict(\\n\",\n            \"    type='LogProcessor', window_size=50, by_epoch=True, num_digits=6)\\n\",\n            \"log_level = 'INFO'\\n\",\n            \"load_from = None\\n\",\n            \"resume = False\\n\",\n            \"file_client_args = dict(backend='disk')\\n\",\n            \"train_cfg = dict(by_epoch=True, max_epochs=40, val_interval=1)\\n\",\n            \"val_cfg = dict()\\n\",\n            \"test_cfg = dict()\\n\",\n            \"optim_wrapper = dict(optimizer=dict(type='Adam', lr=0.0005))\\n\",\n            \"param_scheduler = [\\n\",\n            \"    dict(type='LinearLR', begin=0, end=10, start_factor=0.001, by_epoch=False),\\n\",\n            \"    dict(\\n\",\n            \"        type='MultiStepLR',\\n\",\n            \"        begin=0,\\n\",\n            \"        end=40,\\n\",\n            \"        milestones=[17, 35],\\n\",\n            \"        gamma=0.1,\\n\",\n            \"        by_epoch=True)\\n\",\n            \"]\\n\",\n            \"auto_scale_lr = dict(base_batch_size=512)\\n\",\n            \"codec = dict(\\n\",\n            \"    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\\n\",\n            \"model = dict(\\n\",\n            \"    type='TopdownPoseEstimator',\\n\",\n            \"    data_preprocessor=dict(\\n\",\n            \"        type='PoseDataPreprocessor',\\n\",\n            \"        mean=[123.675, 116.28, 103.53],\\n\",\n            \"        std=[58.395, 57.12, 57.375],\\n\",\n            \"        bgr_to_rgb=True),\\n\",\n            \"    backbone=dict(\\n\",\n            \"        type='HRNet',\\n\",\n            \"        in_channels=3,\\n\",\n            \"        extra=dict(\\n\",\n            \"            stage1=dict(\\n\",\n            \"                num_modules=1,\\n\",\n            \"                num_branches=1,\\n\",\n            \"                block='BOTTLENECK',\\n\",\n            \"                num_blocks=(4, ),\\n\",\n            \"                num_channels=(64, )),\\n\",\n            \"            stage2=dict(\\n\",\n            \"                num_modules=1,\\n\",\n            \"                num_branches=2,\\n\",\n            \"                block='BASIC',\\n\",\n            \"                num_blocks=(4, 4),\\n\",\n            \"                num_channels=(32, 64)),\\n\",\n            \"            stage3=dict(\\n\",\n            \"                num_modules=4,\\n\",\n            \"                num_branches=3,\\n\",\n            \"                block='BASIC',\\n\",\n            \"                num_blocks=(4, 4, 4),\\n\",\n            \"                num_channels=(32, 64, 128)),\\n\",\n            \"            stage4=dict(\\n\",\n            \"                num_modules=3,\\n\",\n            \"                num_branches=4,\\n\",\n            \"                block='BASIC',\\n\",\n            \"                num_blocks=(4, 4, 4, 4),\\n\",\n            \"                num_channels=(32, 64, 128, 256))),\\n\",\n            \"        init_cfg=dict(\\n\",\n            \"            type='Pretrained',\\n\",\n            \"            checkpoint=\\n\",\n            \"            'https://download.openmmlab.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth'\\n\",\n            \"        )),\\n\",\n            \"    head=dict(\\n\",\n            \"        type='HeatmapHead',\\n\",\n            \"        in_channels=32,\\n\",\n            \"        out_channels=17,\\n\",\n            \"        deconv_out_channels=None,\\n\",\n            \"        loss=dict(type='KeypointMSELoss', use_target_weight=True),\\n\",\n            \"        decoder=dict(\\n\",\n            \"            type='MSRAHeatmap',\\n\",\n            \"            input_size=(192, 256),\\n\",\n            \"            heatmap_size=(48, 64),\\n\",\n            \"            sigma=2)),\\n\",\n            \"    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))\\n\",\n            \"dataset_type = 'TinyCocoDataset'\\n\",\n            \"data_mode = 'topdown'\\n\",\n            \"data_root = 'data/coco_tiny'\\n\",\n            \"train_pipeline = [\\n\",\n            \"    dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"    dict(type='GetBBoxCenterScale'),\\n\",\n            \"    dict(type='RandomFlip', direction='horizontal'),\\n\",\n            \"    dict(type='RandomHalfBody'),\\n\",\n            \"    dict(type='RandomBBoxTransform'),\\n\",\n            \"    dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"    dict(\\n\",\n            \"        type='GenerateTarget',\\n\",\n            \"        target_type='heatmap',\\n\",\n            \"        encoder=dict(\\n\",\n            \"            type='MSRAHeatmap',\\n\",\n            \"            input_size=(192, 256),\\n\",\n            \"            heatmap_size=(48, 64),\\n\",\n            \"            sigma=2)),\\n\",\n            \"    dict(type='PackPoseInputs')\\n\",\n            \"]\\n\",\n            \"test_pipeline = [\\n\",\n            \"    dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"    dict(type='GetBBoxCenterScale'),\\n\",\n            \"    dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"    dict(type='PackPoseInputs')\\n\",\n            \"]\\n\",\n            \"train_dataloader = dict(\\n\",\n            \"    batch_size=16,\\n\",\n            \"    num_workers=2,\\n\",\n            \"    persistent_workers=True,\\n\",\n            \"    sampler=dict(type='DefaultSampler', shuffle=True),\\n\",\n            \"    dataset=dict(\\n\",\n            \"        type='TinyCocoDataset',\\n\",\n            \"        data_root='data/coco_tiny',\\n\",\n            \"        data_mode='topdown',\\n\",\n            \"        ann_file='train.json',\\n\",\n            \"        data_prefix=dict(img='images/'),\\n\",\n            \"        pipeline=[\\n\",\n            \"            dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"            dict(type='GetBBoxCenterScale'),\\n\",\n            \"            dict(type='RandomFlip', direction='horizontal'),\\n\",\n            \"            dict(type='RandomHalfBody'),\\n\",\n            \"            dict(type='RandomBBoxTransform'),\\n\",\n            \"            dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"            dict(\\n\",\n            \"                type='GenerateTarget',\\n\",\n            \"                target_type='heatmap',\\n\",\n            \"                encoder=dict(\\n\",\n            \"                    type='MSRAHeatmap',\\n\",\n            \"                    input_size=(192, 256),\\n\",\n            \"                    heatmap_size=(48, 64),\\n\",\n            \"                    sigma=2)),\\n\",\n            \"            dict(type='PackPoseInputs')\\n\",\n            \"        ]))\\n\",\n            \"val_dataloader = dict(\\n\",\n            \"    batch_size=16,\\n\",\n            \"    num_workers=2,\\n\",\n            \"    persistent_workers=True,\\n\",\n            \"    drop_last=False,\\n\",\n            \"    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\\n\",\n            \"    dataset=dict(\\n\",\n            \"        type='TinyCocoDataset',\\n\",\n            \"        data_root='data/coco_tiny',\\n\",\n            \"        data_mode='topdown',\\n\",\n            \"        ann_file='val.json',\\n\",\n            \"        bbox_file=None,\\n\",\n            \"        data_prefix=dict(img='images/'),\\n\",\n            \"        test_mode=True,\\n\",\n            \"        pipeline=[\\n\",\n            \"            dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"            dict(type='GetBBoxCenterScale'),\\n\",\n            \"            dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"            dict(type='PackPoseInputs')\\n\",\n            \"        ]))\\n\",\n            \"test_dataloader = dict(\\n\",\n            \"    batch_size=16,\\n\",\n            \"    num_workers=2,\\n\",\n            \"    persistent_workers=True,\\n\",\n            \"    drop_last=False,\\n\",\n            \"    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\\n\",\n            \"    dataset=dict(\\n\",\n            \"        type='TinyCocoDataset',\\n\",\n            \"        data_root='data/coco_tiny',\\n\",\n            \"        data_mode='topdown',\\n\",\n            \"        ann_file='val.json',\\n\",\n            \"        bbox_file=None,\\n\",\n            \"        data_prefix=dict(img='images/'),\\n\",\n            \"        test_mode=True,\\n\",\n            \"        pipeline=[\\n\",\n            \"            dict(type='LoadImage', file_client_args=dict(backend='disk')),\\n\",\n            \"            dict(type='GetBBoxCenterScale'),\\n\",\n            \"            dict(type='TopdownAffine', input_size=(192, 256)),\\n\",\n            \"            dict(type='PackPoseInputs')\\n\",\n            \"        ]))\\n\",\n            \"val_evaluator = dict(type='PCKAccuracy')\\n\",\n            \"test_evaluator = dict(type='PCKAccuracy')\\n\",\n            \"work_dir = 'work_dirs/hrnet_w32_coco_tiny_256x192'\\n\",\n            \"randomness = dict(seed=0)\\n\",\n            \"\\n\",\n            \"Result has been saved to /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/modules_statistic_results.json\\n\",\n            \"09/15 12:42:07 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Distributed training is not used, all SyncBatchNorm (SyncBN) layers in the model will be automatically reverted to BatchNormXd layers if they are used.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"data sampler\\\" registry tree. As a workaround, the current \\\"data sampler\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"optimizer wrapper constructor\\\" registry tree. As a workaround, the current \\\"optimizer wrapper constructor\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"optimizer\\\" registry tree. As a workaround, the current \\\"optimizer\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"optim_wrapper\\\" registry tree. As a workaround, the current \\\"optim_wrapper\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"parameter scheduler\\\" registry tree. As a workaround, the current \\\"parameter scheduler\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"parameter scheduler\\\" registry tree. As a workaround, the current \\\"parameter scheduler\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"parameter scheduler\\\" registry tree. As a workaround, the current \\\"parameter scheduler\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"parameter scheduler\\\" registry tree. As a workaround, the current \\\"parameter scheduler\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"data sampler\\\" registry tree. As a workaround, the current \\\"data sampler\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"weight initializer\\\" registry tree. As a workaround, the current \\\"weight initializer\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - load model from: https://download.openmmlab.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth\\n\",\n            \"09/15 12:42:08 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - http loads checkpoint from path: https://download.openmmlab.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth\\n\",\n            \"09/15 12:42:09 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - The model and loaded state dict do not match exactly\\n\",\n            \"\\n\",\n            \"unexpected key in source state_dict: head.0.0.0.conv1.weight, head.0.0.0.bn1.weight, head.0.0.0.bn1.bias, head.0.0.0.bn1.running_mean, head.0.0.0.bn1.running_var, head.0.0.0.bn1.num_batches_tracked, head.0.0.0.conv2.weight, head.0.0.0.bn2.weight, head.0.0.0.bn2.bias, head.0.0.0.bn2.running_mean, head.0.0.0.bn2.running_var, head.0.0.0.bn2.num_batches_tracked, head.0.0.0.conv3.weight, head.0.0.0.bn3.weight, head.0.0.0.bn3.bias, head.0.0.0.bn3.running_mean, head.0.0.0.bn3.running_var, head.0.0.0.bn3.num_batches_tracked, head.0.0.0.downsample.0.weight, head.0.0.0.downsample.1.weight, head.0.0.0.downsample.1.bias, head.0.0.0.downsample.1.running_mean, head.0.0.0.downsample.1.running_var, head.0.0.0.downsample.1.num_batches_tracked, head.0.1.0.conv1.weight, head.0.1.0.bn1.weight, head.0.1.0.bn1.bias, head.0.1.0.bn1.running_mean, head.0.1.0.bn1.running_var, head.0.1.0.bn1.num_batches_tracked, head.0.1.0.conv2.weight, head.0.1.0.bn2.weight, head.0.1.0.bn2.bias, head.0.1.0.bn2.running_mean, head.0.1.0.bn2.running_var, head.0.1.0.bn2.num_batches_tracked, head.0.1.0.conv3.weight, head.0.1.0.bn3.weight, head.0.1.0.bn3.bias, head.0.1.0.bn3.running_mean, head.0.1.0.bn3.running_var, head.0.1.0.bn3.num_batches_tracked, head.0.1.0.downsample.0.weight, head.0.1.0.downsample.1.weight, head.0.1.0.downsample.1.bias, head.0.1.0.downsample.1.running_mean, head.0.1.0.downsample.1.running_var, head.0.1.0.downsample.1.num_batches_tracked, head.0.2.0.conv1.weight, head.0.2.0.bn1.weight, head.0.2.0.bn1.bias, head.0.2.0.bn1.running_mean, head.0.2.0.bn1.running_var, head.0.2.0.bn1.num_batches_tracked, head.0.2.0.conv2.weight, head.0.2.0.bn2.weight, head.0.2.0.bn2.bias, head.0.2.0.bn2.running_mean, head.0.2.0.bn2.running_var, head.0.2.0.bn2.num_batches_tracked, head.0.2.0.conv3.weight, head.0.2.0.bn3.weight, head.0.2.0.bn3.bias, head.0.2.0.bn3.running_mean, head.0.2.0.bn3.running_var, head.0.2.0.bn3.num_batches_tracked, head.0.2.0.downsample.0.weight, head.0.2.0.downsample.1.weight, head.0.2.0.downsample.1.bias, head.0.2.0.downsample.1.running_mean, head.0.2.0.downsample.1.running_var, head.0.2.0.downsample.1.num_batches_tracked, head.1.0.0.conv1.weight, head.1.0.0.bn1.weight, head.1.0.0.bn1.bias, head.1.0.0.bn1.running_mean, head.1.0.0.bn1.running_var, head.1.0.0.bn1.num_batches_tracked, head.1.0.0.conv2.weight, head.1.0.0.bn2.weight, head.1.0.0.bn2.bias, head.1.0.0.bn2.running_mean, head.1.0.0.bn2.running_var, head.1.0.0.bn2.num_batches_tracked, head.1.0.0.conv3.weight, head.1.0.0.bn3.weight, head.1.0.0.bn3.bias, head.1.0.0.bn3.running_mean, head.1.0.0.bn3.running_var, head.1.0.0.bn3.num_batches_tracked, head.1.0.0.downsample.0.weight, head.1.0.0.downsample.1.weight, head.1.0.0.downsample.1.bias, head.1.0.0.downsample.1.running_mean, head.1.0.0.downsample.1.running_var, head.1.0.0.downsample.1.num_batches_tracked, head.1.1.0.conv1.weight, head.1.1.0.bn1.weight, head.1.1.0.bn1.bias, head.1.1.0.bn1.running_mean, head.1.1.0.bn1.running_var, head.1.1.0.bn1.num_batches_tracked, head.1.1.0.conv2.weight, head.1.1.0.bn2.weight, head.1.1.0.bn2.bias, head.1.1.0.bn2.running_mean, head.1.1.0.bn2.running_var, head.1.1.0.bn2.num_batches_tracked, head.1.1.0.conv3.weight, head.1.1.0.bn3.weight, head.1.1.0.bn3.bias, head.1.1.0.bn3.running_mean, head.1.1.0.bn3.running_var, head.1.1.0.bn3.num_batches_tracked, head.1.1.0.downsample.0.weight, head.1.1.0.downsample.1.weight, head.1.1.0.downsample.1.bias, head.1.1.0.downsample.1.running_mean, head.1.1.0.downsample.1.running_var, head.1.1.0.downsample.1.num_batches_tracked, head.2.0.0.conv1.weight, head.2.0.0.bn1.weight, head.2.0.0.bn1.bias, head.2.0.0.bn1.running_mean, head.2.0.0.bn1.running_var, head.2.0.0.bn1.num_batches_tracked, head.2.0.0.conv2.weight, head.2.0.0.bn2.weight, head.2.0.0.bn2.bias, head.2.0.0.bn2.running_mean, head.2.0.0.bn2.running_var, head.2.0.0.bn2.num_batches_tracked, head.2.0.0.conv3.weight, head.2.0.0.bn3.weight, head.2.0.0.bn3.bias, head.2.0.0.bn3.running_mean, head.2.0.0.bn3.running_var, head.2.0.0.bn3.num_batches_tracked, head.2.0.0.downsample.0.weight, head.2.0.0.downsample.1.weight, head.2.0.0.downsample.1.bias, head.2.0.0.downsample.1.running_mean, head.2.0.0.downsample.1.running_var, head.2.0.0.downsample.1.num_batches_tracked, head.3.0.0.conv1.weight, head.3.0.0.bn1.weight, head.3.0.0.bn1.bias, head.3.0.0.bn1.running_mean, head.3.0.0.bn1.running_var, head.3.0.0.bn1.num_batches_tracked, head.3.0.0.conv2.weight, head.3.0.0.bn2.weight, head.3.0.0.bn2.bias, head.3.0.0.bn2.running_mean, head.3.0.0.bn2.running_var, head.3.0.0.bn2.num_batches_tracked, head.3.0.0.conv3.weight, head.3.0.0.bn3.weight, head.3.0.0.bn3.bias, head.3.0.0.bn3.running_mean, head.3.0.0.bn3.running_var, head.3.0.0.bn3.num_batches_tracked, head.3.0.0.downsample.0.weight, head.3.0.0.downsample.1.weight, head.3.0.0.downsample.1.bias, head.3.0.0.downsample.1.running_mean, head.3.0.0.downsample.1.running_var, head.3.0.0.downsample.1.num_batches_tracked, fc.weight, fc.bias, stage4.2.fuse_layers.1.0.0.0.weight, stage4.2.fuse_layers.1.0.0.1.weight, stage4.2.fuse_layers.1.0.0.1.bias, stage4.2.fuse_layers.1.0.0.1.running_mean, stage4.2.fuse_layers.1.0.0.1.running_var, stage4.2.fuse_layers.1.0.0.1.num_batches_tracked, stage4.2.fuse_layers.1.2.0.weight, stage4.2.fuse_layers.1.2.1.weight, stage4.2.fuse_layers.1.2.1.bias, stage4.2.fuse_layers.1.2.1.running_mean, stage4.2.fuse_layers.1.2.1.running_var, stage4.2.fuse_layers.1.2.1.num_batches_tracked, stage4.2.fuse_layers.1.3.0.weight, stage4.2.fuse_layers.1.3.1.weight, stage4.2.fuse_layers.1.3.1.bias, stage4.2.fuse_layers.1.3.1.running_mean, stage4.2.fuse_layers.1.3.1.running_var, stage4.2.fuse_layers.1.3.1.num_batches_tracked, stage4.2.fuse_layers.2.0.0.0.weight, stage4.2.fuse_layers.2.0.0.1.weight, stage4.2.fuse_layers.2.0.0.1.bias, stage4.2.fuse_layers.2.0.0.1.running_mean, stage4.2.fuse_layers.2.0.0.1.running_var, stage4.2.fuse_layers.2.0.0.1.num_batches_tracked, stage4.2.fuse_layers.2.0.1.0.weight, stage4.2.fuse_layers.2.0.1.1.weight, stage4.2.fuse_layers.2.0.1.1.bias, stage4.2.fuse_layers.2.0.1.1.running_mean, stage4.2.fuse_layers.2.0.1.1.running_var, stage4.2.fuse_layers.2.0.1.1.num_batches_tracked, stage4.2.fuse_layers.2.1.0.0.weight, stage4.2.fuse_layers.2.1.0.1.weight, stage4.2.fuse_layers.2.1.0.1.bias, stage4.2.fuse_layers.2.1.0.1.running_mean, stage4.2.fuse_layers.2.1.0.1.running_var, stage4.2.fuse_layers.2.1.0.1.num_batches_tracked, stage4.2.fuse_layers.2.3.0.weight, stage4.2.fuse_layers.2.3.1.weight, stage4.2.fuse_layers.2.3.1.bias, stage4.2.fuse_layers.2.3.1.running_mean, stage4.2.fuse_layers.2.3.1.running_var, stage4.2.fuse_layers.2.3.1.num_batches_tracked, stage4.2.fuse_layers.3.0.0.0.weight, stage4.2.fuse_layers.3.0.0.1.weight, stage4.2.fuse_layers.3.0.0.1.bias, stage4.2.fuse_layers.3.0.0.1.running_mean, stage4.2.fuse_layers.3.0.0.1.running_var, stage4.2.fuse_layers.3.0.0.1.num_batches_tracked, stage4.2.fuse_layers.3.0.1.0.weight, stage4.2.fuse_layers.3.0.1.1.weight, stage4.2.fuse_layers.3.0.1.1.bias, stage4.2.fuse_layers.3.0.1.1.running_mean, stage4.2.fuse_layers.3.0.1.1.running_var, stage4.2.fuse_layers.3.0.1.1.num_batches_tracked, stage4.2.fuse_layers.3.0.2.0.weight, stage4.2.fuse_layers.3.0.2.1.weight, stage4.2.fuse_layers.3.0.2.1.bias, stage4.2.fuse_layers.3.0.2.1.running_mean, stage4.2.fuse_layers.3.0.2.1.running_var, stage4.2.fuse_layers.3.0.2.1.num_batches_tracked, stage4.2.fuse_layers.3.1.0.0.weight, stage4.2.fuse_layers.3.1.0.1.weight, stage4.2.fuse_layers.3.1.0.1.bias, stage4.2.fuse_layers.3.1.0.1.running_mean, stage4.2.fuse_layers.3.1.0.1.running_var, stage4.2.fuse_layers.3.1.0.1.num_batches_tracked, stage4.2.fuse_layers.3.1.1.0.weight, stage4.2.fuse_layers.3.1.1.1.weight, stage4.2.fuse_layers.3.1.1.1.bias, stage4.2.fuse_layers.3.1.1.1.running_mean, stage4.2.fuse_layers.3.1.1.1.running_var, stage4.2.fuse_layers.3.1.1.1.num_batches_tracked, stage4.2.fuse_layers.3.2.0.0.weight, stage4.2.fuse_layers.3.2.0.1.weight, stage4.2.fuse_layers.3.2.0.1.bias, stage4.2.fuse_layers.3.2.0.1.running_mean, stage4.2.fuse_layers.3.2.0.1.running_var, stage4.2.fuse_layers.3.2.0.1.num_batches_tracked\\n\",\n            \"\\n\",\n            \"09/15 12:42:09 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"weight initializer\\\" registry tree. As a workaround, the current \\\"weight initializer\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:09 - mmengine - \\u001b[5m\\u001b[4m\\u001b[33mWARNING\\u001b[0m - Failed to search registry with scope \\\"mmpose\\\" in the \\\"weight initializer\\\" registry tree. As a workaround, the current \\\"weight initializer\\\" registry in \\\"mmengine\\\" is used to build instance. This may cause unexpected failure when running the built modules. Please check whether \\\"mmpose\\\" is a correct scope, or whether the registry is initialized.\\n\",\n            \"09/15 12:42:09 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Checkpoints will be saved to /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192 by HardDiskBackend.\\n\",\n            \"09/15 12:42:12 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:12 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 1 epochs\\n\",\n            \"09/15 12:42:13 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:13 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [1][2/2]  pck/PCK@0.05: 0.009035\\n\",\n            \"09/15 12:42:14 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.0090 pck/PCK@0.05 at 1 epoch is saved to best_pck/PCK@0.05_epoch_1.pth.\\n\",\n            \"09/15 12:42:16 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:16 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 2 epochs\\n\",\n            \"09/15 12:42:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [2][2/2]  pck/PCK@0.05: 0.163666\\n\",\n            \"09/15 12:42:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_1.pth is removed\\n\",\n            \"09/15 12:42:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.1637 pck/PCK@0.05 at 2 epoch is saved to best_pck/PCK@0.05_epoch_2.pth.\\n\",\n            \"09/15 12:42:19 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:19 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 3 epochs\\n\",\n            \"09/15 12:42:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [3][2/2]  pck/PCK@0.05: 0.201942\\n\",\n            \"09/15 12:42:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_2.pth is removed\\n\",\n            \"09/15 12:42:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.2019 pck/PCK@0.05 at 3 epoch is saved to best_pck/PCK@0.05_epoch_3.pth.\\n\",\n            \"09/15 12:42:23 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:23 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 4 epochs\\n\",\n            \"09/15 12:42:24 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:24 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [4][2/2]  pck/PCK@0.05: 0.247750\\n\",\n            \"09/15 12:42:24 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_3.pth is removed\\n\",\n            \"09/15 12:42:25 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.2477 pck/PCK@0.05 at 4 epoch is saved to best_pck/PCK@0.05_epoch_4.pth.\\n\",\n            \"09/15 12:42:27 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:27 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 5 epochs\\n\",\n            \"09/15 12:42:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [5][2/2]  pck/PCK@0.05: 0.296205\\n\",\n            \"09/15 12:42:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_4.pth is removed\\n\",\n            \"09/15 12:42:29 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.2962 pck/PCK@0.05 at 5 epoch is saved to best_pck/PCK@0.05_epoch_5.pth.\\n\",\n            \"09/15 12:42:31 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:31 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 6 epochs\\n\",\n            \"09/15 12:42:32 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:32 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [6][2/2]  pck/PCK@0.05: 0.316309\\n\",\n            \"09/15 12:42:32 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_5.pth is removed\\n\",\n            \"09/15 12:42:33 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.3163 pck/PCK@0.05 at 6 epoch is saved to best_pck/PCK@0.05_epoch_6.pth.\\n\",\n            \"09/15 12:42:35 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:35 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 7 epochs\\n\",\n            \"09/15 12:42:36 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:36 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [7][2/2]  pck/PCK@0.05: 0.290834\\n\",\n            \"09/15 12:42:38 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:38 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 8 epochs\\n\",\n            \"09/15 12:42:39 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:39 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [8][2/2]  pck/PCK@0.05: 0.335645\\n\",\n            \"09/15 12:42:39 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_6.pth is removed\\n\",\n            \"09/15 12:42:40 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.3356 pck/PCK@0.05 at 8 epoch is saved to best_pck/PCK@0.05_epoch_8.pth.\\n\",\n            \"09/15 12:42:42 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:42 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 9 epochs\\n\",\n            \"09/15 12:42:43 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:43 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [9][2/2]  pck/PCK@0.05: 0.348761\\n\",\n            \"09/15 12:42:43 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_8.pth is removed\\n\",\n            \"09/15 12:42:44 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.3488 pck/PCK@0.05 at 9 epoch is saved to best_pck/PCK@0.05_epoch_9.pth.\\n\",\n            \"09/15 12:42:46 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:46 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 10 epochs\\n\",\n            \"09/15 12:42:47 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:47 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [10][2/2]  pck/PCK@0.05: 0.310204\\n\",\n            \"09/15 12:42:49 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:49 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 11 epochs\\n\",\n            \"09/15 12:42:50 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:50 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [11][2/2]  pck/PCK@0.05: 0.338200\\n\",\n            \"09/15 12:42:52 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:52 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 12 epochs\\n\",\n            \"09/15 12:42:53 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:53 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [12][2/2]  pck/PCK@0.05: 0.356559\\n\",\n            \"09/15 12:42:53 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_9.pth is removed\\n\",\n            \"09/15 12:42:54 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.3566 pck/PCK@0.05 at 12 epoch is saved to best_pck/PCK@0.05_epoch_12.pth.\\n\",\n            \"09/15 12:42:56 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:42:56 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 13 epochs\\n\",\n            \"09/15 12:42:57 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:42:57 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [13][2/2]  pck/PCK@0.05: 0.384718\\n\",\n            \"09/15 12:42:57 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_12.pth is removed\\n\",\n            \"09/15 12:42:58 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.3847 pck/PCK@0.05 at 13 epoch is saved to best_pck/PCK@0.05_epoch_13.pth.\\n\",\n            \"09/15 12:43:00 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:00 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 14 epochs\\n\",\n            \"09/15 12:43:01 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:01 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [14][2/2]  pck/PCK@0.05: 0.372036\\n\",\n            \"09/15 12:43:03 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:03 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 15 epochs\\n\",\n            \"09/15 12:43:04 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:04 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [15][2/2]  pck/PCK@0.05: 0.331702\\n\",\n            \"09/15 12:43:06 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:06 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 16 epochs\\n\",\n            \"09/15 12:43:07 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:07 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [16][2/2]  pck/PCK@0.05: 0.350346\\n\",\n            \"09/15 12:43:09 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:09 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 17 epochs\\n\",\n            \"09/15 12:43:10 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:10 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [17][2/2]  pck/PCK@0.05: 0.358399\\n\",\n            \"09/15 12:43:12 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:12 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 18 epochs\\n\",\n            \"09/15 12:43:14 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:14 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [18][2/2]  pck/PCK@0.05: 0.377378\\n\",\n            \"09/15 12:43:15 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:15 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 19 epochs\\n\",\n            \"09/15 12:43:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [19][2/2]  pck/PCK@0.05: 0.392675\\n\",\n            \"09/15 12:43:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_13.pth is removed\\n\",\n            \"09/15 12:43:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.3927 pck/PCK@0.05 at 19 epoch is saved to best_pck/PCK@0.05_epoch_19.pth.\\n\",\n            \"09/15 12:43:19 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:19 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 20 epochs\\n\",\n            \"09/15 12:43:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [20][2/2]  pck/PCK@0.05: 0.413536\\n\",\n            \"09/15 12:43:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_19.pth is removed\\n\",\n            \"09/15 12:43:21 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.4135 pck/PCK@0.05 at 20 epoch is saved to best_pck/PCK@0.05_epoch_20.pth.\\n\",\n            \"09/15 12:43:23 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:23 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 21 epochs\\n\",\n            \"09/15 12:43:24 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:24 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [21][2/2]  pck/PCK@0.05: 0.422105\\n\",\n            \"09/15 12:43:24 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_20.pth is removed\\n\",\n            \"09/15 12:43:25 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.4221 pck/PCK@0.05 at 21 epoch is saved to best_pck/PCK@0.05_epoch_21.pth.\\n\",\n            \"09/15 12:43:27 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:27 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 22 epochs\\n\",\n            \"09/15 12:43:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [22][2/2]  pck/PCK@0.05: 0.430300\\n\",\n            \"09/15 12:43:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_21.pth is removed\\n\",\n            \"09/15 12:43:29 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.4303 pck/PCK@0.05 at 22 epoch is saved to best_pck/PCK@0.05_epoch_22.pth.\\n\",\n            \"09/15 12:43:31 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:31 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 23 epochs\\n\",\n            \"09/15 12:43:32 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:32 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [23][2/2]  pck/PCK@0.05: 0.440251\\n\",\n            \"09/15 12:43:32 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_22.pth is removed\\n\",\n            \"09/15 12:43:33 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.4403 pck/PCK@0.05 at 23 epoch is saved to best_pck/PCK@0.05_epoch_23.pth.\\n\",\n            \"09/15 12:43:34 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:34 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 24 epochs\\n\",\n            \"09/15 12:43:36 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:36 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [24][2/2]  pck/PCK@0.05: 0.433262\\n\",\n            \"09/15 12:43:38 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:38 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 25 epochs\\n\",\n            \"09/15 12:43:39 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:39 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [25][2/2]  pck/PCK@0.05: 0.429440\\n\",\n            \"09/15 12:43:41 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:41 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 26 epochs\\n\",\n            \"09/15 12:43:42 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:42 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [26][2/2]  pck/PCK@0.05: 0.423034\\n\",\n            \"09/15 12:43:44 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:44 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 27 epochs\\n\",\n            \"09/15 12:43:45 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:45 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [27][2/2]  pck/PCK@0.05: 0.440554\\n\",\n            \"09/15 12:43:45 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_23.pth is removed\\n\",\n            \"09/15 12:43:46 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.4406 pck/PCK@0.05 at 27 epoch is saved to best_pck/PCK@0.05_epoch_27.pth.\\n\",\n            \"09/15 12:43:48 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:48 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 28 epochs\\n\",\n            \"09/15 12:43:49 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:49 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [28][2/2]  pck/PCK@0.05: 0.454103\\n\",\n            \"09/15 12:43:49 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The previous best checkpoint /home/PJLAB/jiangtao/Documents/git-clone/mmpose/work_dirs/hrnet_w32_coco_tiny_256x192/best_pck/PCK@0.05_epoch_27.pth is removed\\n\",\n            \"09/15 12:43:50 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - The best checkpoint with 0.4541 pck/PCK@0.05 at 28 epoch is saved to best_pck/PCK@0.05_epoch_28.pth.\\n\",\n            \"09/15 12:43:52 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:52 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 29 epochs\\n\",\n            \"09/15 12:43:53 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:53 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [29][2/2]  pck/PCK@0.05: 0.434462\\n\",\n            \"09/15 12:43:55 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:55 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 30 epochs\\n\",\n            \"09/15 12:43:56 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:56 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [30][2/2]  pck/PCK@0.05: 0.434963\\n\",\n            \"09/15 12:43:58 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:43:58 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 31 epochs\\n\",\n            \"09/15 12:43:59 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:43:59 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [31][2/2]  pck/PCK@0.05: 0.445667\\n\",\n            \"09/15 12:44:01 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:01 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 32 epochs\\n\",\n            \"09/15 12:44:03 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:03 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [32][2/2]  pck/PCK@0.05: 0.445784\\n\",\n            \"09/15 12:44:04 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:04 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 33 epochs\\n\",\n            \"09/15 12:44:06 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:06 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [33][2/2]  pck/PCK@0.05: 0.434502\\n\",\n            \"09/15 12:44:08 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:08 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 34 epochs\\n\",\n            \"09/15 12:44:09 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:09 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [34][2/2]  pck/PCK@0.05: 0.435661\\n\",\n            \"09/15 12:44:11 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:11 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 35 epochs\\n\",\n            \"09/15 12:44:12 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:12 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [35][2/2]  pck/PCK@0.05: 0.425407\\n\",\n            \"09/15 12:44:14 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:14 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 36 epochs\\n\",\n            \"09/15 12:44:15 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:15 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [36][2/2]  pck/PCK@0.05: 0.428712\\n\",\n            \"09/15 12:44:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:17 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 37 epochs\\n\",\n            \"09/15 12:44:18 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:18 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [37][2/2]  pck/PCK@0.05: 0.423183\\n\",\n            \"09/15 12:44:20 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:20 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 38 epochs\\n\",\n            \"09/15 12:44:22 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:22 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [38][2/2]  pck/PCK@0.05: 0.432350\\n\",\n            \"09/15 12:44:23 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:23 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 39 epochs\\n\",\n            \"09/15 12:44:25 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:25 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [39][2/2]  pck/PCK@0.05: 0.423967\\n\",\n            \"09/15 12:44:27 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Exp name: td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220915_124206\\n\",\n            \"09/15 12:44:27 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Saving checkpoint at 40 epochs\\n\",\n            \"09/15 12:44:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Evaluating PCKAccuracy (normalized by ``\\\"bbox_size\\\"``)...\\n\",\n            \"09/15 12:44:28 - mmengine - \\u001b[4m\\u001b[37mINFO\\u001b[0m - Epoch(val) [40][2/2]  pck/PCK@0.05: 0.429198\\n\"\n          ]\n        },\n        {\n          \"data\": {\n            \"text/plain\": [\n              \"TopdownPoseEstimator(\\n\",\n              \"  (data_preprocessor): PoseDataPreprocessor()\\n\",\n              \"  (backbone): HRNet(\\n\",\n              \"    (conv1): Conv2d(3, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"    (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"    (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"    (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"    (relu): ReLU(inplace=True)\\n\",\n              \"    (layer1): Sequential(\\n\",\n              \"      (0): Bottleneck(\\n\",\n              \"        (conv1): Conv2d(64, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"        (downsample): Sequential(\\n\",\n              \"          (0): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        )\\n\",\n              \"      )\\n\",\n              \"      (1): Bottleneck(\\n\",\n              \"        (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (2): Bottleneck(\\n\",\n              \"        (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (3): Bottleneck(\\n\",\n              \"        (conv1): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"        (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (conv3): Conv2d(64, 256, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"        (bn3): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"    (transition1): ModuleList(\\n\",\n              \"      (0): Sequential(\\n\",\n              \"        (0): Conv2d(256, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"        (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"        (2): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (1): Sequential(\\n\",\n              \"        (0): Sequential(\\n\",\n              \"          (0): Conv2d(256, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"          (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"          (2): ReLU(inplace=True)\\n\",\n              \"        )\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"    (stage2): Sequential(\\n\",\n              \"      (0): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"    (transition2): ModuleList(\\n\",\n              \"      (0): None\\n\",\n              \"      (1): None\\n\",\n              \"      (2): Sequential(\\n\",\n              \"        (0): Sequential(\\n\",\n              \"          (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"          (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"          (2): ReLU(inplace=True)\\n\",\n              \"        )\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"    (stage3): Sequential(\\n\",\n              \"      (0): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (1): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (2): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (3): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"    (transition3): ModuleList(\\n\",\n              \"      (0): None\\n\",\n              \"      (1): None\\n\",\n              \"      (2): None\\n\",\n              \"      (3): Sequential(\\n\",\n              \"        (0): Sequential(\\n\",\n              \"          (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"          (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"          (2): ReLU(inplace=True)\\n\",\n              \"        )\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"    (stage4): Sequential(\\n\",\n              \"      (0): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (3): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=8.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): None\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (3): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (2): Sequential(\\n\",\n              \"                (0): Conv2d(32, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(64, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (3): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (1): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (3): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=8.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): None\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 64, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 128, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): None\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 128, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (3): ModuleList(\\n\",\n              \"            (0): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(32, 32, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (2): Sequential(\\n\",\n              \"                (0): Conv2d(32, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(64, 64, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"                (2): ReLU(inplace=True)\\n\",\n              \"              )\\n\",\n              \"              (1): Sequential(\\n\",\n              \"                (0): Conv2d(64, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Sequential(\\n\",\n              \"                (0): Conv2d(128, 256, kernel_size=(3, 3), stride=(2, 2), padding=(1, 1), bias=False)\\n\",\n              \"                (1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              )\\n\",\n              \"            )\\n\",\n              \"            (3): None\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"      (2): HRModule(\\n\",\n              \"        (branches): ModuleList(\\n\",\n              \"          (0): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(32, 32, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (1): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(64, 64, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(64, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (2): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(128, 128, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(128, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"          (3): Sequential(\\n\",\n              \"            (0): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (1): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (2): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"            (3): BasicBlock(\\n\",\n              \"              (conv1): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn1): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (conv2): Conv2d(256, 256, kernel_size=(3, 3), stride=(1, 1), padding=(1, 1), bias=False)\\n\",\n              \"              (bn2): BatchNorm2d(256, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (relu): ReLU(inplace=True)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (fuse_layers): ModuleList(\\n\",\n              \"          (0): ModuleList(\\n\",\n              \"            (0): None\\n\",\n              \"            (1): Sequential(\\n\",\n              \"              (0): Conv2d(64, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=2.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (2): Sequential(\\n\",\n              \"              (0): Conv2d(128, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=4.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"            (3): Sequential(\\n\",\n              \"              (0): Conv2d(256, 32, kernel_size=(1, 1), stride=(1, 1), bias=False)\\n\",\n              \"              (1): BatchNorm2d(32, eps=1e-05, momentum=0.1, affine=True, track_running_stats=True)\\n\",\n              \"              (2): Upsample(scale_factor=8.0, mode=nearest)\\n\",\n              \"            )\\n\",\n              \"          )\\n\",\n              \"        )\\n\",\n              \"        (relu): ReLU(inplace=True)\\n\",\n              \"      )\\n\",\n              \"    )\\n\",\n              \"  )\\n\",\n              \"  init_cfg={'type': 'Pretrained', 'checkpoint': 'https://download.openmmlab.com/mmpose/pretrain_models/hrnet_w32-36af842e.pth'}\\n\",\n              \"  (head): HeatmapHead(\\n\",\n              \"    (loss_module): KeypointMSELoss(\\n\",\n              \"      (criterion): MSELoss()\\n\",\n              \"    )\\n\",\n              \"    (deconv_layers): Identity()\\n\",\n              \"    (conv_layers): Identity()\\n\",\n              \"    (final_layer): Conv2d(32, 17, kernel_size=(1, 1), stride=(1, 1))\\n\",\n              \"  )\\n\",\n              \"  init_cfg=[{'type': 'Normal', 'layer': ['Conv2d', 'ConvTranspose2d'], 'std': 0.001}, {'type': 'Constant', 'layer': 'BatchNorm2d', 'val': 1}]\\n\",\n              \")\"\n            ]\n          },\n          \"execution_count\": 7,\n          \"metadata\": {},\n          \"output_type\": \"execute_result\"\n        }\n      ],\n      \"source\": [\n        \"from mmengine.config import Config, DictAction\\n\",\n        \"from mmengine.runner import Runner\\n\",\n        \"\\n\",\n        \"# set preprocess configs to model\\n\",\n        \"cfg.model.setdefault('data_preprocessor', cfg.get('preprocess_cfg', {}))\\n\",\n        \"\\n\",\n        \"# build the runner from config\\n\",\n        \"runner = Runner.from_cfg(cfg)\\n\",\n        \"\\n\",\n        \"# start training\\n\",\n        \"runner.train()\"\n      ]\n    },\n    {\n      \"attachments\": {},\n      \"cell_type\": \"markdown\",\n      \"metadata\": {\n        \"id\": \"sdLwcaojhE2T\"\n      },\n      \"source\": [\n        \"#### Note\\n\",\n        \"The recommended best practice is to convert your customized data into COCO format.\"\n      ]\n    },\n    {\n      \"cell_type\": \"code\",\n      \"execution_count\": null,\n      \"metadata\": {\n        \"id\": \"zJyteZNGqwNk\"\n      },\n      \"outputs\": [],\n      \"source\": []\n    }\n  ],\n  \"metadata\": {\n    \"accelerator\": \"GPU\",\n    \"colab\": {\n      \"provenance\": []\n    },\n    \"gpuClass\": \"standard\",\n    \"kernelspec\": {\n      \"display_name\": \"dev2.0\",\n      \"language\": \"python\",\n      \"name\": \"python3\"\n    },\n    \"language_info\": {\n      \"codemirror_mode\": {\n        \"name\": \"ipython\",\n        \"version\": 3\n      },\n      \"file_extension\": \".py\",\n      \"mimetype\": \"text/x-python\",\n      \"name\": \"python\",\n      \"nbconvert_exporter\": \"python\",\n      \"pygments_lexer\": \"ipython3\",\n      \"version\": \"3.8.5\"\n    },\n    \"vscode\": {\n      \"interpreter\": {\n        \"hash\": \"383ba00087b5a9caebf3648b758a31e474cc01be975489b58f119fa4bc17e1f8\"\n      }\n    },\n    \"widgets\": {\n      \"application/vnd.jupyter.widget-state+json\": {\n        \"08e0412b8dd54d28a26c232e75ea6088\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"FloatProgressModel\",\n          \"state\": {\n            \"_dom_classes\": [],\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"FloatProgressModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/controls\",\n            \"_view_module_version\": \"1.5.0\",\n            \"_view_name\": \"ProgressView\",\n            \"bar_style\": \"success\",\n            \"description\": \"\",\n            \"description_tooltip\": null,\n            \"layout\": \"IPY_MODEL_d2ee56f920a245d9875de8e37596a5c8\",\n            \"max\": 132594821,\n            \"min\": 0,\n            \"orientation\": \"horizontal\",\n            \"style\": \"IPY_MODEL_b5f8c86d48a04afa997fc137e1acd716\",\n            \"value\": 132594821\n          }\n        },\n        \"1c1b09d91dec4e3dadefe953daf50745\": {\n          \"model_module\": \"@jupyter-widgets/base\",\n          \"model_module_version\": \"1.2.0\",\n          \"model_name\": \"LayoutModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/base\",\n            \"_model_module_version\": \"1.2.0\",\n            \"_model_name\": \"LayoutModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"LayoutView\",\n            \"align_content\": null,\n            \"align_items\": null,\n            \"align_self\": null,\n            \"border\": null,\n            \"bottom\": null,\n            \"display\": null,\n            \"flex\": null,\n            \"flex_flow\": null,\n            \"grid_area\": null,\n            \"grid_auto_columns\": null,\n            \"grid_auto_flow\": null,\n            \"grid_auto_rows\": null,\n            \"grid_column\": null,\n            \"grid_gap\": null,\n            \"grid_row\": null,\n            \"grid_template_areas\": null,\n            \"grid_template_columns\": null,\n            \"grid_template_rows\": null,\n            \"height\": null,\n            \"justify_content\": null,\n            \"justify_items\": null,\n            \"left\": null,\n            \"margin\": null,\n            \"max_height\": null,\n            \"max_width\": null,\n            \"min_height\": null,\n            \"min_width\": null,\n            \"object_fit\": null,\n            \"object_position\": null,\n            \"order\": null,\n            \"overflow\": null,\n            \"overflow_x\": null,\n            \"overflow_y\": null,\n            \"padding\": null,\n            \"right\": null,\n            \"top\": null,\n            \"visibility\": null,\n            \"width\": null\n          }\n        },\n        \"2a079d9c0b9845318e6c612ca9601b86\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"HBoxModel\",\n          \"state\": {\n            \"_dom_classes\": [],\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"HBoxModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/controls\",\n            \"_view_module_version\": \"1.5.0\",\n            \"_view_name\": \"HBoxView\",\n            \"box_style\": \"\",\n            \"children\": [\n              \"IPY_MODEL_3554753622334094961a47daf9362c59\",\n              \"IPY_MODEL_08e0412b8dd54d28a26c232e75ea6088\",\n              \"IPY_MODEL_558a9420b0b34be2a2ca8a8b8af9cbfc\"\n            ],\n            \"layout\": \"IPY_MODEL_a9bd3e477f07449788f0e95e3cd13ddc\"\n          }\n        },\n        \"3554753622334094961a47daf9362c59\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"HTMLModel\",\n          \"state\": {\n            \"_dom_classes\": [],\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"HTMLModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/controls\",\n            \"_view_module_version\": \"1.5.0\",\n            \"_view_name\": \"HTMLView\",\n            \"description\": \"\",\n            \"description_tooltip\": null,\n            \"layout\": \"IPY_MODEL_5b2ee1f3e78d4cd993009d04baf76b24\",\n            \"placeholder\": \"​\",\n            \"style\": \"IPY_MODEL_a3e5aa31c3f644b5a677ec49fe2e0832\",\n            \"value\": \"100%\"\n          }\n        },\n        \"558a9420b0b34be2a2ca8a8b8af9cbfc\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"HTMLModel\",\n          \"state\": {\n            \"_dom_classes\": [],\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"HTMLModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/controls\",\n            \"_view_module_version\": \"1.5.0\",\n            \"_view_name\": \"HTMLView\",\n            \"description\": \"\",\n            \"description_tooltip\": null,\n            \"layout\": \"IPY_MODEL_1c1b09d91dec4e3dadefe953daf50745\",\n            \"placeholder\": \"​\",\n            \"style\": \"IPY_MODEL_6af448aebdb744b98a2807f66b1d6e5d\",\n            \"value\": \" 126M/126M [00:14&lt;00:00, 9.32MB/s]\"\n          }\n        },\n        \"5b2ee1f3e78d4cd993009d04baf76b24\": {\n          \"model_module\": \"@jupyter-widgets/base\",\n          \"model_module_version\": \"1.2.0\",\n          \"model_name\": \"LayoutModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/base\",\n            \"_model_module_version\": \"1.2.0\",\n            \"_model_name\": \"LayoutModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"LayoutView\",\n            \"align_content\": null,\n            \"align_items\": null,\n            \"align_self\": null,\n            \"border\": null,\n            \"bottom\": null,\n            \"display\": null,\n            \"flex\": null,\n            \"flex_flow\": null,\n            \"grid_area\": null,\n            \"grid_auto_columns\": null,\n            \"grid_auto_flow\": null,\n            \"grid_auto_rows\": null,\n            \"grid_column\": null,\n            \"grid_gap\": null,\n            \"grid_row\": null,\n            \"grid_template_areas\": null,\n            \"grid_template_columns\": null,\n            \"grid_template_rows\": null,\n            \"height\": null,\n            \"justify_content\": null,\n            \"justify_items\": null,\n            \"left\": null,\n            \"margin\": null,\n            \"max_height\": null,\n            \"max_width\": null,\n            \"min_height\": null,\n            \"min_width\": null,\n            \"object_fit\": null,\n            \"object_position\": null,\n            \"order\": null,\n            \"overflow\": null,\n            \"overflow_x\": null,\n            \"overflow_y\": null,\n            \"padding\": null,\n            \"right\": null,\n            \"top\": null,\n            \"visibility\": null,\n            \"width\": null\n          }\n        },\n        \"6af448aebdb744b98a2807f66b1d6e5d\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"DescriptionStyleModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"DescriptionStyleModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"StyleView\",\n            \"description_width\": \"\"\n          }\n        },\n        \"a3e5aa31c3f644b5a677ec49fe2e0832\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"DescriptionStyleModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"DescriptionStyleModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"StyleView\",\n            \"description_width\": \"\"\n          }\n        },\n        \"a9bd3e477f07449788f0e95e3cd13ddc\": {\n          \"model_module\": \"@jupyter-widgets/base\",\n          \"model_module_version\": \"1.2.0\",\n          \"model_name\": \"LayoutModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/base\",\n            \"_model_module_version\": \"1.2.0\",\n            \"_model_name\": \"LayoutModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"LayoutView\",\n            \"align_content\": null,\n            \"align_items\": null,\n            \"align_self\": null,\n            \"border\": null,\n            \"bottom\": null,\n            \"display\": null,\n            \"flex\": null,\n            \"flex_flow\": null,\n            \"grid_area\": null,\n            \"grid_auto_columns\": null,\n            \"grid_auto_flow\": null,\n            \"grid_auto_rows\": null,\n            \"grid_column\": null,\n            \"grid_gap\": null,\n            \"grid_row\": null,\n            \"grid_template_areas\": null,\n            \"grid_template_columns\": null,\n            \"grid_template_rows\": null,\n            \"height\": null,\n            \"justify_content\": null,\n            \"justify_items\": null,\n            \"left\": null,\n            \"margin\": null,\n            \"max_height\": null,\n            \"max_width\": null,\n            \"min_height\": null,\n            \"min_width\": null,\n            \"object_fit\": null,\n            \"object_position\": null,\n            \"order\": null,\n            \"overflow\": null,\n            \"overflow_x\": null,\n            \"overflow_y\": null,\n            \"padding\": null,\n            \"right\": null,\n            \"top\": null,\n            \"visibility\": null,\n            \"width\": null\n          }\n        },\n        \"b5f8c86d48a04afa997fc137e1acd716\": {\n          \"model_module\": \"@jupyter-widgets/controls\",\n          \"model_module_version\": \"1.5.0\",\n          \"model_name\": \"ProgressStyleModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/controls\",\n            \"_model_module_version\": \"1.5.0\",\n            \"_model_name\": \"ProgressStyleModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"StyleView\",\n            \"bar_color\": null,\n            \"description_width\": \"\"\n          }\n        },\n        \"d2ee56f920a245d9875de8e37596a5c8\": {\n          \"model_module\": \"@jupyter-widgets/base\",\n          \"model_module_version\": \"1.2.0\",\n          \"model_name\": \"LayoutModel\",\n          \"state\": {\n            \"_model_module\": \"@jupyter-widgets/base\",\n            \"_model_module_version\": \"1.2.0\",\n            \"_model_name\": \"LayoutModel\",\n            \"_view_count\": null,\n            \"_view_module\": \"@jupyter-widgets/base\",\n            \"_view_module_version\": \"1.2.0\",\n            \"_view_name\": \"LayoutView\",\n            \"align_content\": null,\n            \"align_items\": null,\n            \"align_self\": null,\n            \"border\": null,\n            \"bottom\": null,\n            \"display\": null,\n            \"flex\": null,\n            \"flex_flow\": null,\n            \"grid_area\": null,\n            \"grid_auto_columns\": null,\n            \"grid_auto_flow\": null,\n            \"grid_auto_rows\": null,\n            \"grid_column\": null,\n            \"grid_gap\": null,\n            \"grid_row\": null,\n            \"grid_template_areas\": null,\n            \"grid_template_columns\": null,\n            \"grid_template_rows\": null,\n            \"height\": null,\n            \"justify_content\": null,\n            \"justify_items\": null,\n            \"left\": null,\n            \"margin\": null,\n            \"max_height\": null,\n            \"max_width\": null,\n            \"min_height\": null,\n            \"min_width\": null,\n            \"object_fit\": null,\n            \"object_position\": null,\n            \"order\": null,\n            \"overflow\": null,\n            \"overflow_x\": null,\n            \"overflow_y\": null,\n            \"padding\": null,\n            \"right\": null,\n            \"top\": null,\n            \"visibility\": null,\n            \"width\": null\n          }\n        }\n      }\n    }\n  },\n  \"nbformat\": 4,\n  \"nbformat_minor\": 0\n}\n"
  },
  {
    "path": "demo/body3d_pose_lifter_demo.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nimport mimetypes\nimport os\nimport time\nfrom argparse import ArgumentParser\nfrom functools import partial\n\nimport cv2\nimport json_tricks as json\nimport mmcv\nimport mmengine\nimport numpy as np\nfrom mmengine.logging import print_log\n\nfrom mmpose.apis import (_track_by_iou, _track_by_oks,\n                         convert_keypoint_definition, extract_pose_sequence,\n                         inference_pose_lifter_model, inference_topdown,\n                         init_model)\nfrom mmpose.models.pose_estimators import PoseLifter\nfrom mmpose.models.pose_estimators.topdown import TopdownPoseEstimator\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import (PoseDataSample, merge_data_samples,\n                               split_instances)\nfrom mmpose.utils import adapt_mmdet_pipeline\n\ntry:\n    from mmdet.apis import inference_detector, init_detector\n    has_mmdet = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmdet = False\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument('det_config', help='Config file for detection')\n    parser.add_argument('det_checkpoint', help='Checkpoint file for detection')\n    parser.add_argument(\n        'pose_estimator_config',\n        type=str,\n        default=None,\n        help='Config file for the 1st stage 2D pose estimator')\n    parser.add_argument(\n        'pose_estimator_checkpoint',\n        type=str,\n        default=None,\n        help='Checkpoint file for the 1st stage 2D pose estimator')\n    parser.add_argument(\n        'pose_lifter_config',\n        help='Config file for the 2nd stage pose lifter model')\n    parser.add_argument(\n        'pose_lifter_checkpoint',\n        help='Checkpoint file for the 2nd stage pose lifter model')\n    parser.add_argument('--input', type=str, default='', help='Video path')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='Whether to show visualizations')\n    parser.add_argument(\n        '--disable-rebase-keypoint',\n        action='store_true',\n        default=False,\n        help='Whether to disable rebasing the predicted 3D pose so its '\n        'lowest keypoint has a height of 0 (landing on the ground). Rebase '\n        'is useful for visualization when the model do not predict the '\n        'global position of the 3D pose.')\n    parser.add_argument(\n        '--disable-norm-pose-2d',\n        action='store_true',\n        default=False,\n        help='Whether to scale the bbox (along with the 2D pose) to the '\n        'average bbox scale of the dataset, and move the bbox (along with the '\n        '2D pose) to the average bbox center of the dataset. This is useful '\n        'when bbox is small, especially in multi-person scenarios.')\n    parser.add_argument(\n        '--num-instances',\n        type=int,\n        default=1,\n        help='The number of 3D poses to be visualized in every frame. If '\n        'less than 0, it will be set to the number of pose results in the '\n        'first frame.')\n    parser.add_argument(\n        '--output-root',\n        type=str,\n        default='',\n        help='Root of the output video file. '\n        'Default not saving the visualization video.')\n    parser.add_argument(\n        '--save-predictions',\n        action='store_true',\n        default=False,\n        help='Whether to save predicted results')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--det-cat-id',\n        type=int,\n        default=0,\n        help='Category id for bounding box detection model')\n    parser.add_argument(\n        '--bbox-thr',\n        type=float,\n        default=0.3,\n        help='Bounding box score threshold')\n    parser.add_argument('--kpt-thr', type=float, default=0.3)\n    parser.add_argument(\n        '--use-oks-tracking', action='store_true', help='Using OKS tracking')\n    parser.add_argument(\n        '--tracking-thr', type=float, default=0.3, help='Tracking threshold')\n    parser.add_argument(\n        '--show-interval', type=int, default=0, help='Sleep seconds per frame')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization')\n    parser.add_argument(\n        '--online',\n        action='store_true',\n        default=False,\n        help='Inference mode. If set to True, can not use future frame'\n        'information when using multi frames for inference in the 2D pose'\n        'detection stage. Default: False.')\n\n    args = parser.parse_args()\n    return args\n\n\ndef process_one_image(args, detector, frame, frame_idx, pose_estimator,\n                      pose_est_results_last, pose_est_results_list, next_id,\n                      pose_lifter, visualize_frame, visualizer):\n    \"\"\"Visualize detected and predicted keypoints of one image.\n\n    Pipeline of this function:\n\n                              frame\n                                |\n                                V\n                        +-----------------+\n                        |     detector    |\n                        +-----------------+\n                                |  det_result\n                                V\n                        +-----------------+\n                        |  pose_estimator |\n                        +-----------------+\n                                |  pose_est_results\n                                V\n            +--------------------------------------------+\n            |  convert 2d kpts into pose-lifting format  |\n            +--------------------------------------------+\n                                |  pose_est_results_list\n                                V\n                    +-----------------------+\n                    | extract_pose_sequence |\n                    +-----------------------+\n                                |  pose_seq_2d\n                                V\n                         +-------------+\n                         | pose_lifter |\n                         +-------------+\n                                |  pose_lift_results\n                                V\n                       +-----------------+\n                       | post-processing |\n                       +-----------------+\n                                |  pred_3d_data_samples\n                                V\n                         +------------+\n                         | visualizer |\n                         +------------+\n\n    Args:\n        args (Argument): Custom command-line arguments.\n        detector (mmdet.BaseDetector): The mmdet detector.\n        frame (np.ndarray): The image frame read from input image or video.\n        frame_idx (int): The index of current frame.\n        pose_estimator (TopdownPoseEstimator): The pose estimator for 2d pose.\n        pose_est_results_last (list(PoseDataSample)): The results of pose\n            estimation from the last frame for tracking instances.\n        pose_est_results_list (list(list(PoseDataSample))): The list of all\n            pose estimation results converted by\n            ``convert_keypoint_definition`` from previous frames. In\n            pose-lifting stage it is used to obtain the 2d estimation sequence.\n        next_id (int): The next track id to be used.\n        pose_lifter (PoseLifter): The pose-lifter for estimating 3d pose.\n        visualize_frame (np.ndarray): The image for drawing the results on.\n        visualizer (Visualizer): The visualizer for visualizing the 2d and 3d\n            pose estimation results.\n\n    Returns:\n        pose_est_results (list(PoseDataSample)): The pose estimation result of\n            the current frame.\n        pose_est_results_list (list(list(PoseDataSample))): The list of all\n            converted pose estimation results until the current frame.\n        pred_3d_instances (InstanceData): The result of pose-lifting.\n            Specifically, the predicted keypoints and scores are saved at\n            ``pred_3d_instances.keypoints`` and\n            ``pred_3d_instances.keypoint_scores``.\n        next_id (int): The next track id to be used.\n    \"\"\"\n    pose_lift_dataset = pose_lifter.cfg.test_dataloader.dataset\n    pose_lift_dataset_name = pose_lifter.dataset_meta['dataset_name']\n\n    # First stage: conduct 2D pose detection in a Topdown manner\n    # use detector to obtain person bounding boxes\n    det_result = inference_detector(detector, frame)\n    pred_instance = det_result.pred_instances.cpu().numpy()\n\n    # filter out the person instances with category and bbox threshold\n    # e.g. 0 for person in COCO\n    bboxes = pred_instance.bboxes\n    bboxes = bboxes[np.logical_and(pred_instance.labels == args.det_cat_id,\n                                   pred_instance.scores > args.bbox_thr)]\n\n    # estimate pose results for current image\n    pose_est_results = inference_topdown(pose_estimator, frame, bboxes)\n\n    if args.use_oks_tracking:\n        _track = partial(_track_by_oks)\n    else:\n        _track = _track_by_iou\n\n    pose_det_dataset_name = pose_estimator.dataset_meta['dataset_name']\n    pose_est_results_converted = []\n\n    # convert 2d pose estimation results into the format for pose-lifting\n    # such as changing the keypoint order, flipping the keypoint, etc.\n    for i, data_sample in enumerate(pose_est_results):\n        pred_instances = data_sample.pred_instances.cpu().numpy()\n        keypoints = pred_instances.keypoints\n        # calculate area and bbox\n        if 'bboxes' in pred_instances:\n            areas = np.array([(bbox[2] - bbox[0]) * (bbox[3] - bbox[1])\n                              for bbox in pred_instances.bboxes])\n            pose_est_results[i].pred_instances.set_field(areas, 'areas')\n        else:\n            areas, bboxes = [], []\n            for keypoint in keypoints:\n                xmin = np.min(keypoint[:, 0][keypoint[:, 0] > 0], initial=1e10)\n                xmax = np.max(keypoint[:, 0])\n                ymin = np.min(keypoint[:, 1][keypoint[:, 1] > 0], initial=1e10)\n                ymax = np.max(keypoint[:, 1])\n                areas.append((xmax - xmin) * (ymax - ymin))\n                bboxes.append([xmin, ymin, xmax, ymax])\n            pose_est_results[i].pred_instances.areas = np.array(areas)\n            pose_est_results[i].pred_instances.bboxes = np.array(bboxes)\n\n        # track id\n        track_id, pose_est_results_last, _ = _track(data_sample,\n                                                    pose_est_results_last,\n                                                    args.tracking_thr)\n        if track_id == -1:\n            if np.count_nonzero(keypoints[:, :, 1]) >= 3:\n                track_id = next_id\n                next_id += 1\n            else:\n                # If the number of keypoints detected is small,\n                # delete that person instance.\n                keypoints[:, :, 1] = -10\n                pose_est_results[i].pred_instances.set_field(\n                    keypoints, 'keypoints')\n                pose_est_results[i].pred_instances.set_field(\n                    pred_instances.bboxes * 0, 'bboxes')\n                pose_est_results[i].set_field(pred_instances, 'pred_instances')\n                track_id = -1\n        pose_est_results[i].set_field(track_id, 'track_id')\n\n        # convert keypoints for pose-lifting\n        pose_est_result_converted = PoseDataSample()\n        pose_est_result_converted.set_field(\n            pose_est_results[i].pred_instances.clone(), 'pred_instances')\n        pose_est_result_converted.set_field(\n            pose_est_results[i].gt_instances.clone(), 'gt_instances')\n        keypoints = convert_keypoint_definition(keypoints,\n                                                pose_det_dataset_name,\n                                                pose_lift_dataset_name)\n        pose_est_result_converted.pred_instances.set_field(\n            keypoints, 'keypoints')\n        pose_est_result_converted.set_field(pose_est_results[i].track_id,\n                                            'track_id')\n        pose_est_results_converted.append(pose_est_result_converted)\n\n    pose_est_results_list.append(pose_est_results_converted.copy())\n\n    # Second stage: Pose lifting\n    # extract and pad input pose2d sequence\n    pose_seq_2d = extract_pose_sequence(\n        pose_est_results_list,\n        frame_idx=frame_idx,\n        causal=pose_lift_dataset.get('causal', False),\n        seq_len=pose_lift_dataset.get('seq_len', 1),\n        step=pose_lift_dataset.get('seq_step', 1))\n\n    # conduct 2D-to-3D pose lifting\n    norm_pose_2d = not args.disable_norm_pose_2d\n    pose_lift_results = inference_pose_lifter_model(\n        pose_lifter,\n        pose_seq_2d,\n        image_size=visualize_frame.shape[:2],\n        norm_pose_2d=norm_pose_2d)\n\n    # post-processing\n    for idx, pose_lift_result in enumerate(pose_lift_results):\n        pose_lift_result.track_id = pose_est_results[idx].get('track_id', 1e4)\n\n        pred_instances = pose_lift_result.pred_instances\n        keypoints = pred_instances.keypoints\n        keypoint_scores = pred_instances.keypoint_scores\n        if keypoint_scores.ndim == 3:\n            keypoint_scores = np.squeeze(keypoint_scores, axis=1)\n            pose_lift_results[\n                idx].pred_instances.keypoint_scores = keypoint_scores\n        if keypoints.ndim == 4:\n            keypoints = np.squeeze(keypoints, axis=1)\n\n        keypoints = keypoints[..., [0, 2, 1]]\n        keypoints[..., 0] = -keypoints[..., 0]\n        keypoints[..., 2] = -keypoints[..., 2]\n\n        # rebase height (z-axis)\n        if not args.disable_rebase_keypoint:\n            keypoints[..., 2] -= np.min(\n                keypoints[..., 2], axis=-1, keepdims=True)\n\n        pose_lift_results[idx].pred_instances.keypoints = keypoints\n\n    pose_lift_results = sorted(\n        pose_lift_results, key=lambda x: x.get('track_id', 1e4))\n\n    pred_3d_data_samples = merge_data_samples(pose_lift_results)\n    det_data_sample = merge_data_samples(pose_est_results)\n    pred_3d_instances = pred_3d_data_samples.get('pred_instances', None)\n\n    if args.num_instances < 0:\n        args.num_instances = len(pose_lift_results)\n\n    # Visualization\n    if visualizer is not None:\n        visualizer.add_datasample(\n            'result',\n            visualize_frame,\n            data_sample=pred_3d_data_samples,\n            det_data_sample=det_data_sample,\n            draw_gt=False,\n            dataset_2d=pose_det_dataset_name,\n            dataset_3d=pose_lift_dataset_name,\n            show=args.show,\n            draw_bbox=True,\n            kpt_thr=args.kpt_thr,\n            num_instances=args.num_instances,\n            wait_time=args.show_interval)\n\n    return pose_est_results, pose_est_results_list, pred_3d_instances, next_id\n\n\ndef main():\n    assert has_mmdet, 'Please install mmdet to run the demo.'\n\n    args = parse_args()\n\n    assert args.show or (args.output_root != '')\n    assert args.input != ''\n    assert args.det_config is not None\n    assert args.det_checkpoint is not None\n\n    detector = init_detector(\n        args.det_config, args.det_checkpoint, device=args.device.lower())\n    detector.cfg = adapt_mmdet_pipeline(detector.cfg)\n\n    pose_estimator = init_model(\n        args.pose_estimator_config,\n        args.pose_estimator_checkpoint,\n        device=args.device.lower())\n\n    assert isinstance(pose_estimator, TopdownPoseEstimator), 'Only \"TopDown\"' \\\n        'model is supported for the 1st stage (2D pose detection)'\n\n    det_kpt_color = pose_estimator.dataset_meta.get('keypoint_colors', None)\n    det_dataset_skeleton = pose_estimator.dataset_meta.get(\n        'skeleton_links', None)\n    det_dataset_link_color = pose_estimator.dataset_meta.get(\n        'skeleton_link_colors', None)\n\n    pose_lifter = init_model(\n        args.pose_lifter_config,\n        args.pose_lifter_checkpoint,\n        device=args.device.lower())\n\n    assert isinstance(pose_lifter, PoseLifter), \\\n        'Only \"PoseLifter\" model is supported for the 2nd stage ' \\\n        '(2D-to-3D lifting)'\n\n    pose_lifter.cfg.visualizer.radius = args.radius\n    pose_lifter.cfg.visualizer.line_width = args.thickness\n    pose_lifter.cfg.visualizer.det_kpt_color = det_kpt_color\n    pose_lifter.cfg.visualizer.det_dataset_skeleton = det_dataset_skeleton\n    pose_lifter.cfg.visualizer.det_dataset_link_color = det_dataset_link_color\n    visualizer = VISUALIZERS.build(pose_lifter.cfg.visualizer)\n\n    # the dataset_meta is loaded from the checkpoint\n    visualizer.set_dataset_meta(pose_lifter.dataset_meta)\n\n    if args.input == 'webcam':\n        input_type = 'webcam'\n    else:\n        input_type = mimetypes.guess_type(args.input)[0].split('/')[0]\n\n    if args.output_root == '':\n        save_output = False\n    else:\n        mmengine.mkdir_or_exist(args.output_root)\n        output_file = os.path.join(args.output_root,\n                                   os.path.basename(args.input))\n        if args.input == 'webcam':\n            output_file += '.mp4'\n        save_output = True\n\n    if args.save_predictions:\n        assert args.output_root != ''\n        args.pred_save_path = f'{args.output_root}/results_' \\\n            f'{os.path.splitext(os.path.basename(args.input))[0]}.json'\n\n    if save_output:\n        fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n\n    pose_est_results_list = []\n    pred_instances_list = []\n    if input_type == 'image':\n        frame = mmcv.imread(args.input, channel_order='rgb')\n        _, _, pred_3d_instances, _ = process_one_image(\n            args=args,\n            detector=detector,\n            frame=frame,\n            frame_idx=0,\n            pose_estimator=pose_estimator,\n            pose_est_results_last=[],\n            pose_est_results_list=pose_est_results_list,\n            next_id=0,\n            pose_lifter=pose_lifter,\n            visualize_frame=frame,\n            visualizer=visualizer)\n\n        if args.save_predictions:\n            # save prediction results\n            pred_instances_list = split_instances(pred_3d_instances)\n\n        if save_output:\n            frame_vis = visualizer.get_image()\n            mmcv.imwrite(mmcv.rgb2bgr(frame_vis), output_file)\n\n    elif input_type in ['webcam', 'video']:\n        next_id = 0\n        pose_est_results = []\n\n        if args.input == 'webcam':\n            video = cv2.VideoCapture(0)\n        else:\n            video = cv2.VideoCapture(args.input)\n\n        (major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')\n        if int(major_ver) < 3:\n            fps = video.get(cv2.cv.CV_CAP_PROP_FPS)\n        else:\n            fps = video.get(cv2.CAP_PROP_FPS)\n\n        video_writer = None\n        frame_idx = 0\n\n        while video.isOpened():\n            success, frame = video.read()\n            frame_idx += 1\n\n            if not success:\n                break\n\n            pose_est_results_last = pose_est_results\n\n            # First stage: 2D pose detection\n            # make person results for current image\n            (pose_est_results, pose_est_results_list, pred_3d_instances,\n             next_id) = process_one_image(\n                 args=args,\n                 detector=detector,\n                 frame=frame,\n                 frame_idx=frame_idx,\n                 pose_estimator=pose_estimator,\n                 pose_est_results_last=pose_est_results_last,\n                 pose_est_results_list=pose_est_results_list,\n                 next_id=next_id,\n                 pose_lifter=pose_lifter,\n                 visualize_frame=mmcv.bgr2rgb(frame),\n                 visualizer=visualizer)\n\n            if args.save_predictions:\n                # save prediction results\n                pred_instances_list.append(\n                    dict(\n                        frame_id=frame_idx,\n                        instances=split_instances(pred_3d_instances)))\n\n            if save_output:\n                frame_vis = visualizer.get_image()\n                if video_writer is None:\n                    # the size of the image with visualization may vary\n                    # depending on the presence of heatmaps\n                    video_writer = cv2.VideoWriter(output_file, fourcc, fps,\n                                                   (frame_vis.shape[1],\n                                                    frame_vis.shape[0]))\n\n                video_writer.write(mmcv.rgb2bgr(frame_vis))\n\n            if args.show:\n                # press ESC to exit\n                if cv2.waitKey(5) & 0xFF == 27:\n                    break\n                time.sleep(args.show_interval)\n\n        video.release()\n\n        if video_writer:\n            video_writer.release()\n    else:\n        args.save_predictions = False\n        raise ValueError(\n            f'file {os.path.basename(args.input)} has invalid format.')\n\n    if args.save_predictions:\n        with open(args.pred_save_path, 'w') as f:\n            json.dump(\n                dict(\n                    meta_info=pose_lifter.dataset_meta,\n                    instance_info=pred_instances_list),\n                f,\n                indent='\\t')\n        print(f'predictions have been saved at {args.pred_save_path}')\n\n    if save_output:\n        input_type = input_type.replace('webcam', 'video')\n        print_log(\n            f'the output {input_type} has been saved at {output_file}',\n            logger='current',\n            level=logging.INFO)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "demo/bottomup_demo.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nimport mimetypes\nimport os\nimport time\nfrom argparse import ArgumentParser\n\nimport cv2\nimport json_tricks as json\nimport mmcv\nimport mmengine\nimport numpy as np\nfrom mmengine.logging import print_log\n\nfrom mmpose.apis import inference_bottomup, init_model\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import split_instances\n\n\ndef process_one_image(args,\n                      img,\n                      pose_estimator,\n                      visualizer=None,\n                      show_interval=0):\n    \"\"\"Visualize predicted keypoints (and heatmaps) of one image.\"\"\"\n\n    # inference a single image\n    batch_results = inference_bottomup(pose_estimator, img)\n    results = batch_results[0]\n\n    # show the results\n    if isinstance(img, str):\n        img = mmcv.imread(img, channel_order='rgb')\n    elif isinstance(img, np.ndarray):\n        img = mmcv.bgr2rgb(img)\n\n    if visualizer is not None:\n        visualizer.add_datasample(\n            'result',\n            img,\n            data_sample=results,\n            draw_gt=False,\n            draw_bbox=False,\n            draw_heatmap=args.draw_heatmap,\n            show_kpt_idx=args.show_kpt_idx,\n            show=args.show,\n            wait_time=show_interval,\n            kpt_thr=args.kpt_thr)\n\n    return results.pred_instances\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument('config', help='Config file')\n    parser.add_argument('checkpoint', help='Checkpoint file')\n    parser.add_argument(\n        '--input', type=str, default='', help='Image/Video file')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='whether to show img')\n    parser.add_argument(\n        '--output-root',\n        type=str,\n        default='',\n        help='root of the output img file. '\n        'Default not saving the visualization images.')\n    parser.add_argument(\n        '--save-predictions',\n        action='store_true',\n        default=False,\n        help='whether to save predicted results')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--draw-heatmap',\n        action='store_true',\n        help='Visualize the predicted heatmap')\n    parser.add_argument(\n        '--show-kpt-idx',\n        action='store_true',\n        default=False,\n        help='Whether to show the index of keypoints')\n    parser.add_argument(\n        '--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization')\n    parser.add_argument(\n        '--show-interval', type=int, default=0, help='Sleep seconds per frame')\n    args = parser.parse_args()\n    return args\n\n\ndef main():\n    args = parse_args()\n    assert args.show or (args.output_root != '')\n    assert args.input != ''\n\n    output_file = None\n    if args.output_root:\n        mmengine.mkdir_or_exist(args.output_root)\n        output_file = os.path.join(args.output_root,\n                                   os.path.basename(args.input))\n        if args.input == 'webcam':\n            output_file += '.mp4'\n\n    if args.save_predictions:\n        assert args.output_root != ''\n        args.pred_save_path = f'{args.output_root}/results_' \\\n            f'{os.path.splitext(os.path.basename(args.input))[0]}.json'\n\n    # build the model from a config file and a checkpoint file\n    if args.draw_heatmap:\n        cfg_options = dict(model=dict(test_cfg=dict(output_heatmaps=True)))\n    else:\n        cfg_options = None\n\n    model = init_model(\n        args.config,\n        args.checkpoint,\n        device=args.device,\n        cfg_options=cfg_options)\n\n    # build visualizer\n    model.cfg.visualizer.radius = args.radius\n    model.cfg.visualizer.line_width = args.thickness\n    visualizer = VISUALIZERS.build(model.cfg.visualizer)\n    visualizer.set_dataset_meta(model.dataset_meta)\n\n    if args.input == 'webcam':\n        input_type = 'webcam'\n    else:\n        input_type = mimetypes.guess_type(args.input)[0].split('/')[0]\n\n    if input_type == 'image':\n        # inference\n        pred_instances = process_one_image(\n            args, args.input, model, visualizer, show_interval=0)\n\n        if args.save_predictions:\n            pred_instances_list = split_instances(pred_instances)\n\n        if output_file:\n            img_vis = visualizer.get_image()\n            mmcv.imwrite(mmcv.rgb2bgr(img_vis), output_file)\n\n    elif input_type in ['webcam', 'video']:\n\n        if args.input == 'webcam':\n            cap = cv2.VideoCapture(0)\n        else:\n            cap = cv2.VideoCapture(args.input)\n\n        video_writer = None\n        pred_instances_list = []\n        frame_idx = 0\n\n        while cap.isOpened():\n            success, frame = cap.read()\n            frame_idx += 1\n\n            if not success:\n                break\n\n            pred_instances = process_one_image(args, frame, model, visualizer,\n                                               0.001)\n\n            if args.save_predictions:\n                # save prediction results\n                pred_instances_list.append(\n                    dict(\n                        frame_id=frame_idx,\n                        instances=split_instances(pred_instances)))\n\n            # output videos\n            if output_file:\n                frame_vis = visualizer.get_image()\n\n                if video_writer is None:\n                    fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n                    # the size of the image with visualization may vary\n                    # depending on the presence of heatmaps\n                    video_writer = cv2.VideoWriter(\n                        output_file,\n                        fourcc,\n                        25,  # saved fps\n                        (frame_vis.shape[1], frame_vis.shape[0]))\n\n                video_writer.write(mmcv.rgb2bgr(frame_vis))\n\n            if args.show:\n                # press ESC to exit\n                if cv2.waitKey(5) & 0xFF == 27:\n                    break\n\n                time.sleep(args.show_interval)\n\n        if video_writer:\n            video_writer.release()\n\n        cap.release()\n\n    else:\n        args.save_predictions = False\n        raise ValueError(\n            f'file {os.path.basename(args.input)} has invalid format.')\n\n    if args.save_predictions:\n        with open(args.pred_save_path, 'w') as f:\n            json.dump(\n                dict(\n                    meta_info=model.dataset_meta,\n                    instance_info=pred_instances_list),\n                f,\n                indent='\\t')\n        print(f'predictions have been saved at {args.pred_save_path}')\n\n    if output_file:\n        input_type = input_type.replace('webcam', 'video')\n        print_log(\n            f'the output {input_type} has been saved at {output_file}',\n            logger='current',\n            level=logging.INFO)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "demo/docs/en/2d_animal_demo.md",
    "content": "## 2D Animal Pose Demo\n\nWe provide a demo script to test a single image or video with top-down pose estimators and animal detectors. Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection) with version >= 3.0.\n\n### 2D Animal Pose Image Demo\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} --det-cat-id ${DET_CAT_ID} \\\n    [--show] [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--draw-heatmap ${DRAW_HEATMAP}] [--radius ${KPT_RADIUS}] \\\n    [--kpt-thr ${KPT_SCORE_THR}] [--bbox-thr ${BBOX_SCORE_THR}] \\\n    [--device ${GPU_ID or CPU}]\n```\n\nThe pre-trained animal pose estimation model can be found from [model zoo](https://mmpose.readthedocs.io/en/latest/model_zoo/animal_2d_keypoint.html).\nTake [animalpose model](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth) as an example:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --show --draw-heatmap --det-cat-id=15\n```\n\nVisualization result:\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187644168-5915551a-0876-4b85-9454-7f92c84ba6fb.jpeg\" height=\"500px\" alt><br>\n\nIf you use a heatmap-based model and set argument `--draw-heatmap`, the predicted heatmap will be visualized together with the keypoints.\n\nThe augement `--det-cat-id=15` selected detected bounding boxes with label 'cat'. 15 is the index of category 'cat' in COCO dataset, on which the detection model is trained.\n\n**COCO-animals**\nIn COCO dataset, there are 80 object categories, including 10 common `animal` categories (14: 'bird', 15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe').\n\nFor other animals, we have also provided some pre-trained animal detection models. Supported models can be found in [detection model zoo](/demo/docs/en/mmdet_modelzoo.md).\n\nTo save visualized results on disk:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --output-root vis_results --draw-heatmap --det-cat-id=15\n```\n\nTo save predicted results on disk:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --output-root vis_results --save-predictions --draw-heatmap --det-cat-id=15\n```\n\nTo run demos on CPU:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_tiny_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_tiny_8xb32-300e_coco/rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --show --draw-heatmap --det-cat-id=15 --device cpu\n```\n\n### 2D Animal Pose Video Demo\n\nVideos share the same interface with images. The difference is that the `${INPUT_PATH}` for videos can be the local path or **URL** link to video file.\n\nFor example,\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input demo/resources/<demo_dog.mp4> \\\n    --output-root vis_results --draw-heatmap --det-cat-id=16\n```\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187655602-907db86e-710b-447a-8ec9-5b623d43d160.gif\" height=\"500px\" alt><br>\n\nThe original video can be downloaded from [Google Drive](https://drive.google.com/file/d/18d8K3wuUpKiDFHvOx0mh1TEwYwpOc5UO/view?usp=sharing).\n\n### 2D Animal Pose Demo with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py tests/data/ap10k \\\n    --pose2d animal --vis-out-dir vis_results/ap10k\n```\n\nThis command infers all images located in `tests/data/ap10k` and saves the visualization results in the `vis_results/ap10k` directory.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229789306-83ea56fa-12f2-4e27-9031-329d335ec26d.jpg\" alt=\"Image 1\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229789324-7fef5688-422d-4663-a57c-d1e1d511e83c.jpg\" alt=\"Image 2\" height=\"200\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface).\n\n### Speed Up Inference\n\nSome tips to speed up MMPose inference:\n\n1. set `model.test_cfg.flip_test=False` in [animalpose_hrnet-w32](../../configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py#85).\n2. use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/en/3.x/model_zoo.html).\n"
  },
  {
    "path": "demo/docs/en/2d_face_demo.md",
    "content": "## 2D Face Keypoint Demo\n\nWe provide a demo script to test a single image or video with face detectors and top-down pose estimators. Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection) with version >= 3.0.\n\n**Face Bounding Box Model Preparation:** The pre-trained face box estimation model can be found in [mmdet model zoo](/demo/docs/en/mmdet_modelzoo.md#face-bounding-box-detection-models).\n\n### 2D Face Image Demo\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} [--output-root ${OUTPUT_DIR}] \\\n    [--show] [--device ${GPU_ID or CPU}] [--save-predictions] \\\n    [--draw-heatmap ${DRAW_HEATMAP}] [--radius ${KPT_RADIUS}] \\\n    [--kpt-thr ${KPT_SCORE_THR}] [--bbox-thr ${BBOX_SCORE_THR}]\n```\n\nThe pre-trained face keypoint estimation models can be found from [model zoo](https://mmpose.readthedocs.io/en/latest/model_zoo/face_2d_keypoint.html).\nTake [aflw model](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth) as an example:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input tests/data/cofw/001766.jpg \\\n    --show --draw-heatmap\n```\n\nVisualization result:\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/d5f4a947-b6a7-465b-b54d-0ffa2f6d353a\" height=\"500px\" alt><br>\n\nIf you use a heatmap-based model and set argument `--draw-heatmap`, the predicted heatmap will be visualized together with the keypoints.\n\nTo save visualized results on disk:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input tests/data/cofw/001766.jpg \\\n    --draw-heatmap --output-root vis_results\n```\n\nTo save the predicted results on disk, please specify `--save-predictions`.\n\nTo run demos on CPU:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input tests/data/cofw/001766.jpg \\\n    --show --draw-heatmap --device=cpu\n```\n\n### 2D Face Video Demo\n\nVideos share the same interface with images. The difference is that the `${INPUT_PATH}` for videos can be the local path or **URL** link to video file.\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input demo/resources/<demo_face.mp4> \\\n    --show --output-root vis_results --radius 1\n```\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/5883f014-d0be-4796-a30e-f1b5dcb6e85d\" height=\"300px\" alt><br>\n\nThe original video can be downloaded from [Google Drive](https://drive.google.com/file/d/1kQt80t6w802b_vgVcmiV_QfcSJ3RWzmb/view?usp=sharing).\n\n### 2D Face Pose Demo with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py tests/data/wflw \\\n    --pose2d face --vis-out-dir vis_results/wflw --radius 1\n```\n\nThis command infers all images located in `tests/data/wflw` and saves the visualization results in the `vis_results/wflw` directory.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229793095-702f9d3b-461f-45bd-8535-d628e33bc907.jpg\" alt=\"Image 1\" width=\"400\"/>\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229793121-9969f014-70da-40b5-8561-e21c3edd1aeb.jpg\" alt=\"Image 2\" width=\"400\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface).\n\n### Speed Up Inference\n\nFor 2D face keypoint estimation models, try to edit the config file. For example, set `model.test_cfg.flip_test=False` in line 90 of [aflw_hrnetv2](../../../configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_8xb64-60e_aflw-256x256.py).\n"
  },
  {
    "path": "demo/docs/en/2d_hand_demo.md",
    "content": "## 2D Hand Keypoint Demo\n\nWe provide a demo script to test a single image or video with hand detectors and top-down pose estimators. Assume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection) with version >= 3.0.\n\n**Hand Box Model Preparation:** The pre-trained hand box estimation model can be found in [mmdet model zoo](/demo/docs/en/mmdet_modelzoo.md#hand-bounding-box-detection-models).\n\n### 2D Hand Image Demo\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} [--output-root ${OUTPUT_DIR}] \\\n    [--show] [--device ${GPU_ID or CPU}] [--save-predictions] \\\n    [--draw-heatmap ${DRAW_HEATMAP}] [--radius ${KPT_RADIUS}] \\\n    [--kpt-thr ${KPT_SCORE_THR}] [--bbox-thr ${BBOX_SCORE_THR}]\n```\n\nThe pre-trained hand pose estimation model can be downloaded from [model zoo](https://mmpose.readthedocs.io/en/latest/model_zoo/hand_2d_keypoint.html).\nTake [onehand10k model](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_onehand10k_256x256-30bc9c6b_20210330.pth) as an example:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input tests/data/onehand10k/9.jpg \\\n    --show --draw-heatmap\n```\n\nVisualization result:\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/3a2794cb-8071-4b9e-9498-c0bb46eb381e\" height=\"500px\" alt><br>\n\nIf you use a heatmap-based model and set argument `--draw-heatmap`, the predicted heatmap will be visualized together with the keypoints.\n\nTo save visualized results on disk:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input tests/data/onehand10k/9.jpg \\\n    --output-root vis_results --show --draw-heatmap\n```\n\nTo save the predicted results on disk, please specify `--save-predictions`.\n\nTo run demos on CPU:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input tests/data/onehand10k/9.jpg \\\n    --show --draw-heatmap  --device cpu\n```\n\n### 2D Hand Keypoints Video Demo\n\nVideos share the same interface with images. The difference is that the `${INPUT_PATH}` for videos can be the local path or **URL** link to video file.\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input data/tests_data_nvgesture_sk_color.avi \\\n    --output-root vis_results --kpt-thr 0.1\n```\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/558e8211-d7ca-4e04-b690-6c455e805ed7\" height=\"300px\" alt><br>\n\nThe original video can be downloaded from [Github](https://raw.githubusercontent.com/open-mmlab/mmpose/master/tests/data/nvgesture/sk_color.avi).\n\n### 2D Hand Keypoints Demo with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py tests/data/onehand10k \\\n    --pose2d hand --vis-out-dir vis_results/onehand10k \\\n    --bbox-thr 0.5 --kpt-thr 0.05\n```\n\nThis command infers all images located in `tests/data/onehand10k` and saves the visualization results in the `vis_results/onehand10k` directory.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229824447-b444e92d-9b5b-4a50-9a32-68be3ff8c527.jpg\" alt=\"Image 1\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229824466-6ae47a40-70a6-451d-94ee-4ffc34204a9c.jpg\" alt=\"Image 2\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229824477-679201c3-1e0b-45fe-b0c7-bab67b245a10.jpg\" alt=\"Image 3\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229824488-bd874362-7401-41a5-8209-51bad1563a11.jpg\" alt=\"Image 4\" height=\"200\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface).\n\n### Speed Up Inference\n\nFor 2D hand keypoint estimation models, try to edit the config file. For example, set `model.test_cfg.flip_test=False` in [onehand10k_hrnetv2](../../configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256.py#90).\n"
  },
  {
    "path": "demo/docs/en/2d_human_pose_demo.md",
    "content": "## 2D Human Pose Demo\n\nWe provide demo scripts to perform human pose estimation on images or videos.\n\n### 2D Human Pose Top-Down Image Demo\n\n#### Use full image as input\n\nWe provide a demo script to test a single image, using the full image as input bounding box.\n\n```shell\npython demo/image_demo.py \\\n    ${IMG_FILE} ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --out-file ${OUTPUT_FILE} \\\n    [--device ${GPU_ID or CPU}] \\\n    [--draw_heatmap]\n```\n\nIf you use a heatmap-based model and set argument `--draw-heatmap`, the predicted heatmap will be visualized together with the keypoints.\n\nThe pre-trained human pose estimation models can be downloaded from [model zoo](https://mmpose.readthedocs.io/en/latest/model_zoo/body_2d_keypoint.html).\nTake [coco model](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth) as an example:\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \\\n    --out-file vis_results.jpg \\\n    --draw-heatmap\n```\n\nTo run this demo on CPU:\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \\\n    --out-file vis_results.jpg \\\n    --draw-heatmap \\\n    --device=cpu\n```\n\nVisualization result:\n\n<img src=\"https://user-images.githubusercontent.com/87690686/187824033-2cce0f55-034a-4127-82e2-52744178bc32.jpg\" height=\"500px\" alt><br>\n\n#### Use mmdet for human bounding box detection\n\nWe provide a demo script to run mmdet for human detection, and mmpose for pose estimation.\n\nAssume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection) with version >= 3.0.\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} \\\n    [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--show] [--draw-heatmap] [--device ${GPU_ID or CPU}] \\\n    [--bbox-thr ${BBOX_SCORE_THR}] [--kpt-thr ${KPT_SCORE_THR}]\n```\n\nExample:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth \\\n    --input tests/data/coco/000000197388.jpg --show --draw-heatmap \\\n    --output-root vis_results/\n```\n\nVisualization result:\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/f14e0129-1e5e-4d74-84fe-28cd62357211\" height=\"500px\" alt><br>\n\nTo save the predicted results on disk, please specify `--save-predictions`.\n\n### 2D Human Pose Top-Down Video Demo\n\nThe above demo script can also take video as input, and run mmdet for human detection, and mmpose for pose estimation. The difference is, the `${INPUT_PATH}` for videos can be the local path or **URL** link to video file.\n\nAssume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection) with version >= 3.0.\n\nExample:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth \\\n    --input tests/data/posetrack18/videos/000001_mpiinew_test/000001_mpiinew_test.mp4 \\\n    --output-root=vis_results/demo --show --draw-heatmap\n```\n\n### 2D Human Pose Bottom-up Image/Video Demo\n\nWe also provide a demo script using bottom-up models to estimate the human pose in an image or a video, which does not rely on human detectors.\n\n```shell\npython demo/bottomup_demo.py \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} \\\n    [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--show] [--device ${GPU_ID or CPU}] \\\n    [--kpt-thr ${KPT_SCORE_THR}]\n```\n\nExample:\n\n```shell\npython demo/bottomup_demo.py \\\n    configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512.py \\\n    https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512_ac7c17bf-20221228.pth \\\n    --input tests/data/coco/000000197388.jpg --output-root=vis_results \\\n    --show --save-predictions\n```\n\nVisualization result:\n\n<img src=\"https://user-images.githubusercontent.com/26127467/207224032-a8dab45d-39e4-4b4e-80e0-3c71a64f5f39.jpg\" height=\"300px\" alt><br>\n\n### 2D Human Pose Estimation with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py \\\n    tests/data/posetrack18/videos/000001_mpiinew_test/000001_mpiinew_test.mp4 \\\n    --pose2d human --vis-out-dir vis_results/posetrack18\n```\n\nThis command infers the video and saves the visualization results in the `vis_results/posetrack18` directory.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229831445-44c9662b-edc5-4ef0-92a6-13558f0906cc.gif\" alt=\"Image 1\" height=\"300\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface).\n\n### Speed Up Inference\n\nSome tips to speed up MMPose inference:\n\nFor top-down models, try to edit the config file. For example,\n\n1. set `model.test_cfg.flip_test=False` in [topdown-res50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py#L56).\n2. use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/en/3.x/model_zoo.html).\n"
  },
  {
    "path": "demo/docs/en/2d_wholebody_pose_demo.md",
    "content": "## 2D Human Whole-Body Pose Demo\n\n### 2D Human Whole-Body Pose Top-Down Image Demo\n\n#### Use full image as input\n\nWe provide a demo script to test a single image, using the full image as input bounding box.\n\n```shell\npython demo/image_demo.py \\\n    ${IMG_FILE} ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --out-file ${OUTPUT_FILE} \\\n    [--device ${GPU_ID or CPU}] \\\n    [--draw_heatmap]\n```\n\nThe pre-trained hand pose estimation models can be downloaded from [model zoo](https://mmpose.readthedocs.io/en/latest/model_zoo/2d_wholebody_keypoint.html).\nTake [coco-wholebody_vipnas_res50_dark](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth) model as an example:\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth \\\n    --out-file vis_results.jpg\n```\n\nTo run demos on CPU:\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth \\\n    --out-file vis_results.jpg \\\n    --device=cpu\n```\n\n#### Use mmdet for human bounding box detection\n\nWe provide a demo script to run mmdet for human detection, and mmpose for pose estimation.\n\nAssume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection) with version >= 3.0.\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} \\\n    [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--show] [--draw-heatmap] [--device ${GPU_ID or CPU}] \\\n    [--bbox-thr ${BBOX_SCORE_THR}] [--kpt-thr ${KPT_SCORE_THR}]\n```\n\nExamples:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \\\n    --input tests/data/coco/000000196141.jpg \\\n    --output-root vis_results/ --show\n```\n\nTo save the predicted results on disk, please specify `--save-predictions`.\n\n### 2D Human Whole-Body Pose Top-Down Video Demo\n\nThe above demo script can also take video as input, and run mmdet for human detection, and mmpose for pose estimation.\n\nAssume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).\n\nExamples:\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \\\n    --input https://user-images.githubusercontent.com/87690686/137440639-fb08603d-9a35-474e-b65f-46b5c06b68d6.mp4 \\\n    --output-root vis_results/ --show\n```\n\nVisualization result:\n\n<img src=\"https://user-images.githubusercontent.com/87690686/190854069-634e1142-d13c-4863-9930-1120057ca77e.gif\" height=\"350px\" alt><br>\n\n### 2D Human Whole-Body Pose Estimation with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py tests/data/crowdpose \\\n    --pose2d wholebody --vis-out-dir vis_results/crowdpose\n```\n\nThis command infers all images located in `tests/data/crowdpose` and saves the visualization results in the `vis_results/crowdpose` directory.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229832887-31edb6d5-bcf0-44a4-a66f-9d523061a6e9.jpg\" alt=\"Image 1\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229832908-bc82dbc9-5e43-4800-acc7-a7da85a653c7.jpg\" alt=\"Image 2\" height=\"200\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface).\n\n### Speed Up Inference\n\nSome tips to speed up MMPose inference:\n\nFor top-down models, try to edit the config file. For example,\n\n1. set `model.test_cfg.flip_test=False` in [pose_hrnet_w48_dark+](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py#L90).\n2. use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/en/3.x/model_zoo.html).\n"
  },
  {
    "path": "demo/docs/en/3d_hand_demo.md",
    "content": "## 3D Hand Demo\n\n<img src=\"https://user-images.githubusercontent.com/28900607/121288285-b8fcbf00-c915-11eb-98e4-ba846de12987.gif\" width=\"600px\" alt><br>\n\n### 3D Hand Estimation Image Demo\n\n#### Using gt hand bounding boxes as input\n\nWe provide a demo script to test a single image, given gt json file.\n\n```shell\npython demo/hand3d_internet_demo.py \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_FILE} \\\n    --output-root ${OUTPUT_ROOT} \\\n    [--save-predictions] \\\n    [--gt-joints-file ${GT_JOINTS_FILE}]\\\n    [--disable-rebase-keypoint] \\\n    [--show] \\\n    [--device ${GPU_ID or CPU}] \\\n    [--kpt-thr ${KPT_THR}] \\\n    [--show-kpt-idx] \\\n    [--show-interval] \\\n    [--radius ${RADIUS}] \\\n    [--thickness ${THICKNESS}]\n```\n\nThe pre-trained hand pose estimation model can be downloaded from [model zoo](https://mmpose.readthedocs.io/en/latest/model_zoo/hand_3d_keypoint.html).\nTake [internet model](https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth) as an example:\n\n```shell\npython demo/hand3d_internet_demo.py \\\n    configs/hand_3d_keypoint/internet/interhand3d/internet_res50_4xb16-20e_interhand3d-256x256.py \\\n    https://download.openmmlab.com/mmpose/hand3d/internet/res50_intehand3dv1.0_all_256x256-42b7f2ac_20210702.pth \\\n    --input tests/data/interhand2.6m/image69148.jpg \\\n    --save-predictions \\\n    --output-root vis_results\n```\n\n### 3D Hand Pose Estimation with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py tests/data/interhand2.6m/image29590.jpg --pose3d hand3d --vis-out-dir vis_results/hand3d\n```\n\nThis command infers the image and saves the visualization results in the `vis_results/hand3d` directory.\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/29218285-aff6-455f-9763-39e8539eae61\" alt=\"Image 1\" height=\"300\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html#inferencer-a-unified-inference-interface).\n"
  },
  {
    "path": "demo/docs/en/3d_human_pose_demo.md",
    "content": "## 3D Human Pose Demo\n\n<img  src=\"https://user-images.githubusercontent.com/15977946/118820606-02df2000-b8e9-11eb-9984-b9228101e780.gif\"  width=\"600px\"  alt><br>\n\n### 3D Human Pose Two-stage Estimation Demo\n\n#### Using mmdet for human bounding box detection and top-down model for the 1st stage (2D pose detection), and inference the 2nd stage (2D-to-3D lifting)\n\nAssume that you have already installed [mmdet](https://github.com/open-mmlab/mmdetection).\n\n```shell\npython  demo/body3d_pose_lifter_demo.py  \\\n${MMDET_CONFIG_FILE} \\\n${MMDET_CHECKPOINT_FILE} \\\n${MMPOSE_CONFIG_FILE_2D} \\\n${MMPOSE_CHECKPOINT_FILE_2D} \\\n${MMPOSE_CONFIG_FILE_3D} \\\n${MMPOSE_CHECKPOINT_FILE_3D} \\\n--input ${VIDEO_PATH or IMAGE_PATH or 'webcam'} \\\n[--show] \\\n[--disable-rebase-keypoint] \\\n[--disable-norm-pose-2d] \\\n[--num-instances ${NUM_INSTANCES}] \\\n[--output-root ${OUT_VIDEO_ROOT}] \\\n[--save-predictions] \\\n[--device ${GPU_ID  or  CPU}] \\\n[--det-cat-id ${DET_CAT_ID}] \\\n[--bbox-thr ${BBOX_THR}] \\\n[--kpt-thr ${KPT_THR}] \\\n[--use-oks-tracking] \\\n[--tracking-thr ${TRACKING_THR}] \\\n[--show-interval ${INTERVAL}] \\\n[--thickness ${THICKNESS}] \\\n[--radius ${RADIUS}] \\\n[--online]\n```\n\nNote that\n\n1. `${VIDEO_PATH}` can be the local path or **URL** link to video file.\n\n2. If the `[--online]` option is set to **True**, future frame information can **not** be used when using multi frames for inference in the 2D pose detection stage.\n\nExamples:\n\nDuring 2D pose detection, for single-frame inference that do not rely on extra frames to get the final results of the current frame and save the prediction results, try this:\n\n```shell\npython demo/body3d_pose_lifter_demo.py  \\\ndemo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\nhttps://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\nconfigs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py \\\nhttps://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth \\\nconfigs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py \\\nhttps://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth  \\\n--input https://user-images.githubusercontent.com/87690686/164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.mp4 \\\n--output-root  vis_results \\\n--save-predictions\n```\n\nDuring 2D pose detection, for multi-frame inference that rely on extra frames to get the final results of the current frame, try this:\n\n```shell\npython demo/body3d_pose_lifter_demo.py \\\ndemo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\nhttps://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\nconfigs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py \\\nhttps://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth \\\nconfigs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py \\\nhttps://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth \\\n--input https://user-images.githubusercontent.com/87690686/164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.mp4 \\\n--output-root  vis_results  \\\n--online\n```\n\n### 3D Human Pose Demo with Inferencer\n\nThe Inferencer provides a convenient interface for inference, allowing customization using model aliases instead of configuration files and checkpoint paths. It supports various input formats, including image paths, video paths, image folder paths, and webcams. Below is an example command:\n\n```shell\npython demo/inferencer_demo.py tests/data/coco/000000000785.jpg \\\n    --pose3d human3d --vis-out-dir vis_results/human3d\n```\n\nThis command infers the image and saves the visualization results in the `vis_results/human3d` directory.\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/9621f51f-59e4-41e5-ab4c-3b03e97f0e9d\" alt=\"Image 1\" height=\"300\"/>\n\nIn addition, the Inferencer supports saving predicted poses. For more information, please refer to the [inferencer document](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html#inferencer-a-unified-inference-interface).\n"
  },
  {
    "path": "demo/docs/en/mmdet_modelzoo.md",
    "content": "## Pre-trained Detection Models\n\n### Human Bounding Box Detection Models\n\nFor human bounding box detection models, please download from [MMDetection Model Zoo](https://mmdetection.readthedocs.io/en/3.x/model_zoo.html).\nMMDetection provides 80-class COCO-pretrained models, which already includes the `person` category.\n\n### Hand Bounding Box Detection Models\n\nFor hand bounding box detection, we simply train our hand box models on OneHand10K dataset using MMDetection.\n\n#### Hand detection results on OneHand10K test set\n\n| Arch                                                              | Box AP |                               ckpt                                |                               log                                |\n| :---------------------------------------------------------------- | :----: | :---------------------------------------------------------------: | :--------------------------------------------------------------: |\n| [Cascade_R-CNN X-101-64x4d-FPN-1class](/demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py) | 0.817  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k-dac19597_20201030.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k_20201030.log.json) |\n| [RTMDet-nano](/demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py) | 0.760  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth) |                                -                                 |\n\n### Face Bounding Box Detection Models\n\nFor face bounding box detection, we train a YOLOX detector on COCO-face data using MMDetection.\n\n#### Face detection results on COCO-face test set\n\n| Arch                                                            | Box AP |                                                  ckpt                                                  |\n| :-------------------------------------------------------------- | :----: | :----------------------------------------------------------------------------------------------------: |\n| [YOLOX-s](/demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py) | 0.408  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth) |\n\n### Animal Bounding Box Detection Models\n\n#### COCO animals\n\nIn COCO dataset, there are 80 object categories, including 10 common `animal` categories (14: 'bird', 15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe')\nFor animals in the categories, please download from [MMDetection Model Zoo](https://mmdetection.readthedocs.io/en/3.x/model_zoo.html).\n\n#### Macaque detection results on MacaquePose test set\n\n| Arch                                                              | Box AP |                               ckpt                                |                               log                                |\n| :---------------------------------------------------------------- | :----: | :---------------------------------------------------------------: | :--------------------------------------------------------------: |\n| [Faster_R-CNN_Res50-FPN-1class](/demo/mmdetection_cfg/faster_rcnn_r50_fpn_1class.py) | 0.840  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/faster_rcnn_r50_fpn_1x_macaque-f64f2812_20210409.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/faster_rcnn_r50_fpn_1x_macaque_20210409.log.json) |\n| [Cascade_R-CNN X-101-64x4d-FPN-1class](/demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py) | 0.879  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque-e45e36f5_20210409.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque_20210409.log.json) |\n"
  },
  {
    "path": "demo/docs/en/webcam_api_demo.md",
    "content": "## Webcam Demo\n\nThe original Webcam API has been deprecated starting from version v1.1.0. Users now have the option to utilize either the Inferencer or the demo script for conducting pose estimation using webcam input.\n\n### Webcam Demo with Inferencer\n\nUsers can utilize the MMPose Inferencer to estimate human poses in webcam inputs by executing the following command:\n\n```shell\npython demo/inferencer_demo.py webcam --pose2d 'human'\n```\n\nFor additional information about the arguments of Inferencer, please refer to the [Inferencer Documentation](/docs/en/user_guides/inference.md).\n\n### Webcam Demo with Demo Script\n\nAll of the demo scripts, except for `demo/image_demo.py`, support webcam input.\n\nTake `demo/topdown_demo_with_mmdet.py` as example, users can utilize this script with webcam input by specifying **`--input webcam`** in the command:\n\n```shell\n# inference with webcam\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input webcam \\\n    --show\n```\n"
  },
  {
    "path": "demo/docs/zh_cn/2d_animal_demo.md",
    "content": "## 2D Animal Pose Demo\n\n本系列文档我们会来介绍如何使用提供了的脚本进行完成基本的推理 demo ，本节先介绍如何对 top-down 结构和动物的 2D 姿态进行单张图片和视频推理，请确保你已经安装了 3.0 以上版本的 [MMDetection](https://github.com/open-mmlab/mmdetection) 。\n\n### 2D 动物图片姿态识别推理\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} --det-cat-id ${DET_CAT_ID} \\\n    [--show] [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--draw-heatmap ${DRAW_HEATMAP}] [--radius ${KPT_RADIUS}] \\\n    [--kpt-thr ${KPT_SCORE_THR}] [--bbox-thr ${BBOX_SCORE_THR}] \\\n    [--device ${GPU_ID or CPU}]\n```\n\n用户可以在 [model zoo](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo/animal_2d_keypoint.html) 获取预训练好的关键点识别模型。\n\n这里我们用 [animalpose model](https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth) 来进行演示：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --show --draw-heatmap --det-cat-id=15\n```\n\n可视化结果如下：\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187644168-5915551a-0876-4b85-9454-7f92c84ba6fb.jpeg\" height=\"500px\" alt><br>\n\n如果使用了 heatmap-based 模型同时设置了 `--draw-heatmap` ，预测的热图也会跟随关键点一同可视化出来。\n\n`--det-cat-id=15` 参数用来指定模型只检测 `cat` 类型，这是基于 COCO 数据集的数据。\n\n**COCO 数据集动物信息**\n\nCOCO 数据集共包含 80 个类别，其中有 10 种常见动物，类别如下：\n\n(14: 'bird', 15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe')\n\n对于其他类型的动物，我们也提供了一些训练好的动物检测模型，用户可以前往 [detection model zoo](/demo/docs/zh_cn/mmdet_modelzoo.md) 下载。\n\n如果想本地保存可视化结果可使用如下命令：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --output-root vis_results --draw-heatmap --det-cat-id=15\n```\n\n如果想本地保存预测结果，需要使用 `--save-predictions` 。\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --output-root vis_results --save-predictions --draw-heatmap --det-cat-id=15\n```\n\n仅使用 CPU：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_tiny_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_tiny_8xb32-300e_coco/rtmdet_tiny_8xb32-300e_coco_20220902_112414-78e30dcc.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input tests/data/animalpose/ca110.jpeg \\\n    --show --draw-heatmap --det-cat-id=15 --device cpu\n```\n\n### 2D 动物视频姿态识别推理\n\n视频和图片使用了同样的接口，区别在于视频推理时 `${INPUT_PATH}` 既可以是本地视频文件的路径也可以是视频文件的 **URL** 地址。\n\n例如：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py \\\n    https://download.openmmlab.com/mmdetection/v3.0/rtmdet/rtmdet_m_8xb32-300e_coco/rtmdet_m_8xb32-300e_coco_20220719_112220-229f527c.pth \\\n    configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py \\\n    https://download.openmmlab.com/mmpose/animal/hrnet/hrnet_w32_animalpose_256x256-1aa7f075_20210426.pth \\\n    --input demo/resources/<demo_dog.mp4> \\\n    --output-root vis_results --draw-heatmap --det-cat-id=16\n```\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187655602-907db86e-710b-447a-8ec9-5b623d43d160.gif\" height=\"500px\" alt><br>\n\n这段视频可以在 [Google Drive](https://drive.google.com/file/d/18d8K3wuUpKiDFHvOx0mh1TEwYwpOc5UO/view?usp=sharing) 下载。\n\n### 使用 Inferencer 进行 2D 动物姿态识别推理\n\nInferencer 提供一个更便捷的推理接口，使得用户可以绕过模型的配置文件和 checkpoint 路径直接使用 model aliases ，支持包括图片路径、视频路径、图片文件夹路径和 webcams 在内的多种输入方式，例如可以这样使用：\n\n```shell\npython demo/inferencer_demo.py tests/data/ap10k \\\n    --pose2d animal --vis-out-dir vis_results/ap10k\n```\n\n该命令会对输入的 `tests/data/ap10k` 下所有的图片进行推理并且把可视化结果都存入 `vis_results/ap10k` 文件夹下。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229789306-83ea56fa-12f2-4e27-9031-329d335ec26d.jpg\" alt=\"Image 1\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229789324-7fef5688-422d-4663-a57c-d1e1d511e83c.jpg\" alt=\"Image 2\" height=\"200\"/>\n\nInferencer 同样支持保存预测结果，更多的信息可以参考 [Inferencer 文档](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface) 。\n\n### 加速推理\n\n用户可以通过修改配置文件来加速，更多具体例子可以参考：\n\n1. 设置 `model.test_cfg.flip_test=False`，如 [animalpose_hrnet-w32](../../configs/animal_2d_keypoint/topdown_heatmap/animalpose/td-hm_hrnet-w32_8xb64-210e_animalpose-256x256.py#85) 所示。\n2. 使用更快的 bounding box 检测器，可参考 [MMDetection](https://mmdetection.readthedocs.io/zh_CN/3.x/model_zoo.html) 。\n"
  },
  {
    "path": "demo/docs/zh_cn/2d_face_demo.md",
    "content": "## 2D Face Keypoint Demo\n\n本节我们继续演示如何使用 demo 脚本进行 2D 脸部关键点的识别。同样的，用户仍要确保开发环境已经安装了 3.0 版本以上的 [MMdetection](https://github.com/open-mmlab/mmdetection) 。\n\n我们在 [mmdet model zoo](/demo/docs/zh_cn/mmdet_modelzoo.md#脸部-bounding-box-检测模型) 提供了一个预训练好的脸部 Bounding Box 预测模型，用户可以前往下载。\n\n### 2D 脸部图片关键点识别推理\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} [--output-root ${OUTPUT_DIR}] \\\n    [--show] [--device ${GPU_ID or CPU}] [--save-predictions] \\\n    [--draw-heatmap ${DRAW_HEATMAP}] [--radius ${KPT_RADIUS}] \\\n    [--kpt-thr ${KPT_SCORE_THR}] [--bbox-thr ${BBOX_SCORE_THR}]\n```\n\n用户可以在 [model zoo](https://mmpose.readthedocs.io/en/dev-1.x/model_zoo/face_2d_keypoint.html) 获取预训练好的脸部关键点识别模型。\n\n这里我们用 [face6 model](https://download.openmmlab.com/mmpose/face/hrnetv2/hrnetv2_w18_aflw_256x256-f2bbc62b_20210125.pth) 来进行演示：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input tests/data/cofw/001766.jpg \\\n    --show --draw-heatmap\n```\n\n可视化结果如下图所示：\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/d5f4a947-b6a7-465b-b54d-0ffa2f6d353a\" height=\"500px\" alt><br>\n\n如果使用了 heatmap-based 模型同时设置了 `--draw-heatmap` ，预测的热图也会跟随关键点一同可视化出来。\n\n如果想本地保存可视化结果可使用如下命令：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input tests/data/cofw/001766.jpg \\\n    --draw-heatmap --output-root vis_results\n```\n\n### 2D 脸部视频关键点识别推理\n\n视频和图片使用了同样的接口，区别在于视频推理时 `${INPUT_PATH}` 既可以是本地视频文件的路径也可以是视频文件的 **URL** 地址。\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py \\\n    https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth \\\n    configs/face_2d_keypoint/rtmpose/face6/rtmpose-m_8xb256-120e_face6-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth \\\n    --input demo/resources/<demo_face.mp4> \\\n    --show  --output-root vis_results --radius 1\n```\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/5883f014-d0be-4796-a30e-f1b5dcb6e85d\" height=\"300px\" alt><br>\n\n这段视频可以在 [Google Drive](https://drive.google.com/file/d/1kQt80t6w802b_vgVcmiV_QfcSJ3RWzmb/view?usp=sharing) 下载。\n\n### 使用 Inferencer 进行 2D 脸部关键点识别推理\n\nInferencer 提供一个更便捷的推理接口，使得用户可以绕过模型的配置文件和 checkpoint 路径直接使用 model aliases ，支持包括图片路径、视频路径、图片文件夹路径和 webcams 在内的多种输入方式，例如可以这样使用：\n\n```shell\npython demo/inferencer_demo.py tests/data/wflw \\\n    --pose2d face --vis-out-dir vis_results/wflw --radius 1\n```\n\n该命令会对输入的 `tests/data/wflw` 下所有的图片进行推理并且把可视化结果都存入 `vis_results/wflw` 文件夹下。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229793095-702f9d3b-461f-45bd-8535-d628e33bc907.jpg\" alt=\"Image 1\" width=\"400\"/>\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229793121-9969f014-70da-40b5-8561-e21c3edd1aeb.jpg\" alt=\"Image 2\" width=\"400\"/>\n\n除此之外， Inferencer 也支持保存预测的姿态结果。具体信息可在 [Inferencer 文档](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/inference.html#inferencer-a-unified-inference-interface) 查看。\n\n### 加速推理\n\n对于 2D 脸部关键点预测模型，用户可以通过修改配置文件中的 `model.test_cfg.flip_test=False` 来加速，例如 [aflw_hrnetv2](../../../configs/face_2d_keypoint/topdown_heatmap/aflw/td-hm_hrnetv2-w18_8xb64-60e_aflw-256x256.py) 中的第 90 行。\n"
  },
  {
    "path": "demo/docs/zh_cn/2d_hand_demo.md",
    "content": "## 2D Hand Keypoint Demo\n\n本节我们继续通过 demo 脚本演示对单张图片或者视频的 2D 手部关键点的识别。同样的，用户仍要确保开发环境已经安装了 3.0 版本以上的 [MMDetection](https://github.com/open-mmlab/mmdetection) 。\n\n我们在 [mmdet model zoo](/demo/docs/zh_cn/mmdet_modelzoo.md#手部-bounding-box-识别模型) 提供了预训练好的手部 Bounding Box 预测模型，用户可以前往下载。\n\n### 2D 手部图片关键点识别\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} [--output-root ${OUTPUT_DIR}] \\\n    [--show] [--device ${GPU_ID or CPU}] [--save-predictions] \\\n    [--draw-heatmap ${DRAW_HEATMAP}] [--radius ${KPT_RADIUS}] \\\n    [--kpt-thr ${KPT_SCORE_THR}] [--bbox-thr ${BBOX_SCORE_THR}]\n```\n\n用户可以在 [model zoo](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo/hand_2d_keypoint.html) 获取预训练好的关键点识别模型。\n\n这里我们用 [onehand10k model](https://download.openmmlab.com/mmpose/hand/hrnetv2/hrnetv2_w18_onehand10k_256x256-30bc9c6b_20210330.pth) 来进行演示：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input tests/data/onehand10k/9.jpg \\\n    --show --draw-heatmap\n```\n\n可视化结果如下：\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/3a2794cb-8071-4b9e-9498-c0bb46eb381e\" height=\"500px\" alt><br>\n\n如果使用了 heatmap-based 模型同时设置了 `--draw-heatmap` ，预测的热图也会跟随关键点一同可视化出来。\n\n如果想本地保存可视化结果可使用如下命令：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input tests/data/onehand10k/9.jpg \\\n    --output-root vis_results --show --draw-heatmap\n```\n\n如果想本地保存预测结果，需要添加 `--save-predictions` 。\n\n如果想用 CPU 进行 demo 需添加 `--device cpu` ：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input tests/data/onehand10k/9.jpg \\\n    --show --draw-heatmap  --device cpu\n```\n\n### 2D 手部视频关键点识别推理\n\n视频和图片使用了同样的接口，区别在于视频推理时 `${INPUT_PATH}` 既可以是本地视频文件的路径也可以是视频文件的 **URL** 地址。\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth \\\n    configs/hand_2d_keypoint/rtmpose/hand5/rtmpose-m_8xb256-210e_hand5-256x256.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth \\\n    --input data/tests_data_nvgesture_sk_color.avi \\\n    --output-root vis_results --kpt-thr 0.1\n```\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/558e8211-d7ca-4e04-b690-6c455e805ed7\" height=\"300px\" alt><br>\n\n<img src=\"https://user-images.githubusercontent.com/26127467/187665873-3ac836ec-8da5-45e1-8d78-c0abe962bd5e.gif\" height=\"500px\" alt><br>\n\n这段视频可以在 [Google Drive](https://raw.githubusercontent.com/open-mmlab/mmpose/master/tests/data/nvgesture/sk_color.avi) 下载到。\n\n### 使用 Inferencer 进行 2D 手部关键点识别推理\n\nInferencer 提供一个更便捷的推理接口，使得用户可以绕过模型的配置文件和 checkpoint 路径直接使用 model aliases ，支持包括图片路径、视频路径、图片文件夹路径和 webcams 在内的多种输入方式，例如可以这样使用：\n\n```shell\npython demo/inferencer_demo.py tests/data/onehand10k \\\n    --pose2d hand --vis-out-dir vis_results/onehand10k \\\n    --bbox-thr 0.5 --kpt-thr 0.05\n```\n\n该命令会对输入的 `tests/data/onehand10k` 下所有的图片进行推理并且把可视化结果都存入 `vis_results/onehand10k` 文件夹下。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229824447-b444e92d-9b5b-4a50-9a32-68be3ff8c527.jpg\" alt=\"Image 1\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229824466-6ae47a40-70a6-451d-94ee-4ffc34204a9c.jpg\" alt=\"Image 2\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229824477-679201c3-1e0b-45fe-b0c7-bab67b245a10.jpg\" alt=\"Image 3\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229824488-bd874362-7401-41a5-8209-51bad1563a11.jpg\" alt=\"Image 4\" height=\"200\"/>\n\n除此之外， Inferencer 也支持保存预测的姿态结果。具体信息可在 [Inferencer 文档](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/inference.html) 查看。\n\n### 加速推理\n\n对于 2D 手部关键点预测模型，用户可以通过修改配置文件中的 `model.test_cfg.flip_test=False` 来加速，如 [onehand10k_hrnetv2](../../configs/hand_2d_keypoint/topdown_heatmap/onehand10k/td-hm_hrnetv2-w18_8xb64-210e_onehand10k-256x256.py#90) 所示。\n"
  },
  {
    "path": "demo/docs/zh_cn/2d_human_pose_demo.md",
    "content": "## 2D Human Pose Demo\n\n本节我们继续使用 demo 脚本演示 2D 人体关键点的识别。同样的，用户仍要确保开发环境已经安装了 3.0 版本以上的 [mmdet](https://github.com/open-mmlab/mmdetection) 。\n\n### 2D 人体姿态 Top-Down 图片检测\n\n#### 使用整张图片作为输入进行检测\n\n此时输入的整张图片会被当作 bounding box 使用。\n\n```shell\npython demo/image_demo.py \\\n    ${IMG_FILE} ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --out-file ${OUTPUT_FILE} \\\n    [--device ${GPU_ID or CPU}] \\\n    [--draw_heatmap]\n```\n\n如果使用了 heatmap-based 模型同时设置了 `--draw-heatmap` ，预测的热图也会跟随关键点一同可视化出来。\n\n用户可以在 [model zoo](https://mmpose.readthedocs.io/zh_CN/latest/model_zoo/body_2d_keypoint.html) 获取预训练好的关键点识别模型。\n\n这里我们用 [coco model](https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth) 来进行演示：\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \\\n    --out-file vis_results.jpg \\\n    --draw-heatmap\n```\n\n使用 CPU 推理：\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_8xb32-210e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_256x192-b9e0b3ab_20200708.pth \\\n    --out-file vis_results.jpg \\\n    --draw-heatmap \\\n    --device=cpu\n```\n\n可视化结果如下：\n\n<img src=\"https://user-images.githubusercontent.com/87690686/187824033-2cce0f55-034a-4127-82e2-52744178bc32.jpg\" height=\"500px\" alt><br>\n\n#### 使用 MMDet 做人体 bounding box 检测\n\n使用 MMDet 进行识别的命令如下所示：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} \\\n    [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--show] [--draw-heatmap] [--device ${GPU_ID or CPU}] \\\n    [--bbox-thr ${BBOX_SCORE_THR}] [--kpt-thr ${KPT_SCORE_THR}]\n```\n\n结合我们的具体例子：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth \\\n    --input tests/data/coco/000000197388.jpg --show --draw-heatmap \\\n    --output-root vis_results/\n```\n\n可视化结果如下：\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/f14e0129-1e5e-4d74-84fe-28cd62357211\" height=\"500px\" alt><br>\n\n想要本地保存识别结果，用户需要加上 `--save-predictions` 。\n\n### 2D 人体姿态 Top-Down 视频检测\n\n我们的脚本同样支持视频作为输入，由 MMDet 完成人体检测后 MMPose 完成 Top-Down 的姿态预估，视频推理时 `${INPUT_PATH}` 既可以是本地视频文件的路径也可以是视频文件的 **URL** 地址。\n\n例如：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/body_2d_keypoint/rtmpose/body8/rtmpose-m_8xb256-420e_body8-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth \\\n    --input tests/data/posetrack18/videos/000001_mpiinew_test/000001_mpiinew_test.mp4 \\\n    --output-root=vis_results/demo --show --draw-heatmap\n```\n\n### 2D 人体姿态 Bottom-Up 图片和视频识别检测\n\n除了 Top-Down ，我们也支持 Bottom-Up 不依赖人体识别器的人体姿态预估识别，使用方式如下：\n\n```shell\npython demo/bottomup_demo.py \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} \\\n    [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--show] [--device ${GPU_ID or CPU}] \\\n    [--kpt-thr ${KPT_SCORE_THR}]\n```\n\n结合具体示例如下：\n\n```shell\npython demo/bottomup_demo.py \\\n    configs/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512.py \\\n    https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/dekr/coco/dekr_hrnet-w32_8xb10-140e_coco-512x512_ac7c17bf-20221228.pth \\\n    --input tests/data/coco/000000197388.jpg --output-root=vis_results \\\n    --show --save-predictions\n```\n\n其可视化结果如图所示：\n\n<img src=\"https://user-images.githubusercontent.com/26127467/207224032-a8dab45d-39e4-4b4e-80e0-3c71a64f5f39.jpg\" height=\"300px\" alt><br>\n\n### 使用 Inferencer 进行 2D 人体姿态识别检测\n\nInferencer 提供一个更便捷的推理接口，使得用户可以绕过模型的配置文件和 checkpoint 路径直接使用 model aliases ，支持包括图片路径、视频路径、图片文件夹路径和 webcams 在内的多种输入方式，例如可以这样使用：\n\n```shell\npython demo/inferencer_demo.py \\\n    tests/data/posetrack18/videos/000001_mpiinew_test/000001_mpiinew_test.mp4 \\\n    --pose2d human --vis-out-dir vis_results/posetrack18\n```\n\n该命令会对输入的 `tests/data/posetrack18` 下的视频进行推理并且把可视化结果存入 `vis_results/posetrack18` 文件夹下。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229831445-44c9662b-edc5-4ef0-92a6-13558f0906cc.gif\" alt=\"Image 1\" height=\"300\"/>\n\nInferencer 支持保存姿态的检测结果，具体的使用可参考 [inferencer document](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/inference.html) 。\n\n### 加速推理\n\n对于 top-down 结构的模型，用户可以通过修改配置文件来加速，更多具体例子可以参考：\n\n1. 设置 `model.test_cfg.flip_test=False`，如 [topdown-res50](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py#L56) 所示。\n2. 使用更快的人体 bounding box 检测器，可参考 [MMDetection](https://mmdetection.readthedocs.io/zh_CN/3.x/model_zoo.html) 。\n"
  },
  {
    "path": "demo/docs/zh_cn/2d_wholebody_pose_demo.md",
    "content": "## 2D Human Whole-Body Pose Demo\n\n### 2D 人体全身姿态 Top-Down 图片识别\n\n#### 使用整张图片作为输入进行检测\n\n此时输入的整张图片会被当作 bounding box 使用。\n\n```shell\npython demo/image_demo.py \\\n    ${IMG_FILE} ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --out-file ${OUTPUT_FILE} \\\n    [--device ${GPU_ID or CPU}] \\\n    [--draw_heatmap]\n```\n\n用户可以在 [model zoo](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo/2d_wholebody_keypoint.html) 获取预训练好的关键点识别模型。\n\n这里我们用 [coco-wholebody_vipnas_res50_dark](https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth) 来进行演示：\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth \\\n    --out-file vis_results.jpg\n```\n\n使用 CPU 推理：\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_vipnas-res50_dark-8xb64-210e_coco-wholebody-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/vipnas/vipnas_res50_wholebody_256x192_dark-67c0ce35_20211112.pth \\\n    --out-file vis_results.jpg \\\n    --device=cpu\n```\n\n#### 使用 MMDet 进行人体 bounding box 检测\n\n使用 MMDet 进行识别的命令格式如下：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    ${MMDET_CONFIG_FILE} ${MMDET_CHECKPOINT_FILE} \\\n    ${MMPOSE_CONFIG_FILE} ${MMPOSE_CHECKPOINT_FILE} \\\n    --input ${INPUT_PATH} \\\n    [--output-root ${OUTPUT_DIR}] [--save-predictions] \\\n    [--show] [--draw-heatmap] [--device ${GPU_ID or CPU}] \\\n    [--bbox-thr ${BBOX_SCORE_THR}] [--kpt-thr ${KPT_SCORE_THR}]\n```\n\n具体可例如：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \\\n    --input tests/data/coco/000000196141.jpg \\\n    --output-root vis_results/ --show\n```\n\n想要本地保存识别结果，用户需要加上 `--save-predictions` 。\n\n### 2D 人体全身姿态 Top-Down 视频识别检测\n\n我们的脚本同样支持视频作为输入，由 MMDet 完成人体检测后 MMPose 完成 Top-Down 的姿态预估。\n\n例如：\n\n```shell\npython demo/topdown_demo_with_mmdet.py \\\n    demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth \\\n    configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py \\\n    https://download.openmmlab.com/mmpose/top_down/hrnet/hrnet_w48_coco_wholebody_384x288_dark-f5726563_20200918.pth \\\n    --input https://user-images.githubusercontent.com/87690686/137440639-fb08603d-9a35-474e-b65f-46b5c06b68d6.mp4 \\\n    --output-root vis_results/ --show\n```\n\n可视化结果如下：\n\n<img src=\"https://user-images.githubusercontent.com/87690686/190854069-634e1142-d13c-4863-9930-1120057ca77e.gif\" height=\"350px\" alt><br>\n\n### 使用 Inferencer 进行 2D 人体全身姿态识别\n\nInferencer 提供一个更便捷的推理接口，使得用户可以绕过模型的配置文件和 checkpoint 路径直接使用 model aliases ，支持包括图片路径、视频路径、图片文件夹路径和 webcams 在内的多种输入方式，例如可以这样使用：\n\n```shell\npython demo/inferencer_demo.py tests/data/crowdpose \\\n    --pose2d wholebody --vis-out-dir vis_results/crowdpose\n```\n\n该命令会对输入的 `tests/data/crowdpose` 下所有图片进行推理并且把可视化结果存入 `vis_results/crowdpose` 文件夹下。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/229832887-31edb6d5-bcf0-44a4-a66f-9d523061a6e9.jpg\" alt=\"Image 1\" height=\"200\"/> <img src=\"https://user-images.githubusercontent.com/26127467/229832908-bc82dbc9-5e43-4800-acc7-a7da85a653c7.jpg\" alt=\"Image 2\" height=\"200\"/>\n\nInferencer 支持保存姿态的检测结果，具体的使用可参考 [Inferencer 文档](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/#inferencer-a-unified-inference-interface) 。\n\n### 加速推理\n\n对于 top-down 结构的模型，用户可以通过修改配置文件来加速，更多具体例子可以参考：\n\n1. 设置 `model.test_cfg.flip_test=False`，用户可参考 [pose_hrnet_w48_dark+](/configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/td-hm_hrnet-w48_dark-8xb32-210e_coco-wholebody-384x288.py#L90) 。\n2. 使用更快的人体 bounding box 检测器，如 [MMDetection](https://mmdetection.readthedocs.io/zh_CN/3.x/model_zoo.html) 。\n"
  },
  {
    "path": "demo/docs/zh_cn/3d_human_pose_demo.md",
    "content": "coming soon\n"
  },
  {
    "path": "demo/docs/zh_cn/mmdet_modelzoo.md",
    "content": "## Pre-trained Detection Models\n\n### 人体 Bounding Box 检测模型\n\nMMDetection 提供了基于 COCO 的包括 `person` 在内的 80 个类别的预训练模型，用户可前往 [MMDetection Model Zoo](https://mmdetection.readthedocs.io/zh_CN/3.x/model_zoo.html) 下载并将其用作人体 bounding box 识别模型。\n\n### 手部 Bounding Box 检测模型\n\n对于手部 bounding box 检测模型，我们提供了一个通过 MMDetection 基于 OneHand10K 数据库训练的模型。\n\n#### 基于 OneHand10K 测试集的测试结果\n\n| Arch                                                              | Box AP |                               ckpt                                |                               log                                |\n| :---------------------------------------------------------------- | :----: | :---------------------------------------------------------------: | :--------------------------------------------------------------: |\n| [Cascade_R-CNN X-101-64x4d-FPN-1class](/demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py) | 0.817  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k-dac19597_20201030.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_onehand10k_20201030.log.json) |\n| [RTMDet-nano](/demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py) | 0.760  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth) |                                -                                 |\n\n### 脸部 Bounding Box 检测模型\n\n对于脸部 bounding box 检测模型，我们提供了一个通过 MMDetection 基于 COCO-Face 数据库训练的 YOLOX 检测器。\n\n#### 基于 COCO-face 测试集的测试结果\n\n| Arch                                                            | Box AP |                                                  ckpt                                                  |\n| :-------------------------------------------------------------- | :----: | :----------------------------------------------------------------------------------------------------: |\n| [YOLOX-s](/demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py) | 0.408  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/yolo-x_8xb8-300e_coco-face_13274d7c.pth) |\n\n### 动物 Bounding Box 检测模型\n\n#### COCO animals\n\nCOCO 数据集内包括了 10 种常见的 `animal` 类型：\n\n(14: 'bird', 15: 'cat', 16: 'dog', 17: 'horse', 18: 'sheep', 19: 'cow', 20: 'elephant', 21: 'bear', 22: 'zebra', 23: 'giraffe') 。\n\n用户如果需要使用以上类别的动物检测模型，可以前往 [MMDetection Model Zoo](https://mmdetection.readthedocs.io/zh_CN/3.x/model_zoo.html) 下载。\n\n#### 基于 MacaquePose 测试集的测试结果\n\n| Arch                                                              | Box AP |                               ckpt                                |                               log                                |\n| :---------------------------------------------------------------- | :----: | :---------------------------------------------------------------: | :--------------------------------------------------------------: |\n| [Faster_R-CNN_Res50-FPN-1class](/demo/mmdetection_cfg/faster_rcnn_r50_fpn_1class.py) | 0.840  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/faster_rcnn_r50_fpn_1x_macaque-f64f2812_20210409.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/faster_rcnn_r50_fpn_1x_macaque_20210409.log.json) |\n| [Cascade_R-CNN X-101-64x4d-FPN-1class](/demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py) | 0.879  | [ckpt](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque-e45e36f5_20210409.pth) | [log](https://download.openmmlab.com/mmpose/mmdet_pretrained/cascade_rcnn_x101_64x4d_fpn_20e_macaque_20210409.log.json) |\n"
  },
  {
    "path": "demo/docs/zh_cn/webcam_api_demo.md",
    "content": "## 摄像头推理\n\n从版本 v1.1.0 开始，原来的摄像头 API 已被弃用。用户现在可以选择使用推理器（Inferencer）或 Demo 脚本从摄像头读取的视频中进行姿势估计。\n\n### 使用推理器进行摄像头推理\n\n用户可以通过执行以下命令来利用 MMPose Inferencer 对摄像头输入进行人体姿势估计：\n\n```shell\npython demo/inferencer_demo.py webcam --pose2d 'human'\n```\n\n有关推理器的参数详细信息，请参阅 [推理器文档](/docs/en/user_guides/inference.md)。\n\n### 使用 Demo 脚本进行摄像头推理\n\n除了 `demo/image_demo.py` 之外，所有的 Demo 脚本都支持摄像头输入。\n\n以 `demo/topdown_demo_with_mmdet.py` 为例，用户可以通过在命令中指定 **`--input webcam`** 来使用该脚本对摄像头输入进行推理：\n\n```shell\n# inference with webcam\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input webcam \\\n    --show\n```\n"
  },
  {
    "path": "demo/hand3d_internet_demo.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nimport mimetypes\nimport os\nimport time\nfrom argparse import ArgumentParser\n\nimport cv2\nimport json_tricks as json\nimport mmcv\nimport mmengine\nimport numpy as np\nfrom mmengine.logging import print_log\n\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import (PoseDataSample, merge_data_samples,\n                               split_instances)\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument('config', help='Config file')\n    parser.add_argument('checkpoint', help='Checkpoint file')\n    parser.add_argument(\n        '--input', type=str, default='', help='Image/Video file')\n    parser.add_argument(\n        '--output-root',\n        type=str,\n        default='',\n        help='root of the output img file. '\n        'Default not saving the visualization images.')\n    parser.add_argument(\n        '--save-predictions',\n        action='store_true',\n        default=False,\n        help='whether to save predicted results')\n    parser.add_argument(\n        '--disable-rebase-keypoint',\n        action='store_true',\n        default=False,\n        help='Whether to disable rebasing the predicted 3D pose so its '\n        'lowest keypoint has a height of 0 (landing on the ground). Rebase '\n        'is useful for visualization when the model do not predict the '\n        'global position of the 3D pose.')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='whether to show result')\n    parser.add_argument('--device', default='cpu', help='Device for inference')\n    parser.add_argument(\n        '--kpt-thr',\n        type=float,\n        default=0.3,\n        help='Visualizing keypoint thresholds')\n    parser.add_argument(\n        '--show-kpt-idx',\n        action='store_true',\n        default=False,\n        help='Whether to show the index of keypoints')\n    parser.add_argument(\n        '--show-interval', type=int, default=0, help='Sleep seconds per frame')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization')\n\n    args = parser.parse_args()\n    return args\n\n\ndef process_one_image(args, img, model, visualizer=None, show_interval=0):\n    \"\"\"Visualize predicted keypoints of one image.\"\"\"\n    # inference a single image\n    pose_results = inference_topdown(model, img)\n    # post-processing\n    pose_results_2d = []\n    for idx, res in enumerate(pose_results):\n        pred_instances = res.pred_instances\n        keypoints = pred_instances.keypoints\n        rel_root_depth = pred_instances.rel_root_depth\n        scores = pred_instances.keypoint_scores\n        hand_type = pred_instances.hand_type\n\n        res_2d = PoseDataSample()\n        gt_instances = res.gt_instances.clone()\n        pred_instances = pred_instances.clone()\n        res_2d.gt_instances = gt_instances\n        res_2d.pred_instances = pred_instances\n\n        # add relative root depth to left hand joints\n        keypoints[:, 21:, 2] += rel_root_depth\n\n        # set joint scores according to hand type\n        scores[:, :21] *= hand_type[:, [0]]\n        scores[:, 21:] *= hand_type[:, [1]]\n        # normalize kpt score\n        if scores.max() > 1:\n            scores /= 255\n\n        res_2d.pred_instances.set_field(keypoints[..., :2].copy(), 'keypoints')\n\n        # rotate the keypoint to make z-axis correspondent to height\n        # for better visualization\n        vis_R = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])\n        keypoints[..., :3] = keypoints[..., :3] @ vis_R\n\n        # rebase height (z-axis)\n        if not args.disable_rebase_keypoint:\n            valid = scores > 0\n            keypoints[..., 2] -= np.min(\n                keypoints[valid, 2], axis=-1, keepdims=True)\n\n        pose_results[idx].pred_instances.keypoints = keypoints\n        pose_results[idx].pred_instances.keypoint_scores = scores\n        pose_results_2d.append(res_2d)\n\n    data_samples = merge_data_samples(pose_results)\n    data_samples_2d = merge_data_samples(pose_results_2d)\n\n    # show the results\n    if isinstance(img, str):\n        img = mmcv.imread(img, channel_order='rgb')\n    elif isinstance(img, np.ndarray):\n        img = mmcv.bgr2rgb(img)\n\n    if visualizer is not None:\n        visualizer.add_datasample(\n            'result',\n            img,\n            data_sample=data_samples,\n            det_data_sample=data_samples_2d,\n            draw_gt=False,\n            draw_bbox=True,\n            kpt_thr=args.kpt_thr,\n            convert_keypoint=False,\n            axis_azimuth=-115,\n            axis_limit=200,\n            axis_elev=15,\n            show_kpt_idx=args.show_kpt_idx,\n            show=args.show,\n            wait_time=show_interval)\n\n    # if there is no instance detected, return None\n    return data_samples.get('pred_instances', None)\n\n\ndef main():\n    args = parse_args()\n\n    assert args.input != ''\n    assert args.show or (args.output_root != '')\n\n    output_file = None\n    if args.output_root:\n        mmengine.mkdir_or_exist(args.output_root)\n        output_file = os.path.join(args.output_root,\n                                   os.path.basename(args.input))\n        if args.input == 'webcam':\n            output_file += '.mp4'\n\n    if args.save_predictions:\n        assert args.output_root != ''\n        args.pred_save_path = f'{args.output_root}/results_' \\\n            f'{os.path.splitext(os.path.basename(args.input))[0]}.json'\n\n    # build the model from a config file and a checkpoint file\n    model = init_model(\n        args.config, args.checkpoint, device=args.device.lower())\n\n    # init visualizer\n    model.cfg.visualizer.radius = args.radius\n    model.cfg.visualizer.line_width = args.thickness\n\n    visualizer = VISUALIZERS.build(model.cfg.visualizer)\n    visualizer.set_dataset_meta(model.dataset_meta)\n\n    if args.input == 'webcam':\n        input_type = 'webcam'\n    else:\n        input_type = mimetypes.guess_type(args.input)[0].split('/')[0]\n\n    if input_type == 'image':\n        # inference\n        pred_instances = process_one_image(args, args.input, model, visualizer)\n\n        if args.save_predictions:\n            pred_instances_list = split_instances(pred_instances)\n\n        if output_file:\n            img_vis = visualizer.get_image()\n            mmcv.imwrite(mmcv.rgb2bgr(img_vis), output_file)\n\n    elif input_type in ['webcam', 'video']:\n\n        if args.input == 'webcam':\n            cap = cv2.VideoCapture(0)\n        else:\n            cap = cv2.VideoCapture(args.input)\n\n        video_writer = None\n        pred_instances_list = []\n        frame_idx = 0\n\n        while cap.isOpened():\n            success, frame = cap.read()\n            frame_idx += 1\n\n            if not success:\n                break\n\n            # topdown pose estimation\n            pred_instances = process_one_image(args, frame, model, visualizer,\n                                               0.001)\n\n            if args.save_predictions:\n                # save prediction results\n                pred_instances_list.append(\n                    dict(\n                        frame_id=frame_idx,\n                        instances=split_instances(pred_instances)))\n\n            # output videos\n            if output_file:\n                frame_vis = visualizer.get_image()\n\n                if video_writer is None:\n                    fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n                    # the size of the image with visualization may vary\n                    # depending on the presence of heatmaps\n                    video_writer = cv2.VideoWriter(\n                        output_file,\n                        fourcc,\n                        25,  # saved fps\n                        (frame_vis.shape[1], frame_vis.shape[0]))\n\n                video_writer.write(mmcv.rgb2bgr(frame_vis))\n\n            if args.show:\n                # press ESC to exit\n                if cv2.waitKey(5) & 0xFF == 27:\n                    break\n\n                time.sleep(args.show_interval)\n\n        if video_writer:\n            video_writer.release()\n\n        cap.release()\n\n    else:\n        args.save_predictions = False\n        raise ValueError(\n            f'file {os.path.basename(args.input)} has invalid format.')\n\n    if args.save_predictions:\n        with open(args.pred_save_path, 'w') as f:\n            json.dump(\n                dict(\n                    meta_info=model.dataset_meta,\n                    instance_info=pred_instances_list),\n                f,\n                indent='\\t')\n        print_log(\n            f'predictions have been saved at {args.pred_save_path}',\n            logger='current',\n            level=logging.INFO)\n\n    if output_file is not None:\n        input_type = input_type.replace('webcam', 'video')\n        print_log(\n            f'the output {input_type} has been saved at {output_file}',\n            logger='current',\n            level=logging.INFO)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "demo/image_demo.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nfrom argparse import ArgumentParser\n\nfrom mmcv.image import imread\nfrom mmengine.logging import print_log\n\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import merge_data_samples\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument('img', help='Image file')\n    parser.add_argument('config', help='Config file')\n    parser.add_argument('checkpoint', help='Checkpoint file')\n    parser.add_argument('--out-file', default=None, help='Path to output file')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--draw-heatmap',\n        action='store_true',\n        help='Visualize the predicted heatmap')\n    parser.add_argument(\n        '--show-kpt-idx',\n        action='store_true',\n        default=False,\n        help='Whether to show the index of keypoints')\n    parser.add_argument(\n        '--skeleton-style',\n        default='mmpose',\n        type=str,\n        choices=['mmpose', 'openpose'],\n        help='Skeleton style selection')\n    parser.add_argument(\n        '--kpt-thr',\n        type=float,\n        default=0.3,\n        help='Visualizing keypoint thresholds')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization')\n    parser.add_argument(\n        '--alpha', type=float, default=0.8, help='The transparency of bboxes')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='whether to show img')\n    args = parser.parse_args()\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    # build the model from a config file and a checkpoint file\n    if args.draw_heatmap:\n        cfg_options = dict(model=dict(test_cfg=dict(output_heatmaps=True)))\n    else:\n        cfg_options = None\n\n    model = init_model(\n        args.config,\n        args.checkpoint,\n        device=args.device,\n        cfg_options=cfg_options)\n\n    # init visualizer\n    model.cfg.visualizer.radius = args.radius\n    model.cfg.visualizer.alpha = args.alpha\n    model.cfg.visualizer.line_width = args.thickness\n\n    visualizer = VISUALIZERS.build(model.cfg.visualizer)\n    visualizer.set_dataset_meta(\n        model.dataset_meta, skeleton_style=args.skeleton_style)\n\n    # inference a single image\n    batch_results = inference_topdown(model, args.img)\n    results = merge_data_samples(batch_results)\n\n    # show the results\n    img = imread(args.img, channel_order='rgb')\n    visualizer.add_datasample(\n        'result',\n        img,\n        data_sample=results,\n        draw_gt=False,\n        draw_bbox=True,\n        kpt_thr=args.kpt_thr,\n        draw_heatmap=args.draw_heatmap,\n        show_kpt_idx=args.show_kpt_idx,\n        skeleton_style=args.skeleton_style,\n        show=args.show,\n        out_file=args.out_file)\n\n    if args.out_file is not None:\n        print_log(\n            f'the output image has been saved at {args.out_file}',\n            logger='current',\n            level=logging.INFO)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "demo/inferencer_demo.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom argparse import ArgumentParser\nfrom typing import Dict\n\nfrom mmpose.apis.inferencers import MMPoseInferencer, get_model_aliases\n\nfilter_args = dict(bbox_thr=0.3, nms_thr=0.3, pose_based_nms=False)\nPOSE2D_SPECIFIC_ARGS = dict(\n    yoloxpose=dict(bbox_thr=0.01, nms_thr=0.65, pose_based_nms=True),\n    rtmo=dict(bbox_thr=0.1, nms_thr=0.65, pose_based_nms=True),\n)\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument(\n        'inputs',\n        type=str,\n        nargs='?',\n        help='Input image/video path or folder path.')\n\n    # init args\n    parser.add_argument(\n        '--pose2d',\n        type=str,\n        default=None,\n        help='Pretrained 2D pose estimation algorithm. It\\'s the path to the '\n        'config file or the model name defined in metafile.')\n    parser.add_argument(\n        '--pose2d-weights',\n        type=str,\n        default=None,\n        help='Path to the custom checkpoint file of the selected pose model. '\n        'If it is not specified and \"pose2d\" is a model name of metafile, '\n        'the weights will be loaded from metafile.')\n    parser.add_argument(\n        '--pose3d',\n        type=str,\n        default=None,\n        help='Pretrained 3D pose estimation algorithm. It\\'s the path to the '\n        'config file or the model name defined in metafile.')\n    parser.add_argument(\n        '--pose3d-weights',\n        type=str,\n        default=None,\n        help='Path to the custom checkpoint file of the selected pose model. '\n        'If it is not specified and \"pose3d\" is a model name of metafile, '\n        'the weights will be loaded from metafile.')\n    parser.add_argument(\n        '--det-model',\n        type=str,\n        default=None,\n        help='Config path or alias of detection model.')\n    parser.add_argument(\n        '--det-weights',\n        type=str,\n        default=None,\n        help='Path to the checkpoints of detection model.')\n    parser.add_argument(\n        '--det-cat-ids',\n        type=int,\n        nargs='+',\n        default=0,\n        help='Category id for detection model.')\n    parser.add_argument(\n        '--scope',\n        type=str,\n        default='mmpose',\n        help='Scope where modules are defined.')\n    parser.add_argument(\n        '--device',\n        type=str,\n        default=None,\n        help='Device used for inference. '\n        'If not specified, the available device will be automatically used.')\n    parser.add_argument(\n        '--show-progress',\n        action='store_true',\n        help='Display the progress bar during inference.')\n\n    # The default arguments for prediction filtering differ for top-down\n    # and bottom-up models. We assign the default arguments according to the\n    # selected pose2d model\n    args, _ = parser.parse_known_args()\n    for model in POSE2D_SPECIFIC_ARGS:\n        if args.pose2d is not None and model in args.pose2d:\n            filter_args.update(POSE2D_SPECIFIC_ARGS[model])\n            break\n\n    # call args\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        help='Display the image/video in a popup window.')\n    parser.add_argument(\n        '--draw-bbox',\n        action='store_true',\n        help='Whether to draw the bounding boxes.')\n    parser.add_argument(\n        '--draw-heatmap',\n        action='store_true',\n        default=False,\n        help='Whether to draw the predicted heatmaps.')\n    parser.add_argument(\n        '--bbox-thr',\n        type=float,\n        default=filter_args['bbox_thr'],\n        help='Bounding box score threshold')\n    parser.add_argument(\n        '--nms-thr',\n        type=float,\n        default=filter_args['nms_thr'],\n        help='IoU threshold for bounding box NMS')\n    parser.add_argument(\n        '--pose-based-nms',\n        type=lambda arg: arg.lower() in ('true', 'yes', 't', 'y', '1'),\n        default=filter_args['pose_based_nms'],\n        help='Whether to use pose-based NMS')\n    parser.add_argument(\n        '--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')\n    parser.add_argument(\n        '--tracking-thr', type=float, default=0.3, help='Tracking threshold')\n    parser.add_argument(\n        '--use-oks-tracking',\n        action='store_true',\n        help='Whether to use OKS as similarity in tracking')\n    parser.add_argument(\n        '--disable-norm-pose-2d',\n        action='store_true',\n        help='Whether to scale the bbox (along with the 2D pose) to the '\n        'average bbox scale of the dataset, and move the bbox (along with the '\n        '2D pose) to the average bbox center of the dataset. This is useful '\n        'when bbox is small, especially in multi-person scenarios.')\n    parser.add_argument(\n        '--disable-rebase-keypoint',\n        action='store_true',\n        default=False,\n        help='Whether to disable rebasing the predicted 3D pose so its '\n        'lowest keypoint has a height of 0 (landing on the ground). Rebase '\n        'is useful for visualization when the model do not predict the '\n        'global position of the 3D pose.')\n    parser.add_argument(\n        '--num-instances',\n        type=int,\n        default=1,\n        help='The number of 3D poses to be visualized in every frame. If '\n        'less than 0, it will be set to the number of pose results in the '\n        'first frame.')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization.')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization.')\n    parser.add_argument(\n        '--skeleton-style',\n        default='mmpose',\n        type=str,\n        choices=['mmpose', 'openpose'],\n        help='Skeleton style selection')\n    parser.add_argument(\n        '--black-background',\n        action='store_true',\n        help='Plot predictions on a black image')\n    parser.add_argument(\n        '--vis-out-dir',\n        type=str,\n        default='',\n        help='Directory for saving visualized results.')\n    parser.add_argument(\n        '--pred-out-dir',\n        type=str,\n        default='',\n        help='Directory for saving inference results.')\n    parser.add_argument(\n        '--show-alias',\n        action='store_true',\n        help='Display all the available model aliases.')\n\n    call_args = vars(parser.parse_args())\n\n    init_kws = [\n        'pose2d', 'pose2d_weights', 'scope', 'device', 'det_model',\n        'det_weights', 'det_cat_ids', 'pose3d', 'pose3d_weights',\n        'show_progress'\n    ]\n    init_args = {}\n    for init_kw in init_kws:\n        init_args[init_kw] = call_args.pop(init_kw)\n\n    display_alias = call_args.pop('show_alias')\n\n    return init_args, call_args, display_alias\n\n\ndef display_model_aliases(model_aliases: Dict[str, str]) -> None:\n    \"\"\"Display the available model aliases and their corresponding model\n    names.\"\"\"\n    aliases = list(model_aliases.keys())\n    max_alias_length = max(map(len, aliases))\n    print(f'{\"ALIAS\".ljust(max_alias_length+2)}MODEL_NAME')\n    for alias in sorted(aliases):\n        print(f'{alias.ljust(max_alias_length+2)}{model_aliases[alias]}')\n\n\ndef main():\n    init_args, call_args, display_alias = parse_args()\n    if display_alias:\n        model_alises = get_model_aliases(init_args['scope'])\n        display_model_aliases(model_alises)\n    else:\n        inferencer = MMPoseInferencer(**init_args)\n        for _ in inferencer(**call_args):\n            pass\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_1class.py",
    "content": "# runtime settings\ndefault_scope = 'mmdet'\n\ndefault_hooks = dict(\n    timer=dict(type='IterTimerHook'),\n    logger=dict(type='LoggerHook', interval=50),\n    param_scheduler=dict(type='ParamSchedulerHook'),\n    checkpoint=dict(type='CheckpointHook', interval=1),\n    sampler_seed=dict(type='DistSamplerSeedHook'),\n    visualization=dict(type='DetVisualizationHook'))\n\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'),\n)\n\nvis_backends = [dict(type='LocalVisBackend')]\nvisualizer = dict(\n    type='DetLocalVisualizer', vis_backends=vis_backends, name='visualizer')\nlog_processor = dict(type='LogProcessor', window_size=50, by_epoch=True)\n\nlog_level = 'INFO'\nload_from = None\nresume = False\n\n# model settings\nmodel = dict(\n    type='CascadeRCNN',\n    data_preprocessor=dict(\n        type='DetDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True,\n        pad_mask=True,\n        pad_size_divisor=32),\n    backbone=dict(\n        type='ResNeXt',\n        depth=101,\n        groups=64,\n        base_width=4,\n        num_stages=4,\n        out_indices=(0, 1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        style='pytorch',\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://resnext101_64x4d')),\n    neck=dict(\n        type='FPN',\n        in_channels=[256, 512, 1024, 2048],\n        out_channels=256,\n        num_outs=5),\n    rpn_head=dict(\n        type='RPNHead',\n        in_channels=256,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='AnchorGenerator',\n            scales=[8],\n            ratios=[0.5, 1.0, 2.0],\n            strides=[4, 8, 16, 32, 64]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[.0, .0, .0, .0],\n            target_stds=[1.0, 1.0, 1.0, 1.0]),\n        loss_cls=dict(\n            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n        loss_bbox=dict(type='SmoothL1Loss', beta=1.0 / 9.0, loss_weight=1.0)),\n    roi_head=dict(\n        type='CascadeRoIHead',\n        num_stages=3,\n        stage_loss_weights=[1, 0.5, 0.25],\n        bbox_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        bbox_head=[\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=1,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0., 0., 0., 0.],\n                    target_stds=[0.1, 0.1, 0.2, 0.2]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0,\n                               loss_weight=1.0)),\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=1,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0., 0., 0., 0.],\n                    target_stds=[0.05, 0.05, 0.1, 0.1]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0,\n                               loss_weight=1.0)),\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=1,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0., 0., 0., 0.],\n                    target_stds=[0.033, 0.033, 0.067, 0.067]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0, loss_weight=1.0))\n        ]),\n    # model training and testing settings\n    train_cfg=dict(\n        rpn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.7,\n                neg_iou_thr=0.3,\n                min_pos_iou=0.3,\n                match_low_quality=True,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=256,\n                pos_fraction=0.5,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=False),\n            allowed_border=0,\n            pos_weight=-1,\n            debug=False),\n        rpn_proposal=dict(\n            nms_pre=2000,\n            max_per_img=2000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=[\n            dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.5,\n                    neg_iou_thr=0.5,\n                    min_pos_iou=0.5,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False),\n            dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.6,\n                    neg_iou_thr=0.6,\n                    min_pos_iou=0.6,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False),\n            dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.7,\n                    neg_iou_thr=0.7,\n                    min_pos_iou=0.7,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False)\n        ]),\n    test_cfg=dict(\n        rpn=dict(\n            nms_pre=1000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            score_thr=0.05,\n            nms=dict(type='nms', iou_threshold=0.5),\n            max_per_img=100)))\n\n# dataset settings\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco/'\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='Resize', scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PackDetInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(1333, 800), keep_ratio=True),\n    # If you don't have a gt annotation, delete the pipeline\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\ntrain_dataloader = dict(\n    batch_size=2,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    batch_sampler=dict(type='AspectRatioBatchSampler'),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='annotations/instances_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        filter_cfg=dict(filter_empty_gt=True, min_size=32),\n        pipeline=train_pipeline))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='annotations/instances_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/instances_val2017.json',\n    metric='bbox',\n    format_only=False)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "demo/mmdetection_cfg/cascade_rcnn_x101_64x4d_fpn_coco.py",
    "content": "checkpoint_config = dict(interval=1)\n# yapf:disable\nlog_config = dict(\n    interval=50,\n    hooks=[\n        dict(type='TextLoggerHook'),\n        # dict(type='TensorboardLoggerHook')\n    ])\n# yapf:enable\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\n\n# optimizer\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\noptimizer_config = dict(grad_clip=None)\n# learning policy\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=500,\n    warmup_ratio=0.001,\n    step=[16, 19])\ntotal_epochs = 20\n\n# model settings\nmodel = dict(\n    type='CascadeRCNN',\n    pretrained='open-mmlab://resnext101_64x4d',\n    backbone=dict(\n        type='ResNeXt',\n        depth=101,\n        groups=64,\n        base_width=4,\n        num_stages=4,\n        out_indices=(0, 1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        style='pytorch'),\n    neck=dict(\n        type='FPN',\n        in_channels=[256, 512, 1024, 2048],\n        out_channels=256,\n        num_outs=5),\n    rpn_head=dict(\n        type='RPNHead',\n        in_channels=256,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='AnchorGenerator',\n            scales=[8],\n            ratios=[0.5, 1.0, 2.0],\n            strides=[4, 8, 16, 32, 64]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[.0, .0, .0, .0],\n            target_stds=[1.0, 1.0, 1.0, 1.0]),\n        loss_cls=dict(\n            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n        loss_bbox=dict(type='SmoothL1Loss', beta=1.0 / 9.0, loss_weight=1.0)),\n    roi_head=dict(\n        type='CascadeRoIHead',\n        num_stages=3,\n        stage_loss_weights=[1, 0.5, 0.25],\n        bbox_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        bbox_head=[\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=80,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0., 0., 0., 0.],\n                    target_stds=[0.1, 0.1, 0.2, 0.2]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0,\n                               loss_weight=1.0)),\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=80,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0., 0., 0., 0.],\n                    target_stds=[0.05, 0.05, 0.1, 0.1]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0,\n                               loss_weight=1.0)),\n            dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=80,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0., 0., 0., 0.],\n                    target_stds=[0.033, 0.033, 0.067, 0.067]),\n                reg_class_agnostic=True,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', beta=1.0, loss_weight=1.0))\n        ]),\n    # model training and testing settings\n    train_cfg=dict(\n        rpn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.7,\n                neg_iou_thr=0.3,\n                min_pos_iou=0.3,\n                match_low_quality=True,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=256,\n                pos_fraction=0.5,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=False),\n            allowed_border=0,\n            pos_weight=-1,\n            debug=False),\n        rpn_proposal=dict(\n            nms_pre=2000,\n            max_per_img=2000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=[\n            dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.5,\n                    neg_iou_thr=0.5,\n                    min_pos_iou=0.5,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False),\n            dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.6,\n                    neg_iou_thr=0.6,\n                    min_pos_iou=0.6,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False),\n            dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.7,\n                    neg_iou_thr=0.7,\n                    min_pos_iou=0.7,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False)\n        ]),\n    test_cfg=dict(\n        rpn=dict(\n            nms_pre=1000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            score_thr=0.05,\n            nms=dict(type='nms', iou_threshold=0.5),\n            max_per_img=100)))\n\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', flip_ratio=0.5),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(1333, 800),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='Pad', size_divisor=32),\n            dict(type='DefaultFormatBundle'),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    samples_per_gpu=2,\n    workers_per_gpu=2,\n    train=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_train2017.json',\n        img_prefix=f'{data_root}/train2017/',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_val2017.json',\n        img_prefix=f'{data_root}/val2017/',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_val2017.json',\n        img_prefix=f'{data_root}/val2017/',\n        pipeline=test_pipeline))\nevaluation = dict(interval=1, metric='bbox')\n"
  },
  {
    "path": "demo/mmdetection_cfg/faster_rcnn_r50_fpn_1class.py",
    "content": "checkpoint_config = dict(interval=1)\n# yapf:disable\nlog_config = dict(\n    interval=50,\n    hooks=[\n        dict(type='TextLoggerHook'),\n        # dict(type='TensorboardLoggerHook')\n    ])\n# yapf:enable\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\n# optimizer\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\noptimizer_config = dict(grad_clip=None)\n# learning policy\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=500,\n    warmup_ratio=0.001,\n    step=[8, 11])\ntotal_epochs = 12\n\nmodel = dict(\n    type='FasterRCNN',\n    pretrained='torchvision://resnet50',\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        num_stages=4,\n        out_indices=(0, 1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        norm_eval=True,\n        style='pytorch'),\n    neck=dict(\n        type='FPN',\n        in_channels=[256, 512, 1024, 2048],\n        out_channels=256,\n        num_outs=5),\n    rpn_head=dict(\n        type='RPNHead',\n        in_channels=256,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='AnchorGenerator',\n            scales=[8],\n            ratios=[0.5, 1.0, 2.0],\n            strides=[4, 8, 16, 32, 64]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[.0, .0, .0, .0],\n            target_stds=[1.0, 1.0, 1.0, 1.0]),\n        loss_cls=dict(\n            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),\n    roi_head=dict(\n        type='StandardRoIHead',\n        bbox_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        bbox_head=dict(\n            type='Shared2FCBBoxHead',\n            in_channels=256,\n            fc_out_channels=1024,\n            roi_feat_size=7,\n            num_classes=1,\n            bbox_coder=dict(\n                type='DeltaXYWHBBoxCoder',\n                target_means=[0., 0., 0., 0.],\n                target_stds=[0.1, 0.1, 0.2, 0.2]),\n            reg_class_agnostic=False,\n            loss_cls=dict(\n                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),\n            loss_bbox=dict(type='L1Loss', loss_weight=1.0))),\n    # model training and testing settings\n    train_cfg=dict(\n        rpn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.7,\n                neg_iou_thr=0.3,\n                min_pos_iou=0.3,\n                match_low_quality=True,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=256,\n                pos_fraction=0.5,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=False),\n            allowed_border=-1,\n            pos_weight=-1,\n            debug=False),\n        rpn_proposal=dict(\n            nms_pre=2000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.5,\n                neg_iou_thr=0.5,\n                min_pos_iou=0.5,\n                match_low_quality=False,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=512,\n                pos_fraction=0.25,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=True),\n            pos_weight=-1,\n            debug=False)),\n    test_cfg=dict(\n        rpn=dict(\n            nms_pre=1000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            score_thr=0.05,\n            nms=dict(type='nms', iou_threshold=0.5),\n            max_per_img=100)\n        # soft-nms is also supported for rcnn testing\n        # e.g., nms=dict(type='soft_nms', iou_threshold=0.5, min_score=0.05)\n    ))\n\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', flip_ratio=0.5),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels']),\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(1333, 800),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='Pad', size_divisor=32),\n            dict(type='DefaultFormatBundle'),\n            dict(type='Collect', keys=['img']),\n        ])\n]\ndata = dict(\n    samples_per_gpu=2,\n    workers_per_gpu=2,\n    train=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_train2017.json',\n        img_prefix=f'{data_root}/train2017/',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_val2017.json',\n        img_prefix=f'{data_root}/val2017/',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_val2017.json',\n        img_prefix=f'{data_root}/val2017/',\n        pipeline=test_pipeline))\nevaluation = dict(interval=1, metric='bbox')\n"
  },
  {
    "path": "demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py",
    "content": "# runtime settings\ndefault_scope = 'mmdet'\n\ndefault_hooks = dict(\n    timer=dict(type='IterTimerHook'),\n    logger=dict(type='LoggerHook', interval=50),\n    param_scheduler=dict(type='ParamSchedulerHook'),\n    checkpoint=dict(type='CheckpointHook', interval=1),\n    sampler_seed=dict(type='DistSamplerSeedHook'),\n    visualization=dict(type='DetVisualizationHook'))\n\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'),\n)\n\nvis_backends = [dict(type='LocalVisBackend')]\nvisualizer = dict(\n    type='DetLocalVisualizer', vis_backends=vis_backends, name='visualizer')\nlog_processor = dict(type='LogProcessor', window_size=50, by_epoch=True)\n\nlog_level = 'INFO'\nload_from = None\nresume = False\n\n# model settings\nmodel = dict(\n    type='FasterRCNN',\n    data_preprocessor=dict(\n        type='DetDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True,\n        pad_size_divisor=32),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        num_stages=4,\n        out_indices=(0, 1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        norm_eval=True,\n        style='pytorch',\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),\n    neck=dict(\n        type='FPN',\n        in_channels=[256, 512, 1024, 2048],\n        out_channels=256,\n        num_outs=5),\n    rpn_head=dict(\n        type='RPNHead',\n        in_channels=256,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='AnchorGenerator',\n            scales=[8],\n            ratios=[0.5, 1.0, 2.0],\n            strides=[4, 8, 16, 32, 64]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[.0, .0, .0, .0],\n            target_stds=[1.0, 1.0, 1.0, 1.0]),\n        loss_cls=dict(\n            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),\n    roi_head=dict(\n        type='StandardRoIHead',\n        bbox_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        bbox_head=dict(\n            type='Shared2FCBBoxHead',\n            in_channels=256,\n            fc_out_channels=1024,\n            roi_feat_size=7,\n            num_classes=80,\n            bbox_coder=dict(\n                type='DeltaXYWHBBoxCoder',\n                target_means=[0., 0., 0., 0.],\n                target_stds=[0.1, 0.1, 0.2, 0.2]),\n            reg_class_agnostic=False,\n            loss_cls=dict(\n                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),\n            loss_bbox=dict(type='L1Loss', loss_weight=1.0))),\n    # model training and testing settings\n    train_cfg=dict(\n        rpn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.7,\n                neg_iou_thr=0.3,\n                min_pos_iou=0.3,\n                match_low_quality=True,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=256,\n                pos_fraction=0.5,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=False),\n            allowed_border=-1,\n            pos_weight=-1,\n            debug=False),\n        rpn_proposal=dict(\n            nms_pre=2000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.5,\n                neg_iou_thr=0.5,\n                min_pos_iou=0.5,\n                match_low_quality=False,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=512,\n                pos_fraction=0.25,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=True),\n            pos_weight=-1,\n            debug=False)),\n    test_cfg=dict(\n        rpn=dict(\n            nms_pre=1000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            score_thr=0.05,\n            nms=dict(type='nms', iou_threshold=0.5),\n            max_per_img=100)\n        # soft-nms is also supported for rcnn testing\n        # e.g., nms=dict(type='soft_nms', iou_threshold=0.5, min_score=0.05)\n    ))\n\n# dataset settings\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco/'\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='Resize', scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PackDetInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(1333, 800), keep_ratio=True),\n    # If you don't have a gt annotation, delete the pipeline\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\ntrain_dataloader = dict(\n    batch_size=2,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    batch_sampler=dict(type='AspectRatioBatchSampler'),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='annotations/instances_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        filter_cfg=dict(filter_empty_gt=True, min_size=32),\n        pipeline=train_pipeline))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='annotations/instances_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/instances_val2017.json',\n    metric='bbox',\n    format_only=False)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "demo/mmdetection_cfg/mask_rcnn_r50_fpn_2x_coco.py",
    "content": "model = dict(\n    type='MaskRCNN',\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        num_stages=4,\n        out_indices=(0, 1, 2, 3),\n        frozen_stages=1,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        norm_eval=True,\n        style='pytorch',\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50')),\n    neck=dict(\n        type='FPN',\n        in_channels=[256, 512, 1024, 2048],\n        out_channels=256,\n        num_outs=5),\n    rpn_head=dict(\n        type='RPNHead',\n        in_channels=256,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='AnchorGenerator',\n            scales=[8],\n            ratios=[0.5, 1.0, 2.0],\n            strides=[4, 8, 16, 32, 64]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[0.0, 0.0, 0.0, 0.0],\n            target_stds=[1.0, 1.0, 1.0, 1.0]),\n        loss_cls=dict(\n            type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n        loss_bbox=dict(type='L1Loss', loss_weight=1.0)),\n    roi_head=dict(\n        type='StandardRoIHead',\n        bbox_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=7, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        bbox_head=dict(\n            type='Shared2FCBBoxHead',\n            in_channels=256,\n            fc_out_channels=1024,\n            roi_feat_size=7,\n            num_classes=80,\n            bbox_coder=dict(\n                type='DeltaXYWHBBoxCoder',\n                target_means=[0.0, 0.0, 0.0, 0.0],\n                target_stds=[0.1, 0.1, 0.2, 0.2]),\n            reg_class_agnostic=False,\n            loss_cls=dict(\n                type='CrossEntropyLoss', use_sigmoid=False, loss_weight=1.0),\n            loss_bbox=dict(type='L1Loss', loss_weight=1.0)),\n        mask_roi_extractor=dict(\n            type='SingleRoIExtractor',\n            roi_layer=dict(type='RoIAlign', output_size=14, sampling_ratio=0),\n            out_channels=256,\n            featmap_strides=[4, 8, 16, 32]),\n        mask_head=dict(\n            type='FCNMaskHead',\n            num_convs=4,\n            in_channels=256,\n            conv_out_channels=256,\n            num_classes=80,\n            loss_mask=dict(\n                type='CrossEntropyLoss', use_mask=True, loss_weight=1.0))),\n    train_cfg=dict(\n        rpn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.7,\n                neg_iou_thr=0.3,\n                min_pos_iou=0.3,\n                match_low_quality=True,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=256,\n                pos_fraction=0.5,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=False),\n            allowed_border=-1,\n            pos_weight=-1,\n            debug=False),\n        rpn_proposal=dict(\n            nms_pre=2000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            assigner=dict(\n                type='MaxIoUAssigner',\n                pos_iou_thr=0.5,\n                neg_iou_thr=0.5,\n                min_pos_iou=0.5,\n                match_low_quality=True,\n                ignore_iof_thr=-1),\n            sampler=dict(\n                type='RandomSampler',\n                num=512,\n                pos_fraction=0.25,\n                neg_pos_ub=-1,\n                add_gt_as_proposals=True),\n            mask_size=28,\n            pos_weight=-1,\n            debug=False)),\n    test_cfg=dict(\n        rpn=dict(\n            nms_pre=1000,\n            max_per_img=1000,\n            nms=dict(type='nms', iou_threshold=0.7),\n            min_bbox_size=0),\n        rcnn=dict(\n            score_thr=0.05,\n            nms=dict(type='nms', iou_threshold=0.5),\n            max_per_img=100,\n            mask_thr_binary=0.5)))\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco/'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True, with_mask=True),\n    dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', flip_ratio=0.5),\n    dict(\n        type='Normalize',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        to_rgb=True),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks'])\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(1333, 800),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(\n                type='Normalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\n                to_rgb=True),\n            dict(type='Pad', size_divisor=32),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='Collect', keys=['img'])\n        ])\n]\ndata = dict(\n    samples_per_gpu=2,\n    workers_per_gpu=2,\n    train=dict(\n        type='CocoDataset',\n        ann_file='data/coco/annotations/instances_train2017.json',\n        img_prefix='data/coco/train2017/',\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(type='LoadAnnotations', with_bbox=True, with_mask=True),\n            dict(type='Resize', img_scale=(1333, 800), keep_ratio=True),\n            dict(type='RandomFlip', flip_ratio=0.5),\n            dict(\n                type='Normalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\n                to_rgb=True),\n            dict(type='Pad', size_divisor=32),\n            dict(type='DefaultFormatBundle'),\n            dict(\n                type='Collect',\n                keys=['img', 'gt_bboxes', 'gt_labels', 'gt_masks'])\n        ]),\n    val=dict(\n        type='CocoDataset',\n        ann_file='data/coco/annotations/instances_val2017.json',\n        img_prefix='data/coco/val2017/',\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(\n                type='MultiScaleFlipAug',\n                img_scale=(1333, 800),\n                flip=False,\n                transforms=[\n                    dict(type='Resize', keep_ratio=True),\n                    dict(type='RandomFlip'),\n                    dict(\n                        type='Normalize',\n                        mean=[123.675, 116.28, 103.53],\n                        std=[58.395, 57.12, 57.375],\n                        to_rgb=True),\n                    dict(type='Pad', size_divisor=32),\n                    dict(type='ImageToTensor', keys=['img']),\n                    dict(type='Collect', keys=['img'])\n                ])\n        ]),\n    test=dict(\n        type='CocoDataset',\n        ann_file='data/coco/annotations/instances_val2017.json',\n        img_prefix='data/coco/val2017/',\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(\n                type='MultiScaleFlipAug',\n                img_scale=(1333, 800),\n                flip=False,\n                transforms=[\n                    dict(type='Resize', keep_ratio=True),\n                    dict(type='RandomFlip'),\n                    dict(\n                        type='Normalize',\n                        mean=[123.675, 116.28, 103.53],\n                        std=[58.395, 57.12, 57.375],\n                        to_rgb=True),\n                    dict(type='Pad', size_divisor=32),\n                    dict(type='ImageToTensor', keys=['img']),\n                    dict(type='Collect', keys=['img'])\n                ])\n        ]))\nevaluation = dict(metric=['bbox', 'segm'])\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\noptimizer_config = dict(grad_clip=None)\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=500,\n    warmup_ratio=0.001,\n    step=[16, 22])\nrunner = dict(type='EpochBasedRunner', max_epochs=24)\ncheckpoint_config = dict(interval=1)\nlog_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])\ncustom_hooks = [dict(type='NumClassCheckHook')]\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\n"
  },
  {
    "path": "demo/mmdetection_cfg/rtmdet_m_640-8xb32_coco-person.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_m_8xb32-300e_coco.py'\n\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth'  # noqa\n\nmodel = dict(\n    backbone=dict(\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=checkpoint)),\n    bbox_head=dict(num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\ntrain_dataloader = dict(dataset=dict(metainfo=dict(classes=('person', ))))\n\nval_dataloader = dict(dataset=dict(metainfo=dict(classes=('person', ))))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "demo/mmdetection_cfg/rtmdet_m_8xb32-300e_coco.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_m_8xb32-300e_coco.py'\n"
  },
  {
    "path": "demo/mmdetection_cfg/rtmdet_nano_320-8xb32_coco-person.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_l_8xb32-300e_coco.py'\n\ninput_shape = 320\n\nmodel = dict(\n    backbone=dict(\n        deepen_factor=0.33,\n        widen_factor=0.25,\n        use_depthwise=True,\n    ),\n    neck=dict(\n        in_channels=[64, 128, 256],\n        out_channels=64,\n        num_csp_blocks=1,\n        use_depthwise=True,\n    ),\n    bbox_head=dict(\n        in_channels=64,\n        feat_channels=64,\n        share_conv=False,\n        exp_on_reg=False,\n        use_depthwise=True,\n        num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='CachedMosaic',\n        img_scale=(input_shape, input_shape),\n        pad_val=114.0,\n        max_cached_images=20,\n        random_pop=False),\n    dict(\n        type='RandomResize',\n        scale=(input_shape * 2, input_shape * 2),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='RandomResize',\n        scale=(input_shape, input_shape),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(input_shape, input_shape), keep_ratio=True),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ntrain_dataloader = dict(\n    dataset=dict(pipeline=train_pipeline, metainfo=dict(classes=('person', ))))\n\nval_dataloader = dict(\n    dataset=dict(pipeline=test_pipeline, metainfo=dict(classes=('person', ))))\ntest_dataloader = val_dataloader\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='PipelineSwitchHook',\n        switch_epoch=280,\n        switch_pipeline=train_pipeline_stage2)\n]\n"
  },
  {
    "path": "demo/mmdetection_cfg/rtmdet_nano_320-8xb32_hand.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_l_8xb32-300e_coco.py'\n\ninput_shape = 320\n\nmodel = dict(\n    backbone=dict(\n        deepen_factor=0.33,\n        widen_factor=0.25,\n        use_depthwise=True,\n    ),\n    neck=dict(\n        in_channels=[64, 128, 256],\n        out_channels=64,\n        num_csp_blocks=1,\n        use_depthwise=True,\n    ),\n    bbox_head=dict(\n        in_channels=64,\n        feat_channels=64,\n        share_conv=False,\n        exp_on_reg=False,\n        use_depthwise=True,\n        num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\n# file_client_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({'data/': 's3://openmmlab/datasets/'}))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='CachedMosaic',\n        img_scale=(input_shape, input_shape),\n        pad_val=114.0,\n        max_cached_images=20,\n        random_pop=False),\n    dict(\n        type='RandomResize',\n        scale=(input_shape * 2, input_shape * 2),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='RandomResize',\n        scale=(input_shape, input_shape),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(input_shape, input_shape), keep_ratio=True),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ndata_mode = 'topdown'\ndata_root = 'data/'\n\ntrain_dataset = dict(\n    _delete_=True,\n    type='ConcatDataset',\n    datasets=[\n        dict(\n            type='mmpose.OneHand10KDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='onehand10k/annotations/onehand10k_train.json',\n            data_prefix=dict(img='pose/OneHand10K/')),\n        dict(\n            type='mmpose.FreiHandDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='freihand/annotations/freihand_train.json',\n            data_prefix=dict(img='pose/FreiHand/')),\n        dict(\n            type='mmpose.Rhd2DDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='rhd/annotations/rhd_train.json',\n            data_prefix=dict(img='pose/RHD/')),\n        dict(\n            type='mmpose.HalpeHandDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='halpe/annotations/halpe_train_v1.json',\n            data_prefix=dict(\n                img='pose/Halpe/hico_20160224_det/images/train2015/')  # noqa\n        )\n    ],\n    ignore_keys=[\n        'CLASSES', 'dataset_keypoint_weights', 'dataset_name', 'flip_indices',\n        'flip_pairs', 'keypoint_colors', 'keypoint_id2name',\n        'keypoint_name2id', 'lower_body_ids', 'num_keypoints',\n        'num_skeleton_links', 'sigmas', 'skeleton_link_colors',\n        'skeleton_links', 'upper_body_ids'\n    ],\n)\n\ntest_dataset = dict(\n    _delete_=True,\n    type='mmpose.OneHand10KDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    pipeline=test_pipeline,\n    ann_file='onehand10k/annotations/onehand10k_test.json',\n    data_prefix=dict(img='pose/OneHand10K/'),\n)\n\ntrain_dataloader = dict(dataset=train_dataset)\nval_dataloader = dict(dataset=test_dataset)\ntest_dataloader = val_dataloader\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='PipelineSwitchHook',\n        switch_epoch=280,\n        switch_pipeline=train_pipeline_stage2)\n]\n\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'onehand10k/annotations/onehand10k_test.json',\n    metric='bbox',\n    format_only=False)\ntest_evaluator = val_evaluator\n\ntrain_cfg = dict(val_interval=1)\n"
  },
  {
    "path": "demo/mmdetection_cfg/rtmdet_tiny_8xb32-300e_coco.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_tiny_8xb32-300e_coco.py'\n"
  },
  {
    "path": "demo/mmdetection_cfg/ssdlite_mobilenetv2-scratch_8xb24-600e_coco.py",
    "content": "# model settings\ndata_preprocessor = dict(\n    type='DetDataPreprocessor',\n    mean=[123.675, 116.28, 103.53],\n    std=[58.395, 57.12, 57.375],\n    bgr_to_rgb=True,\n    pad_size_divisor=1)\nmodel = dict(\n    type='SingleStageDetector',\n    data_preprocessor=data_preprocessor,\n    backbone=dict(\n        type='MobileNetV2',\n        out_indices=(4, 7),\n        norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),\n        init_cfg=dict(type='TruncNormal', layer='Conv2d', std=0.03)),\n    neck=dict(\n        type='SSDNeck',\n        in_channels=(96, 1280),\n        out_channels=(96, 1280, 512, 256, 256, 128),\n        level_strides=(2, 2, 2, 2),\n        level_paddings=(1, 1, 1, 1),\n        l2_norm_scale=None,\n        use_depthwise=True,\n        norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),\n        act_cfg=dict(type='ReLU6'),\n        init_cfg=dict(type='TruncNormal', layer='Conv2d', std=0.03)),\n    bbox_head=dict(\n        type='SSDHead',\n        in_channels=(96, 1280, 512, 256, 256, 128),\n        num_classes=80,\n        use_depthwise=True,\n        norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),\n        act_cfg=dict(type='ReLU6'),\n        init_cfg=dict(type='Normal', layer='Conv2d', std=0.001),\n\n        # set anchor size manually instead of using the predefined\n        # SSD300 setting.\n        anchor_generator=dict(\n            type='SSDAnchorGenerator',\n            scale_major=False,\n            strides=[16, 32, 64, 107, 160, 320],\n            ratios=[[2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3]],\n            min_sizes=[48, 100, 150, 202, 253, 304],\n            max_sizes=[100, 150, 202, 253, 304, 320]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[.0, .0, .0, .0],\n            target_stds=[0.1, 0.1, 0.2, 0.2])),\n    # model training and testing settings\n    train_cfg=dict(\n        assigner=dict(\n            type='MaxIoUAssigner',\n            pos_iou_thr=0.5,\n            neg_iou_thr=0.5,\n            min_pos_iou=0.,\n            ignore_iof_thr=-1,\n            gt_max_assign_all=False),\n        sampler=dict(type='PseudoSampler'),\n        smoothl1_beta=1.,\n        allowed_border=-1,\n        pos_weight=-1,\n        neg_pos_ratio=3,\n        debug=False),\n    test_cfg=dict(\n        nms_pre=1000,\n        nms=dict(type='nms', iou_threshold=0.45),\n        min_bbox_size=0,\n        score_thr=0.02,\n        max_per_img=200))\nenv_cfg = dict(cudnn_benchmark=True)\n\n# dataset settings\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco/'\n\ninput_size = 320\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='Expand',\n        mean=data_preprocessor['mean'],\n        to_rgb=data_preprocessor['bgr_to_rgb'],\n        ratio_range=(1, 4)),\n    dict(\n        type='MinIoURandomCrop',\n        min_ious=(0.1, 0.3, 0.5, 0.7, 0.9),\n        min_crop_size=0.3),\n    dict(type='Resize', scale=(input_size, input_size), keep_ratio=False),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='PhotoMetricDistortion',\n        brightness_delta=32,\n        contrast_range=(0.5, 1.5),\n        saturation_range=(0.5, 1.5),\n        hue_delta=18),\n    dict(type='PackDetInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(input_size, input_size), keep_ratio=False),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\ntrain_dataloader = dict(\n    batch_size=24,\n    num_workers=4,\n    batch_sampler=None,\n    dataset=dict(\n        _delete_=True,\n        type='RepeatDataset',\n        times=5,\n        dataset=dict(\n            type=dataset_type,\n            data_root=data_root,\n            ann_file='annotations/instances_train2017.json',\n            data_prefix=dict(img='train2017/'),\n            filter_cfg=dict(filter_empty_gt=True, min_size=32),\n            pipeline=train_pipeline)))\nval_dataloader = dict(\n    batch_size=8,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='annotations/instances_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "demo/mmdetection_cfg/ssdlite_mobilenetv2_scratch_600e_onehand.py",
    "content": "# =========================================================\n# from 'mmdetection/configs/_base_/default_runtime.py'\n# =========================================================\ndefault_scope = 'mmdet'\ncheckpoint_config = dict(interval=1)\n# yapf:disable\nlog_config = dict(\n    interval=50,\n    hooks=[\n        dict(type='TextLoggerHook'),\n        # dict(type='TensorboardLoggerHook')\n    ])\n# yapf:enable\ncustom_hooks = [dict(type='NumClassCheckHook')]\n# =========================================================\n\n# model settings\ndata_preprocessor = dict(\n    type='DetDataPreprocessor',\n    mean=[123.675, 116.28, 103.53],\n    std=[58.395, 57.12, 57.375],\n    bgr_to_rgb=True,\n    pad_size_divisor=1)\nmodel = dict(\n    type='SingleStageDetector',\n    data_preprocessor=data_preprocessor,\n    backbone=dict(\n        type='MobileNetV2',\n        out_indices=(4, 7),\n        norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),\n        init_cfg=dict(type='TruncNormal', layer='Conv2d', std=0.03)),\n    neck=dict(\n        type='SSDNeck',\n        in_channels=(96, 1280),\n        out_channels=(96, 1280, 512, 256, 256, 128),\n        level_strides=(2, 2, 2, 2),\n        level_paddings=(1, 1, 1, 1),\n        l2_norm_scale=None,\n        use_depthwise=True,\n        norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),\n        act_cfg=dict(type='ReLU6'),\n        init_cfg=dict(type='TruncNormal', layer='Conv2d', std=0.03)),\n    bbox_head=dict(\n        type='SSDHead',\n        in_channels=(96, 1280, 512, 256, 256, 128),\n        num_classes=1,\n        use_depthwise=True,\n        norm_cfg=dict(type='BN', eps=0.001, momentum=0.03),\n        act_cfg=dict(type='ReLU6'),\n        init_cfg=dict(type='Normal', layer='Conv2d', std=0.001),\n\n        # set anchor size manually instead of using the predefined\n        # SSD300 setting.\n        anchor_generator=dict(\n            type='SSDAnchorGenerator',\n            scale_major=False,\n            strides=[16, 32, 64, 107, 160, 320],\n            ratios=[[2, 3], [2, 3], [2, 3], [2, 3], [2, 3], [2, 3]],\n            min_sizes=[48, 100, 150, 202, 253, 304],\n            max_sizes=[100, 150, 202, 253, 304, 320]),\n        bbox_coder=dict(\n            type='DeltaXYWHBBoxCoder',\n            target_means=[.0, .0, .0, .0],\n            target_stds=[0.1, 0.1, 0.2, 0.2])),\n    # model training and testing settings\n    train_cfg=dict(\n        assigner=dict(\n            type='MaxIoUAssigner',\n            pos_iou_thr=0.5,\n            neg_iou_thr=0.5,\n            min_pos_iou=0.,\n            ignore_iof_thr=-1,\n            gt_max_assign_all=False),\n        sampler=dict(type='PseudoSampler'),\n        smoothl1_beta=1.,\n        allowed_border=-1,\n        pos_weight=-1,\n        neg_pos_ratio=3,\n        debug=False),\n    test_cfg=dict(\n        nms_pre=1000,\n        nms=dict(type='nms', iou_threshold=0.45),\n        min_bbox_size=0,\n        score_thr=0.02,\n        max_per_img=200))\ncudnn_benchmark = True\n\n# dataset settings\nfile_client_args = dict(backend='disk')\n\ndataset_type = 'CocoDataset'\ndata_root = 'data/onehand10k/'\nclasses = ('hand', )\ninput_size = 320\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(input_size, input_size), keep_ratio=False),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\nval_dataloader = dict(\n    batch_size=8,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='annotations/onehand10k_test.json',\n        test_mode=True,\n        pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n\n# optimizer\noptimizer = dict(type='SGD', lr=0.015, momentum=0.9, weight_decay=4.0e-5)\noptimizer_config = dict(grad_clip=None)\n\n# learning policy\nlr_config = dict(\n    policy='CosineAnnealing',\n    warmup='linear',\n    warmup_iters=500,\n    warmup_ratio=0.001,\n    min_lr=0)\nrunner = dict(type='EpochBasedRunner', max_epochs=120)\n\n# Avoid evaluation and saving weights too frequently\nevaluation = dict(interval=5, metric='bbox')\ncheckpoint_config = dict(interval=5)\ncustom_hooks = [\n    dict(type='NumClassCheckHook'),\n    dict(type='CheckInvalidLossHook', interval=50, priority='VERY_LOW')\n]\n\nlog_config = dict(interval=5)\n\n# NOTE: `auto_scale_lr` is for automatically scaling LR,\n# USER SHOULD NOT CHANGE ITS VALUES.\n# base_batch_size = (8 GPUs) x (24 samples per GPU)\nauto_scale_lr = dict(base_batch_size=192)\n\nload_from = 'https://download.openmmlab.com/mmdetection/'\n'v2.0/ssd/ssdlite_mobilenetv2_scratch_600e_coco/'\n'ssdlite_mobilenetv2_scratch_600e_coco_20210629_110627-974d9307.pth'\n\nvis_backends = [dict(type='LocalVisBackend')]\nvisualizer = dict(\n    type='DetLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n"
  },
  {
    "path": "demo/mmdetection_cfg/yolov3_d53_320_273e_coco.py",
    "content": "# model settings\nmodel = dict(\n    type='YOLOV3',\n    pretrained='open-mmlab://darknet53',\n    backbone=dict(type='Darknet', depth=53, out_indices=(3, 4, 5)),\n    neck=dict(\n        type='YOLOV3Neck',\n        num_scales=3,\n        in_channels=[1024, 512, 256],\n        out_channels=[512, 256, 128]),\n    bbox_head=dict(\n        type='YOLOV3Head',\n        num_classes=80,\n        in_channels=[512, 256, 128],\n        out_channels=[1024, 512, 256],\n        anchor_generator=dict(\n            type='YOLOAnchorGenerator',\n            base_sizes=[[(116, 90), (156, 198), (373, 326)],\n                        [(30, 61), (62, 45), (59, 119)],\n                        [(10, 13), (16, 30), (33, 23)]],\n            strides=[32, 16, 8]),\n        bbox_coder=dict(type='YOLOBBoxCoder'),\n        featmap_strides=[32, 16, 8],\n        loss_cls=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            loss_weight=1.0,\n            reduction='sum'),\n        loss_conf=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            loss_weight=1.0,\n            reduction='sum'),\n        loss_xy=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            loss_weight=2.0,\n            reduction='sum'),\n        loss_wh=dict(type='MSELoss', loss_weight=2.0, reduction='sum')),\n    # training and testing settings\n    train_cfg=dict(\n        assigner=dict(\n            type='GridAssigner',\n            pos_iou_thr=0.5,\n            neg_iou_thr=0.5,\n            min_pos_iou=0)),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        conf_thr=0.005,\n        nms=dict(type='nms', iou_threshold=0.45),\n        max_per_img=100))\n# dataset settings\ndataset_type = 'CocoDataset'\ndata_root = 'data/coco'\nimg_norm_cfg = dict(mean=[0, 0, 0], std=[255., 255., 255.], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadImageFromFile', to_float32=True),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='PhotoMetricDistortion'),\n    dict(\n        type='Expand',\n        mean=img_norm_cfg['mean'],\n        to_rgb=img_norm_cfg['to_rgb'],\n        ratio_range=(1, 2)),\n    dict(\n        type='MinIoURandomCrop',\n        min_ious=(0.4, 0.5, 0.6, 0.7, 0.8, 0.9),\n        min_crop_size=0.3),\n    dict(type='Resize', img_scale=(320, 320), keep_ratio=True),\n    dict(type='RandomFlip', flip_ratio=0.5),\n    dict(type='Normalize', **img_norm_cfg),\n    dict(type='Pad', size_divisor=32),\n    dict(type='DefaultFormatBundle'),\n    dict(type='Collect', keys=['img', 'gt_bboxes', 'gt_labels'])\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(320, 320),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(type='Normalize', **img_norm_cfg),\n            dict(type='Pad', size_divisor=32),\n            dict(type='DefaultFormatBundle'),\n            dict(type='Collect', keys=['img'])\n        ])\n]\ndata = dict(\n    samples_per_gpu=8,\n    workers_per_gpu=4,\n    train=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_train2017.json',\n        img_prefix=f'{data_root}/train2017/',\n        pipeline=train_pipeline),\n    val=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_val2017.json',\n        img_prefix=f'{data_root}/val2017/',\n        pipeline=test_pipeline),\n    test=dict(\n        type=dataset_type,\n        ann_file=f'{data_root}/annotations/instances_val2017.json',\n        img_prefix=f'{data_root}/val2017/',\n        pipeline=test_pipeline))\n# optimizer\noptimizer = dict(type='SGD', lr=0.001, momentum=0.9, weight_decay=0.0005)\noptimizer_config = dict(grad_clip=dict(max_norm=35, norm_type=2))\n# learning policy\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=2000,  # same as burn-in in darknet\n    warmup_ratio=0.1,\n    step=[218, 246])\n# runtime settings\nrunner = dict(type='EpochBasedRunner', max_epochs=273)\nevaluation = dict(interval=1, metric=['bbox'])\n\ncheckpoint_config = dict(interval=1)\n# yapf:disable\nlog_config = dict(\n    interval=50,\n    hooks=[\n        dict(type='TextLoggerHook'),\n        # dict(type='TensorboardLoggerHook')\n    ])\n# yapf:enable\ncustom_hooks = [dict(type='NumClassCheckHook')]\n\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\n"
  },
  {
    "path": "demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py",
    "content": "train_cfg = dict(type='EpochBasedTrainLoop', max_epochs=300, val_interval=10)\nval_cfg = dict(type='ValLoop')\ntest_cfg = dict(type='TestLoop')\nparam_scheduler = [\n    dict(\n        type='mmdet.QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=0.0005,\n        begin=5,\n        T_max=285,\n        end=285,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(type='ConstantLR', by_epoch=True, factor=1, begin=285, end=300)\n]\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(\n        type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0005, nesterov=True),\n    paramwise_cfg=dict(norm_decay_mult=0.0, bias_decay_mult=0.0))\nauto_scale_lr = dict(enable=False, base_batch_size=64)\ndefault_scope = 'mmdet'\ndefault_hooks = dict(\n    timer=dict(type='IterTimerHook'),\n    logger=dict(type='LoggerHook', interval=50),\n    param_scheduler=dict(type='ParamSchedulerHook'),\n    checkpoint=dict(type='CheckpointHook', interval=10, max_keep_ckpts=3),\n    sampler_seed=dict(type='DistSamplerSeedHook'),\n    visualization=dict(type='DetVisualizationHook'))\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'))\nvis_backends = [dict(type='LocalVisBackend')]\nvisualizer = dict(\n    type='DetLocalVisualizer',\n    vis_backends=[dict(type='LocalVisBackend')],\n    name='visualizer')\nlog_processor = dict(type='LogProcessor', window_size=50, by_epoch=True)\nlog_level = 'INFO'\nload_from = 'https://download.openmmlab.com/mmdetection/' \\\n            'v2.0/yolox/yolox_s_8x8_300e_coco/' \\\n            'yolox_s_8x8_300e_coco_20211121_095711-4592a793.pth'\nresume = False\nimg_scale = (640, 640)\nmodel = dict(\n    type='YOLOX',\n    data_preprocessor=dict(\n        type='DetDataPreprocessor',\n        pad_size_divisor=32,\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=10)\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(2, 3, 4),\n        use_depthwise=False,\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish')),\n    neck=dict(\n        type='YOLOXPAFPN',\n        in_channels=[128, 256, 512],\n        out_channels=128,\n        num_csp_blocks=1,\n        use_depthwise=False,\n        upsample_cfg=dict(scale_factor=2, mode='nearest'),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish')),\n    bbox_head=dict(\n        type='YOLOXHead',\n        num_classes=1,\n        in_channels=128,\n        feat_channels=128,\n        stacked_convs=2,\n        strides=(8, 16, 32),\n        use_depthwise=False,\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        loss_cls=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_obj=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_l1=dict(type='L1Loss', reduction='sum', loss_weight=1.0)),\n    train_cfg=dict(assigner=dict(type='SimOTAAssigner', center_radius=2.5)),\n    test_cfg=dict(score_thr=0.01, nms=dict(type='nms', iou_threshold=0.65)))\ndata_root = 'data/coco/'\ndataset_type = 'CocoDataset'\nbackend_args = dict(backend='local')\ntrain_pipeline = [\n    dict(type='Mosaic', img_scale=(640, 640), pad_val=114.0),\n    dict(\n        type='RandomAffine', scaling_ratio_range=(0.1, 2),\n        border=(-320, -320)),\n    dict(\n        type='MixUp',\n        img_scale=(640, 640),\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='Resize', scale=(640, 640), keep_ratio=True),\n    dict(\n        type='Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='FilterAnnotations', min_gt_bbox_wh=(1, 1), keep_empty=False),\n    dict(type='PackDetInputs')\n]\ntrain_dataset = dict(\n    type='MultiImageMixDataset',\n    dataset=dict(\n        type='CocoDataset',\n        data_root='data/coco/',\n        ann_file='annotations/instances_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=[\n            dict(type='LoadImageFromFile', backend_args=dict(backend='local')),\n            dict(type='LoadAnnotations', with_bbox=True)\n        ],\n        filter_cfg=dict(filter_empty_gt=False, min_size=32)),\n    pipeline=[\n        dict(type='Mosaic', img_scale=(640, 640), pad_val=114.0),\n        dict(\n            type='RandomAffine',\n            scaling_ratio_range=(0.1, 2),\n            border=(-320, -320)),\n        dict(\n            type='MixUp',\n            img_scale=(640, 640),\n            ratio_range=(0.8, 1.6),\n            pad_val=114.0),\n        dict(type='YOLOXHSVRandomAug'),\n        dict(type='RandomFlip', prob=0.5),\n        dict(type='Resize', scale=(640, 640), keep_ratio=True),\n        dict(\n            type='Pad',\n            pad_to_square=True,\n            pad_val=dict(img=(114.0, 114.0, 114.0))),\n        dict(\n            type='FilterAnnotations', min_gt_bbox_wh=(1, 1), keep_empty=False),\n        dict(type='PackDetInputs')\n    ])\ntest_pipeline = [\n    dict(type='LoadImageFromFile', backend_args=dict(backend='local')),\n    dict(type='Resize', scale=(640, 640), keep_ratio=True),\n    dict(\n        type='Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\ntrain_dataloader = dict(\n    batch_size=8,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='MultiImageMixDataset',\n        dataset=dict(\n            type='CocoDataset',\n            data_root='data/coco/',\n            ann_file='annotations/coco_face_train.json',\n            data_prefix=dict(img='train2017/'),\n            pipeline=[\n                dict(\n                    type='LoadImageFromFile',\n                    backend_args=dict(backend='local')),\n                dict(type='LoadAnnotations', with_bbox=True)\n            ],\n            filter_cfg=dict(filter_empty_gt=False, min_size=32),\n            metainfo=dict(CLASSES=('person', ), PALETTE=(220, 20, 60))),\n        pipeline=[\n            dict(type='Mosaic', img_scale=(640, 640), pad_val=114.0),\n            dict(\n                type='RandomAffine',\n                scaling_ratio_range=(0.1, 2),\n                border=(-320, -320)),\n            dict(\n                type='MixUp',\n                img_scale=(640, 640),\n                ratio_range=(0.8, 1.6),\n                pad_val=114.0),\n            dict(type='YOLOXHSVRandomAug'),\n            dict(type='RandomFlip', prob=0.5),\n            dict(type='Resize', scale=(640, 640), keep_ratio=True),\n            dict(\n                type='Pad',\n                pad_to_square=True,\n                pad_val=dict(img=(114.0, 114.0, 114.0))),\n            dict(\n                type='FilterAnnotations',\n                min_gt_bbox_wh=(1, 1),\n                keep_empty=False),\n            dict(type='PackDetInputs')\n        ]))\nval_dataloader = dict(\n    batch_size=8,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root='data/coco/',\n        ann_file='annotations/coco_face_val.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=[\n            dict(type='LoadImageFromFile', backend_args=dict(backend='local')),\n            dict(type='Resize', scale=(640, 640), keep_ratio=True),\n            dict(\n                type='Pad',\n                pad_to_square=True,\n                pad_val=dict(img=(114.0, 114.0, 114.0))),\n            dict(type='LoadAnnotations', with_bbox=True),\n            dict(\n                type='PackDetInputs',\n                meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                           'scale_factor'))\n        ],\n        metainfo=dict(CLASSES=('person', ), PALETTE=(220, 20, 60))))\ntest_dataloader = dict(\n    batch_size=8,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type='CocoDataset',\n        data_root='data/coco/',\n        ann_file='annotations/coco_face_val.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=[\n            dict(type='LoadImageFromFile', backend_args=dict(backend='local')),\n            dict(type='Resize', scale=(640, 640), keep_ratio=True),\n            dict(\n                type='Pad',\n                pad_to_square=True,\n                pad_val=dict(img=(114.0, 114.0, 114.0))),\n            dict(type='LoadAnnotations', with_bbox=True),\n            dict(\n                type='PackDetInputs',\n                meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                           'scale_factor'))\n        ],\n        metainfo=dict(CLASSES=('person', ), PALETTE=(220, 20, 60))))\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file='data/coco/annotations/coco_face_val.json',\n    metric='bbox')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file='data/coco/annotations/instances_val2017.json',\n    metric='bbox')\nmax_epochs = 300\nnum_last_epochs = 15\ninterval = 10\nbase_lr = 0.01\ncustom_hooks = [\n    dict(type='YOLOXModeSwitchHook', num_last_epochs=15, priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0001,\n        strict_load=False,\n        update_buffers=True,\n        priority=49)\n]\nmetainfo = dict(CLASSES=('person', ), PALETTE=(220, 20, 60))\nlauncher = 'pytorch'\n"
  },
  {
    "path": "demo/mmtracking_cfg/deepsort_faster-rcnn_fpn_4e_mot17-private-half.py",
    "content": "model = dict(\n    detector=dict(\n        type='FasterRCNN',\n        backbone=dict(\n            type='ResNet',\n            depth=50,\n            num_stages=4,\n            out_indices=(0, 1, 2, 3),\n            frozen_stages=1,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            norm_eval=True,\n            style='pytorch',\n            init_cfg=dict(\n                type='Pretrained', checkpoint='torchvision://resnet50')),\n        neck=dict(\n            type='FPN',\n            in_channels=[256, 512, 1024, 2048],\n            out_channels=256,\n            num_outs=5),\n        rpn_head=dict(\n            type='RPNHead',\n            in_channels=256,\n            feat_channels=256,\n            anchor_generator=dict(\n                type='AnchorGenerator',\n                scales=[8],\n                ratios=[0.5, 1.0, 2.0],\n                strides=[4, 8, 16, 32, 64]),\n            bbox_coder=dict(\n                type='DeltaXYWHBBoxCoder',\n                target_means=[0.0, 0.0, 0.0, 0.0],\n                target_stds=[1.0, 1.0, 1.0, 1.0],\n                clip_border=False),\n            loss_cls=dict(\n                type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n            loss_bbox=dict(\n                type='SmoothL1Loss', beta=0.1111111111111111,\n                loss_weight=1.0)),\n        roi_head=dict(\n            type='StandardRoIHead',\n            bbox_roi_extractor=dict(\n                type='SingleRoIExtractor',\n                roi_layer=dict(\n                    type='RoIAlign', output_size=7, sampling_ratio=0),\n                out_channels=256,\n                featmap_strides=[4, 8, 16, 32]),\n            bbox_head=dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=1,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0.0, 0.0, 0.0, 0.0],\n                    target_stds=[0.1, 0.1, 0.2, 0.2],\n                    clip_border=False),\n                reg_class_agnostic=False,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', loss_weight=1.0))),\n        train_cfg=dict(\n            rpn=dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.7,\n                    neg_iou_thr=0.3,\n                    min_pos_iou=0.3,\n                    match_low_quality=True,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=256,\n                    pos_fraction=0.5,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=False),\n                allowed_border=-1,\n                pos_weight=-1,\n                debug=False),\n            rpn_proposal=dict(\n                nms_pre=2000,\n                max_per_img=1000,\n                nms=dict(type='nms', iou_threshold=0.7),\n                min_bbox_size=0),\n            rcnn=dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.5,\n                    neg_iou_thr=0.5,\n                    min_pos_iou=0.5,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False)),\n        test_cfg=dict(\n            rpn=dict(\n                nms_pre=1000,\n                max_per_img=1000,\n                nms=dict(type='nms', iou_threshold=0.7),\n                min_bbox_size=0),\n            rcnn=dict(\n                score_thr=0.05,\n                nms=dict(type='nms', iou_threshold=0.5),\n                max_per_img=100)),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmtracking/'\n            'mot/faster_rcnn/faster-rcnn_r50_fpn_4e_mot17-half-64ee2ed4.pth')),\n    type='DeepSORT',\n    motion=dict(type='KalmanFilter', center_only=False),\n    reid=dict(\n        type='BaseReID',\n        backbone=dict(\n            type='ResNet',\n            depth=50,\n            num_stages=4,\n            out_indices=(3, ),\n            style='pytorch'),\n        neck=dict(type='GlobalAveragePooling', kernel_size=(8, 4), stride=1),\n        head=dict(\n            type='LinearReIDHead',\n            num_fcs=1,\n            in_channels=2048,\n            fc_channels=1024,\n            out_channels=128,\n            num_classes=380,\n            loss=dict(type='CrossEntropyLoss', loss_weight=1.0),\n            loss_pairwise=dict(\n                type='TripletLoss', margin=0.3, loss_weight=1.0),\n            norm_cfg=dict(type='BN1d'),\n            act_cfg=dict(type='ReLU')),\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmtracking/'\n            'mot/reid/tracktor_reid_r50_iter25245-a452f51f.pth')),\n    tracker=dict(\n        type='SortTracker',\n        obj_score_thr=0.5,\n        reid=dict(\n            num_samples=10,\n            img_scale=(256, 128),\n            img_norm_cfg=None,\n            match_score_thr=2.0),\n        match_iou_thr=0.5,\n        momentums=None,\n        num_tentatives=2,\n        num_frames_retain=100))\ndataset_type = 'MOTChallengeDataset'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadMultiImagesFromFile', to_float32=True),\n    dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),\n    dict(\n        type='SeqResize',\n        img_scale=(1088, 1088),\n        share_params=True,\n        ratio_range=(0.8, 1.2),\n        keep_ratio=True,\n        bbox_clip_border=False),\n    dict(type='SeqPhotoMetricDistortion', share_params=True),\n    dict(\n        type='SeqRandomCrop',\n        share_params=False,\n        crop_size=(1088, 1088),\n        bbox_clip_border=False),\n    dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),\n    dict(\n        type='SeqNormalize',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        to_rgb=True),\n    dict(type='SeqPad', size_divisor=32),\n    dict(type='MatchInstances', skip_nomatch=True),\n    dict(\n        type='VideoCollect',\n        keys=[\n            'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',\n            'gt_instance_ids'\n        ]),\n    dict(type='SeqDefaultFormatBundle', ref_prefix='ref')\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(1088, 1088),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(\n                type='Normalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\n                to_rgb=True),\n            dict(type='Pad', size_divisor=32),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='VideoCollect', keys=['img'])\n        ])\n]\ndata_root = 'data/MOT17/'\ndata = dict(\n    samples_per_gpu=2,\n    workers_per_gpu=2,\n    train=dict(\n        type='MOTChallengeDataset',\n        visibility_thr=-1,\n        ann_file='data/MOT17/annotations/half-train_cocoformat.json',\n        img_prefix='data/MOT17/train',\n        ref_img_sampler=dict(\n            num_ref_imgs=1,\n            frame_range=10,\n            filter_key_img=True,\n            method='uniform'),\n        pipeline=[\n            dict(type='LoadMultiImagesFromFile', to_float32=True),\n            dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),\n            dict(\n                type='SeqResize',\n                img_scale=(1088, 1088),\n                share_params=True,\n                ratio_range=(0.8, 1.2),\n                keep_ratio=True,\n                bbox_clip_border=False),\n            dict(type='SeqPhotoMetricDistortion', share_params=True),\n            dict(\n                type='SeqRandomCrop',\n                share_params=False,\n                crop_size=(1088, 1088),\n                bbox_clip_border=False),\n            dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),\n            dict(\n                type='SeqNormalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\n                to_rgb=True),\n            dict(type='SeqPad', size_divisor=32),\n            dict(type='MatchInstances', skip_nomatch=True),\n            dict(\n                type='VideoCollect',\n                keys=[\n                    'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',\n                    'gt_instance_ids'\n                ]),\n            dict(type='SeqDefaultFormatBundle', ref_prefix='ref')\n        ]),\n    val=dict(\n        type='MOTChallengeDataset',\n        ann_file='data/MOT17/annotations/half-val_cocoformat.json',\n        img_prefix='data/MOT17/train',\n        ref_img_sampler=None,\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(\n                type='MultiScaleFlipAug',\n                img_scale=(1088, 1088),\n                flip=False,\n                transforms=[\n                    dict(type='Resize', keep_ratio=True),\n                    dict(type='RandomFlip'),\n                    dict(\n                        type='Normalize',\n                        mean=[123.675, 116.28, 103.53],\n                        std=[58.395, 57.12, 57.375],\n                        to_rgb=True),\n                    dict(type='Pad', size_divisor=32),\n                    dict(type='ImageToTensor', keys=['img']),\n                    dict(type='VideoCollect', keys=['img'])\n                ])\n        ]),\n    test=dict(\n        type='MOTChallengeDataset',\n        ann_file='data/MOT17/annotations/half-val_cocoformat.json',\n        img_prefix='data/MOT17/train',\n        ref_img_sampler=None,\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(\n                type='MultiScaleFlipAug',\n                img_scale=(1088, 1088),\n                flip=False,\n                transforms=[\n                    dict(type='Resize', keep_ratio=True),\n                    dict(type='RandomFlip'),\n                    dict(\n                        type='Normalize',\n                        mean=[123.675, 116.28, 103.53],\n                        std=[58.395, 57.12, 57.375],\n                        to_rgb=True),\n                    dict(type='Pad', size_divisor=32),\n                    dict(type='ImageToTensor', keys=['img']),\n                    dict(type='VideoCollect', keys=['img'])\n                ])\n        ]))\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\noptimizer_config = dict(grad_clip=None)\ncheckpoint_config = dict(interval=1)\nlog_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=100,\n    warmup_ratio=0.01,\n    step=[3])\ntotal_epochs = 4\nevaluation = dict(metric=['bbox', 'track'], interval=1)\nsearch_metrics = ['MOTA', 'IDF1', 'FN', 'FP', 'IDs', 'MT', 'ML']\n"
  },
  {
    "path": "demo/mmtracking_cfg/tracktor_faster-rcnn_r50_fpn_4e_mot17-private.py",
    "content": "model = dict(\n    detector=dict(\n        type='FasterRCNN',\n        pretrained='torchvision://resnet50',\n        backbone=dict(\n            type='ResNet',\n            depth=50,\n            num_stages=4,\n            out_indices=(0, 1, 2, 3),\n            frozen_stages=1,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            norm_eval=True,\n            style='pytorch'),\n        neck=dict(\n            type='FPN',\n            in_channels=[256, 512, 1024, 2048],\n            out_channels=256,\n            num_outs=5),\n        rpn_head=dict(\n            type='RPNHead',\n            in_channels=256,\n            feat_channels=256,\n            anchor_generator=dict(\n                type='AnchorGenerator',\n                scales=[8],\n                ratios=[0.5, 1.0, 2.0],\n                strides=[4, 8, 16, 32, 64]),\n            bbox_coder=dict(\n                type='DeltaXYWHBBoxCoder',\n                target_means=[0.0, 0.0, 0.0, 0.0],\n                target_stds=[1.0, 1.0, 1.0, 1.0],\n                clip_border=False),\n            loss_cls=dict(\n                type='CrossEntropyLoss', use_sigmoid=True, loss_weight=1.0),\n            loss_bbox=dict(\n                type='SmoothL1Loss', beta=0.1111111111111111,\n                loss_weight=1.0)),\n        roi_head=dict(\n            type='StandardRoIHead',\n            bbox_roi_extractor=dict(\n                type='SingleRoIExtractor',\n                roi_layer=dict(\n                    type='RoIAlign', output_size=7, sampling_ratio=0),\n                out_channels=256,\n                featmap_strides=[4, 8, 16, 32]),\n            bbox_head=dict(\n                type='Shared2FCBBoxHead',\n                in_channels=256,\n                fc_out_channels=1024,\n                roi_feat_size=7,\n                num_classes=1,\n                bbox_coder=dict(\n                    type='DeltaXYWHBBoxCoder',\n                    target_means=[0.0, 0.0, 0.0, 0.0],\n                    target_stds=[0.1, 0.1, 0.2, 0.2],\n                    clip_border=False),\n                reg_class_agnostic=False,\n                loss_cls=dict(\n                    type='CrossEntropyLoss',\n                    use_sigmoid=False,\n                    loss_weight=1.0),\n                loss_bbox=dict(type='SmoothL1Loss', loss_weight=1.0))),\n        train_cfg=dict(\n            rpn=dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.7,\n                    neg_iou_thr=0.3,\n                    min_pos_iou=0.3,\n                    match_low_quality=True,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=256,\n                    pos_fraction=0.5,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=False),\n                allowed_border=-1,\n                pos_weight=-1,\n                debug=False),\n            rpn_proposal=dict(\n                nms_pre=2000,\n                max_per_img=1000,\n                nms=dict(type='nms', iou_threshold=0.7),\n                min_bbox_size=0),\n            rcnn=dict(\n                assigner=dict(\n                    type='MaxIoUAssigner',\n                    pos_iou_thr=0.5,\n                    neg_iou_thr=0.5,\n                    min_pos_iou=0.5,\n                    match_low_quality=False,\n                    ignore_iof_thr=-1),\n                sampler=dict(\n                    type='RandomSampler',\n                    num=512,\n                    pos_fraction=0.25,\n                    neg_pos_ub=-1,\n                    add_gt_as_proposals=True),\n                pos_weight=-1,\n                debug=False)),\n        test_cfg=dict(\n            rpn=dict(\n                nms_pre=1000,\n                max_per_img=1000,\n                nms=dict(type='nms', iou_threshold=0.7),\n                min_bbox_size=0),\n            rcnn=dict(\n                score_thr=0.05,\n                nms=dict(type='nms', iou_threshold=0.5),\n                max_per_img=100))),\n    type='Tracktor',\n    pretrains=dict(\n        detector='https://download.openmmlab.com/mmtracking/'\n        'mot/faster_rcnn/faster-rcnn_r50_fpn_4e_mot17-ffa52ae7.pth',\n        reid='https://download.openmmlab.com/mmtracking/mot/'\n        'reid/reid_r50_6e_mot17-4bf6b63d.pth'),\n    reid=dict(\n        type='BaseReID',\n        backbone=dict(\n            type='ResNet',\n            depth=50,\n            num_stages=4,\n            out_indices=(3, ),\n            style='pytorch'),\n        neck=dict(type='GlobalAveragePooling', kernel_size=(8, 4), stride=1),\n        head=dict(\n            type='LinearReIDHead',\n            num_fcs=1,\n            in_channels=2048,\n            fc_channels=1024,\n            out_channels=128,\n            num_classes=378,\n            loss=dict(type='CrossEntropyLoss', loss_weight=1.0),\n            loss_pairwise=dict(\n                type='TripletLoss', margin=0.3, loss_weight=1.0),\n            norm_cfg=dict(type='BN1d'),\n            act_cfg=dict(type='ReLU'))),\n    motion=dict(\n        type='CameraMotionCompensation',\n        warp_mode='cv2.MOTION_EUCLIDEAN',\n        num_iters=100,\n        stop_eps=1e-05),\n    tracker=dict(\n        type='TracktorTracker',\n        obj_score_thr=0.5,\n        regression=dict(\n            obj_score_thr=0.5,\n            nms=dict(type='nms', iou_threshold=0.6),\n            match_iou_thr=0.3),\n        reid=dict(\n            num_samples=10,\n            img_scale=(256, 128),\n            img_norm_cfg=None,\n            match_score_thr=2.0,\n            match_iou_thr=0.2),\n        momentums=None,\n        num_frames_retain=10))\ndataset_type = 'MOTChallengeDataset'\nimg_norm_cfg = dict(\n    mean=[123.675, 116.28, 103.53], std=[58.395, 57.12, 57.375], to_rgb=True)\ntrain_pipeline = [\n    dict(type='LoadMultiImagesFromFile', to_float32=True),\n    dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),\n    dict(\n        type='SeqResize',\n        img_scale=(1088, 1088),\n        share_params=True,\n        ratio_range=(0.8, 1.2),\n        keep_ratio=True,\n        bbox_clip_border=False),\n    dict(type='SeqPhotoMetricDistortion', share_params=True),\n    dict(\n        type='SeqRandomCrop',\n        share_params=False,\n        crop_size=(1088, 1088),\n        bbox_clip_border=False),\n    dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),\n    dict(\n        type='SeqNormalize',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        to_rgb=True),\n    dict(type='SeqPad', size_divisor=32),\n    dict(type='MatchInstances', skip_nomatch=True),\n    dict(\n        type='VideoCollect',\n        keys=[\n            'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',\n            'gt_instance_ids'\n        ]),\n    dict(type='SeqDefaultFormatBundle', ref_prefix='ref')\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='MultiScaleFlipAug',\n        img_scale=(1088, 1088),\n        flip=False,\n        transforms=[\n            dict(type='Resize', keep_ratio=True),\n            dict(type='RandomFlip'),\n            dict(\n                type='Normalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\n                to_rgb=True),\n            dict(type='Pad', size_divisor=32),\n            dict(type='ImageToTensor', keys=['img']),\n            dict(type='VideoCollect', keys=['img'])\n        ])\n]\ndata_root = 'data/MOT17/'\ndata = dict(\n    samples_per_gpu=2,\n    workers_per_gpu=2,\n    train=dict(\n        type='MOTChallengeDataset',\n        visibility_thr=-1,\n        ann_file='data/MOT17/annotations/train_cocoformat.json',\n        img_prefix='data/MOT17/train',\n        ref_img_sampler=dict(\n            num_ref_imgs=1,\n            frame_range=10,\n            filter_key_img=True,\n            method='uniform'),\n        pipeline=[\n            dict(type='LoadMultiImagesFromFile', to_float32=True),\n            dict(type='SeqLoadAnnotations', with_bbox=True, with_track=True),\n            dict(\n                type='SeqResize',\n                img_scale=(1088, 1088),\n                share_params=True,\n                ratio_range=(0.8, 1.2),\n                keep_ratio=True,\n                bbox_clip_border=False),\n            dict(type='SeqPhotoMetricDistortion', share_params=True),\n            dict(\n                type='SeqRandomCrop',\n                share_params=False,\n                crop_size=(1088, 1088),\n                bbox_clip_border=False),\n            dict(type='SeqRandomFlip', share_params=True, flip_ratio=0.5),\n            dict(\n                type='SeqNormalize',\n                mean=[123.675, 116.28, 103.53],\n                std=[58.395, 57.12, 57.375],\n                to_rgb=True),\n            dict(type='SeqPad', size_divisor=32),\n            dict(type='MatchInstances', skip_nomatch=True),\n            dict(\n                type='VideoCollect',\n                keys=[\n                    'img', 'gt_bboxes', 'gt_labels', 'gt_match_indices',\n                    'gt_instance_ids'\n                ]),\n            dict(type='SeqDefaultFormatBundle', ref_prefix='ref')\n        ]),\n    val=dict(\n        type='MOTChallengeDataset',\n        ann_file='data/MOT17/annotations/train_cocoformat.json',\n        img_prefix='data/MOT17/train',\n        ref_img_sampler=None,\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(\n                type='MultiScaleFlipAug',\n                img_scale=(1088, 1088),\n                flip=False,\n                transforms=[\n                    dict(type='Resize', keep_ratio=True),\n                    dict(type='RandomFlip'),\n                    dict(\n                        type='Normalize',\n                        mean=[123.675, 116.28, 103.53],\n                        std=[58.395, 57.12, 57.375],\n                        to_rgb=True),\n                    dict(type='Pad', size_divisor=32),\n                    dict(type='ImageToTensor', keys=['img']),\n                    dict(type='VideoCollect', keys=['img'])\n                ])\n        ]),\n    test=dict(\n        type='MOTChallengeDataset',\n        ann_file='data/MOT17/annotations/train_cocoformat.json',\n        img_prefix='data/MOT17/train',\n        ref_img_sampler=None,\n        pipeline=[\n            dict(type='LoadImageFromFile'),\n            dict(\n                type='MultiScaleFlipAug',\n                img_scale=(1088, 1088),\n                flip=False,\n                transforms=[\n                    dict(type='Resize', keep_ratio=True),\n                    dict(type='RandomFlip'),\n                    dict(\n                        type='Normalize',\n                        mean=[123.675, 116.28, 103.53],\n                        std=[58.395, 57.12, 57.375],\n                        to_rgb=True),\n                    dict(type='Pad', size_divisor=32),\n                    dict(type='ImageToTensor', keys=['img']),\n                    dict(type='VideoCollect', keys=['img'])\n                ])\n        ]))\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\noptimizer_config = dict(grad_clip=None)\ncheckpoint_config = dict(interval=1)\nlog_config = dict(interval=50, hooks=[dict(type='TextLoggerHook')])\ndist_params = dict(backend='nccl')\nlog_level = 'INFO'\nload_from = None\nresume_from = None\nworkflow = [('train', 1)]\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=100,\n    warmup_ratio=0.01,\n    step=[3])\ntotal_epochs = 4\nevaluation = dict(metric=['bbox', 'track'], interval=1)\nsearch_metrics = ['MOTA', 'IDF1', 'FN', 'FP', 'IDs', 'MT', 'ML']\ntest_set = 'train'\n"
  },
  {
    "path": "demo/topdown_demo_with_mmdet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nimport mimetypes\nimport os\nimport time\nfrom argparse import ArgumentParser\n\nimport cv2\nimport json_tricks as json\nimport mmcv\nimport mmengine\nimport numpy as np\nfrom mmengine.logging import print_log\n\nfrom mmpose.apis import inference_topdown\nfrom mmpose.apis import init_model as init_pose_estimator\nfrom mmpose.evaluation.functional import nms\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import merge_data_samples, split_instances\nfrom mmpose.utils import adapt_mmdet_pipeline\n\ntry:\n    from mmdet.apis import inference_detector, init_detector\n    has_mmdet = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmdet = False\n\n\ndef process_one_image(args,\n                      img,\n                      detector,\n                      pose_estimator,\n                      visualizer=None,\n                      show_interval=0):\n    \"\"\"Visualize predicted keypoints (and heatmaps) of one image.\"\"\"\n\n    # predict bbox\n    det_result = inference_detector(detector, img)\n    pred_instance = det_result.pred_instances.cpu().numpy()\n    bboxes = np.concatenate(\n        (pred_instance.bboxes, pred_instance.scores[:, None]), axis=1)\n    bboxes = bboxes[np.logical_and(pred_instance.labels == args.det_cat_id,\n                                   pred_instance.scores > args.bbox_thr)]\n    bboxes = bboxes[nms(bboxes, args.nms_thr), :4]\n\n    # predict keypoints\n    pose_results = inference_topdown(pose_estimator, img, bboxes)\n    data_samples = merge_data_samples(pose_results)\n\n    # show the results\n    if isinstance(img, str):\n        img = mmcv.imread(img, channel_order='rgb')\n    elif isinstance(img, np.ndarray):\n        img = mmcv.bgr2rgb(img)\n\n    if visualizer is not None:\n        visualizer.add_datasample(\n            'result',\n            img,\n            data_sample=data_samples,\n            draw_gt=False,\n            draw_heatmap=args.draw_heatmap,\n            draw_bbox=args.draw_bbox,\n            show_kpt_idx=args.show_kpt_idx,\n            skeleton_style=args.skeleton_style,\n            show=args.show,\n            wait_time=show_interval,\n            kpt_thr=args.kpt_thr)\n\n    # if there is no instance detected, return None\n    return data_samples.get('pred_instances', None)\n\n\ndef main():\n    \"\"\"Visualize the demo images.\n\n    Using mmdet to detect the human.\n    \"\"\"\n    parser = ArgumentParser()\n    parser.add_argument('det_config', help='Config file for detection')\n    parser.add_argument('det_checkpoint', help='Checkpoint file for detection')\n    parser.add_argument('pose_config', help='Config file for pose')\n    parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')\n    parser.add_argument(\n        '--input', type=str, default='', help='Image/Video file')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='whether to show img')\n    parser.add_argument(\n        '--output-root',\n        type=str,\n        default='',\n        help='root of the output img file. '\n        'Default not saving the visualization images.')\n    parser.add_argument(\n        '--save-predictions',\n        action='store_true',\n        default=False,\n        help='whether to save predicted results')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--det-cat-id',\n        type=int,\n        default=0,\n        help='Category id for bounding box detection model')\n    parser.add_argument(\n        '--bbox-thr',\n        type=float,\n        default=0.3,\n        help='Bounding box score threshold')\n    parser.add_argument(\n        '--nms-thr',\n        type=float,\n        default=0.3,\n        help='IoU threshold for bounding box NMS')\n    parser.add_argument(\n        '--kpt-thr',\n        type=float,\n        default=0.3,\n        help='Visualizing keypoint thresholds')\n    parser.add_argument(\n        '--draw-heatmap',\n        action='store_true',\n        default=False,\n        help='Draw heatmap predicted by the model')\n    parser.add_argument(\n        '--show-kpt-idx',\n        action='store_true',\n        default=False,\n        help='Whether to show the index of keypoints')\n    parser.add_argument(\n        '--skeleton-style',\n        default='mmpose',\n        type=str,\n        choices=['mmpose', 'openpose'],\n        help='Skeleton style selection')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization')\n    parser.add_argument(\n        '--show-interval', type=int, default=0, help='Sleep seconds per frame')\n    parser.add_argument(\n        '--alpha', type=float, default=0.8, help='The transparency of bboxes')\n    parser.add_argument(\n        '--draw-bbox', action='store_true', help='Draw bboxes of instances')\n\n    assert has_mmdet, 'Please install mmdet to run the demo.'\n\n    args = parser.parse_args()\n\n    assert args.show or (args.output_root != '')\n    assert args.input != ''\n    assert args.det_config is not None\n    assert args.det_checkpoint is not None\n\n    output_file = None\n    if args.output_root:\n        mmengine.mkdir_or_exist(args.output_root)\n        output_file = os.path.join(args.output_root,\n                                   os.path.basename(args.input))\n        if args.input == 'webcam':\n            output_file += '.mp4'\n\n    if args.save_predictions:\n        assert args.output_root != ''\n        args.pred_save_path = f'{args.output_root}/results_' \\\n            f'{os.path.splitext(os.path.basename(args.input))[0]}.json'\n\n    # build detector\n    detector = init_detector(\n        args.det_config, args.det_checkpoint, device=args.device)\n    detector.cfg = adapt_mmdet_pipeline(detector.cfg)\n\n    # build pose estimator\n    pose_estimator = init_pose_estimator(\n        args.pose_config,\n        args.pose_checkpoint,\n        device=args.device,\n        cfg_options=dict(\n            model=dict(test_cfg=dict(output_heatmaps=args.draw_heatmap))))\n\n    # build visualizer\n    pose_estimator.cfg.visualizer.radius = args.radius\n    pose_estimator.cfg.visualizer.alpha = args.alpha\n    pose_estimator.cfg.visualizer.line_width = args.thickness\n    visualizer = VISUALIZERS.build(pose_estimator.cfg.visualizer)\n    # the dataset_meta is loaded from the checkpoint and\n    # then pass to the model in init_pose_estimator\n    visualizer.set_dataset_meta(\n        pose_estimator.dataset_meta, skeleton_style=args.skeleton_style)\n\n    if args.input == 'webcam':\n        input_type = 'webcam'\n    else:\n        input_type = mimetypes.guess_type(args.input)[0].split('/')[0]\n\n    if input_type == 'image':\n\n        # inference\n        pred_instances = process_one_image(args, args.input, detector,\n                                           pose_estimator, visualizer)\n\n        if args.save_predictions:\n            pred_instances_list = split_instances(pred_instances)\n\n        if output_file:\n            img_vis = visualizer.get_image()\n            mmcv.imwrite(mmcv.rgb2bgr(img_vis), output_file)\n\n    elif input_type in ['webcam', 'video']:\n\n        if args.input == 'webcam':\n            cap = cv2.VideoCapture(0)\n        else:\n            cap = cv2.VideoCapture(args.input)\n\n        video_writer = None\n        pred_instances_list = []\n        frame_idx = 0\n\n        while cap.isOpened():\n            success, frame = cap.read()\n            frame_idx += 1\n\n            if not success:\n                break\n\n            # topdown pose estimation\n            pred_instances = process_one_image(args, frame, detector,\n                                               pose_estimator, visualizer,\n                                               0.001)\n\n            if args.save_predictions:\n                # save prediction results\n                pred_instances_list.append(\n                    dict(\n                        frame_id=frame_idx,\n                        instances=split_instances(pred_instances)))\n\n            # output videos\n            if output_file:\n                frame_vis = visualizer.get_image()\n\n                if video_writer is None:\n                    fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n                    # the size of the image with visualization may vary\n                    # depending on the presence of heatmaps\n                    video_writer = cv2.VideoWriter(\n                        output_file,\n                        fourcc,\n                        25,  # saved fps\n                        (frame_vis.shape[1], frame_vis.shape[0]))\n\n                video_writer.write(mmcv.rgb2bgr(frame_vis))\n\n            if args.show:\n                # press ESC to exit\n                if cv2.waitKey(5) & 0xFF == 27:\n                    break\n\n                time.sleep(args.show_interval)\n\n        if video_writer:\n            video_writer.release()\n\n        cap.release()\n\n    else:\n        args.save_predictions = False\n        raise ValueError(\n            f'file {os.path.basename(args.input)} has invalid format.')\n\n    if args.save_predictions:\n        with open(args.pred_save_path, 'w') as f:\n            json.dump(\n                dict(\n                    meta_info=pose_estimator.dataset_meta,\n                    instance_info=pred_instances_list),\n                f,\n                indent='\\t')\n        print(f'predictions have been saved at {args.pred_save_path}')\n\n    if output_file:\n        input_type = input_type.replace('webcam', 'video')\n        print_log(\n            f'the output {input_type} has been saved at {output_file}',\n            logger='current',\n            level=logging.INFO)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "docker/Dockerfile",
    "content": "ARG PYTORCH=\"1.8.1\"\nARG CUDA=\"10.2\"\nARG CUDNN=\"7\"\n\nFROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel\n\nENV TORCH_CUDA_ARCH_LIST=\"6.0 6.1 7.0+PTX\"\nENV TORCH_NVCC_FLAGS=\"-Xfatbin -compress-all\"\nENV CMAKE_PREFIX_PATH=\"$(dirname $(which conda))/../\"\n\n# To fix GPG key error when running apt-get update\nRUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/cuda/repos/ubuntu1804/x86_64/3bf863cc.pub\nRUN apt-key adv --fetch-keys https://developer.download.nvidia.com/compute/machine-learning/repos/ubuntu1804/x86_64/7fa2af80.pub\n\nRUN apt-get update && apt-get install -y git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 libgl1-mesa-glx\\\n    && apt-get clean \\\n    && rm -rf /var/lib/apt/lists/*\n\n# Install xtcocotools\nRUN pip install cython\nRUN pip install xtcocotools\n\n# Install MMEngine and MMCV\nRUN pip install openmim\nRUN mim install mmengine \"mmcv>=2.0.0\"\n\n# Install MMPose\nRUN conda clean --all\nRUN git clone https://github.com/open-mmlab/mmpose.git /mmpose\nWORKDIR /mmpose\nRUN git checkout main\nENV FORCE_CUDA=\"1\"\nRUN pip install -r requirements/build.txt\nRUN pip install --no-cache-dir -e .\n"
  },
  {
    "path": "docker/serve/Dockerfile",
    "content": "ARG PYTORCH=\"1.8.1\"\nARG CUDA=\"10.2\"\nARG CUDNN=\"7\"\nFROM pytorch/pytorch:${PYTORCH}-cuda${CUDA}-cudnn${CUDNN}-devel\n\nARG MMCV=\"2.0.0rc4\"\nARG MMPOSE=\"1.3.2\"\n\nENV PYTHONUNBUFFERED TRUE\n\nRUN apt-get update && \\\n    DEBIAN_FRONTEND=noninteractive apt-get install --no-install-recommends -y \\\n    ca-certificates \\\n    g++ \\\n    openjdk-11-jre-headless \\\n    # MMDet Requirements\n    ffmpeg libsm6 libxext6 git ninja-build libglib2.0-0 libsm6 libxrender-dev libxext6 \\\n    && rm -rf /var/lib/apt/lists/*\n\nENV PATH=\"/opt/conda/bin:$PATH\"\nRUN export FORCE_CUDA=1\n\n\n# MMLAB\nARG PYTORCH\nARG CUDA\nRUN pip install mmengine\nRUN [\"/bin/bash\", \"-c\", \"pip install mmcv==${MMCV}} -f https://download.openmmlab.com/mmcv/dist/cu${CUDA//./}/torch${PYTORCH}/index.html\"]\nRUN pip install mmpose==${MMPOSE}\n\n# TORCHSEVER\nRUN pip install torchserve torch-model-archiver\n\nRUN useradd -m model-server \\\n    && mkdir -p /home/model-server/tmp\n\nCOPY entrypoint.sh /usr/local/bin/entrypoint.sh\n\nRUN chmod +x /usr/local/bin/entrypoint.sh \\\n    && chown -R model-server /home/model-server\n\nCOPY config.properties /home/model-server/config.properties\nRUN mkdir /home/model-server/model-store && chown -R model-server /home/model-server/model-store\n\nEXPOSE 8080 8081 8082\n\nUSER model-server\nWORKDIR /home/model-server\nENV TEMP=/home/model-server/tmp\nENTRYPOINT [\"/usr/local/bin/entrypoint.sh\"]\nCMD [\"serve\"]\n"
  },
  {
    "path": "docker/serve/config.properties",
    "content": "inference_address=http://0.0.0.0:8080\nmanagement_address=http://0.0.0.0:8081\nmetrics_address=http://0.0.0.0:8082\nmodel_store=/home/model-server/model-store\nload_models=all\n"
  },
  {
    "path": "docker/serve/entrypoint.sh",
    "content": "#!/bin/bash\nset -e\n\nif [[ \"$1\" = \"serve\" ]]; then\n    shift 1\n    torchserve --start --ts-config /home/model-server/config.properties\nelse\n    eval \"$@\"\nfi\n\n# prevent docker exit\ntail -f /dev/null\n"
  },
  {
    "path": "docs/en/.readthedocs.yaml",
    "content": "version: 2\n\nformats:\n  - epub\n\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.8\"\n\nsphinx:\n  configuration: docs/en/conf.py\n\npython:\n  install:\n    - requirements: requirements/docs.txt\n    - requirements: requirements/readthedocs.txt\n"
  },
  {
    "path": "docs/en/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs/en/_static/css/readthedocs.css",
    "content": ".header-logo {\n    background-image: url(\"../images/mmpose-logo.png\");\n    background-size: 120px 50px;\n    height: 50px;\n    width: 120px;\n}\n\ntable.autosummary td {\n    width: 35%\n}\n"
  },
  {
    "path": "docs/en/advanced_guides/codecs.md",
    "content": "# Learn about Codecs\n\nIn the keypoint detection task, depending on the algorithm, it is often necessary to generate targets in different formats, such as normalized coordinates, vectors and heatmaps, etc. Similarly, for the model outputs, a decoding process is required to transform them into coordinates.\n\nEncoding and decoding are closely related and inverse each other. In earlier versions of MMPose, encoding and decoding are implemented at different modules, making it less intuitive and unified.\n\nMMPose 1.0 introduced a new module **Codec** to integrate the encoding and decoding together in a modular and user-friendly form.\n\nHere is a diagram to show where the `Codec` is:\n\n![pose_estimator_en](https://github.com/open-mmlab/mmpose/assets/13503330/0764baab-41c7-4a1d-ab64-5d7f9dfc8eec)\n\n## Basic Concepts\n\nA typical codec consists of two parts:\n\n- Encoder\n- Decoder\n\n### Encoder\n\nThe encoder transforms the coordinates in the input image space into the needed target format:\n\n- Normalized Coordinates\n- One-dimensional Vectors\n- Gaussian Heatmaps\n\nFor example, in the Regression-based method, the encoder will be:\n\n```Python\ndef encode(self,\n           keypoints: np.ndarray,\n           keypoints_visible: Optional[np.ndarray] = None) -> dict:\n    \"\"\"Encoding keypoints from input image space to normalized space.\n\n    Args:\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n\n    Returns:\n        dict:\n        - keypoint_labels (np.ndarray): The normalized regression labels in\n            shape (N, K, D) where D is 2 for 2d coordinates\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (N, K)\n    \"\"\"\n    if keypoints_visible is None:\n        keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n    w, h = self.input_size\n    valid = ((keypoints >= 0) &\n             (keypoints <= [w - 1, h - 1])).all(axis=-1) & (\n                 keypoints_visible > 0.5)\n\n    keypoint_labels = (keypoints / np.array([w, h])).astype(np.float32)\n    keypoint_weights = np.where(valid, 1., 0.).astype(np.float32)\n\n    encoded = dict(\n        keypoint_labels=keypoint_labels, keypoint_weights=keypoint_weights)\n\n    return encoded\n```\n\nThe encoded data is converted to Tensor format in `PackPoseInputs` and packed in `data_sample.gt_instance_labels` for model calls. By default it will consist of the following encoded fields:\n\n- `keypoint_labels`\n- `keypoint_weights`\n- `keypoints_visible_weights`\n\nTo specify data fields to be packed, you can define the `label_mapping_table` attribute in the codec. For example, in `VideoPoseLifting`:\n\n```Python\nlabel_mapping_table = dict(\n        trajectory_weights='trajectory_weights',\n        lifting_target_label='lifting_target_label',\n        lifting_target_weight='lifting_target_weight',\n)\n```\n\n`data_sample.gt_instance_labels` are generally used for loss calculation, as demonstrated by `loss()` in `RegressionHead`.\n\n```Python\ndef loss(self,\n         inputs: Tuple[Tensor],\n         batch_data_samples: OptSampleList,\n         train_cfg: ConfigType = {}) -> dict:\n    \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n    pred_outputs = self.forward(inputs)\n\n    keypoint_labels = torch.cat(\n        [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n    keypoint_weights = torch.cat([\n        d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n    ])\n\n    # calculate losses\n    losses = dict()\n    loss = self.loss_module(pred_outputs, keypoint_labels,\n                            keypoint_weights.unsqueeze(-1))\n\n    losses.update(loss_kpt=loss)\n    ### Omitted ###\n```\n\n```{note}\nEncoder also defines data to be packed in `data_sample.gt_instances` and `data_sample.gt_fields`. Modify `instance_mapping_table` and `field_mapping_table` in the codec will specify values to be packed respectively. For default values, please check [BaseKeypointCodec](https://github.com/open-mmlab/mmpose/blob/main/mmpose/codecs/base.py).\n```\n\n### Decoder\n\nThe decoder transforms the model outputs into coordinates in the input image space, which is the opposite processing of the encoder.\n\nFor example, in the Regression-based method, the decoder will be:\n\n```Python\ndef decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Decode keypoint coordinates from normalized space to input image\n    space.\n\n    Args:\n        encoded (np.ndarray): Coordinates in shape (N, K, D)\n\n    Returns:\n        tuple:\n        - keypoints (np.ndarray): Decoded coordinates in shape (N, K, D)\n        - scores (np.ndarray): The keypoint scores in shape (N, K).\n            It usually represents the confidence of the keypoint prediction\n\n    \"\"\"\n\n    if encoded.shape[-1] == 2:\n        N, K, _ = encoded.shape\n        normalized_coords = encoded.copy()\n        scores = np.ones((N, K), dtype=np.float32)\n    elif encoded.shape[-1] == 4:\n        # split coords and sigma if outputs contain output_sigma\n        normalized_coords = encoded[..., :2].copy()\n        output_sigma = encoded[..., 2:4].copy()\n        scores = (1 - output_sigma).mean(axis=-1)\n    else:\n        raise ValueError(\n            'Keypoint dimension should be 2 or 4 (with sigma), '\n            f'but got {encoded.shape[-1]}')\n\n    w, h = self.input_size\n    keypoints = normalized_coords * np.array([w, h])\n\n    return keypoints, scores\n```\n\nBy default, the `decode()` method only performs decoding on a single instance. You can also implement the `batch_decode()` method to boost the decoding process.\n\n## Common Usage\n\nThe example below shows how to use a codec in your config:\n\n- Define the Codec\n- Generate Targets\n- Head\n\n### Define the Codec\n\nTake the Regression-based method to generate normalized coordinates as an example, you can define a `codec` in your config as follows:\n\n```Python\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n```\n\n### Generate Targets\n\nIn pipelines, A codec should be passed into `GenerateTarget` to work as the `encoder`:\n\n```Python\ndict(type='GenerateTarget', encoder=codec)\n```\n\n### Head\n\nIn MMPose workflows, we decode the model outputs in `Head`, which requires a codec to work as the `decoder`:\n\n```Python\nhead=dict(\n    type='RLEHead',\n    in_channels=2048,\n    num_joints=17,\n    loss=dict(type='RLELoss', use_target_weight=True),\n    decoder=codec\n)\n```\n\nHere is the phase of a config file:\n\n```Python\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))                     ## definition ##\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),                                                         ## Head ##\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),   ## Generate Target ##\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n```\n\n## Supported Codecs\n\nSupported codecs are in [$MMPOSE/mmpose/codecs/](https://github.com/open-mmlab/mmpose/tree/dev-1.x/mmpose/codecs). Here is a list:\n\n- [RegressionLabel](#RegressionLabel)\n- [IntegralRegressionLabel](#IntegralRegressionLabel)\n- [MSRAHeatmap](#MSRAHeatmap)\n- [UDPHeatmap](#UDPHeatmap)\n- [MegviiHeatmap](#MegviiHeatmap)\n- [SPR](#SPR)\n- [SimCC](#SimCC)\n- [DecoupledHeatmap](#DecoupledHeatmap)\n- [ImagePoseLifting](#ImagePoseLifting)\n- [VideoPoseLifting](#VideoPoseLifting)\n- [MotionBERTLabel](#MotionBERTLabel)\n\n### RegressionLabel\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/regression_label.py#L12)\n\nThe `RegressionLabel` codec is used to generate normalized coordinates as the regression targets.\n\n**Input**\n\n- Encoding keypoints from input image space to normalized space.\n\n**Output**\n\n- Decoding normalized coordinates from normalized space to input image space.\n\nRelated works:\n\n- [DeepPose](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#deeppose-cvpr-2014)\n- [RLE](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#rle-iccv-2021)\n\n### IntegralRegressionLabel\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/integral_regression_label.py)\n\nThe `IntegralRegressionLabel` codec is used to generate normalized coordinates as the regression targets.\n\n**Input**\n\n- Encoding keypoints from input image space to normalized space, and generate Gaussian heatmaps as well.\n\n**Output**\n\n- Decoding normalized coordinates from normalized space to input image space.\n\nRelated works:\n\n- [IPR](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#ipr-eccv-2018)\n- [DSNT](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#dsnt-2018)\n- [Debias IPR](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#debias-ipr-iccv-2021)\n\n### MSRAHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/msra_heatmap.py)\n\nThe `MSRAHeatmap` codec is used to generate Gaussian heatmaps as the targets.\n\n**Input**\n\n- Encoding keypoints from input image space to output space as 2D Gaussian heatmaps.\n\n**Output**\n\n- Decoding 2D Gaussian heatmaps from output space to input image space as coordinates.\n\nRelated works:\n\n- [SimpleBaseline2D](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#simplebaseline2d-eccv-2018)\n- [CPM](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#cpm-cvpr-2016)\n- [HRNet](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#hrnet-cvpr-2019)\n- [DARK](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#darkpose-cvpr-2020)\n\n### UDPHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/udp_heatmap.py)\n\nThe `UDPHeatmap` codec is used to generate Gaussian heatmaps as the targets.\n\n**Input**\n\n- Encoding keypoints from input image space to output space as 2D Gaussian heatmaps.\n\n**Output**\n\n- Decoding 2D Gaussian heatmaps from output space to input image space as coordinates.\n\nRelated works:\n\n- [UDP](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#udp-cvpr-2020)\n\n### MegviiHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/megvii_heatmap.py)\n\nThe `MegviiHeatmap` codec is used to generate Gaussian heatmaps as the targets, which is usually used in Megvii's works.\n\n**Input**\n\n- Encoding keypoints from input image space to output space as 2D Gaussian heatmaps.\n\n**Output**\n\n- Decoding 2D Gaussian heatmaps from output space to input image space as coordinates.\n\nRelated works:\n\n- [MSPN](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#mspn-arxiv-2019)\n- [RSN](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#rsn-eccv-2020)\n\n### SPR\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/spr.py)\n\nThe `SPR` codec is used to generate Gaussian heatmaps of instances' center, and offsets as the targets.\n\n**Input**\n\n- Encoding keypoints from input image space to output space as 2D Gaussian heatmaps and offsets.\n\n**Output**\n\n- Decoding 2D Gaussian heatmaps and offsets from output space to input image space as coordinates.\n\nRelated works:\n\n- [DEKR](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#dekr-cvpr-2021)\n\n### SimCC\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/simcc_label.py)\n\nThe `SimCC` codec is used to generate 1D Gaussian representations as the targets.\n\n**Input**\n\n- Encoding keypoints from input image space to output space as 1D Gaussian representations.\n\n**Output**\n\n- Decoding 1D Gaussian representations from output space to input image space as coordinates.\n\nRelated works:\n\n- [SimCC](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#simcc-eccv-2022)\n- [RTMPose](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#rtmpose-arxiv-2023)\n\n### DecoupledHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/decoupled_heatmap.py)\n\nThe `DecoupledHeatmap` codec is used to generate Gaussian heatmaps as the targets.\n\n**Input**\n\n- Encoding human center points and keypoints from input image space to output space as 2D Gaussian heatmaps.\n\n**Output**\n\n- Decoding 2D Gaussian heatmaps from output space to input image space as coordinates.\n\nRelated works:\n\n- [CID](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#cid-cvpr-2022)\n\n### ImagePoseLifting\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/image_pose_lifting.py)\n\nThe `ImagePoseLifting` codec is used for image 2D-to-3D pose lifting.\n\n**Input**\n\n- Encoding 2d keypoints from input image space to normalized 3d space.\n\n**Output**\n\n- Decoding 3d keypoints from normalized space to input image space.\n\nRelated works:\n\n- [SimpleBaseline3D](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#simplebaseline3d-iccv-2017)\n\n### VideoPoseLifting\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/video_pose_lifting.py)\n\nThe `VideoPoseLifting` codec is used for video 2D-to-3D pose lifting.\n\n**Input**\n\n- Encoding 2d keypoints from input image space to normalized 3d space.\n\n**Output**\n\n- Decoding 3d keypoints from normalized space to input image space.\n\nRelated works:\n\n- [VideoPose3D](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#videopose3d-cvpr-2019)\n\n### MotionBERTLabel\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/motionbert_label.py)\n\nThe `MotionBERTLabel` codec is used for video 2D-to-3D pose lifting.\n\n**Input**\n\n- Encoding 2d keypoints from input image space to normalized 3d space.\n\n**Output**\n\n- Decoding 3d keypoints from normalized space to input image space.\n\nRelated works:\n\n- [MotionBERT](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo/body_3d_keypoint.html#pose-lift-motionbert-on-h36m)\n"
  },
  {
    "path": "docs/en/advanced_guides/customize_datasets.md",
    "content": "# Customize Datasets\n\n## Customize datasets by reorganizing data to COCO format\n\nThe simplest way to use the custom dataset is to convert your annotation format to COCO dataset format.\n\nThe annotation JSON files in COCO format have the following necessary keys:\n\n```python\n'images': [\n    {\n        'file_name': '000000001268.jpg',\n        'height': 427,\n        'width': 640,\n        'id': 1268\n    },\n    ...\n],\n'annotations': [\n    {\n        'segmentation': [[426.36,\n            ...\n            424.34,\n            223.3]],\n        'keypoints': [0,0,0,\n            0,0,0,\n            0,0,0,\n            427,220,2,\n            443,222,2,\n            414,228,2,\n            449,232,2,\n            408,248,1,\n            454,261,2,\n            0,0,0,\n            0,0,0,\n            411,287,2,\n            431,287,2,\n            0,0,0,\n            458,265,2,\n            0,0,0,\n            466,300,1],\n        'num_keypoints': 10,\n        'area': 3894.5826,\n        'iscrowd': 0,\n        'image_id': 1268,\n        'bbox': [402.34, 205.02, 65.26, 88.45],\n        'category_id': 1,\n        'id': 215218\n    },\n    ...\n],\n'categories': [\n    {'id': 1, 'name': 'person'},\n ]\n```\n\nThere are three necessary keys in the json file:\n\n- `images`: contains a list of images with their information like `file_name`, `height`, `width`, and `id`.\n- `annotations`: contains the list of instance annotations.\n- `categories`: contains the category name ('person') and its ID (1).\n\nIf the annotations have been organized in COCO format, there is no need to create a new dataset class. You can use `CocoDataset` class alternatively.\n\n## Create a custom dataset_info config file for the dataset\n\nAdd a new dataset info config file that contains the metainfo about the dataset.\n\n```\nconfigs/_base_/datasets/custom.py\n```\n\nAn example of the dataset config is as follows.\n\n- `keypoint_info` contains the information about each keypoint.\n  1. `name`: the keypoint name. The keypoint name must be unique.\n  2. `id`: the keypoint id.\n  3. `color`: (\\[B, G, R\\]) is used for keypoint visualization.\n  4. `type`: 'upper' or 'lower', will be used in data augmentation [RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py#L263).\n  5. `swap`: indicates the 'swap pair' (also known as 'flip pair'). When applying image horizontal flip, the left part will become the right part, used in data augmentation [RandomFlip](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py#L94). We need to flip the keypoints accordingly.\n- `skeleton_info` contains information about the keypoint connectivity, which is used for visualization.\n- `joint_weights` assigns different loss weights to different keypoints.\n- `sigmas` is used to calculate the OKS score. You can read [keypoints-eval](https://cocodataset.org/#keypoints-eval) to learn more about it.\n\nHere is an simplified example of dataset_info config file ([full text](/configs/_base_/datasets/coco.py)).\n\n```\ndataset_info = dict(\n    dataset_name='coco',\n    paper_info=dict(\n        author='Lin, Tsung-Yi and Maire, Michael and '\n        'Belongie, Serge and Hays, James and '\n        'Perona, Pietro and Ramanan, Deva and '\n        r'Doll{\\'a}r, Piotr and Zitnick, C Lawrence',\n        title='Microsoft coco: Common objects in context',\n        container='European conference on computer vision',\n        year='2014',\n        homepage='http://cocodataset.org/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        ...\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        ...\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n```\n\n## Create a custom dataset class\n\nIf the annotations are not organized in COCO format, you need to create a custom dataset class by the following steps:\n\n1. First create a package inside the `mmpose/datasets/datasets` folder.\n\n2. Create a class definition of your dataset in the package folder and register it in the registry with a name. Without a name, it will keep giving the error. `KeyError: 'XXXXX is not in the dataset registry'`\n\n   ```\n   from mmengine.dataset import BaseDataset\n   from mmpose.registry import DATASETS\n\n   @DATASETS.register_module(name='MyCustomDataset')\n   class MyCustomDataset(BaseDataset):\n   ```\n\n   You can refer to [this doc](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html) on how to build customed dataset class with `mmengine.BaseDataset`.\n\n3. Make sure you have updated the `__init__.py` of your package folder\n\n4. Make sure you have updated the `__init__.py` of the dataset package folder.\n\n## Create a custom training config file\n\nCreate a custom training config file as per your need and the model/architecture you want to use in the configs folder. You may modify an existing config file to use the new custom dataset.\n\nIn `configs/my_custom_config.py`:\n\n```python\n...\n# dataset and dataloader settings\ndataset_type = 'MyCustomDataset' # or 'CocoDataset'\n\ntrain_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # ann file is stored at {data_root}/{ann_file}\n        # e.g. aaa/annotations/xxx.json\n        ann_file='annotations/xxx.json',\n        # img is stored at {data_root}/{img}/\n        # e.g. aaa/train/c.jpg\n        data_prefix=dict(img='train'),\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n\nval_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # ann file is stored at {data_root}/{ann_file}\n        # e.g. aaa/annotations/yyy.json\n        ann_file='annotations/yyy.json',\n        # img is stored at {data_root}/{img}/\n        # e.g. aaa/val/c.jpg\n        data_prefix=dict(img='val'),\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n\ntest_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # ann file is stored at {data_root}/{ann_file}\n        # e.g. aaa/annotations/zzz.json\n        ann_file='annotations/zzz.json',\n        # img is stored at {data_root}/{img}/\n        # e.g. aaa/test/c.jpg\n        data_prefix=dict(img='test'),\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n...\n```\n\nMake sure you have provided all the paths correctly.\n\n## Dataset Wrappers\n\nThe following dataset wrappers are supported in [MMEngine](https://github.com/open-mmlab/mmengine), you can refer to [MMEngine tutorial](https://mmengine.readthedocs.io/en/latest) to learn how to use it.\n\n- [ConcatDataset](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html#concatdataset)\n- [RepeatDataset](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html#repeatdataset)\n\n### CombinedDataset\n\nMMPose provides [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) to combine multiple datasets with different annotations. A combined dataset can be defined in config files as:\n\n```python\ndataset_1 = dict(\n    type='dataset_type_1',\n    data_root='aaa',\n    # ann file is stored at {data_root}/{ann_file}\n    # e.g. aaa/annotations/train.json\n    data_prefix=dict(img_path='train'),\n    # img is stored at {data_root}/{img}/\n    # e.g. aaa/train/c.jpg\n    ann_file='annotations/train.json',\n    pipeline=[\n        # the converter transforms convert data into a unified format\n        converter_transform_1\n    ])\n\ndataset_2 = dict(\n    type='dataset_type_2',\n    data_root='bbb',\n    # ann file is stored at {data_root}/{ann_file}\n    # e.g. bbb/annotations/train.json\n    data_prefix=dict(img_path='train'),\n    # img is stored at {data_root}/{img}/\n    # e.g. bbb/train/c.jpg\n    ann_file='annotations/train.json',\n    pipeline=[\n        converter_transform_2\n    ])\n\nshared_pipeline = [\n    LoadImage(),\n    ParseImage(),\n]\n\ncombined_dataset = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='path/to/your/metainfo'),\n    datasets=[dataset_1, dataset_2],\n    pipeline=shared_pipeline,\n)\n```\n\n- **MetaInfo of combined dataset** determines the annotation format. Either metainfo of a sub-dataset or a customed dataset metainfo is valid here. To custom a dataset metainfo, please refer to [Create a custom dataset_info config file for the dataset](#create-a-custom-datasetinfo-config-file-for-the-dataset).\n\n- **Converter transforms of sub-datasets** are applied when there exist mismatches of annotation format between sub-datasets and the combined dataset. For example, the number and order of keypoints might be different in the combined dataset and the sub-datasets. Then [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11) can be used to unify the keypoints number and order.\n\n- More details about [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) and [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11) can be found in [Advanced Guides - Training with Mixed Datasets](../user_guides/mixed_datasets.md).\n"
  },
  {
    "path": "docs/en/advanced_guides/customize_evaluation.md",
    "content": "# Customize Evaluation\n\nComing soon.\n\nCurrently, you can refer to [Evaluation Tutorial of MMEngine](https://mmengine.readthedocs.io/en/latest/tutorials/evaluation.html) to customize your own evaluation.\n"
  },
  {
    "path": "docs/en/advanced_guides/customize_logging.md",
    "content": "# Customize Logging\n\nComing soon.\n"
  },
  {
    "path": "docs/en/advanced_guides/customize_optimizer.md",
    "content": "# Customize Optimizer and Scheduler\n\nComing soon.\n"
  },
  {
    "path": "docs/en/advanced_guides/customize_transforms.md",
    "content": "# Customize Data Transformation and Augmentation\n\n## DATA TRANSFORM\n\nIn the OpenMMLab algorithm library, the construction of the dataset and the preparation of the data are decoupled from each other. Usually, the construction of the dataset only analyzes the dataset and records the basic information of each sample, while the preparation of the data is through a series of According to the basic information of the sample, perform data loading, preprocessing, formatting and other operations.\n\n### The use of data transformation\n\nThe **data transformation** and **data augmentation** classes in **MMPose** are defined in the [$MMPose/datasets/transforms](https://github.com/open-mmlab/mmpose/tree/dev-1.x/mmpose/datasets/transforms) directory, and the corresponding file structure is as follows:\n\n```txt\nmmpose\n|----datasets\n    |----transforms\n        |----bottomup_transforms    # Button-Up transforms\n        |----common_transforms      # Common Transforms\n        |----converting             # Keypoint converting\n        |----formatting             # Input data formatting\n        |----loading                # Raw data loading\n        |----pose3d_transforms      # Pose3d-transforms\n        |----topdown_transforms     # Top-Down transforms\n```\n\nIn **MMPose**, **data augmentation** and **data transformation** is a stage that users often need to consider. You can refer to the following process to design related stages:\n\n[![](https://mermaid.ink/img/pako:eNp9UbFOwzAQ_ZXIczuQbBkYKAKKOlRpJ5TlGp8TC9sX2WdVpeq_Y0cClahl8rv3nt_d2WfRkURRC2Xo2A3gudg0rSuKEA-9h3Eo9h5cUORteMj8i9FjPt_AqCeSp4wbYmBNLuPdoBVPJAb9hRmtyJB_18zkc4lO3mlQZv4VHXpg3IPvkf-_UGV-C93nlgKu3Riv_Q0c1xZ6LJbLx_kWSdvAAc0t7aqc5Cl3Srqrroi81C5NHbJnzs26lH9zyplc_UbcGr8SC2HRW9Ay_do5e1vBA1psRZ2gRAXRcCtad0lWiEy7k-tEzT7iQsRRpomeNaSntKJWYEJiR3AfRD_15RuTF7md?type=png)](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UbFOwzAQ_ZXIczuQbBkYKAKKOlRpJ5TlGp8TC9sX2WdVpeq_Y0cClahl8rv3nt_d2WfRkURRC2Xo2A3gudg0rSuKEA-9h3Eo9h5cUORteMj8i9FjPt_AqCeSp4wbYmBNLuPdoBVPJAb9hRmtyJB_18zkc4lO3mlQZv4VHXpg3IPvkf-_UGV-C93nlgKu3Riv_Q0c1xZ6LJbLx_kWSdvAAc0t7aqc5Cl3Srqrroi81C5NHbJnzs26lH9zyplc_UbcGr8SC2HRW9Ay_do5e1vBA1psRZ2gRAXRcCtad0lWiEy7k-tEzT7iQsRRpomeNaSntKJWYEJiR3AfRD_15RuTF7md)\n\nThe `common_transforms` component provides commonly used `RandomFlip`, `RandomHalfBody` **data augmentation**.\n\n- Operations such as `Shift`, `Rotate`, and `Resize` in the `Top-Down` method are reflected in the [RandomBBoxTransform](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L435) method.\n- The [BottomupResize](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L327) method is embodied in the `Buttom-Up` algorithm.\n- `pose-3d` is the [RandomFlipAroundRoot](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/pose3d_transforms.py#L13) method.\n\n**MMPose** provides corresponding data conversion interfaces for `Top-Down`, `Button-Up`, and `pose-3d`. Transform the image and coordinate labels from the `original_image_space` to the `input_image_space` by using an affine transformation.\n\n- The `Top-Down` method is manifested as [TopdownAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/topdown_transforms.py#L14).\n- The `Bottom-Up` method is embodied as [BottomupRandomAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L134).\n\nTaking `RandomFlip` as an example, this method randomly transforms the `original_image` and converts it into an `input_image` or an `intermediate_image`. To define a data transformation process, you need to inherit the [BaseTransform](https://github.com/open-mmlab/mmcv/blob/main/mmcv/transforms/base.py) class and register with `TRANSFORM`:\n\n```python\nfrom mmcv.transforms import BaseTransform\nfrom mmpose.registry import TRANSFORMS\n\n@TRANSFORMS.register_module()\nclass RandomFlip(BaseTransform):\n      \"\"\"Randomly flip the image, bbox and keypoints.\n\n    Required Keys:\n\n        - img\n        - img_shape\n        - flip_indices\n        - input_size (optional)\n        - bbox (optional)\n        - bbox_center (optional)\n        - keypoints (optional)\n        - keypoints_visible (optional)\n        - img_mask (optional)\n\n    Modified Keys:\n\n        - img\n        - bbox (optional)\n        - bbox_center (optional)\n        - keypoints (optional)\n        - keypoints_visible (optional)\n        - img_mask (optional)\n\n    Added Keys:\n\n        - flip\n        - flip_direction\n\n    Args:\n        prob (float | list[float]): The flipping probability. If a list is\n            given, the argument `direction` should be a list with the same\n            length. And each element in `prob` indicates the flipping\n            probability of the corresponding one in ``direction``. Defaults\n            to 0.5\n        direction (str | list[str]): The flipping direction. Options are\n            ``'horizontal'``, ``'vertical'`` and ``'diagonal'``. If a list is\n            is given, each data sample's flipping direction will be sampled\n            from a distribution determined by the argument ``prob``. Defaults\n            to ``'horizontal'``.\n    \"\"\"\n    def __init__(self,\n                prob: Union[float, List[float]] = 0.5,\n                direction: Union[str, List[str]] = 'horizontal') -> None:\n      if isinstance(prob, list):\n          assert is_list_of(prob, float)\n          assert 0 <= sum(prob) <= 1\n      elif isinstance(prob, float):\n          assert 0 <= prob <= 1\n      else:\n          raise ValueError(f'probs must be float or list of float, but \\\n                            got `{type(prob)}`.')\n      self.prob = prob\n\n      valid_directions = ['horizontal', 'vertical', 'diagonal']\n      if isinstance(direction, str):\n          assert direction in valid_directions\n      elif isinstance(direction, list):\n          assert is_list_of(direction, str)\n          assert set(direction).issubset(set(valid_directions))\n      else:\n          raise ValueError(f'direction must be either str or list of str, \\\n                              but got `{type(direction)}`.')\n      self.direction = direction\n\n      if isinstance(prob, list):\n          assert len(prob) == len(self.direction)\n```\n\n**Input**:\n\n- `prob` specifies the probability of transformation in horizontal, vertical, diagonal, etc., and is a `list` of floating-point numbers in the range \\[0,1\\].\n- `direction` specifies the direction of data transformation:\n  - `horizontal`\n  - `vertical`\n  - `diagonal`\n\n**Output**:\n\n- Return a `dict` data after data transformation.\n\nHere is a simple example of using `diagonal  RandomFlip`：\n\n```python\nfrom mmpose.datasets.transforms import LoadImage, RandomFlip\nimport mmcv\n\n# Load the original image from the path\nresults = dict(\n  img_path='data/test/multi-person.jpeg'\n  )\ntransform = LoadImage()\nresults = transform(results)\n# At this point, the original image loaded is a `dict`\n# that contains the following attributes`:\n# - `img_path`: Absolute path of image\n# - `img`: Pixel points of the image\n# - `img_shape`: The shape of the image\n# - `ori_shape`: The original shape of the image\n\n# Perform diagonal flip transformation on the original image\ntransform = RandomFlip(prob=1., direction='diagonal')\nresults = transform(results)\n# At this point, the original image loaded is a `dict`\n# that contains the following attributes`:\n# - `img_path`: Absolute path of image\n# - `img`: Pixel points of the image\n# - `img_shape`: The shape of the image\n# - `ori_shape`: The original shape of the image\n# - `flip`: Is the image flipped and transformed\n# - `flip_direction`: The direction in which\n# the image is flipped and transformed\n\n# Get the image after flipping and transformation\nmmcv.imshow(results['img'])\n```\n\nFor more information on using custom data transformations and enhancements, please refer to [$MMPose/test/test_datasets/test_transforms/test_common_transforms](https://github.com/open-mmlab/mmpose/blob/main/tests/test_datasets/test_transforms/test_common_transforms.py#L59)。\n\n#### RandomHalfBody\n\nThe [RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L263) **data augmentation** algorithm probabilistically transforms the data of the upper or lower body.\n\n**Input**:\n\n- `min_total_keypoints` minimum total keypoints\n- `min_half_keypoints` minimum half-body keypoints\n- `padding` The filling ratio of the bbox\n- `prob` accepts the probability of half-body transformation when the number of key points meets the requirements\n\n**Output**:\n\n- Return a `dict` data after data transformation.\n\n#### Topdown Affine\n\nThe [TopdownAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/topdown_transforms.py#L14) data transformation algorithm transforms the `original image` into an `input image` through affine transformation\n\n- `input_size` The bbox area will be cropped and corrected to the \\[w,h\\] size\n- `use_udp` whether to use fair data process [UDP](https://arxiv.org/abs/1911.07524).\n\n**Output**:\n\n- Return a `dict` data after data transformation.\n\n### Using Data Augmentation and Transformation in the Pipeline\n\nThe **data augmentation** and **data transformation** process in the configuration file can be the following example:\n\n```python\ntrain_pipeline_stage2 = [\n    ...\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(\n         type='TopdownAffine',\n         input_size=codec['input_size']),\n    ...\n]\n```\n\nThe pipeline in the example performs **data enhancement** on the `input data`, performs random horizontal transformation and half-body transformation, and performs `Top-Down` `Shift`, `Rotate`, and `Resize` operations, and implements affine transformation through `TopdownAffine` operations to transform to the `input_image_space`.\n"
  },
  {
    "path": "docs/en/advanced_guides/dataflow.md",
    "content": "# Dataflow in MMPose\n\nComing soon.\n"
  },
  {
    "path": "docs/en/advanced_guides/implement_new_models.md",
    "content": "# Implement New Models\n\nThis tutorial will introduce how to implement your own models in MMPose. After summarizing, we split the need to implement new models into two categories:\n\n1. Based on the algorithm paradigm supported by MMPose, customize the modules (backbone, neck, head, codec, etc.) in the model\n2. Implement new algorithm paradigm\n\n## Basic Concepts\n\nWhat you want to implement is one of the above, and this section is important to you because it is the basic principle of building models in the OpenMMLab.\n\nIn MMPose, all the code related to the implementation of the model structure is stored in the [models directory](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models) :\n\n```shell\nmmpose\n|----models\n     |----backbones             #\n     |----data_preprocessors    # image normalization\n     |----heads                 #\n     |----losses                # loss functions\n     |----necks                 #\n     |----pose_estimators       # algorithm paradigm\n     |----utils                 #\n```\n\nYou can refer to the following flow chart to locate the module you need to implement:\n\n![image](https://github.com/open-mmlab/mmpose/assets/13503330/f4eeb99c-e2a1-4907-9d46-f110c51f0814)\n\n## Pose Estimatiors\n\nIn pose estimatiors, we will define the inference process of a model, and decode the model output results in `predict()`, first transform it from `output space` to `input image space` using the [codec](./codecs.md), and then combine the meta information to transform to `original image space`.\n\n![pose_estimator_en](https://github.com/open-mmlab/mmpose/assets/13503330/0764baab-41c7-4a1d-ab64-5d7f9dfc8eec)\n\nCurrently, MMPose supports the following types of pose estimator:\n\n1. [Top-down](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/topdown.py): The input of the pose model is a cropped single target (animal, human body, human face, human hand, plant, clothes, etc.) image, and the output is the key point prediction result of the target\n2. [Bottom-up](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/bottomup.py): The input of the pose model is an image containing any number of targets, and the output is the key point prediction result of all targets in the image\n3. [Pose Lifting](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/pose_lifter.py): The input of the pose model is a 2D keypoint coordinate array, and the output is a 3D keypoint coordinate array\n\nIf the model you want to implement does not belong to the above algorithm paradigm, then you need to inherit the [BasePoseEstimator](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/base.py) class to define your own algorithm paradigm.\n\n## Backbones\n\nIf you want to implement a new backbone network, you need to create a new file in the [backbones directory](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/backbones) to define it.\n\nThe new backbone network needs to inherit the [BaseBackbone](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/backbones/base_backbone.py) class, and there is no difference in other aspects from inheriting `nn.Module` to create.\n\nAfter completing the implementation of the backbone network, you need to use `MODELS` to register it:\n\n```Python3\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\n@MODELS.register_module()\nclass YourNewBackbone(BaseBackbone):\n```\n\nFinally, please remember to import your new backbone network in [\\_\\_init\\_\\_.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/backbones/__init__.py) .\n\n## Heads\n\nThe addition of a new prediction head is similar to the backbone network process. You need to create a new file in the [heads directory](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/heads) to define it, and then inherit [BaseHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py) .\n\nOne thing to note is that in MMPose, the loss function is calculated in the Head. According to the different training and evaluation stages, `loss()` and `predict()` are executed respectively.\n\nIn `predict()`, the model will call the `decode()` method of the corresponding codec to transform the model output result from `output space` to `input image space`.\n\nAfter completing the implementation of the prediction head, you need to use `MODELS` to register it:\n\n```Python3\nfrom mmpose.registry import MODELS\nfrom ..base_head import BaseHead\n\n@MODELS.register_module()\nclass YourNewHead(BaseHead):\n```\n\nFinally, please remember to import your new prediction head in [\\_\\_init\\_\\_.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/__init__.py).\n\n### Head with Keypoints Visibility Prediction\n\nMany models predict keypoint visibility based on confidence in coordinate predictions. However, this approach is suboptimal. Our [VisPredictHead](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/heads/hybrid_heads/vis_head.py) wrapper enables heads to directly predict keypoint visibility from ground truth training data, improving reliability. To add visibility prediction, wrap your head module with VisPredictHead in the config file.\n\n```python\nmodel=dict(\n     ...\n     head=dict(\n          type='VisPredictHead',\n          loss=dict(\n               type='BCELoss',\n               use_target_weight=True,\n               use_sigmoid=True,\n               loss_weight=1e-3),\n          pose_cfg=dict(\n               type='HeatmapHead',\n               in_channels=2048,\n               out_channels=17,\n               loss=dict(type='KeypointMSELoss', use_target_weight=True),\n               decoder=codec)),\n     ...\n)\n```\n\nTo implement such a head module wrapper, we only need to inherit [BaseHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py), then pass the pose head configuration in `__init__()` and instantiate it through `MODELS.build()`. As shown below:\n\n```python\n@MODELS.register_module()\nclass VisPredictHead(BaseHead):\n    \"\"\"VisPredictHead must be used together with other heads. It can predict\n    keypoints coordinates of and their visibility simultaneously. In the\n    current version, it only supports top-down approaches.\n\n    Args:\n        pose_cfg (Config): Config to construct keypoints prediction head\n        loss (Config): Config for visibility loss. Defaults to use\n            :class:`BCELoss`\n        use_sigmoid (bool): Whether to use sigmoid activation function\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(self,\n                 pose_cfg: ConfigType,\n                 loss: ConfigType = dict(\n                     type='BCELoss', use_target_weight=False,\n                     use_sigmoid=True),\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = pose_cfg['in_channels']\n        if pose_cfg.get('num_joints', None) is not None:\n            self.out_channels = pose_cfg['num_joints']\n        elif pose_cfg.get('out_channels', None) is not None:\n            self.out_channels = pose_cfg['out_channels']\n        else:\n            raise ValueError('VisPredictHead requires \\'num_joints\\' or'\n                             ' \\'out_channels\\' in the pose_cfg.')\n\n        self.loss_module = MODELS.build(loss)\n\n        self.pose_head = MODELS.build(pose_cfg)\n        self.pose_cfg = pose_cfg\n\n        self.use_sigmoid = loss.get('use_sigmoid', False)\n\n        modules = [\n            nn.AdaptiveAvgPool2d(1),\n            nn.Flatten(),\n            nn.Linear(self.in_channels, self.out_channels)\n        ]\n        if self.use_sigmoid:\n            modules.append(nn.Sigmoid())\n\n        self.vis_head = nn.Sequential(*modules)\n```\n\nThen you can implement other parts of the code as a normal head.\n"
  },
  {
    "path": "docs/en/api.rst",
    "content": "mmpose.apis\n-------------\n.. automodule:: mmpose.apis\n    :members:\n\nmmpose.codecs\n-------------\n.. automodule:: mmpose.codecs\n    :members:\n\nmmpose.models\n---------------\nbackbones\n^^^^^^^^^^^\n.. automodule:: mmpose.models.backbones\n    :members:\n\nnecks\n^^^^^^^^^^^\n.. automodule:: mmpose.models.necks\n    :members:\n\ndetectors\n^^^^^^^^^^^\n.. automodule:: mmpose.models.pose_estimators\n    :members:\n\nheads\n^^^^^^^^^^^^^^^\n.. automodule:: mmpose.models.heads\n    :members:\n\nlosses\n^^^^^^^^^^^\n.. automodule:: mmpose.models.losses\n    :members:\n\nmisc\n^^^^^^^^^^^\n.. automodule:: mmpose.models.utils\n    :members:\n\nmmpose.datasets\n-----------------\n.. automodule:: mmpose.datasets\n    :members:\n\ndatasets\n^^^^^^^^^^^\n.. automodule:: mmpose.datasets.datasets.base\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.body\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.face\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.hand\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.animal\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.fashion\n    :members:\n    :noindex:\n\ntransforms\n^^^^^^^^^^^\n.. automodule:: mmpose.datasets.transforms.loading\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.common_transforms\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.topdown_transforms\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.bottomup_transforms\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.formatting\n    :members:\n\nmmpose.structures\n---------------\n.. automodule:: mmpose.structures\n    :members:\n\nbbox\n^^^^^^^^^^^\n.. automodule:: mmpose.structures.bbox\n    :members:\n\nkeypoint\n^^^^^^^^^^^\n.. automodule:: mmpose.structures.keypoint\n    :members:\n\n\nmmpose.registry\n---------------\n.. automodule:: mmpose.registry\n    :members:\n\nmmpose.evaluation\n-----------------\nmetrics\n^^^^^^^^^^^\n.. automodule:: mmpose.evaluation.metrics\n    :members:\n\nfunctional\n^^^^^^^^^^^\n.. automodule:: mmpose.evaluation.functional\n    :members:\n\nmmpose.visualization\n--------------------\n.. automodule:: mmpose.visualization\n    :members:\n\nmmpose.engine\n---------------\nhooks\n^^^^^^^^^^^\n.. automodule:: mmpose.engine.hooks\n    :members:\n"
  },
  {
    "path": "docs/en/collect_modelzoo.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport re\nfrom collections import defaultdict\nfrom glob import glob\n\nfrom addict import Addict\nfrom titlecase import titlecase\n\n\ndef _get_model_docs():\n    \"\"\"Get all model document files.\n\n    Returns:\n        list[str]: file paths\n    \"\"\"\n    config_root = osp.join('..', '..', 'configs')\n    pattern = osp.sep.join(['*'] * 4) + '.md'\n    docs = glob(osp.join(config_root, pattern))\n    docs = [doc for doc in docs if '_base_' not in doc]\n    return docs\n\n\ndef _parse_model_doc_path(path):\n    \"\"\"Parse doc file path.\n\n    Typical path would be like:\n\n        configs/<task>/<algorithm>/<dataset>/<setting>.md\n\n    An example is:\n\n        \"configs/animal_2d_keypoint/topdown_heatmap/\n        animalpose/resnet_animalpose.md\"\n\n    Returns:\n        tuple:\n        - task (str): e.g. ``'Animal 2D Keypoint'``\n        - dataset (str): e.g. ``'animalpose'``\n        - keywords (tuple): e.g. ``('topdown heatmap', 'resnet')``\n    \"\"\"\n    _path = path.split(osp.sep)\n    _rel_path = _path[_path.index('configs'):]\n\n    # get task\n    def _titlecase_callback(word, **kwargs):\n        if word == '2d':\n            return '2D'\n        if word == '3d':\n            return '3D'\n\n    task = titlecase(\n        _rel_path[1].replace('_', ' '), callback=_titlecase_callback)\n\n    # get dataset\n    dataset = _rel_path[3]\n\n    # get keywords\n    keywords_algo = (_rel_path[2], )\n    keywords_setting = tuple(_rel_path[4][:-3].split('_'))\n    keywords = keywords_algo + keywords_setting\n\n    return task, dataset, keywords\n\n\ndef _get_paper_refs():\n    \"\"\"Get all paper references.\n\n    Returns:\n        Dict[str, List[str]]: keys are paper categories and values are lists\n        of paper paths.\n    \"\"\"\n    papers = glob('../src/papers/*/*.md')\n    paper_refs = defaultdict(list)\n    for fn in papers:\n        category = fn.split(osp.sep)[3]\n        paper_refs[category].append(fn)\n\n    return paper_refs\n\n\ndef _parse_paper_ref(fn):\n    \"\"\"Get paper name and indicator pattern from a paper reference file.\n\n    Returns:\n        tuple:\n        - paper_name (str)\n        - paper_indicator (str)\n    \"\"\"\n    indicator = None\n    with open(fn, 'r', encoding='utf-8') as f:\n        for line in f.readlines():\n            if line.startswith('<summary'):\n                indicator = line\n                break\n    if indicator is None:\n        raise ValueError(f'Invalid paper reference file {fn}')\n\n    paper_name = re.sub(r'\\<.*?\\>', '', indicator).strip()\n    return paper_name, indicator\n\n\ndef main():\n\n    # Build output folders\n    os.makedirs('model_zoo', exist_ok=True)\n    os.makedirs('model_zoo_papers', exist_ok=True)\n\n    # Collect all document contents\n    model_doc_list = _get_model_docs()\n    model_docs = Addict()\n\n    for path in model_doc_list:\n        task, dataset, keywords = _parse_model_doc_path(path)\n        with open(path, 'r', encoding='utf-8') as f:\n            doc = {\n                'task': task,\n                'dataset': dataset,\n                'keywords': keywords,\n                'path': path,\n                'content': f.read()\n            }\n        model_docs[task][dataset][keywords] = doc\n\n    # Write files by task\n    for task, dataset_dict in model_docs.items():\n        lines = [f'# {task}', '']\n        for dataset, keywords_dict in dataset_dict.items():\n            lines += [\n                '<hr/>', '<br/><br/>', '', f'## {titlecase(dataset)} Dataset',\n                ''\n            ]\n\n            for keywords, doc in keywords_dict.items():\n                keyword_strs = [\n                    titlecase(x.replace('_', ' ')) for x in keywords\n                ]\n                dataset_str = titlecase(dataset)\n                if dataset_str in keyword_strs:\n                    keyword_strs.remove(dataset_str)\n\n                lines += [\n                    '<br/>', '',\n                    (f'### {\" + \".join(keyword_strs)}'\n                     f' on {dataset_str}'), '', doc['content'], ''\n                ]\n\n        fn = osp.join('model_zoo', f'{task.replace(\" \", \"_\").lower()}.md')\n        with open(fn, 'w', encoding='utf-8') as f:\n            f.write('\\n'.join(lines))\n\n    # Write files by paper\n    paper_refs = _get_paper_refs()\n\n    for paper_cat, paper_list in paper_refs.items():\n        lines = []\n        for paper_fn in paper_list:\n            paper_name, indicator = _parse_paper_ref(paper_fn)\n            paperlines = []\n            for task, dataset_dict in model_docs.items():\n                for dataset, keywords_dict in dataset_dict.items():\n                    for keywords, doc_info in keywords_dict.items():\n\n                        if indicator not in doc_info['content']:\n                            continue\n\n                        keyword_strs = [\n                            titlecase(x.replace('_', ' ')) for x in keywords\n                        ]\n\n                        dataset_str = titlecase(dataset)\n                        if dataset_str in keyword_strs:\n                            keyword_strs.remove(dataset_str)\n                        paperlines += [\n                            '<br/>', '',\n                            (f'### {\" + \".join(keyword_strs)}'\n                             f' on {dataset_str}'), '', doc_info['content'], ''\n                        ]\n            if paperlines:\n                lines += ['<hr/>', '<br/><br/>', '', f'## {paper_name}', '']\n                lines += paperlines\n\n        if lines:\n            lines = [f'# {titlecase(paper_cat)}', ''] + lines\n            with open(\n                    osp.join('model_zoo_papers', f'{paper_cat.lower()}.md'),\n                    'w',\n                    encoding='utf-8') as f:\n                f.write('\\n'.join(lines))\n\n\nif __name__ == '__main__':\n    print('collect model zoo documents')\n    main()\n"
  },
  {
    "path": "docs/en/collect_projects.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport re\nfrom glob import glob\n\n\ndef _get_project_docs():\n    \"\"\"Get all project document files.\n\n    Returns:\n        list[str]: file paths\n    \"\"\"\n    project_root = osp.join('..', '..', 'projects')\n    pattern = osp.sep.join(['*'] * 2) + '.md'\n    docs = glob(osp.join(project_root, pattern))\n    docs = [\n        doc for doc in docs\n        if 'example_project' not in doc and '_CN' not in doc\n    ]\n    return docs\n\n\ndef _parse_project_doc_path(fn):\n    \"\"\"Get project name and banner from a project reference file.\n\n    Returns:\n        tuple:\n        - project_name (str)\n        - project_banner (str)\n    \"\"\"\n    project_banner, project_name = None, None\n    with open(fn, 'r', encoding='utf-8') as f:\n        for line in f.readlines():\n            if re.match('^( )*<img', line) and not project_banner:\n                project_banner = line\n            if line.startswith('# ') and not project_name:\n                project_name = line\n            if project_name and project_banner:\n                break\n    if project_name is None or project_banner is None:\n        raise ValueError(f'Invalid paper reference file {fn}')\n\n    project_name = re.sub(r'^\\# ', '', project_name).strip()\n    project_banner = project_banner.strip()\n    return project_name, project_banner\n\n\ndef _get_project_intro_doc():\n    project_intro_doc = []\n    with open(\n            osp.join('..', '..', 'projects', 'README.md'), 'r',\n            encoding='utf-8') as f:\n        for line in f.readlines():\n            if line.startswith('# Welcome'):\n                continue\n            if './faq.md' in line:\n                line = line.replace('./faq.md', '#faq')\n            if './' in line:\n                line = line.replace('./', '/projects/')\n            project_intro_doc.append(line)\n            if line.startswith('## Project List'):\n                break\n    return project_intro_doc\n\n\ndef _get_faq_doc():\n    faq_doc = ['\\n']\n    with open(\n            osp.join('..', '..', 'projects', 'faq.md'), 'r',\n            encoding='utf-8') as f:\n        for line in f.readlines():\n            if '#' in line:\n                line = re.sub(r'^\\#', '##', line)\n            faq_doc.append(line)\n    return faq_doc\n\n\ndef main():\n\n    # Build output folders\n    os.makedirs('projects', exist_ok=True)\n\n    # Collect all document contents\n    project_doc_list = _get_project_docs()\n\n    project_lines = []\n    for path in project_doc_list:\n        name, banner = _parse_project_doc_path(path)\n        _path = path.split(osp.sep)\n        _rel_path = _path[_path.index('projects'):-1]\n        url = '/' + '/'.join(_rel_path)\n        _name = name.split(':', 1)\n        name, description = _name[0], '' if len(\n            _name) < 2 else f': {_name[-1]}'\n        project_lines += [\n            f'- **{name}**{description} [\\\\[github\\\\]]({url})', '',\n            '<div align=\"center\">', ' ' + banner, '</div>', '<br/>', ''\n        ]\n\n    project_intro_doc = _get_project_intro_doc()\n    faq_doc = _get_faq_doc()\n\n    with open(\n            osp.join('projects', 'community_projects.md'), 'w',\n            encoding='utf-8') as f:\n        f.write('# Projects from Community Contributors\\n')\n        f.write(''.join(project_intro_doc))\n        f.write('\\n'.join(project_lines))\n        f.write(''.join(faq_doc))\n\n\nif __name__ == '__main__':\n    print('collect project documents')\n    main()\n"
  },
  {
    "path": "docs/en/conf.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common options. For a full\n# list see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\n# -- Path setup --------------------------------------------------------------\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n\nimport os\nimport subprocess\nimport sys\n\nimport pytorch_sphinx_theme\n\nsys.path.insert(0, os.path.abspath('../..'))\n\n# -- Project information -----------------------------------------------------\n\nproject = 'MMPose'\ncopyright = '2020-2021, OpenMMLab'\nauthor = 'MMPose Authors'\n\n# The full version, including alpha/beta/rc tags\nversion_file = '../../mmpose/version.py'\n\n\ndef get_version():\n    with open(version_file, 'r') as f:\n        exec(compile(f.read(), version_file, 'exec'))\n    return locals()['__version__']\n\n\nrelease = get_version()\n\n# -- General configuration ---------------------------------------------------\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.viewcode',\n    'sphinx_markdown_tables', 'sphinx_copybutton', 'myst_parser',\n    'sphinx.ext.autosummary'\n]\n\nautodoc_mock_imports = ['json_tricks', 'mmpose.version']\n\n# Ignore >>> when copying code\ncopybutton_prompt_text = r'>>> |\\.\\.\\. '\ncopybutton_prompt_is_regexp = True\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This pattern also affects html_static_path and html_extra_path.\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n# -- Options for HTML output -------------------------------------------------\nsource_suffix = {\n    '.rst': 'restructuredtext',\n    '.md': 'markdown',\n}\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = 'pytorch_sphinx_theme'\nhtml_theme_path = [pytorch_sphinx_theme.get_html_theme_path()]\nhtml_theme_options = {\n    'menu': [\n        {\n            'name': 'GitHub',\n            'url': 'https://github.com/open-mmlab/mmpose/tree/main'\n        },\n    ],\n    # Specify the language of the shared menu\n    'menu_lang':\n    'en'\n}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n\nlanguage = 'en'\n\nhtml_static_path = ['_static']\nhtml_css_files = ['css/readthedocs.css']\n\n# Enable ::: for my_st\nmyst_enable_extensions = ['colon_fence']\n\nmaster_doc = 'index'\n\n\ndef builder_inited_handler(app):\n    subprocess.run(['python', './collect_modelzoo.py'])\n    subprocess.run(['python', './collect_projects.py'])\n    subprocess.run(['sh', './merge_docs.sh'])\n    subprocess.run(['python', './stats.py'])\n\n\ndef setup(app):\n    app.connect('builder-inited', builder_inited_handler)\n"
  },
  {
    "path": "docs/en/contribution_guide.md",
    "content": "# How to Contribute to MMPose\n\nWelcome to join the MMPose community, we are committed to building cutting-edge computer vision foundational library. All kinds of contributions are welcomed, including but not limited to:\n\n- **Fix bugs**\n  1. If the modification involves significant changes, it's recommended to create an issue first that describes the error information and how to trigger the bug. Other developers will discuss it with you and propose a proper solution.\n  2. Fix the bug and add the corresponding unit test, submit the PR.\n- **Add new features or components**\n  1. If the new feature or module involves a large amount of code changes, we suggest you to submit an issue first, and we will confirm the necessity of the function with you.\n  2. Implement the new feature and add unit tests, submit the PR.\n- **Improve documentation or translation**\n  - If you find errors or incomplete documentation, please submit a PR directly.\n\n```{note}\n- If you hope to contribute to MMPose 1.0, please create a new branch from dev-1.x and submit a PR to the dev-1.x branch.\n- If you are the author of papers in this field and would like to include your work to MMPose, please contact us. We will much appreciate your contribution.\n- If you hope to share your MMPose-based projects with the community at once, consider creating a PR to `Projects` directory, which will simplify the review process and bring in the projects as soon as possible. Checkout our [example project](/projects/example_project)\n- If you wish to join the MMPose developers, please feel free to contact us and we will invite you to join the MMPose developers group.\n```\n\n## Preparation\n\nThe commands for processing pull requests are implemented using Git, and this chapter details Git Configuration and associated GitHub.\n\n### Git Configuration\n\nFirst, you need to install Git and configure your Git username and email.\n\n```shell\n# view the Git version\ngit --version\n```\n\nSecond, check your Git config and ensure that `user.name` and `user.email` are properly configured.\n\n```shell\n# view the Git config\ngit config --global --list\n# configure the user name and email\ngit config --global user.name \"Change your user name here\"\ngit config --global user.email \"Change your user email here\"\n```\n\n## Pull Request Workflow\n\nIf you’re not familiar with Pull Request, don’t worry! The following guidance will tell you how to create a Pull Request step by step. If you want to dive into the development mode of Pull Request, you can refer to the [official documents](https://docs.github.com/en/github/collaborating-with-issues-and-pull-requests/about-pull-requests).\n\n### 1. Fork and Clone\n\nIf you are posting a pull request for the first time, you should fork the OpenMMLab repositories by clicking the **Fork** button in the top right corner of the GitHub page, and the forked repositories will appear under your GitHub profile.\n\n![](https://user-images.githubusercontent.com/13503330/223318144-a49c6cef-b1fb-45b8-aa2b-0833d0e3fd5c.png)\n\nThen you need to clone the forked repository to your local machine.\n\n```shell\n# clone the forked repository\ngit clone https://github.com/username/mmpose.git\n\n# Add official repository as upstream remote\ncd mmpose\ngit remote add upstream https://github.com/open-mmlab/mmpose.git\n```\n\nEnter the following command in the terminal to see if the remote repository was successfully added.\n\n```shell\ngit remote -v\n```\n\nIf the following message appears, you have successfully added a remote repository.\n\n```Shell\norigin\thttps://github.com/{username}/mmpose.git (fetch)\norigin\thttps://github.com/{username}/mmpose.git (push)\nupstream\thttps://github.com/open-mmlab/mmpose.git (fetch)\nupstream\thttps://github.com/open-mmlab/mmpose.git (push)\n```\n\n```{note}\nHere’s a brief introduction to the origin and upstream. When we use “git clone”, we create an “origin” remote by default, which points to the repository cloned from. As for “upstream”, we add it ourselves to point to the target repository. Of course, if you don’t like the name “upstream”, you could name it as you wish. Usually, we’ll push the code to “origin”. If the pushed code conflicts with the latest code in official(“upstream”), we should pull the latest code from upstream to resolve the conflicts, and then push to “origin” again. The posted Pull Request will be updated automatically.\n```\n\n### 2. Configure pre-commit\n\nYou should configure pre-commit in the local development environment to make sure the code style matches that of OpenMMLab. Note: The following code should be executed under the MMPOSE directory.\n\n```Shell\npip install -U pre-commit\npre-commit install\n```\n\nCheck that pre-commit is configured successfully, and install the hooks defined in `.pre-commit-config.yaml`.\n\n```Shell\npre-commit run --all-files\n```\n\n![](https://user-images.githubusercontent.com/57566630/202368856-0465a90d-8fce-4345-918e-67b8b9c82614.png)\n\n```{note}\nChinese users may fail to download the pre-commit hooks due to the network issue. In this case, you could download these hooks from:\n\npip install -U pre-commit -i https://pypi.tuna.tsinghua.edu.cn/simple\n\nor:\n\npip install -U pre-commit -i https://pypi.mirrors.ustc.edu.cn/simple\n```\n\nIf the installation process is interrupted, you can repeatedly run `pre-commit run ...` to continue the installation.\n\nIf the code does not conform to the code style specification, pre-commit will raise a warning and fixes some of the errors automatically.\n\n![](https://user-images.githubusercontent.com/57566630/202369176-67642454-0025-4023-a095-263529107aa3.png)\n\n### 3. Create a development branch\n\nAfter configuring the pre-commit, we should create a branch based on the dev branch to develop the new feature or fix the bug. The proposed branch name is `username/pr_name`.\n\n```Shell\ngit checkout -b username/refactor_contributing_doc\n```\n\nIn subsequent development, if the dev branch of the local repository lags behind the dev branch of the official repository, you need to pull the upstream dev branch first and then rebase it to the local development branch.\n\n```Shell\ngit checkout username/refactor_contributing_doc\ngit fetch upstream\ngit rebase upstream/dev-1.x\n```\n\nWhen rebasing, if a conflict arises, you need to resolve the conflict manually, then execute the `git add` command, and then execute the `git rebase --continue` command until the rebase is complete.\n\n### 4. Commit the code and pass the unit test\n\nAfter the local development is done, we need to pass the unit tests locally and then commit the code.\n\n```shell\n# run unit test\npytest tests/\n\n# commit the code\ngit add .\ngit commit -m \"commit message\"\n```\n\n### 5. Push the code to the remote repository\n\nAfter the local development is done, we need to push the code to the remote repository.\n\n```Shell\ngit push origin username/refactor_contributing_doc\n```\n\n### 6. Create a Pull Request\n\n#### (1) Create a Pull Request on GitHub\n\n![](https://user-images.githubusercontent.com/13503330/223321382-e6068e18-1d91-4458-8328-b1c7c907b3b2.png)\n\n#### (2) Fill in the Pull Request template\n\n![](https://user-images.githubusercontent.com/57566630/167307569-a794b967-6e28-4eac-a942-00deb657815f.png)\n\n## Code Style\n\n### Python\n\nWe adopt [PEP8](https://www.python.org/dev/peps/pep-0008/) as the preferred code style, and use the following tools for linting and formatting:\n\n- [flake8](https://github.com/PyCQA/flake8): A wrapper around some linter tools.\n- [isort](https://github.com/timothycrosley/isort): A Python utility to sort imports.\n- [yapf](https://github.com/google/yapf): A formatter for Python files.\n- [codespell](https://github.com/codespell-project/codespell): A Python utility to fix common misspellings in text files.\n- [mdformat](https://github.com/executablebooks/mdformat): Mdformat is an opinionated Markdown formatter that can be used to enforce a consistent style in Markdown files.\n- [docformatter](https://github.com/myint/docformatter): A formatter to format docstring.\n\nStyle configurations of yapf and isort can be found in [setup.cfg](/setup.cfg).\n\nWe use [pre-commit hook](https://pre-commit.com/) that checks and formats for `flake8`, `yapf`, `isort`, `trailing whitespaces`, `markdown files`,\nfixes `end-of-files`, `double-quoted-strings`, `python-encoding-pragma`, `mixed-line-ending`, sorts `requirments.txt` automatically on every commit.\nThe config for a pre-commit hook is stored in [.pre-commit-config](/.pre-commit-config.yaml).\n\n```{note}\nBefore you create a PR, make sure that your code lints and is formatted by yapf.\n```\n\n### C++ and CUDA\n\nWe follow the [Google C++ Style Guide](https://google.github.io/styleguide/cppguide.html).\n"
  },
  {
    "path": "docs/en/dataset_zoo/2d_animal_keypoint.md",
    "content": "# 2D Animal Keypoint Dataset\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [Animal-Pose](#animal-pose) \\[ [Homepage](https://sites.google.com/view/animal-pose/) \\]\n- [AP-10K](#ap-10k) \\[ [Homepage](https://github.com/AlexTheBad/AP-10K/) \\]\n- [Horse-10](#horse-10) \\[ [Homepage](http://www.mackenziemathislab.org/horse10) \\]\n- [MacaquePose](#macaquepose) \\[ [Homepage](http://pri.ehub.kyoto-u.ac.jp/datasets/macaquepose/index.html) \\]\n- [Vinegar Fly](#vinegar-fly) \\[ [Homepage](https://github.com/jgraving/DeepPoseKit-Data) \\]\n- [Desert Locust](#desert-locust) \\[ [Homepage](https://github.com/jgraving/DeepPoseKit-Data) \\]\n- [Grévy’s Zebra](#grvys-zebra) \\[ [Homepage](https://github.com/jgraving/DeepPoseKit-Data) \\]\n- [ATRW](#atrw) \\[ [Homepage](https://cvwc2019.github.io/challenge.html) \\]\n- [Animal Kingdom](#Animal-Kindom) \\[ [Homepage](https://openaccess.thecvf.com/content/CVPR2022/html/Ng_Animal_Kingdom_A_Large_and_Diverse_Dataset_for_Animal_Behavior_CVPR_2022_paper.html) \\]\n\n## Animal-Pose\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227796953-95ae1e30-5323-43f8-9a19-c4c2326e9835.png\" height=\"200px\">\n</div>\n\nFor [Animal-Pose](https://sites.google.com/view/animal-pose/) dataset, we prepare the dataset as follows:\n\n1. Download the images of [PASCAL VOC2012](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/#data), especially the five categories (dog, cat, sheep, cow, horse), which we use as trainval dataset.\n2. Download the [test-set](https://drive.google.com/drive/folders/1DwhQobZlGntOXxdm7vQsE4bqbFmN3b9y?usp=sharing) images with raw annotations (1000 images, 5 categories).\n3. We have pre-processed the annotations to make it compatible with MMPose. Please download the annotation files from [annotations](https://download.openmmlab.com/mmpose/datasets/animalpose_annotations.tar). If you would like to generate the annotations by yourself, please check our dataset parsing [codes](/tools/dataset_converters/parse_animalpose_dataset.py).\n\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── animalpose\n        │\n        │-- VOC2012\n        │   │-- Annotations\n        │   │-- ImageSets\n        │   │-- JPEGImages\n        │   │-- SegmentationClass\n        │   │-- SegmentationObject\n        │\n        │-- animalpose_image_part2\n        │   │-- cat\n        │   │-- cow\n        │   │-- dog\n        │   │-- horse\n        │   │-- sheep\n        │\n        │-- annotations\n        │   │-- animalpose_train.json\n        │   |-- animalpose_val.json\n        │   |-- animalpose_trainval.json\n        │   │-- animalpose_test.json\n        │\n        │-- PASCAL2011_animal_annotation\n        │   │-- cat\n        │   │   |-- 2007_000528_1.xml\n        │   │   |-- 2007_000549_1.xml\n        │   │   │-- ...\n        │   │-- cow\n        │   │-- dog\n        │   │-- horse\n        │   │-- sheep\n        │\n        │-- annimalpose_anno2\n        │   │-- cat\n        │   │   |-- ca1.xml\n        │   │   |-- ca2.xml\n        │   │   │-- ...\n        │   │-- cow\n        │   │-- dog\n        │   │-- horse\n        │   │-- sheep\n```\n\nThe official dataset does not provide the official train/val/test set split.\nWe choose the images from PascalVOC for train & val. In total, we have 3608 images and 5117 annotations for train+val, where\n2798 images with 4000 annotations are used for training, and 810 images with 1117 annotations are used for validation.\nThose images from other sources (1000 images with 1000 annotations) are used for testing.\n\n## AP-10K\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227797151-091dc21a-d944-49c9-8b62-cc47fa89e69f.png\" height=\"200px\">\n</div>\n\nFor [AP-10K](https://github.com/AlexTheBad/AP-10K/) dataset, images and annotations can be downloaded from [download](https://drive.google.com/file/d/1-FNNGcdtAQRehYYkGY1y4wzFNg4iWNad/view?usp=sharing).\nNote, this data and annotation data is for non-commercial use only.\n\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ap10k\n        │-- annotations\n        │   │-- ap10k-train-split1.json\n        │   |-- ap10k-train-split2.json\n        │   |-- ap10k-train-split3.json\n        │   │-- ap10k-val-split1.json\n        │   |-- ap10k-val-split2.json\n        │   |-- ap10k-val-split3.json\n        │   |-- ap10k-test-split1.json\n        │   |-- ap10k-test-split2.json\n        │   |-- ap10k-test-split3.json\n        │-- data\n        │   │-- 000000000001.jpg\n        │   │-- 000000000002.jpg\n        │   │-- ...\n```\n\nThe annotation files in 'annotation' folder contains 50 labeled animal species. There are total 10,015 labeled images with 13,028 instances in the AP-10K dataset. We randonly split them into train, val, and test set following the ratio of 7:1:2.\n\n## Horse-10\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/WACV2021/html/Mathis_Pretraining_Boosts_Out-of-Domain_Robustness_for_Pose_Estimation_WACV_2021_paper.html\">Horse-10 (WACV'2021)</a></summary>\n\n```bibtex\n@inproceedings{mathis2021pretraining,\n  title={Pretraining boosts out-of-domain robustness for pose estimation},\n  author={Mathis, Alexander and Biasi, Thomas and Schneider, Steffen and Yuksekgonul, Mert and Rogers, Byron and Bethge, Matthias and Mathis, Mackenzie W},\n  booktitle={Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision},\n  pages={1859--1868},\n  year={2021}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227797934-32bc1b2c-7957-4a29-94df-8e431842ab3b.png\" height=\"200px\">\n</div>\n\nFor [Horse-10](http://www.mackenziemathislab.org/horse10) dataset, images can be downloaded from [download](http://www.mackenziemathislab.org/horse10).\nPlease download the annotation files from [horse10_annotations](https://download.openmmlab.com/mmpose/datasets/horse10_annotations.tar). Note, this data and annotation data is for non-commercial use only, per the authors (see http://horse10.deeplabcut.org for more information).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── horse10\n        │-- annotations\n        │   │-- horse10-train-split1.json\n        │   |-- horse10-train-split2.json\n        │   |-- horse10-train-split3.json\n        │   │-- horse10-test-split1.json\n        │   |-- horse10-test-split2.json\n        │   |-- horse10-test-split3.json\n        │-- labeled-data\n        │   │-- BrownHorseinShadow\n        │   │-- BrownHorseintoshadow\n        │   │-- ...\n```\n\n## MacaquePose\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/pmc7874091/\">MacaquePose (bioRxiv'2020)</a></summary>\n\n```bibtex\n@article{labuguen2020macaquepose,\n  title={MacaquePose: A novel ‘in the wild’macaque monkey pose dataset for markerless motion capture},\n  author={Labuguen, Rollyn and Matsumoto, Jumpei and Negrete, Salvador and Nishimaru, Hiroshi and Nishijo, Hisao and Takada, Masahiko and Go, Yasuhiro and Inoue, Ken-ichi and Shibata, Tomohiro},\n  journal={bioRxiv},\n  year={2020},\n  publisher={Cold Spring Harbor Laboratory}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227799576-f10f8469-9432-4139-beb4-195037dee72c.png\" height=\"200px\">\n</div>\n\nFor [MacaquePose](http://pri.ehub.kyoto-u.ac.jp/datasets/macaquepose/index.html) dataset, images can be downloaded from [download](http://pri.ehub.kyoto-u.ac.jp/datasets/macaquepose/download.php).\nPlease download the annotation files from [macaque_annotations](https://download.openmmlab.com/mmpose/datasets/macaque_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── macaque\n        │-- annotations\n        │   │-- macaque_train.json\n        │   |-- macaque_test.json\n        │-- images\n        │   │-- 01418849d54b3005.jpg\n        │   │-- 0142d1d1a6904a70.jpg\n        │   │-- 01ef2c4c260321b7.jpg\n        │   │-- 020a1c75c8c85238.jpg\n        │   │-- 020b1506eef2557d.jpg\n        │   │-- ...\n```\n\nSince the official dataset does not provide the test set, we randomly select 12500 images for training, and the rest for evaluation (see [code](/tools/dataset/parse_macaquepose_dataset.py)).\n\n## Vinegar Fly\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.nature.com/articles/s41592-018-0234-5\">Vinegar Fly (Nature Methods'2019)</a></summary>\n\n```bibtex\n@article{pereira2019fast,\n  title={Fast animal pose estimation using deep neural networks},\n  author={Pereira, Talmo D and Aldarondo, Diego E and Willmore, Lindsay and Kislin, Mikhail and Wang, Samuel S-H and Murthy, Mala and Shaevitz, Joshua W},\n  journal={Nature methods},\n  volume={16},\n  number={1},\n  pages={117--125},\n  year={2019},\n  publisher={Nature Publishing Group}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227802774-bb4e4ef2-2ade-42ad-80f1-97f2a7faa9e2.png\" height=\"200px\">\n</div>\n\nFor [Vinegar Fly](https://github.com/jgraving/DeepPoseKit-Data) dataset, images can be downloaded from [vinegar_fly_images](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_images.tar).\nPlease download the annotation files from [vinegar_fly_annotations](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── fly\n        │-- annotations\n        │   │-- fly_train.json\n        │   |-- fly_test.json\n        │-- images\n        │   │-- 0.jpg\n        │   │-- 1.jpg\n        │   │-- 2.jpg\n        │   │-- 3.jpg\n        │   │-- ...\n```\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation (see [code](/tools/dataset_converters/parse_deepposekit_dataset.py)).\n\n## Desert Locust\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Desert Locust (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227802779-09d0ec8c-8971-4c67-a315-e2d1355f7f72.png\" height=\"200px\">\n</div>\n\nFor [Desert Locust](https://github.com/jgraving/DeepPoseKit-Data) dataset, images can be downloaded from [locust_images](https://download.openmmlab.com/mmpose/datasets/locust_images.tar).\nPlease download the annotation files from [locust_annotations](https://download.openmmlab.com/mmpose/datasets/locust_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── locust\n        │-- annotations\n        │   │-- locust_train.json\n        │   |-- locust_test.json\n        │-- images\n        │   │-- 0.jpg\n        │   │-- 1.jpg\n        │   │-- 2.jpg\n        │   │-- 3.jpg\n        │   │-- ...\n```\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation (see [code](/tools/dataset_converters/parse_deepposekit_dataset.py)).\n\n## Grévy’s Zebra\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Grévy’s Zebra (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227802783-ace952bb-1ff9-4720-80a8-c63cc9e714b6.png\" height=\"200px\">\n</div>\nFor [Grévy’s Zebra](https://github.com/jgraving/DeepPoseKit-Data) dataset, images can be downloaded from [zebra_images](https://download.openmmlab.com/mmpose/datasets/zebra_images.tar).\nPlease download the annotation files from [zebra_annotations](https://download.openmmlab.com/mmpose/datasets/zebra_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── zebra\n        │-- annotations\n        │   │-- zebra_train.json\n        │   |-- zebra_test.json\n        │-- images\n        │   │-- 0.jpg\n        │   │-- 1.jpg\n        │   │-- 2.jpg\n        │   │-- 3.jpg\n        │   │-- ...\n```\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation (see [code](/tools/dataset_converters/parse_deepposekit_dataset.py)).\n\n## ATRW\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1906.05586\">ATRW (ACM MM'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020atrw,\n  title={ATRW: A Benchmark for Amur Tiger Re-identification in the Wild},\n  author={Li, Shuyuan and Li, Jianguo and Tang, Hanlin and Qian, Rui and Lin, Weiyao},\n  booktitle={Proceedings of the 28th ACM International Conference on Multimedia},\n  pages={2590--2598},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227797386-fce99241-8a0e-4a40-a179-dad013e6c5a4.png\" height=\"200px\">\n</div>\nATRW captures images of the Amur tiger (also known as Siberian tiger, Northeast-China tiger) in the wild.\nFor [ATRW](https://cvwc2019.github.io/challenge.html) dataset, please download images from\n[Pose_train](https://lilablobssc.blob.core.windows.net/cvwc2019/train/atrw_pose_train.tar.gz),\n[Pose_val](https://lilablobssc.blob.core.windows.net/cvwc2019/train/atrw_pose_val.tar.gz), and\n[Pose_test](https://lilablobssc.blob.core.windows.net/cvwc2019/test/atrw_pose_test.tar.gz).\nNote that in the ATRW official annotation files, the key \"file_name\" is written as \"filename\". To make it compatible with\nother coco-type json files, we have modified this key.\nPlease download the modified annotation files from [atrw_annotations](https://download.openmmlab.com/mmpose/datasets/atrw_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── atrw\n        │-- annotations\n        │   │-- keypoint_train.json\n        │   │-- keypoint_val.json\n        │   │-- keypoint_trainval.json\n        │-- images\n        │   │-- train\n        │   │   │-- 000002.jpg\n        │   │   │-- 000003.jpg\n        │   │   │-- ...\n        │   │-- val\n        │   │   │-- 000001.jpg\n        │   │   │-- 000013.jpg\n        │   │   │-- ...\n        │   │-- test\n        │   │   │-- 000000.jpg\n        │   │   │-- 000004.jpg\n        │   │   │-- ...\n```\n\n## Animal Kingdom\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.08129\">Animal Kingdom (CVPR'2022)</a></summary>\n</details>\n<div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/53283758/8591989e-91fa-4f6e-99c8-48b614de862e\" height=\"200px\">\n</div>\n\n```bibtex\n@inproceedings{Ng_2022_CVPR,\n    author    = {Ng, Xun Long and Ong, Kian Eng and Zheng, Qichen and Ni, Yun and Yeo, Si Yong and Liu, Jun},\n    title     = {Animal Kingdom: A Large and Diverse Dataset for Animal Behavior Understanding},\n    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n    month     = {June},\n    year      = {2022},\n    pages     = {19023-19034}\n }\n```\n\nFor [Animal Kingdom](https://github.com/sutdcv/Animal-Kingdom) dataset, images can be downloaded from [here](https://forms.office.com/pages/responsepage.aspx?id=drd2NJDpck-5UGJImDFiPVRYpnTEMixKqPJ1FxwK6VZUQkNTSkRISTNORUI2TDBWMUpZTlQ5WUlaSyQlQCN0PWcu).\nPlease Extract dataset under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ak\n        |--annotations\n        │  │-- ak_P1\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P2\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_amphibian\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_bird\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_fish\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_mammal\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_reptile\n        │      │-- train.json\n        │      │-- test.json\n        │-- images\n        │   │-- AAACXZTV\n        │   │   │--AAACXZTV_f000059.jpg\n        │   │   │--...\n        │   │-- AAAUILHH\n        │   │   │--AAAUILHH_f000098.jpg\n        │   │   │--...\n        │   │-- ...\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/2d_body_keypoint.md",
    "content": "# 2D Body Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- Images\n  - [COCO](#coco) \\[ [Homepage](http://cocodataset.org/) \\]\n  - [MPII](#mpii) \\[ [Homepage](http://human-pose.mpi-inf.mpg.de/) \\]\n  - [MPII-TRB](#mpii-trb) \\[ [Homepage](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) \\]\n  - [AI Challenger](#aic) \\[ [Homepage](https://github.com/AIChallenger/AI_Challenger_2017) \\]\n  - [CrowdPose](#crowdpose) \\[ [Homepage](https://github.com/Jeff-sjtu/CrowdPose) \\]\n  - [OCHuman](#ochuman) \\[ [Homepage](https://github.com/liruilong940607/OCHumanApi) \\]\n  - [MHP](#mhp) \\[ [Homepage](https://lv-mhp.github.io/dataset) \\]\n  - [Human-Art](#humanart) \\[ [Homepage](https://idea-research.github.io/HumanArt/) \\]\n  - [ExLPose](#exlpose-dataset) \\[ [Homepage](http://cg.postech.ac.kr/research/ExLPose/) \\]\n- Videos\n  - [PoseTrack18](#posetrack18) \\[ [Homepage](https://posetrack.net/users/download.php) \\]\n  - [sub-JHMDB](#sub-jhmdb-dataset) \\[ [Homepage](http://jhmdb.is.tue.mpg.de/dataset) \\]\n\n## COCO\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864552-489d03de-e1b8-4ca2-8ac1-80dd99826cb7.png\" height=\"300px\">\n</div>\n\nFor [COCO](http://cocodataset.org/) data, please download from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\n[HRNet-Human-Pose-Estimation](https://github.com/HRNet/HRNet-Human-Pose-Estimation) provides person detection result of COCO val2017 to reproduce our multi-person pose estimation results.\nPlease download from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nOptionally, to evaluate on COCO'2017 test-dev, please download the [image-info](https://download.openmmlab.com/mmpose/datasets/person_keypoints_test-dev-2017.json).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- person_keypoints_train2017.json\n        │   |-- person_keypoints_val2017.json\n        │   |-- person_keypoints_test-dev-2017.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        |   |-- COCO_test-dev2017_detections_AP_H_609_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\n## MPII\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864660-e5f51e7d-deca-41d8-9725-8b5432bcc0e6.png\" height=\"300px\">\n</div>\n\nFor [MPII](http://human-pose.mpi-inf.mpg.de/) data, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/).\nWe have converted the original annotation files into json format, please download them from [mpii_annotations](https://download.openmmlab.com/mmpose/datasets/mpii_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mpii\n        |── annotations\n        |   |── mpii_gt_val.mat\n        |   |── mpii_test.json\n        |   |── mpii_train.json\n        |   |── mpii_trainval.json\n        |   `── mpii_val.json\n        `── images\n            |── 000001163.jpg\n            |── 000003072.jpg\n\n```\n\nDuring training and inference, the prediction result will be saved as '.mat' format by default. We also provide a tool to convert this '.mat' to more readable '.json' format.\n\n```shell\npython tools/dataset/mat2json ${PRED_MAT_FILE} ${GT_JSON_FILE} ${OUTPUT_PRED_JSON_FILE}\n```\n\nFor example,\n\n```shell\npython tools/dataset/mat2json work_dirs/res50_mpii_256x256/pred.mat data/mpii/annotations/mpii_val.json pred.json\n```\n\n## MPII-TRB\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Duan_TRB_A_Novel_Triplet_Representation_for_Understanding_2D_Human_Body_ICCV_2019_paper.html\">MPII-TRB (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{duan2019trb,\n  title={TRB: A Novel Triplet Representation for Understanding 2D Human Body},\n  author={Duan, Haodong and Lin, Kwan-Yee and Jin, Sheng and Liu, Wentao and Qian, Chen and Ouyang, Wanli},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={9479--9488},\n  year={2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864382-ab722299-6806-4ae4-babb-7bcc5fb09662.png\" height=\"300px\">\n</div>\n\nFor [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) data, please download from [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/).\nPlease download the annotation files from [mpii_trb_annotations](https://download.openmmlab.com/mmpose/datasets/mpii_trb_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mpii\n        |── annotations\n        |   |── mpii_trb_train.json\n        |   |── mpii_trb_val.json\n        `── images\n            |── 000001163.jpg\n            |── 000003072.jpg\n\n```\n\n## AIC\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864755-dd19644e-fccb-458b-a8c0-de55920261f5.png\" height=\"300px\">\n</div>\n\nFor [AIC](https://github.com/AIChallenger/AI_Challenger_2017) data, please download from [AI Challenger 2017](https://github.com/AIChallenger/AI_Challenger_2017), 2017 Train/Val is needed for keypoints training and validation.\nPlease download the annotation files from [aic_annotations](https://download.openmmlab.com/mmpose/datasets/aic_annotations.tar).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── aic\n        │-- annotations\n        │   │-- aic_train.json\n        │   |-- aic_val.json\n        │-- ai_challenger_keypoint_train_20170902\n        │   │-- keypoint_train_images_20170902\n        │   │   │-- 0000252aea98840a550dac9a78c476ecb9f47ffa.jpg\n        │   │   │-- 000050f770985ac9653198495ef9b5c82435d49c.jpg\n        │   │   │-- ...\n        `-- ai_challenger_keypoint_validation_20170911\n            │-- keypoint_validation_images_20170911\n                │-- 0002605c53fb92109a3f2de4fc3ce06425c3b61f.jpg\n                │-- 0003b55a2c991223e6d8b4b820045bd49507bf6d.jpg\n                │-- ...\n```\n\n## CrowdPose\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864868-54a98493-df3a-44d8-acbc-6ec22043dfb9.png\" height=\"300px\">\n</div>\n\nFor [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose) data, please download from [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose).\nPlease download the annotation files and human detection results from [crowdpose_annotations](https://download.openmmlab.com/mmpose/datasets/crowdpose_annotations.tar).\nFor top-down approaches, we follow [CrowdPose](https://arxiv.org/abs/1812.00324) to use the [pre-trained weights](https://pjreddie.com/media/files/yolov3.weights) of [YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) to generate the detected human bounding boxes.\nFor model training, we follow [HigherHRNet](https://github.com/HRNet/HigherHRNet-Human-Pose-Estimation) to train models on CrowdPose train/val dataset, and evaluate models on CrowdPose test dataset.\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── crowdpose\n        │-- annotations\n        │   │-- mmpose_crowdpose_train.json\n        │   │-- mmpose_crowdpose_val.json\n        │   │-- mmpose_crowdpose_trainval.json\n        │   │-- mmpose_crowdpose_test.json\n        │   │-- det_for_crowd_test_0.1_0.5.json\n        │-- images\n            │-- 100000.jpg\n            │-- 100001.jpg\n            │-- 100002.jpg\n            │-- ...\n```\n\n## OCHuman\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Zhang_Pose2Seg_Detection_Free_Human_Instance_Segmentation_CVPR_2019_paper.html\">OCHuman (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{zhang2019pose2seg,\n  title={Pose2seg: Detection free human instance segmentation},\n  author={Zhang, Song-Hai and Li, Ruilong and Dong, Xin and Rosin, Paul and Cai, Zixi and Han, Xi and Yang, Dingcheng and Huang, Haozhi and Hu, Shi-Min},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={889--898},\n  year={2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864552-489d03de-e1b8-4ca2-8ac1-80dd99826cb7.png\" height=\"300px\">\n</div>\n\nFor [OCHuman](https://github.com/liruilong940607/OCHumanApi) data, please download the images and annotations from [OCHuman](https://github.com/liruilong940607/OCHumanApi),\nMove them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ochuman\n        │-- annotations\n        │   │-- ochuman_coco_format_val_range_0.00_1.00.json\n        │   |-- ochuman_coco_format_test_range_0.00_1.00.json\n        |-- images\n            │-- 000001.jpg\n            │-- 000002.jpg\n            │-- 000003.jpg\n            │-- ...\n\n```\n\n## MHP\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://dl.acm.org/doi/abs/10.1145/3240508.3240509\">MHP (ACM MM'2018)</a></summary>\n\n```bibtex\n@inproceedings{zhao2018understanding,\n  title={Understanding humans in crowded scenes: Deep nested adversarial learning and a new benchmark for multi-human parsing},\n  author={Zhao, Jian and Li, Jianshu and Cheng, Yu and Sim, Terence and Yan, Shuicheng and Feng, Jiashi},\n  booktitle={Proceedings of the 26th ACM international conference on Multimedia},\n  pages={792--800},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227865030-2fd33ade-2cc2-4b67-aca0-6dea2124b63c.png\" height=\"300px\">\n</div>\n\nFor [MHP](https://lv-mhp.github.io/dataset) data, please download from [MHP](https://lv-mhp.github.io/dataset).\nPlease download the annotation files from [mhp_annotations](https://download.openmmlab.com/mmpose/datasets/mhp_annotations.tar.gz).\nPlease download and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mhp\n        │-- annotations\n        │   │-- mhp_train.json\n        │   │-- mhp_val.json\n        │\n        `-- train\n        │   │-- images\n        │   │   │-- 1004.jpg\n        │   │   │-- 10050.jpg\n        │   │   │-- ...\n        │\n        `-- val\n        │   │-- images\n        │   │   │-- 10059.jpg\n        │   │   │-- 10068.jpg\n        │   │   │-- ...\n        │\n        `-- test\n        │   │-- images\n        │   │   │-- 1005.jpg\n        │   │   │-- 10052.jpg\n        │   │   │-- ...~~~~\n```\n\n## Human-Art dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://idea-research.github.io/HumanArt/\">Human-Art (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ju2023humanart,\n    title={Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes},\n    author={Ju, Xuan and Zeng, Ailing and Jianan, Wang and Qiang, Xu and Lei, Zhang},\n    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR),\n    year={2023}}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864552-489d03de-e1b8-4ca2-8ac1-80dd99826cb7.png\" height=\"300px\">\n</div>\n\nFor [Human-Art](https://idea-research.github.io/HumanArt/) data, please download the images and annotation files from [its website](https://idea-research.github.io/HumanArt/). You need to fill in the [data form](https://docs.google.com/forms/d/e/1FAIpQLScroT_jvw6B9U2Qca1_cl5Kmmu1ceKtlh6DJNmWLte8xNEhEw/viewform) to get access to the data.\nMove them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n|── data\n    │── HumanArt\n        │-- images\n        │   │-- 2D_virtual_human\n        │   │   |-- cartoon\n        │   │   |   |-- 000000000000.jpg\n        │   │   |   |-- ...\n        │   │   |-- digital_art\n        │   │   |-- ...\n        │   |-- 3D_virtual_human\n        │   |-- real_human\n        |-- annotations\n        │   │-- validation_humanart.json\n        │   │-- training_humanart_coco.json\n        |-- person_detection_results\n        │   │-- HumanArt_validation_detections_AP_H_56_person.json\n```\n\nYou can choose whether to download other annotation files in Human-Art. If you want to use additional annotation files (e.g. validation set of cartoon), you need to edit the corresponding code in config file.\n\n## ExLPose dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://cg.postech.ac.kr/research/ExLPose/\">ExLPose (2023)</a></summary>\n\n```bibtex\n@inproceedings{ExLPose_2023_CVPR,\n title={Human Pose Estimation in Extremely Low-Light Conditions},\n author={Sohyun Lee, Jaesung Rim, Boseung Jeong, Geonu Kim, ByungJu Woo, Haechan Lee, Sunghyun Cho, Suha Kwak},\n booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n year={2023}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/71805205/d2c7d552-249a-4ac0-8ac3-1467ace59f2f\" height=\"300px\">\n</div>\n\nFor [ExLPose](http://cg.postech.ac.kr/research/ExLPose/) data, please download from [ExLPose](https://drive.google.com/drive/folders/1E0Is4_cShxvsbJlep_aNEYLJpmHzq9FL),\nMove them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ExLPose\n        │-- annotations\n        |   |-- ExLPose\n        │       |-- ExLPose_test_LL-A.json\n        │       |-- ExLPose_test_LL-E.json\n        │       |-- ExLPose_test_LL-H.json\n        │       |-- ExLPose_test_LL-N.json\n        │       |-- ExLPose_test_WL.json\n        │       |-- ExLPose_train_LL.json\n        │       |-- ExLPose_train_WL.json\n        |-- bright\n        |   |-- imgs_0119_3_vid000002_exp100_bright_000052__gain_0.00_exposure_1000.png\n        |   |-- imgs_0119_3_vid000002_exp200_bright_000052__gain_6.02_exposure_500.png\n        |   |-- ...\n        |-- dark\n            |-- imgs_0119_3_vid000002_exp100_dark_000052__gain_0.00_exposure_1000.png\n            |-- imgs_0119_3_vid000005_exp200_dark_000002__gain_1.60_exposure_500.png\n            |-- ...\n```\n\n## PoseTrack18\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Andriluka_PoseTrack_A_Benchmark_CVPR_2018_paper.html\">PoseTrack18 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{andriluka2018posetrack,\n  title={Posetrack: A benchmark for human pose estimation and tracking},\n  author={Andriluka, Mykhaylo and Iqbal, Umar and Insafutdinov, Eldar and Pishchulin, Leonid and Milan, Anton and Gall, Juergen and Schiele, Bernt},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={5167--5176},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227865114-3f98c673-f6d0-4518-ae99-653f475f9fc8.png\" height=\"300px\">\n</div>\n\nFor [PoseTrack18](https://posetrack.net/users/download.php) data, please download from [PoseTrack18](https://posetrack.net/users/download.php).\nPlease download the annotation files from [posetrack18_annotations](https://download.openmmlab.com/mmpose/datasets/posetrack18_annotations.tar).\nWe have merged the video-wise separated official annotation files into two json files (posetrack18_train & posetrack18_val.json). We also generate the [mask files](https://download.openmmlab.com/mmpose/datasets/posetrack18_mask.tar) to speed up training.\nFor top-down approaches, we use [MMDetection](https://github.com/open-mmlab/mmdetection) pre-trained [Cascade R-CNN](https://download.openmmlab.com/mmdetection/v2.0/cascade_rcnn/cascade_rcnn_x101_64x4d_fpn_20e_coco/cascade_rcnn_x101_64x4d_fpn_20e_coco_20200509_224357-051557b1.pth) (X-101-64x4d-FPN) to generate the detected human bounding boxes.\nPlease download and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── posetrack18\n        │-- annotations\n        │   │-- posetrack18_train.json\n        │   │-- posetrack18_val.json\n        │   │-- posetrack18_val_human_detections.json\n        │   │-- train\n        │   │   │-- 000001_bonn_train.json\n        │   │   │-- 000002_bonn_train.json\n        │   │   │-- ...\n        │   │-- val\n        │   │   │-- 000342_mpii_test.json\n        │   │   │-- 000522_mpii_test.json\n        │   │   │-- ...\n        │   `-- test\n        │       │-- 000001_mpiinew_test.json\n        │       │-- 000002_mpiinew_test.json\n        │       │-- ...\n        │\n        `-- images\n        │   │-- train\n        │   │   │-- 000001_bonn_train\n        │   │   │   │-- 000000.jpg\n        │   │   │   │-- 000001.jpg\n        │   │   │   │-- ...\n        │   │   │-- ...\n        │   │-- val\n        │   │   │-- 000342_mpii_test\n        │   │   │   │-- 000000.jpg\n        │   │   │   │-- 000001.jpg\n        │   │   │   │-- ...\n        │   │   │-- ...\n        │   `-- test\n        │       │-- 000001_mpiinew_test\n        │       │   │-- 000000.jpg\n        │       │   │-- 000001.jpg\n        │       │   │-- ...\n        │       │-- ...\n        `-- mask\n            │-- train\n            │   │-- 000002_bonn_train\n            │   │   │-- 000000.jpg\n            │   │   │-- 000001.jpg\n            │   │   │-- ...\n            │   │-- ...\n            `-- val\n                │-- 000522_mpii_test\n                │   │-- 000000.jpg\n                │   │-- 000001.jpg\n                │   │-- ...\n                │-- ...\n```\n\nThe official evaluation tool for PoseTrack should be installed from GitHub.\n\n```shell\npip install git+https://github.com/svenkreiss/poseval.git\n```\n\n## sub-JHMDB dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RSN (ECCV'2020)</a></summary>\n\n```bibtex\n@misc{cai2020learning,\n    title={Learning Delicate Local Representations for Multi-Person Pose Estimation},\n    author={Yuanhao Cai and Zhicheng Wang and Zhengxiong Luo and Binyi Yin and Angang Du and Haoqian Wang and Xinyu Zhou and Erjin Zhou and Xiangyu Zhang and Jian Sun},\n    year={2020},\n    eprint={2003.04030},\n    archivePrefix={arXiv},\n    primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227865619-d65f64ae-991d-4693-99c2-caecd1beb1fc.png\" height=\"300px\">\n</div>\n\nFor [sub-JHMDB](http://jhmdb.is.tue.mpg.de/dataset) data, please download the [images](<(http://files.is.tue.mpg.de/jhmdb/Rename_Images.tar.gz)>) from [JHMDB](http://jhmdb.is.tue.mpg.de/dataset),\nPlease download the annotation files from [jhmdb_annotations](https://download.openmmlab.com/mmpose/datasets/jhmdb_annotations.tar).\nMove them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── jhmdb\n        │-- annotations\n        │   │-- Sub1_train.json\n        │   |-- Sub1_test.json\n        │   │-- Sub2_train.json\n        │   |-- Sub2_test.json\n        │   │-- Sub3_train.json\n        │   |-- Sub3_test.json\n        |-- Rename_Images\n            │-- brush_hair\n            │   │--April_09_brush_hair_u_nm_np1_ba_goo_0\n            |   │   │--00001.png\n            |   │   │--00002.png\n            │-- catch\n            │-- ...\n\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/2d_face_keypoint.md",
    "content": "# 2D Face Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [300W](#300w-dataset) \\[ [Homepage](https://ibug.doc.ic.ac.uk/resources/300-W/) \\]\n- [300VW](#300vw-dataset) \\[ [Homepage](https://ibug.doc.ic.ac.uk/resources/300-VW/) \\]\n- [WFLW](#wflw-dataset) \\[ [Homepage](https://wywu.github.io/projects/LAB/WFLW.html) \\]\n- [AFLW](#aflw-dataset) \\[ [Homepage](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/) \\]\n- [COFW](#cofw-dataset) \\[ [Homepage](http://www.vision.caltech.edu/xpburgos/ICCV13/) \\]\n- [COCO-WholeBody-Face](#coco-wholebody-face) \\[ [Homepage](https://github.com/jin-s13/COCO-WholeBody/) \\]\n- [LaPa](#lapa-dataset) \\[ [Homepage](https://github.com/JDAI-CV/lapa-dataset) \\]\n\n## 300W Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.sciencedirect.com/science/article/pii/S0262885616000147\">300W (IMAVIS'2016)</a></summary>\n\n```bibtex\n@article{sagonas2016300,\n  title={300 faces in-the-wild challenge: Database and results},\n  author={Sagonas, Christos and Antonakos, Epameinondas and Tzimiropoulos, Georgios and Zafeiriou, Stefanos and Pantic, Maja},\n  journal={Image and vision computing},\n  volume={47},\n  pages={3--18},\n  year={2016},\n  publisher={Elsevier}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227780043-e557acc3-5966-48ba-ac9e-b6c5916f1e55.jpg\" height=\"200px\">\n</div>\n\nFor 300W data, please download images from [300W Dataset](https://ibug.doc.ic.ac.uk/resources/300-W/).\nPlease download the annotation files from [300w_annotations](https://download.openmmlab.com/mmpose/datasets/300w_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── 300w\n        |── annotations\n        |   |── face_landmarks_300w_train.json\n        |   |── face_landmarks_300w_valid.json\n        |   |── face_landmarks_300w_valid_common.json\n        |   |── face_landmarks_300w_valid_challenge.json\n        |   |── face_landmarks_300w_test.json\n        `── images\n            |── afw\n            |   |── 1051618982_1.jpg\n            |   |── 111076519_1.jpg\n            |    ...\n            |── helen\n            |   |── trainset\n            |   |   |── 100032540_1.jpg\n            |   |   |── 100040721_1.jpg\n            |   |    ...\n            |   |── testset\n            |   |   |── 296814969_3.jpg\n            |   |   |── 2968560214_1.jpg\n            |   |    ...\n            |── ibug\n            |   |── image_003_1.jpg\n            |   |── image_004_1.jpg\n            |    ...\n            |── lfpw\n            |   |── trainset\n            |   |   |── image_0001.png\n            |   |   |── image_0002.png\n            |   |    ...\n            |   |── testset\n            |   |   |── image_0001.png\n            |   |   |── image_0002.png\n            |   |    ...\n            `── Test\n                |── 01_Indoor\n                |   |── indoor_001.png\n                |   |── indoor_002.png\n                |    ...\n                `── 02_Outdoor\n                    |── outdoor_001.png\n                    |── outdoor_002.png\n                     ...\n```\n\n## 300VW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2015_workshops/w25/papers/Shen_The_First_Facial_ICCV_2015_paper.pdf\">300VW (ICCVW'2015)</a></summary>\n\n```bibtex\n@inproceedings{shen2015first,\n  title={The first facial landmark tracking in-the-wild challenge: Benchmark and results},\n  author={Shen, Jie and Zafeiriou, Stefanos and Chrysos, Grigoris G and Kossaifi, Jean and Tzimiropoulos, Georgios and Pantic, Maja},\n  booktitle={Proceedings of the IEEE international conference on computer vision workshops},\n  pages={50--58},\n  year={2015}\n}\n```\n\n</details>\n\nFor 300VW data, please register and download images from [300VW Dataset](https://ibug.doc.ic.ac.uk/download/300VW_Dataset_2015_12_14.zip/).\nUnzip and use the \"tools/dataset_converters/300vw2coco.py\" to process the data.\n\n<!-- Please download the annotation files from [300w_annotations](https://download.openmmlab.com/mmpose/datasets/300w_annotations.tar). -->\n\nPut the 300VW under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── 300vw\n        |── annotations\n        |   |── train.json\n        |   |── test_1.json\n        |   |── test_2.json\n        |   `── test_3.json\n        `── images\n            |── 001\n            |   `── imgs\n            |       |── 000001.png\n            |       |── 000002.png\n            |       ...\n            |── 002\n            |   `── imgs\n            |       |── 000001.png\n            |       |── 000002.png\n            |       ...\n            |   ...\n```\n\n## WFLW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227785100-4b3d1e39-0d64-47c0-9e55-c947ce70866e.png\" height=\"200px\">\n</div>\n\nFor WFLW data, please download images from [WFLW Dataset](https://wywu.github.io/projects/LAB/WFLW.html).\nPlease download the annotation files from [wflw_annotations](https://download.openmmlab.com/mmpose/datasets/wflw_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── wflw\n        |── annotations\n        |   |── face_landmarks_wflw_train.json\n        |   |── face_landmarks_wflw_test.json\n        |   |── face_landmarks_wflw_test_blur.json\n        |   |── face_landmarks_wflw_test_occlusion.json\n        |   |── face_landmarks_wflw_test_expression.json\n        |   |── face_landmarks_wflw_test_largepose.json\n        |   |── face_landmarks_wflw_test_illumination.json\n        |   |── face_landmarks_wflw_test_makeup.json\n        |\n        `── images\n            |── 0--Parade\n            |   |── 0_Parade_marchingband_1_1015.jpg\n            |   |── 0_Parade_marchingband_1_1031.jpg\n            |    ...\n            |── 1--Handshaking\n            |   |── 1_Handshaking_Handshaking_1_105.jpg\n            |   |── 1_Handshaking_Handshaking_1_107.jpg\n            |    ...\n            ...\n```\n\nWe also supply a script which can convert the raw WFLW annotations to COCO style. The script's output is not completely consistent with the annotations downloaded from the URL, but it does not affect training and testing.\n\n## AFLW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6130513/\">AFLW (ICCVW'2011)</a></summary>\n\n```bibtex\n@inproceedings{koestinger2011annotated,\n  title={Annotated facial landmarks in the wild: A large-scale, real-world database for facial landmark localization},\n  author={Koestinger, Martin and Wohlhart, Paul and Roth, Peter M and Bischof, Horst},\n  booktitle={2011 IEEE international conference on computer vision workshops (ICCV workshops)},\n  pages={2144--2151},\n  year={2011},\n  organization={IEEE}\n}\n```\n\n</details>\n\nFor AFLW data, please download images from [AFLW Dataset](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/).\nPlease download the annotation files from [aflw_annotations](https://download.openmmlab.com/mmpose/datasets/aflw_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── aflw\n        |── annotations\n        |   |── face_landmarks_aflw_train.json\n        |   |── face_landmarks_aflw_test_frontal.json\n        |   |── face_landmarks_aflw_test.json\n        `── images\n            |── flickr\n                |── 0\n                |   |── image00002.jpg\n                |   |── image00013.jpg\n                |    ...\n                |── 2\n                |   |── image00004.jpg\n                |   |── image00006.jpg\n                |    ...\n                `── 3\n                    |── image00032.jpg\n                    |── image00035.jpg\n                     ...\n```\n\n## COFW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2013/html/Burgos-Artizzu_Robust_Face_Landmark_2013_ICCV_paper.html\">COFW (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{burgos2013robust,\n  title={Robust face landmark estimation under occlusion},\n  author={Burgos-Artizzu, Xavier P and Perona, Pietro and Doll{\\'a}r, Piotr},\n  booktitle={Proceedings of the IEEE international conference on computer vision},\n  pages={1513--1520},\n  year={2013}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227786792-06604943-c062-4bcd-bb2d-a2f78d80115b.png\" height=\"200px\">\n</div>\n\nFor COFW data, please download from [COFW Dataset (Color Images)](http://www.vision.caltech.edu/xpburgos/ICCV13/Data/COFW_color.zip).\nMove `COFW_train_color.mat` and `COFW_test_color.mat` to `data/cofw/` and make them look like:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n```\n\nRun the following script under `{MMPose}/data`\n\n`python tools/dataset_converters/parse_cofw_dataset.py`\n\nAnd you will get\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n        |── annotations\n        |   |── cofw_train.json\n        |   |── cofw_test.json\n        |── images\n            |── 000001.jpg\n            |── 000002.jpg\n```\n\n## COCO-WholeBody (Face)\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227787217-2f226dc0-e5d7-4d0b-9ab8-68b53a5467c2.png\" height=\"200px\">\n</div>\n\nFor [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/) dataset, images can be downloaded from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\nDownload COCO-WholeBody annotations for COCO-WholeBody annotations for [Train](https://drive.google.com/file/d/1thErEToRbmM9uLNi1JXXfOsaS5VK2FXf/view?usp=sharing) / [Validation](https://drive.google.com/file/d/1N6VgwKnj8DeyGXCvp1eYgNbRmw6jdfrb/view?usp=sharing) (Google Drive).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- coco_wholebody_train_v1.0.json\n        │   |-- coco_wholebody_val_v1.0.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n\n## LaPa\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://aaai.org/ojs/index.php/AAAI/article/view/6832/6686\">LaPa (AAAI'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020new,\n  title={A New Dataset and Boundary-Attention Semantic Segmentation for Face Parsing.},\n  author={Liu, Yinglu and Shi, Hailin and Shen, Hao and Si, Yue and Wang, Xiaobo and Mei, Tao},\n  booktitle={AAAI},\n  pages={11637--11644},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://github.com/lucia123/lapa-dataset/raw/master/sample.png\" height=\"200px\">\n</div>\n\nFor [LaPa](https://github.com/JDAI-CV/lapa-dataset) dataset, images can be downloaded from [their github page](https://github.com/JDAI-CV/lapa-dataset).\n\nDownload and extract them under $MMPOSE/data, and use our `tools/dataset_converters/lapa2coco.py` to make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── LaPa\n        │-- annotations\n        │   │-- lapa_train.json\n        │   |-- lapa_val.json\n        │   |-- lapa_test.json\n        |   |-- lapa_trainval.json\n        │-- train\n        │   │-- images\n        │   │-- labels\n        │   │-- landmarks\n        │-- val\n        │   │-- images\n        │   │-- labels\n        │   │-- landmarks\n        `-- test\n        │   │-- images\n        │   │-- labels\n        │   │-- landmarks\n\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/2d_fashion_landmark.md",
    "content": "# 2D Fashion Landmark Dataset\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [DeepFashion](#deepfashion) \\[ [Homepage](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html) \\]\n- [DeepFashion2](#deepfashion2) \\[ [Homepage](https://github.com/switchablenorms/DeepFashion2) \\]\n\n## DeepFashion (Fashion Landmark Detection, FLD)\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Liu_DeepFashion_Powering_Robust_CVPR_2016_paper.html\">DeepFashion (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuLQWTcvpr16DeepFashion,\n author = {Liu, Ziwei and Luo, Ping and Qiu, Shi and Wang, Xiaogang and Tang, Xiaoou},\n title = {DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations},\n booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n month = {June},\n year = {2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46475-6_15\">DeepFashion (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuYLWTeccv16FashionLandmark,\n author = {Liu, Ziwei and Yan, Sijie and Luo, Ping and Wang, Xiaogang and Tang, Xiaoou},\n title = {Fashion Landmark Detection in the Wild},\n booktitle = {European Conference on Computer Vision (ECCV)},\n month = {October},\n year = {2016}\n }\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227774588-443fc5cc-7842-472a-abd5-827f0e3fd27f.png\" height=\"150px\">\n</div>\n\nFor [DeepFashion](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html) dataset, images can be downloaded from [download](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html).\nPlease download the annotation files from [fld_annotations](https://download.openmmlab.com/mmpose/datasets/fld_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── fld\n        │-- annotations\n        │   │-- fld_upper_train.json\n        │   |-- fld_upper_val.json\n        │   |-- fld_upper_test.json\n        │   │-- fld_lower_train.json\n        │   |-- fld_lower_val.json\n        │   |-- fld_lower_test.json\n        │   │-- fld_full_train.json\n        │   |-- fld_full_val.json\n        │   |-- fld_full_test.json\n        │-- img\n        │   │-- img_00000001.jpg\n        │   │-- img_00000002.jpg\n        │   │-- img_00000003.jpg\n        │   │-- img_00000004.jpg\n        │   │-- img_00000005.jpg\n        │   │-- ...\n```\n\n## DeepFashion2\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/1901.07973.pdf\">DeepFashion2 (CVPR'2019)</a></summary>\n\n```bibtex\n@article{DeepFashion2,\n  author = {Yuying Ge and Ruimao Zhang and Lingyun Wu and Xiaogang Wang and Xiaoou Tang and Ping Luo},\n  title={A Versatile Benchmark for Detection, Pose Estimation, Segmentation and Re-Identification of Clothing Images},\n  journal={CVPR},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\nFor [DeepFashion2](https://github.com/switchablenorms/DeepFashion2) dataset, images can be downloaded from [download](https://drive.google.com/drive/folders/125F48fsMBz2EF0Cpqk6aaHet5VH399Ok?usp=sharing).\nPlease download the [annotation files](https://drive.google.com/file/d/1RM9l9EaB9ULRXhoCS72PkCXtJ4Cn4i6O/view?usp=share_link). These annotation files are converted by [deepfashion2_to_coco.py](https://github.com/switchablenorms/DeepFashion2/blob/master/evaluation/deepfashion2_to_coco.py).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── deepfashion2\n        │── train\n            │-- deepfashion2_short_sleeved_outwear_train.json\n            │-- deepfashion2_short_sleeved_dress_train.json\n            │-- deepfashion2_skirt_train.json\n            │-- deepfashion2_sling_dress_train.json\n            │-- ...\n            │-- image\n            │   │-- 000001.jpg\n            │   │-- 000002.jpg\n            │   │-- 000003.jpg\n            │   │-- 000004.jpg\n            │   │-- 000005.jpg\n            │   │-- ...\n        │── validation\n            │-- deepfashion2_short_sleeved_dress_validation.json\n            │-- deepfashion2_long_sleeved_shirt_validation.json\n            │-- deepfashion2_trousers_validation.json\n            │-- deepfashion2_skirt_validation.json\n            │-- ...\n            │-- image\n            │   │-- 000001.jpg\n            │   │-- 000002.jpg\n            │   │-- 000003.jpg\n            │   │-- 000004.jpg\n            │   │-- 000005.jpg\n            │   │-- ...\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/2d_hand_keypoint.md",
    "content": "# 2D Hand Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [OneHand10K](#onehand10k) \\[ [Homepage](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) \\]\n- [FreiHand](#freihand-dataset) \\[ [Homepage](https://lmb.informatik.uni-freiburg.de/projects/freihand/) \\]\n- [CMU Panoptic HandDB](#cmu-panoptic-handdb) \\[ [Homepage](http://domedb.perception.cs.cmu.edu/handdb.html) \\]\n- [InterHand2.6M](#interhand26m) \\[ [Homepage](https://mks0601.github.io/InterHand2.6M/) \\]\n- [RHD](#rhd-dataset) \\[ [Homepage](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html) \\]\n- [COCO-WholeBody-Hand](#coco-wholebody-hand) \\[ [Homepage](https://github.com/jin-s13/COCO-WholeBody/) \\]\n\n## OneHand10K\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) data, please download from [OneHand10K Dataset](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html).\nPlease download the annotation files from [onehand10k_annotations](https://download.openmmlab.com/mmpose/datasets/onehand10k_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── onehand10k\n        |── annotations\n        |   |── onehand10k_train.json\n        |   |── onehand10k_test.json\n        `── Train\n        |   |── source\n        |       |── 0.jpg\n        |       |── 1.jpg\n        |        ...\n        `── Test\n            |── source\n                |── 0.jpg\n                |── 1.jpg\n\n```\n\n## FreiHAND Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Zimmermann_FreiHAND_A_Dataset_for_Markerless_Capture_of_Hand_Pose_and_ICCV_2019_paper.html\">FreiHand (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{zimmermann2019freihand,\n  title={Freihand: A dataset for markerless capture of hand pose and shape from single rgb images},\n  author={Zimmermann, Christian and Ceylan, Duygu and Yang, Jimei and Russell, Bryan and Argus, Max and Brox, Thomas},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={813--822},\n  year={2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [FreiHAND](https://lmb.informatik.uni-freiburg.de/projects/freihand/) data, please download from [FreiHand Dataset](https://lmb.informatik.uni-freiburg.de/resources/datasets/FreihandDataset.en.html).\nSince the official dataset does not provide validation set, we randomly split the training data into 8:1:1 for train/val/test.\nPlease download the annotation files from [freihand_annotations](https://download.openmmlab.com/mmpose/datasets/frei_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── freihand\n        |── annotations\n        |   |── freihand_train.json\n        |   |── freihand_val.json\n        |   |── freihand_test.json\n        `── training\n            |── rgb\n            |   |── 00000000.jpg\n            |   |── 00000001.jpg\n            |    ...\n            |── mask\n                |── 00000000.jpg\n                |── 00000001.jpg\n                 ...\n```\n\n## CMU Panoptic HandDB\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2017/html/Simon_Hand_Keypoint_Detection_CVPR_2017_paper.html\">CMU Panoptic HandDB (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{simon2017hand,\n  title={Hand keypoint detection in single images using multiview bootstrapping},\n  author={Simon, Tomas and Joo, Hanbyul and Matthews, Iain and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={1145--1153},\n  year={2017}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html), please download from [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html).\nFollowing [Simon et al](https://arxiv.org/abs/1704.07809), panoptic images (hand143_panopticdb) and MPII & NZSL training sets (manual_train) are used for training, while MPII & NZSL test set (manual_test) for testing.\nPlease download the annotation files from [panoptic_annotations](https://download.openmmlab.com/mmpose/datasets/panoptic_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── panoptic\n        |── annotations\n        |   |── panoptic_train.json\n        |   |── panoptic_test.json\n        |\n        `── hand143_panopticdb\n        |   |── imgs\n        |   |   |── 00000000.jpg\n        |   |   |── 00000001.jpg\n        |   |    ...\n        |\n        `── hand_labels\n            |── manual_train\n            |   |── 000015774_01_l.jpg\n            |   |── 000015774_01_r.jpg\n            |    ...\n            |\n            `── manual_test\n                |── 000648952_02_l.jpg\n                |── 000835470_01_l.jpg\n                 ...\n```\n\n## InterHand2.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterHand2.6M (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771753-5df1d722-59bd-4815-b85f-64a5ef79bbf5.png\" height=\"200px\">\n</div>\n\nFor [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/), please download from [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/).\nPlease download the annotation files from [annotations](https://download.openmmlab.com/mmpose/datasets/interhand2.6m_annotations.zip).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── interhand2.6m\n        |── annotations\n        |   |── all\n        |   |── human_annot\n        |   |── machine_annot\n        |   |── skeleton.txt\n        |   |── subject.txt\n        |\n        `── images\n        |   |── train\n        |   |   |-- Capture0 ~ Capture26\n        |   |── val\n        |   |   |-- Capture0\n        |   |── test\n        |   |   |-- Capture0 ~ Capture7\n```\n\n## RHD Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227772014-f7406a2b-2e64-42fb-8081-200d40104553.png\" height=\"200px\">\n</div>\n\nFor [RHD Dataset](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html), please download from [RHD Dataset](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html).\nPlease download the annotation files from [rhd_annotations](https://download.openmmlab.com/mmpose/datasets/rhd_annotations.zip).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── rhd\n        |── annotations\n        |   |── rhd_train.json\n        |   |── rhd_test.json\n        `── training\n        |   |── color\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── depth\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── mask\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        `── evaluation\n        |   |── color\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── depth\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── mask\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n```\n\n## COCO-WholeBody (Hand)\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/) dataset, images can be downloaded from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\nDownload COCO-WholeBody annotations for COCO-WholeBody annotations for [Train](https://drive.google.com/file/d/1thErEToRbmM9uLNi1JXXfOsaS5VK2FXf/view?usp=sharing) / [Validation](https://drive.google.com/file/d/1N6VgwKnj8DeyGXCvp1eYgNbRmw6jdfrb/view?usp=sharing) (Google Drive).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- coco_wholebody_train_v1.0.json\n        │   |-- coco_wholebody_val_v1.0.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n"
  },
  {
    "path": "docs/en/dataset_zoo/2d_wholebody_keypoint.md",
    "content": "# 2D Wholebody Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [COCO-WholeBody](#coco-wholebody) \\[ [Homepage](https://github.com/jin-s13/COCO-WholeBody/) \\]\n- [Halpe](#halpe) \\[ [Homepage](https://github.com/Fang-Haoshu/Halpe-FullBody/) \\]\n\n## COCO-WholeBody\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227770977-c8f00355-c43a-467e-8444-d307789cf4b2.png\" height=\"300px\">\n</div>\n\nFor [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/) dataset, images can be downloaded from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\nDownload COCO-WholeBody annotations for COCO-WholeBody annotations for [Train](https://drive.google.com/file/d/1thErEToRbmM9uLNi1JXXfOsaS5VK2FXf/view?usp=sharing) / [Validation](https://drive.google.com/file/d/1N6VgwKnj8DeyGXCvp1eYgNbRmw6jdfrb/view?usp=sharing) (Google Drive).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- coco_wholebody_train_v1.0.json\n        │   |-- coco_wholebody_val_v1.0.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) (version>=1.5) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n\n## Halpe\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2004.00945\">Halpe (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020pastanet,\n  title={PaStaNet: Toward Human Activity Knowledge Engine},\n  author={Li, Yong-Lu and Xu, Liang and Liu, Xinpeng and Huang, Xijie and Xu, Yue and Wang, Shiyi and Fang, Hao-Shu and Ma, Ze and Chen, Mingyang and Lu, Cewu},\n  booktitle={CVPR},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771087-b839ea5b-4461-4ba7-8a9a-823b78e2ca44.png\" height=\"300px\">\n</div>\n\nFor [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/) dataset, please download images and annotations from [Halpe download](https://github.com/Fang-Haoshu/Halpe-FullBody).\nThe images of the training set are from [HICO-Det](https://drive.google.com/open?id=1QZcJmGVlF9f4h-XLWe9Gkmnmj2z1gSnk) and those of the validation set are from [COCO](http://images.cocodataset.org/zips/val2017.zip).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── halpe\n        │-- annotations\n        │   │-- halpe_train_v1.json\n        │   |-- halpe_val_v1.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- hico_20160224_det\n        │   │-- anno_bbox.mat\n        │   │-- anno.mat\n        │   │-- README\n        │   │-- images\n        │   │   │-- train2015\n        │   │   │   │-- HICO_train2015_00000001.jpg\n        │   │   │   │-- HICO_train2015_00000002.jpg\n        │   │   │   │-- HICO_train2015_00000003.jpg\n        │   │   │   │-- ...\n        │   │   │-- test2015\n        │   │-- tools\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) (version>=1.5) to support Halpe evaluation:\n\n`pip install xtcocotools`\n\n## UBody\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2303.16160\">UBody (CVPR'2023)</a></summary>\n\n```bibtex\n@article{lin2023one,\n  title={One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer},\n  author={Lin, Jing and Zeng, Ailing and Wang, Haoqian and Zhang, Lei and Li, Yu},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  year={2023},\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/15952744/0c97e43a-46a9-46a3-a5dd-b84bf9d6d6f2\" height=\"300px\">\n</div>\n\nFor [Ubody](https://github.com/IDEA-Research/OSX) dataset, videos and annotations can be downloaded from [OSX homepage](https://github.com/IDEA-Research/OSX).\n\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── UBody\n        ├── annotations\n        │   ├── ConductMusic\n        │   ├── Entertainment\n        │   ├── Fitness\n        │   ├── Interview\n        │   ├── LiveVlog\n        │   ├── Magic_show\n        │   ├── Movie\n        │   ├── Olympic\n        │   ├── Online_class\n        │   ├── SignLanguage\n        │   ├── Singing\n        │   ├── Speech\n        │   ├── TVShow\n        │   ├── TalkShow\n        │   └── VideoConference\n        ├── splits\n        │   ├── inter_scene_test_list.npy\n        │   └── intra_scene_test_list.npy\n        ├── videos\n        │   ├── ConductMusic\n        │   ├── Entertainment\n        │   ├── Fitness\n        │   ├── Interview\n        │   ├── LiveVlog\n        │   ├── Magic_show\n        │   ├── Movie\n        │   ├── Olympic\n        │   ├── Online_class\n        │   ├── SignLanguage\n        │   ├── Singing\n        │   ├── Speech\n        │   ├── TVShow\n        │   ├── TalkShow\n        │   └── VideoConference\n```\n\nConvert videos to images then split them into train/val set:\n\n```shell\npython tools/dataset_converters/ubody_kpts_to_coco.py\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) (version>=1.5) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n"
  },
  {
    "path": "docs/en/dataset_zoo/3d_body_keypoint.md",
    "content": "# 3D Body Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [Human3.6M](#human36m) \\[ [Homepage](http://vision.imar.ro/human3.6m/description.php) \\]\n- [CMU Panoptic](#cmu-panoptic) \\[ [Homepage](http://domedb.perception.cs.cmu.edu/) \\]\n- [Campus/Shelf](#campus-and-shelf) \\[ [Homepage](http://campar.in.tum.de/Chair/MultiHumanPose) \\]\n- [UBody](#ubody3d) \\[ [Homepage](https://osx-ubody.github.io/) \\]\n\n## Human3.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227866174-0355e7dd-6965-4d1a-8bb6-32e8dce4cefc.png\" height=\"300px\">\n</div>\n\nFor [Human3.6M](http://vision.imar.ro/human3.6m/description.php), please download from the official website and run the [preprocessing script](/tools/dataset_converters/preprocess_h36m.py), which will extract camera parameters and pose annotations at full framerate (50 FPS) and downsampled framerate (10 FPS). The processed data should have the following structure:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── h36m\n        ├── annotation_body3d\n        |   ├── cameras.pkl\n        |   ├── fps50\n        |   |   ├── h36m_test.npz\n        |   |   ├── h36m_train.npz\n        |   |   ├── joint2d_rel_stats.pkl\n        |   |   ├── joint2d_stats.pkl\n        |   |   ├── joint3d_rel_stats.pkl\n        |   |   `── joint3d_stats.pkl\n        |   `── fps10\n        |       ├── h36m_test.npz\n        |       ├── h36m_train.npz\n        |       ├── joint2d_rel_stats.pkl\n        |       ├── joint2d_stats.pkl\n        |       ├── joint3d_rel_stats.pkl\n        |       `── joint3d_stats.pkl\n        `── images\n            ├── S1\n            |   ├── S1_Directions_1.54138969\n            |   |   ├── S1_Directions_1.54138969_00001.jpg\n            |   |   ├── S1_Directions_1.54138969_00002.jpg\n            |   |   ├── ...\n            |   ├── ...\n            ├── S5\n            ├── S6\n            ├── S7\n            ├── S8\n            ├── S9\n            `── S11\n```\n\n## CMU Panoptic\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content_iccv_2015/html/Joo_Panoptic_Studio_A_ICCV_2015_paper.html\">CMU Panoptic (ICCV'2015)</a></summary>\n\n```bibtex\n@Article = {joo_iccv_2015,\nauthor = {Hanbyul Joo, Hao Liu, Lei Tan, Lin Gui, Bart Nabbe, Iain Matthews, Takeo Kanade, Shohei Nobuhara, and Yaser Sheikh},\ntitle = {Panoptic Studio: A Massively Multiview System for Social Motion Capture},\nbooktitle = {ICCV},\nyear = {2015}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227866246-1af9441b-4f6c-4340-ae98-e40d6b4e8e55.png\" height=\"300px\">\n</div>\n\nPlease follow [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch) to prepare this dataset.\n\n1. Download the dataset by following the instructions in [panoptic-toolbox](https://github.com/CMU-Perceptual-Computing-Lab/panoptic-toolbox) and extract them under `$MMPOSE/data/panoptic`.\n\n2. Only download those sequences that are needed. You can also just download a subset of camera views by specifying the number of views (HD_Video_Number) and changing the camera order in `./scripts/getData.sh`. The used sequences and camera views can be found in [VoxelPose](https://arxiv.org/abs/2004.06239). Note that the sequence \"160906_band3\" might not be available due to errors on the server of CMU Panoptic.\n\n3. Note that we only use HD videos,  calibration data, and 3D Body Keypoint in the codes. You can comment out other irrelevant codes such as downloading 3D Face data in `./scripts/getData.sh`.\n\nThe directory tree should be like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── panoptic\n        ├── 16060224_haggling1\n        |   |   ├── hdImgs\n        |   |   ├── hdvideos\n        |   |   ├── hdPose3d_stage1_coco19\n        |   |   ├── calibration_160224_haggling1.json\n        ├── 160226_haggling1\n            ├── ...\n```\n\n## Campus and Shelf\n\n<details>\n<summary align=\"right\"><a href=\"http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf\">Campus and Shelf (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings {belagian14multi,\n    title = {{3D} Pictorial Structures for Multiple Human Pose Estimation},\n    author = {Belagiannis, Vasileios and Amin, Sikandar and Andriluka, Mykhaylo and Schiele, Bernt and Navab\n    Nassir and Ilic, Slobo\n    booktitle = {IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR)},\n    year = {2014},\n    month = {June},\n    organization={IEEE}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227866373-ed8e6d1a-581b-4b88-93f5-2bc2caddbf6c.png\" height=\"300px\">\n</div>\n\nPlease follow [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch) to prepare these two datasets.\n\n1. Please download the datasets from the [official website](http://campar.in.tum.de/Chair/MultiHumanPose) and extract them under `$MMPOSE/data/campus` and `$MMPOSE/data/shelf`, respectively. The original data include images as well as the ground truth pose file `actorsGT.mat`.\n\n2. We directly use the processed camera parameters from [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch). You can download them from this repository and place in under `$MMPOSE/data/campus/calibration_campus.json` and `$MMPOSE/data/shelf/calibration_shelf.json`, respectively.\n\n3. Like [Voxelpose](https://github.com/microsoft/voxelpose-pytorch), due to the limited and incomplete annotations of the two datasets, we don't train the model using this dataset. Instead, we directly use the 2D pose estimator trained on COCO, and use independent 3D human poses from the CMU Panoptic dataset to train our 3D model. It lies in `${MMPOSE}/data/panoptic_training_pose.pkl`.\n\n4. Like [Voxelpose](https://github.com/microsoft/voxelpose-pytorch), for testing, we first estimate 2D poses and generate 2D heatmaps for these two datasets. You can download the predicted poses from [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch) and place them in  `$MMPOSE/data/campus/pred_campus_maskrcnn_hrnet_coco.pkl` and `$MMPOSE/data/shelf/pred_shelf_maskrcnn_hrnet_coco.pkl`, respectively. You can also use the models trained on COCO dataset (like HigherHRNet) to generate 2D heatmaps directly.\n\nThe directory tree should be like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── panoptic_training_pose.pkl\n    ├── campus\n    |   ├── Camera0\n    |   |   |   ├── campus4-c0-00000.png\n    |   |   |   ├── ...\n    |   |   |   ├── campus4-c0-01999.png\n    |   ...\n    |   ├── Camera2\n    |   |   |   ├── campus4-c2-00000.png\n    |   |   |   ├── ...\n    |   |   |   ├── campus4-c2-01999.png\n    |   ├── calibration_campus.json\n    |   ├── pred_campus_maskrcnn_hrnet_coco.pkl\n    |   ├── actorsGT.mat\n    ├── shelf\n    |   ├── Camera0\n    |   |   |   ├── img_000000.png\n    |   |   |   ├── ...\n    |   |   |   ├── img_003199.png\n    |   ...\n    |   ├── Camera4\n    |   |   |   ├── img_000000.png\n    |   |   |   ├── ...\n    |   |   |   ├── img_003199.png\n    |   ├── calibration_shelf.json\n    |   ├── pred_shelf_maskrcnn_hrnet_coco.pkl\n    |   ├── actorsGT.mat\n```\n\n## UBody3d\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2303.16160\">UBody (CVPR'2023)</a></summary>\n\n```bibtex\n@article{lin2023one,\n  title={One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer},\n  author={Lin, Jing and Zeng, Ailing and Wang, Haoqian and Zhang, Lei and Li, Yu},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  year={2023},\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/15952744/0c97e43a-46a9-46a3-a5dd-b84bf9d6d6f2\" height=\"300px\">\n</div>\n\nFor [Ubody](https://github.com/IDEA-Research/OSX) dataset, videos and annotations can be downloaded from [OSX homepage](https://github.com/IDEA-Research/OSX).\n\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── UBody\n        ├── annotations\n        │   ├── ConductMusic\n        │   ├── Entertainment\n        │   ├── Fitness\n        │   ├── Interview\n        │   ├── LiveVlog\n        │   ├── Magic_show\n        │   ├── Movie\n        │   ├── Olympic\n        │   ├── Online_class\n        │   ├── SignLanguage\n        │   ├── Singing\n        │   ├── Speech\n        │   ├── TVShow\n        │   ├── TalkShow\n        │   └── VideoConference\n        ├── splits\n        │   ├── inter_scene_test_list.npy\n        │   └── intra_scene_test_list.npy\n        ├── videos\n        │   ├── ConductMusic\n        │   ├── Entertainment\n        │   ├── Fitness\n        │   ├── Interview\n        │   ├── LiveVlog\n        │   ├── Magic_show\n        │   ├── Movie\n        │   ├── Olympic\n        │   ├── Online_class\n        │   ├── SignLanguage\n        │   ├── Singing\n        │   ├── Speech\n        │   ├── TVShow\n        │   ├── TalkShow\n        │   └── VideoConference\n```\n\nConvert videos to images then split them into train/val set:\n\n```shell\npython tools/dataset_converters/ubody_kpts_to_coco.py\n```\n\nBefore generating 3D keypoints, you need to install SMPLX tools and download human models, please refer to [Github](https://github.com/vchoutas/smplx#installation) and [SMPLX](https://smpl-x.is.tue.mpg.de/download.php).\n\n```shell\npip install smplx\n```\n\nThe directory tree of human models should be like this:\n\n```text\nhuman_model_path\n|── smplx\n    ├── SMPLX_NEUTRAL.npz\n    ├── SMPLX_NEUTRAL.pkl\n```\n\nAfter the above preparations are finished, execute the following script:\n\n```shell\npython tools/dataset_converters/ubody_smplx_to_coco.py --data-root {$MMPOSE/data/UBody} --human-model-path {$MMPOSE/data/human_model_path/}\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/3d_body_mesh.md",
    "content": "# 3D Body Mesh Recovery Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nTo achieve high-quality human mesh estimation, we use multiple datasets for training.\nThe following items should be prepared for human mesh training:\n\n<!-- TOC -->\n\n- [3D Body Mesh Recovery Datasets](#3d-body-mesh-recovery-datasets)\n  - [Notes](#notes)\n    - [Annotation Files for Human Mesh Estimation](#annotation-files-for-human-mesh-estimation)\n    - [SMPL Model](#smpl-model)\n  - [COCO](#coco)\n  - [Human3.6M](#human36m)\n  - [MPI-INF-3DHP](#mpi-inf-3dhp)\n  - [LSP](#lsp)\n  - [LSPET](#lspet)\n  - [CMU MoShed Data](#cmu-moshed-data)\n\n<!-- TOC -->\n\n## Notes\n\n### Annotation Files for Human Mesh Estimation\n\nFor human mesh estimation, we use multiple datasets for training.\nThe annotation of different datasets are preprocessed to the same format. Please\nfollow the [preprocess procedure](https://github.com/nkolot/SPIN/tree/master/datasets/preprocess)\nof SPIN to generate the annotation files or download the processed files from\n[here](https://download.openmmlab.com/mmpose/datasets/mesh_annotation_files.zip),\nand make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mesh_annotation_files\n        ├── coco_2014_train.npz\n        ├── h36m_valid_protocol1.npz\n        ├── h36m_valid_protocol2.npz\n        ├── hr-lspet_train.npz\n        ├── lsp_dataset_original_train.npz\n        ├── mpi_inf_3dhp_train.npz\n        └── mpii_train.npz\n```\n\n### SMPL Model\n\n```bibtex\n@article{loper2015smpl,\n  title={SMPL: A skinned multi-person linear model},\n  author={Loper, Matthew and Mahmood, Naureen and Romero, Javier and Pons-Moll, Gerard and Black, Michael J},\n  journal={ACM transactions on graphics (TOG)},\n  volume={34},\n  number={6},\n  pages={1--16},\n  year={2015},\n  publisher={ACM New York, NY, USA}\n}\n```\n\nFor human mesh estimation, SMPL model is used to generate the human mesh.\nPlease download the [gender neutral SMPL model](http://smplify.is.tue.mpg.de/),\n[joints regressor](https://download.openmmlab.com/mmpose/datasets/joints_regressor_cmr.npy)\nand [mean parameters](https://download.openmmlab.com/mmpose/datasets/smpl_mean_params.npz)\nunder `$MMPOSE/models/smpl`, and make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── ...\n├── models\n    │── smpl\n        ├── joints_regressor_cmr.npy\n        ├── smpl_mean_params.npz\n        └── SMPL_NEUTRAL.pkl\n```\n\n## COCO\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nFor [COCO](http://cocodataset.org/) data, please download from [COCO download](http://cocodataset.org/#download). COCO'2014 Train is needed for human mesh estimation training.\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- train2014\n        │   ├── COCO_train2014_000000000009.jpg\n        │   ├── COCO_train2014_000000000025.jpg\n        │   ├── COCO_train2014_000000000030.jpg\n        |   │-- ...\n\n```\n\n## Human3.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\nFor [Human3.6M](http://vision.imar.ro/human3.6m/description.php), we use the MoShed data provided in [HMR](https://github.com/akanazawa/hmr) for training.\nHowever, due to license limitations, we are not allowed to redistribute the MoShed data.\n\nFor the evaluation on Human3.6M dataset, please follow the\n[preprocess procedure](https://github.com/nkolot/SPIN/tree/master/datasets/preprocess)\nof SPIN to extract test images from\n[Human3.6M](http://vision.imar.ro/human3.6m/description.php) original videos,\nand make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── Human3.6M\n        ├── images\n            ├── S11_Directions_1.54138969_000001.jpg\n            ├── S11_Directions_1.54138969_000006.jpg\n            ├── S11_Directions_1.54138969_000011.jpg\n            ├── ...\n```\n\nThe download of Human3.6M dataset is quite difficult, you can also download the\n[zip file](https://drive.google.com/file/d/1WnRJD9FS3NUf7MllwgLRJJC-JgYFr8oi/view?usp=sharing)\nof the test images. However, due to the license limitations, we are not allowed to\nredistribute the images either. So the users need to download the original video and\nextract the images by themselves.\n\n## MPI-INF-3DHP\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{mono-3dhp2017,\n author = {Mehta, Dushyant and Rhodin, Helge and Casas, Dan and Fua, Pascal and Sotnychenko, Oleksandr and Xu, Weipeng and Theobalt, Christian},\n title = {Monocular 3D Human Pose Estimation In The Wild Using Improved CNN Supervision},\n booktitle = {3D Vision (3DV), 2017 Fifth International Conference on},\n url = {http://gvv.mpi-inf.mpg.de/3dhp_dataset},\n year = {2017},\n organization={IEEE},\n doi={10.1109/3dv.2017.00064},\n}\n```\n\nFor [MPI-INF-3DHP](http://gvv.mpi-inf.mpg.de/3dhp-dataset/), please follow the\n[preprocess procedure](https://github.com/nkolot/SPIN/tree/master/datasets/preprocess)\nof SPIN to sample images, and make them like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── mpi_inf_3dhp_test_set\n    │   ├── TS1\n    │   ├── TS2\n    │   ├── TS3\n    │   ├── TS4\n    │   ├── TS5\n    │   └── TS6\n    ├── S1\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S2\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S3\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S4\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S5\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S6\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S7\n    │   ├── Seq1\n    │   └── Seq2\n    └── S8\n        ├── Seq1\n        └── Seq2\n```\n\n## LSP\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{johnson2010clustered,\n  title={Clustered Pose and Nonlinear Appearance Models for Human Pose Estimation.},\n  author={Johnson, Sam and Everingham, Mark},\n  booktitle={bmvc},\n  volume={2},\n  number={4},\n  pages={5},\n  year={2010},\n  organization={Citeseer}\n}\n```\n\nFor [LSP](https://sam.johnson.io/research/lsp.html), please download the high resolution version\n[LSP dataset original](http://sam.johnson.io/research/lsp_dataset_original.zip).\nExtract them under `$MMPOSE/data`, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── lsp_dataset_original\n        ├── images\n            ├── im0001.jpg\n            ├── im0002.jpg\n            └── ...\n```\n\n## LSPET\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{johnson2011learning,\n  title={Learning effective human pose estimation from inaccurate annotation},\n  author={Johnson, Sam and Everingham, Mark},\n  booktitle={CVPR 2011},\n  pages={1465--1472},\n  year={2011},\n  organization={IEEE}\n}\n```\n\nFor [LSPET](https://sam.johnson.io/research/lspet.html), please download its high resolution form\n[HR-LSPET](http://datasets.d2.mpi-inf.mpg.de/hr-lspet/hr-lspet.zip).\nExtract them under `$MMPOSE/data`, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── lspet_dataset\n        ├── images\n        │   ├── im00001.jpg\n        │   ├── im00002.jpg\n        │   ├── im00003.jpg\n        │   └── ...\n        └── joints.mat\n```\n\n## CMU MoShed Data\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{kanazawa2018end,\n  title={End-to-end recovery of human shape and pose},\n  author={Kanazawa, Angjoo and Black, Michael J and Jacobs, David W and Malik, Jitendra},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={7122--7131},\n  year={2018}\n}\n```\n\nReal-world SMPL parameters are used for the adversarial training in human mesh estimation.\nThe MoShed data provided in [HMR](https://github.com/akanazawa/hmr) is included in this\n[zip file](https://download.openmmlab.com/mmpose/datasets/mesh_annotation_files.zip).\nPlease download and extract it under `$MMPOSE/data`, and make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mesh_annotation_files\n        ├── CMU_mosh.npz\n        └── ...\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/3d_hand_keypoint.md",
    "content": "# 3D Hand Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [InterHand2.6M](#interhand26m) \\[ [Homepage](https://mks0601.github.io/InterHand2.6M/) \\]\n\n## InterHand2.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterHand2.6M (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227867693-e36c2cbd-4089-4734-a310-37cb5db6cafa.png\" height=\"200px\">\n</div>\n\nFor [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/), please download from [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/).\nPlease download the annotation files from [annotations](https://download.openmmlab.com/mmpose/datasets/interhand2.6m_annotations.zip).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── interhand2.6m\n        |── annotations\n        |   |── all\n        |   |── human_annot\n        |   |── machine_annot\n        |   |── skeleton.txt\n        |   |── subject.txt\n        |\n        `── images\n        |   |── train\n        |   |   |-- Capture0 ~ Capture26\n        |   |── val\n        |   |   |-- Capture0\n        |   |── test\n        |   |   |-- Capture0 ~ Capture7\n```\n"
  },
  {
    "path": "docs/en/dataset_zoo/3d_wholebody_keypoint.md",
    "content": "# 3D Body Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [H3WB](#h3wb) \\[ [Homepage](https://github.com/wholebody3d/wholebody3d) \\]\n\n## H3WB\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2211.15692\">H3WB (ICCV'2023)</a></summary>\n\n```bibtex\n@InProceedings{Zhu_2023_ICCV,\n    author    = {Zhu, Yue and Samet, Nermin and Picard, David},\n    title     = {H3WB: Human3.6M 3D WholeBody Dataset and Benchmark},\n    booktitle = {Proceedings of the IEEE/CVF International Conference on Computer Vision (ICCV)},\n    month     = {October},\n    year      = {2023},\n    pages     = {20166-20177}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227770977-c8f00355-c43a-467e-8444-d307789cf4b2.png\" height=\"300px\">\n</div>\n\nFor [H3WB](https://github.com/wholebody3d/wholebody3d), please follow the [document](3d_body_keypoint.md#human36m) to download [Human3.6M](http://vision.imar.ro/human3.6m/description.php) dataset, then download the H3WB annotations from the official [webpage](https://github.com/wholebody3d/wholebody3d). NOTES: please follow their [updates](https://github.com/wholebody3d/wholebody3d?tab=readme-ov-file#updates) to download the annotations.\n\nThe data should have the following structure:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── h36m\n        ├── annotation_body3d\n        |   ├── cameras.pkl\n        |   ├── h3wb_train.npz\n        |   ├── fps50\n        |   |   ├── h36m_test.npz\n        |   |   ├── h36m_train.npz\n        |   |   ├── joint2d_rel_stats.pkl\n        |   |   ├── joint2d_stats.pkl\n        |   |   ├── joint3d_rel_stats.pkl\n        |   |   `── joint3d_stats.pkl\n        |   `── fps10\n        |       ├── h36m_test.npz\n        |       ├── h36m_train.npz\n        |       ├── joint2d_rel_stats.pkl\n        |       ├── joint2d_stats.pkl\n        |       ├── joint3d_rel_stats.pkl\n        |       `── joint3d_stats.pkl\n        `── images\n            ├── S1\n            |   ├── S1_Directions_1.54138969\n            |   |   ├── S1_Directions_1.54138969_00001.jpg\n            |   |   ├── S1_Directions_1.54138969_00002.jpg\n            |   |   ├── ...\n            |   ├── ...\n            ├── S5\n            ├── S6\n            ├── S7\n            ├── S8\n            ├── S9\n            `── S11\n```\n"
  },
  {
    "path": "docs/en/faq.md",
    "content": "# FAQ\n\nWe list some common issues faced by many users and their corresponding solutions here.\nFeel free to enrich the list if you find any frequent issues and have ways to help others to solve them.\nIf the contents here do not cover your issue, please create an issue using the [provided templates](/.github/ISSUE_TEMPLATE/error-report.md) and make sure you fill in all required information in the template.\n\n## Installation\n\nCompatibility issue between MMCV and MMPose; \"AssertionError: MMCV==xxx is used but incompatible. Please install mmcv>=xxx, \\<=xxx.\"\n\nHere are the version correspondences between `mmdet`, `mmcv` and `mmpose`:\n\n- mmdet 2.x \\<=> mmpose 0.x \\<=> mmcv 1.x\n- mmdet 3.x \\<=> mmpose 1.x \\<=> mmcv 2.x\n\nDetailed compatible MMPose and MMCV versions are shown as below. Please choose the correct version of MMCV to avoid installation issues.\n\n### MMPose 1.x\n\n| MMPose version |      MMCV/MMEngine version      |\n| :------------: | :-----------------------------: |\n|     1.3.2      |  mmcv>=2.0.1, mmengine>=0.9.0   |\n|     1.3.1      |  mmcv>=2.0.1, mmengine>=0.9.0   |\n|     1.3.0      |  mmcv>=2.0.1, mmengine>=0.9.0   |\n|     1.2.0      |  mmcv>=2.0.1, mmengine>=0.8.0   |\n|     1.1.0      |  mmcv>=2.0.1, mmengine>=0.8.0   |\n|     1.0.0      |  mmcv>=2.0.0, mmengine>=0.7.0   |\n|    1.0.0rc1    | mmcv>=2.0.0rc4, mmengine>=0.6.0 |\n|    1.0.0rc0    | mmcv>=2.0.0rc0, mmengine>=0.0.1 |\n|    1.0.0b0     | mmcv>=2.0.0rc0, mmengine>=0.0.1 |\n\n### MMPose 0.x\n\n| MMPose version |       MMCV version        |\n| :------------: | :-----------------------: |\n|      0.x       | mmcv-full>=1.3.8, \\<1.8.0 |\n|     0.29.0     | mmcv-full>=1.3.8, \\<1.7.0 |\n|     0.28.1     | mmcv-full>=1.3.8, \\<1.7.0 |\n|     0.28.0     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.27.0     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.26.0     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.25.1     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.25.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.24.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.23.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.22.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.21.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.20.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.19.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.18.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.17.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.16.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.14.0     | mmcv-full>=1.1.3, \\<1.4.0 |\n|     0.13.0     | mmcv-full>=1.1.3, \\<1.4.0 |\n|     0.12.0     |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.11.0     |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.10.0     |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.9.0      |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.8.0      |  mmcv-full>=1.1.1, \\<1.2  |\n|     0.7.0      |  mmcv-full>=1.1.1, \\<1.2  |\n\n- **Unable to install xtcocotools**\n\n  1. Try to install it using pypi manually `pip install xtcocotools`.\n  2. If step1 does not work. Try to install it from [source](https://github.com/jin-s13/xtcocoapi).\n\n  ```\n  git clone https://github.com/jin-s13/xtcocoapi\n  cd xtcocoapi\n  python setup.py install\n  ```\n\n- **No matching distribution found for xtcocotools>=1.6**\n\n  1. Install cython by `pip install cython`.\n  2. Install xtcocotools from [source](https://github.com/jin-s13/xtcocoapi).\n\n  ```\n  git clone https://github.com/jin-s13/xtcocoapi\n  cd xtcocoapi\n  python setup.py install\n  ```\n\n- **\"No module named 'mmcv.ops'\"; \"No module named 'mmcv.\\_ext'\"**\n\n  1. Uninstall existing mmcv in the environment using `pip uninstall mmcv`.\n  2. Install mmcv following [mmcv installation instruction](https://mmcv.readthedocs.io/en/2.x/get_started/installation.html).\n\n## Data\n\n- **What if my custom dataset does not have bounding box label?**\n\n  We can estimate the bounding box of a person as the minimal box that tightly bounds all the keypoints.\n\n- **What is `COCO_val2017_detections_AP_H_56_person.json`? Can I train pose models without it?**\n\n  \"COCO_val2017_detections_AP_H_56_person.json\" contains the \"detected\" human bounding boxes for COCO validation set, which are generated by FasterRCNN.\n  One can choose to use gt bounding boxes to evaluate models, by setting `bbox_file=None` in `val_dataloader.dataset` in config. Or one can use detected boxes to evaluate\n  the generalizability of models, by setting `bbox_file='COCO_val2017_detections_AP_H_56_person.json'`.\n\n## Training\n\n- **RuntimeError: Address already in use**\n\n  Set the environment variables `MASTER_PORT=XXX`. For example:\n\n  ```shell\n  MASTER_PORT=29517 GPUS=16 GPUS_PER_NODE=8 CPUS_PER_TASK=2 ./tools/slurm_train.sh train res50 configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192.py work_dirs/res50_coco_256x192\n  ```\n\n- **\"Unexpected keys in source state dict\" when loading pre-trained weights**\n\n  It's normal that some layers in the pretrained model are not used in the pose model. ImageNet-pretrained classification network and the pose network may have different architectures (e.g. no classification head). So some unexpected keys in source state dict is actually expected.\n\n- **How to use trained models for backbone pre-training ?**\n\n  Refer to [Migration - Step3: Model - Backbone](../migration.md).\n\n  When training, the unexpected keys will be ignored.\n\n- **How to visualize the training accuracy/loss curves in real-time ?**\n\n  Modify `vis_backends` in config file like:\n\n  ```python\n  vis_backends = [\n    dict(type='LocalVisBackend'),\n    dict(type='TensorboardVisBackend')\n  ]\n  ```\n\n  You can refer to [user_guides/visualization.md](../user_guides/visualization.md).\n\n- **Log info is NOT printed**\n\n  Use smaller log interval. For example, change `interval=50` to `interval=1` in the config:\n\n  ```python\n  # hooks\n  default_hooks = dict(logger=dict(interval=1))\n  ```\n\n## Evaluation\n\n- **How to evaluate on MPII test dataset?**\n  Since we do not have the ground-truth for test dataset, we cannot evaluate it 'locally'.\n  If you would like to evaluate the performance on test set, you have to upload the pred.mat (which is generated during testing) to the official server via email, according to [the MPII guideline](http://human-pose.mpi-inf.mpg.de/#evaluation).\n\n- **For top-down 2d pose estimation, why predicted joint coordinates can be out of the bounding box (bbox)?**\n  We do not directly use the bbox to crop the image. bbox will be first transformed to center & scale, and the scale will be multiplied by a factor (1.25) to include some context. If the ratio of width/height is different from that of model input (possibly 192/256), we will adjust the bbox.\n\n## Inference\n\n- **How to run mmpose on CPU?**\n\n  Run demos with `--device=cpu`.\n\n- **How to speed up inference?**\n\n  A few approaches may help to improve the inference speed:\n\n  1. Set `flip_test=False` in `init_cfg` in the config file.\n  2. For top-down models, use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/en/3.x/model_zoo.html).\n\n- **What is the definition of each keypoint index?**\n\n  Check the [meta information file](https://github.com/open-mmlab/mmpose/tree/main/configs/_base_/datasets) for the dataset used to train the model you are using. They key `keypoint_info` includes the definition of each keypoint.\n"
  },
  {
    "path": "docs/en/guide_to_framework.md",
    "content": "# A 20-minute Tour to MMPose\n\nMMPose 1.0 is built upon a brand-new framework. For developers with basic knowledge of deep learning, this tutorial provides a overview of MMPose 1.0 framework design. Whether you are **a user of the previous version of MMPose**, or **a beginner of MMPose wishing to start with v1.0**, this tutorial will show you how to build a project based on MMPose 1.0.\n\n```{note}\nThis  tutorial covers what developers will concern when using MMPose 1.0:\n\n- Overall code architecture\n\n- How to manage modules with configs\n\n- How to use my own custom datasets\n\n- How to add new modules(backbone, head, loss function, etc.)\n```\n\nThe content of this tutorial is organized as follows:\n\n- [A 20 Minute Guide to MMPose Framework](#a-20-minute-guide-to-mmpose-framework)\n  - [Structure](#structure)\n  - [Overview](#overview)\n  - [Step1: Configs](#step1-configs)\n  - [Step2: Data](#step2-data)\n    - [Dataset Meta Information](#dataset-meta-information)\n    - [Dataset](#dataset)\n    - [Pipeline](#pipeline)\n      - [i. Augmentation](#i-augmentation)\n      - [ii. Transformation](#ii-transformation)\n      - [iii. Encoding](#iii-encoding)\n      - [iv. Packing](#iv-packing)\n  - [Step3: Model](#step3-model)\n    - [Data Preprocessor](#data-preprocessor)\n    - [Backbone](#backbone)\n    - [Neck](#neck)\n    - [Head](#head)\n\n## Structure\n\nThe file structure of MMPose 1.0 is as follows:\n\n```shell\nmmpose\n|----apis\n|----structures\n|----datasets\n     |----transforms\n|----codecs\n|----models\n     |----pose_estimators\n     |----data_preprocessors\n     |----backbones\n     |----necks\n     |----heads\n     |----losses\n|----engine\n     |----hooks\n|----evaluation\n|----visualization\n```\n\n- **apis** provides high-level APIs for model inference\n- **structures** provides data structures like bbox, keypoint and PoseDataSample\n- **datasets** supports various datasets for pose estimation\n  - **transforms** contains a lot of useful data augmentation transforms\n- **codecs** provides pose encoders and decoders: an encoder encodes poses (mostly keypoints) into learning targets (e.g. heatmaps), and a decoder decodes model outputs into pose predictions\n- **models** provides all components of pose estimation models in a modular structure\n  - **pose_estimators** defines all pose estimation model classes\n  - **data_preprocessors** is for preprocessing the input data of the model\n  - **backbones** provides a collection of backbone networks\n  - **necks** contains various neck modules\n  - **heads** contains various prediction heads that perform pose estimation\n  - **losses** contains various loss functions\n- **engine** provides runtime components related to pose estimation\n  - **hooks** provides various hooks of the runner\n- **evaluation** provides metrics for evaluating model performance\n- **visualization** is for visualizing skeletons, heatmaps and other information\n\n## Overview\n\n![overall-en](https://user-images.githubusercontent.com/13503330/187372008-2a94bad5-5252-4155-9ae3-3da1c426f569.png)\n\nGenerally speaking, there are **five parts** developers will use during project development:\n\n- **General:** Environment, Hook, Checkpoint, Logger, etc.\n\n- **Data:** Dataset, Dataloader, Data Augmentation, etc.\n\n- **Training:** Optimizer, Learning Rate Scheduler, etc.\n\n- **Model:** Backbone, Neck, Head, Loss function, etc.\n\n- **Evaluation:** Metric, Evaluator, etc.\n\nAmong them, modules related to **General**, **Training** and **Evaluation** are often provided by the training framework [MMEngine](https://github.com/open-mmlab/mmengine), and developers only need to call APIs and adjust the parameters.  Developers mainly focus on implementing the **Data** and **Model** parts.\n\n## Step1: Configs\n\nIn MMPose, we use a Python file as config for the definition and parameter management of the whole project. Therefore, we strongly recommend the developers who use MMPose for the first time to refer to [Configs](./user_guides/configs.md).\n\nNote that all new modules need to be registered using `Registry` and imported in `__init__.py` in the corresponding directory before we can create their instances from configs.\n\n## Step2: Data\n\nThe organization of data in MMPose contains:\n\n- Dataset Meta Information\n- Dataset\n- Pipeline\n\n### Dataset Meta Information\n\nThe meta information of a pose dataset usually includes the definition of keypoints and skeleton, symmetrical characteristic, and keypoint properties (e.g. belonging to upper or lower body, weights and sigmas). These information is important in data preprocessing, model training and evaluation. In MMpose, the dataset meta information is stored in configs files under [$MMPOSE/configs/\\_base\\_/datasets](https://github.com/open-mmlab/mmpose/tree/main/configs/_base_/datasets).\n\nTo use a custom dataset in MMPose, you need to add a new config file of the dataset meta information. Take the MPII dataset ([$MMPOSE/configs/\\_base\\_/datasets/mpii.py](https://github.com/open-mmlab/mmpose/blob/main/configs/_base_/datasets/mpii.py)) as an example. Here is its dataset information:\n\n```Python\ndataset_info = dict(\n    dataset_name='mpii',\n    paper_info=dict(\n        author='Mykhaylo Andriluka and Leonid Pishchulin and '\n        'Peter Gehler and Schiele, Bernt',\n        title='2D Human Pose Estimation: New Benchmark and '\n        'State of the Art Analysis',\n        container='IEEE Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2014',\n        homepage='http://human-pose.mpi-inf.mpg.de/',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_ankle',\n            id=0,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        ## omitted\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        ## omitted\n    },\n    joint_weights=[\n        1.5, 1.2, 1., 1., 1.2, 1.5, 1., 1., 1., 1., 1.5, 1.2, 1., 1., 1.2, 1.5\n    ],\n    # Adapted from COCO dataset.\n    sigmas=[\n        0.089, 0.083, 0.107, 0.107, 0.083, 0.089, 0.026, 0.026, 0.026, 0.026,\n        0.062, 0.072, 0.179, 0.179, 0.072, 0.062\n    ])\n```\n\n- `keypoint_info` contains the information about each keypoint.\n  1. `name`: the keypoint name. The keypoint name must be unique.\n  2. `id`: the keypoint id.\n  3. `color`: (\\[B, G, R\\]) is used for keypoint visualization.\n  4. `type`: 'upper' or 'lower', will be used in data augmentation [RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py#L263).\n  5. `swap`: indicates the 'swap pair' (also known as 'flip pair'). When applying image horizontal flip, the left part will become the right part, used in data augmentation [RandomFlip](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py#L94). We need to flip the keypoints accordingly.\n- `skeleton_info` contains information about the keypoint connectivity, which is used for visualization.\n- `joint_weights` assigns different loss weights to different keypoints.\n- `sigmas` is used to calculate the OKS score. You can read [keypoints-eval](https://cocodataset.org/#keypoints-eval) to learn more about it.\n\nIn the model config, the user needs to specify the metainfo path of the custom dataset (e.g. `$MMPOSE/configs/_base_/datasets/{your_dataset}.py`) as follows:\n\n```python\n# dataset and dataloader settings\ndataset_type = 'MyCustomDataset' # or 'CocoDataset'\n\ntrain_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # ann file is stored at {data_root}/{ann_file}\n        # e.g. aaa/annotations/train.json\n        ann_file='annotations/train.json',\n        # img is stored at {data_root}/{img}/\n        # e.g. aaa/train/c.jpg\n        data_prefix=dict(img='train'),\n        # specify the new dataset meta information config file\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n\nval_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # ann file is stored at {data_root}/{ann_file}\n        # e.g. aaa/annotations/val.json\n        ann_file='annotations/val.json',\n        # img is stored at {data_root}/{img}/\n        # e.g. aaa/val/c.jpg\n        data_prefix=dict(img='val'),\n        # specify the new dataset meta information config file\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n\ntest_dataloader = val_dataloader\n```\n\nMore specifically speaking, if you organize your data as follows:\n\n```shell\ndata\n├── annotations\n│   ├── train.json\n│   ├── val.json\n├── train\n│   ├── images\n│   │   ├── 000001.jpg\n├── val\n│   ├── images\n│   │   ├── 000002.jpg\n```\n\nYou need to set your config as follows:\n\n```\ndataset=dict(\n    ...\n    data_root='data/',\n    ann_file='annotations/train.json',\n    data_prefix=dict(img='train/images/'),\n    ...),\n```\n\n### Dataset\n\nTo use custom dataset in MMPose, we recommend converting the annotations into a supported format (e.g. COCO or MPII) and directly using our implementation of the corresponding dataset. If this is not applicable, you may need to implement your own dataset class.\n\nMore details about using custom datasets can be found in [Customize Datasets](./advanced_guides/customize_datasets.md).\n\n```{note}\nIf you wish to inherit from the `BaseDataset` provided by [MMEngine](https://github.com/open-mmlab/mmengine). Please refer to this [documents](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html) for details.\n```\n\n#### 2D Dataset\n\nMost 2D keypoint datasets in MMPose **organize the annotations in a COCO-like style**. Thus we provide a base class [BaseCocoStyleDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_coco_style_dataset.py) for these datasets. We recommend that users subclass [BaseCocoStyleDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_coco_style_dataset.py) and override the methods as needed (usually `__init__()` and `_load_annotations()`) to extend to a new custom 2D keypoint dataset.\n\n```{note}\nPlease refer to [COCO](./dataset_zoo/2d_body_keypoint.md) for more details about the COCO data format.\n```\n\nThe bbox format in MMPose is in `xyxy` instead of `xywh`, which is consistent with the format used in other OpenMMLab projects like [MMDetection](https://github.com/open-mmlab/mmdetection).  We provide useful utils for bbox format conversion, such as `bbox_xyxy2xywh`, `bbox_xywh2xyxy`, `bbox_xyxy2cs`, etc., which are defined in [$MMPOSE/mmpose/structures/bbox/transforms.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/structures/bbox/transforms.py).\n\nLet's take the implementation of the CrowPose dataset ([$MMPOSE/mmpose/datasets/datasets/body/crowdpose_dataset.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/body/crowdpose_dataset.py)) in COCO format as an example.\n\n```Python\n@DATASETS.register_module()\nclass CrowdPoseDataset(BaseCocoStyleDataset):\n    \"\"\"CrowdPose dataset for pose estimation.\n\n    \"CrowdPose: Efficient Crowded Scenes Pose Estimation and\n    A New Benchmark\", CVPR'2019.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1812.00324>`__.\n\n    CrowdPose keypoints::\n\n        0: 'left_shoulder',\n        1: 'right_shoulder',\n        2: 'left_elbow',\n        3: 'right_elbow',\n        4: 'left_wrist',\n        5: 'right_wrist',\n        6: 'left_hip',\n        7: 'right_hip',\n        8: 'left_knee',\n        9: 'right_knee',\n        10: 'left_ankle',\n        11: 'right_ankle',\n        12: 'top_head',\n        13: 'neck'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/crowdpose.py')\n```\n\nFor COCO-style datasets, we only need to inherit from [BaseCocoStyleDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_coco_style_dataset.py) and specify `METAINFO`, then the dataset class is ready to use.\n\n#### 3D Dataset\n\nwe provide a base class [BaseMocapDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_mocap_dataset.py) for 3D datasets. We recommend that users subclass [BaseMocapDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_mocap_dataset.py) and override the methods as needed (usually `__init__()` and `_load_annotations()`) to extend to a new custom 3D keypoint dataset.\n\n### Pipeline\n\nData augmentations and transformations during pre-processing are organized as a pipeline. Here is an example of typical pipelines：\n\n```Python\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n```\n\nIn a keypoint detection task, data will be transformed among three scale spaces:\n\n- **Original Image Space**: the space where the original images and annotations are stored. The sizes of different images are not necessarily the same\n\n- **Input Image Space**: the image space used for model input. All **images** and **annotations** will be transformed into this space, such as `256x256`, `256x192`, etc.\n\n- **Output Space**: the scale space where model outputs are located, such as `64x64(Heatmap)`，`1x1(Regression)`, etc. The supervision signal is also in this space during training\n\nHere is a diagram to show the workflow of data transformation among the three scale spaces:\n\n![tour_en](https://github.com/open-mmlab/mmpose/assets/13503330/e82710e6-4181-4eb0-8185-7075b43dbec3)\n\nIn MMPose, the modules used for data transformation are under [$MMPOSE/mmpose/datasets/transforms](https://github.com/open-mmlab/mmpose/tree/main/mmpose/datasets/transforms), and their workflow is shown as follows:\n\n![transforms-en](https://user-images.githubusercontent.com/13503330/187190352-a7662346-b8da-4256-9192-c7a84b15cbb5.png)\n\n#### i. Augmentation\n\nCommonly used transforms are defined in [$MMPOSE/mmpose/datasets/transforms/common_transforms.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py), such as [RandomFlip](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L94), [RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L263), etc. For top-down methods, `Shift`, `Rotate`and `Resize` are implemented by [RandomBBoxTransform](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L433). For bottom-up methods, [BottomupRandomAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L134) is used.\n\nTransforms for 3d pose data are defined in [$MMPOSE/mmpose/datasets/transforms/pose3d_transforms.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/pose3d_transforms.py)\n\n```{note}\nMost data transforms depend on `bbox_center` and `bbox_scale`, which can be obtained by [GetBBoxCenterScale](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L31).\n```\n\n#### ii. Transformation\n\nFor 2D image inputs, affine transformation is used to convert images and annotations from the original image space to the input space. This is done by [TopdownAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/topdown_transforms.py#L14) for top-down methods and [BottomupRandomAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L134) for bottom-up methods.\n\nFor pose lifting tasks, transformation is merged into [Encoding](./guide_to_framework.md#iii-encoding).\n\n#### iii. Encoding\n\nIn training phase, after the data is transformed from the original image space into the input space, it is necessary to use [GenerateTarget](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L873) to obtain the training target(e.g. Gaussian Heatmaps). We name this process **Encoding**. Conversely, the process of getting the corresponding coordinates from Gaussian Heatmaps is called **Decoding**.\n\nIn MMPose, we collect Encoding and Decoding processes into a **Codec**, in which `encode()` and `decode()` are implemented.\n\nCurrently we support the following types of Targets.\n\n- `heatmap`: Gaussian heatmaps\n- `keypoint_label`: keypoint representation (e.g. normalized coordinates)\n- `keypoint_xy_label`: axis-wise keypoint representation\n- `heatmap+keypoint_label`: Gaussian heatmaps and keypoint representation\n- `multiscale_heatmap`: multi-scale Gaussian heatmaps\n- `lifting_target_label`: 3D lifting target keypoint representation\n\nand the generated targets will be packed as follows.\n\n- `heatmaps`: Gaussian heatmaps\n- `keypoint_labels`: keypoint representation (e.g. normalized coordinates)\n- `keypoint_x_labels`: keypoint x-axis representation\n- `keypoint_y_labels`: keypoint y-axis representation\n- `keypoint_weights`: keypoint visibility and weights\n- `lifting_target_label`: 3D lifting target representation\n- `lifting_target_weight`: 3D lifting target visibility and weights\n\nNote that we unify the data format of top-down, pose-lifting and bottom-up methods, which means that a new dimension is added to represent different instances from the same image, in shape:\n\n```Python\n[batch_size, num_instances, num_keypoints, dim_coordinates]\n```\n\n- top-down and pose-lifting: `[B, 1, K, D]`\n\n- bottom-up: `[B, N, K, D]`\n\nThe provided codecs are stored under [$MMPOSE/mmpose/codecs](https://github.com/open-mmlab/mmpose/tree/main/mmpose/codecs).\n\n```{note}\nIf you wish to customize a new codec, you can refer to [Codec](./user_guides/codecs.md) for more details.\n```\n\n#### iv. Packing\n\nAfter the data is transformed, you need to pack it using [PackPoseInputs](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/formatting.py).\n\nThis method converts the data stored in the dictionary `results` into standard data structures in MMPose, such as `InstanceData`, `PixelData`, [PoseDataSample](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/structures/pose_data_sample.py), etc.\n\nSpecifically, we divide the data into `gt` (ground-truth) and `pred` (prediction), each of which has the following types:\n\n- **instances**(numpy.array): instance-level raw annotations or predictions in the original scale space\n- **instance_labels**(torch.tensor): instance-level training labels (e.g. normalized coordinates, keypoint visibility) in the output scale space\n- **fields**(torch.tensor): pixel-level training labels or predictions (e.g. Gaussian Heatmaps) in the output scale space\n\nThe following is an example of the implementation of [PoseDataSample](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/structures/pose_data_sample.py) under the hood:\n\n```Python\ndef get_pose_data_sample(self):\n    # meta\n    pose_meta = dict(\n        img_shape=(600, 900),   # [h, w, c]\n        crop_size=(256, 192),   # [h, w]\n        heatmap_size=(64, 48),  # [h, w]\n    )\n\n    # gt_instances\n    gt_instances = InstanceData()\n    gt_instances.bboxes = np.random.rand(1, 4)\n    gt_instances.keypoints = np.random.rand(1, 17, 2)\n\n    # gt_instance_labels\n    gt_instance_labels = InstanceData()\n    gt_instance_labels.keypoint_labels = torch.rand(1, 17, 2)\n    gt_instance_labels.keypoint_weights = torch.rand(1, 17)\n\n    # pred_instances\n    pred_instances = InstanceData()\n    pred_instances.keypoints = np.random.rand(1, 17, 2)\n    pred_instances.keypoint_scores = np.random.rand(1, 17)\n\n    # gt_fields\n    gt_fields = PixelData()\n    gt_fields.heatmaps = torch.rand(17, 64, 48)\n\n    # pred_fields\n    pred_fields = PixelData()\n    pred_fields.heatmaps = torch.rand(17, 64, 48)\n    data_sample = PoseDataSample(\n        gt_instances=gt_instances,\n        pred_instances=pred_instances,\n        gt_fields=gt_fields,\n        pred_fields=pred_fields,\n        metainfo=pose_meta)\n\n    return data_sample\n```\n\n## Step3: Model\n\nIn MMPose 1.0, the model consists of the following components:\n\n- **Data Preprocessor**: perform data normalization and channel transposition\n\n- **Backbone**: used for feature extraction\n\n- **Neck**: GAP，FPN, etc. are optional\n\n- **Head**: used to implement the core algorithm and loss function\n\nWe define a base class [BasePoseEstimator](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/pose_estimators/base.py) for the model in [$MMPOSE/models/pose_estimators/base.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/base.py). All models, e.g. [TopdownPoseEstimator](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/pose_estimators/topdown.py), should inherit from this base class and override the corresponding methods.\n\nThree modes are provided in `forward()` of the estimator:\n\n- `mode == 'loss'`: return the result of loss function for model training\n\n- `mode == 'predict'`: return the prediction result in the input space, used for model inference\n\n- `mode == 'tensor'`: return the model output in the output space, i.e. model forward propagation only, for model export\n\nDevelopers should build the components by calling the corresponding registry. Taking the top-down model as an example:\n\n```Python\n@MODELS.register_module()\nclass TopdownPoseEstimator(BasePoseEstimator):\n    def __init__(self,\n                 backbone: ConfigType,\n                 neck: OptConfigType = None,\n                 head: OptConfigType = None,\n                 train_cfg: OptConfigType = None,\n                 test_cfg: OptConfigType = None,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None):\n        super().__init__(data_preprocessor, init_cfg)\n\n        self.backbone = MODELS.build(backbone)\n\n        if neck is not None:\n            self.neck = MODELS.build(neck)\n\n        if head is not None:\n            self.head = MODELS.build(head)\n```\n\n### Data Preprocessor\n\nStarting from MMPose 1.0, we have added a new module to the model called data preprocessor, which performs data preprocessings like image normalization and channel transposition. It can benefit from the high computing power of devices like GPU, and improve the integrity in model export and deployment.\n\nA typical `data_preprocessor` in the config is as follows:\n\n```Python\ndata_preprocessor=dict(\n    type='PoseDataPreprocessor',\n    mean=[123.675, 116.28, 103.53],\n    std=[58.395, 57.12, 57.375],\n    bgr_to_rgb=True),\n```\n\nIt will transpose the channel order of the input image from `bgr` to `rgb` and normalize the data according to `mean` and `std`.\n\n### Backbone\n\nMMPose provides some commonly used backbones under [$MMPOSE/mmpose/models/backbones](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/backbones).\n\nIn practice, developers often use pre-trained backbone weights for transfer learning, which can improve the performance of the model on small datasets.\n\nIn MMPose, you can use the pre-trained weights by setting `init_cfg` in config:\n\n```Python\ninit_cfg=dict(\n    type='Pretrained',\n    checkpoint='PATH/TO/YOUR_MODEL_WEIGHTS.pth'),\n```\n\nIf you want to load a checkpoint to your backbone, you should specify the `prefix`:\n\n```Python\ninit_cfg=dict(\n    type='Pretrained',\n    prefix='backbone.',\n    checkpoint='PATH/TO/YOUR_CHECKPOINT.pth'),\n```\n\n`checkpoint` can be either a local path or a download link. Thus, if you wish to use a pre-trained model provided by Torchvision(e.g. ResNet50), you can simply use:\n\n```Python\ninit_cfg=dict(\n    type='Pretrained',\n    checkpoint='torchvision://resnet50')\n```\n\nIn addition to these commonly used backbones, you can easily use backbones from other repositories in the OpenMMLab family such as MMClassification, which all share the same config system and provide pre-trained weights.\n\nIt should be emphasized that if you add a new backbone, you need to register it by doing:\n\n```Python\n@MODELS.register_module()\nclass YourBackbone(BaseBackbone):\n```\n\nBesides, import it in [$MMPOSE/mmpose/models/backbones/\\_\\_init\\_\\_.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/backbones/__init__.py), and add it to `__all__`.\n\n### Neck\n\nNeck is usually a module between Backbone and Head, which is used in some algorithms. Here are some commonly used Neck:\n\n- Global Average Pooling (GAP)\n\n- Feature Pyramid Networks (FPN)\n\n- Feature Map Processor (FMP)\n\n  The [FeatureMapProcessor](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/necks/fmap_proc_neck.py) is a flexible PyTorch module designed to transform the feature outputs generated by backbones into a format suitable for heads. It achieves this by utilizing non-parametric operations such as selecting, concatenating, and rescaling. Below are some examples along with their corresponding configurations:\n\n  - Select operation\n\n    ```python\n    neck=dict(type='FeatureMapProcessor', select_index=0)\n    ```\n\n    <img src=\"https://user-images.githubusercontent.com/26127467/227108468-b44c9c13-9e51-403c-a035-b17b5268acc3.png\" height=\"100px\" alt><br>\n\n  - Concatenate operation\n\n    ```python\n    neck=dict(type='FeatureMapProcessor', concat=True)\n    ```\n\n    <img src=\"https://user-images.githubusercontent.com/26127467/227108705-4d197c71-4019-42cb-abdb-ba159111abb4.png\" height=\"85px\" alt><br>\n\n    Note that all feature maps will be resized to match the shape of the first feature map (index 0) prior to concatenation.\n\n  - rescale operation\n\n    ```python\n    neck=dict(type='FeatureMapProcessor', scale_factor=2.0)\n    ```\n\n    <img src=\"https://user-images.githubusercontent.com/26127467/227109402-94106e4b-b941-4ce9-8201-c64920d82ed1.png\" height=\"120px\" alt><br>\n\n### Head\n\nGenerally speaking, Head is often the core of an algorithm, which is used to make predictions and perform loss calculation.\n\nModules related to Head in MMPose are defined under [$MMPOSE/mmpose/models/heads](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/heads), and developers need to inherit the base class `BaseHead` when customizing Head and override the following methods:\n\n- forward()\n\n- predict()\n\n- loss()\n\nSpecifically, `predict()` method needs to return pose predictions in the image space, which is obtained from the model output though the decoding function provided by the codec. We implement this process in [BaseHead.decode()](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py).\n\nOn the other hand, we will perform test-time augmentation(TTA) in `predict()`.\n\nA commonly used TTA is `flip_test`, namely, an image and its flipped version are sent into the model to inference, and the output of the flipped version will be flipped back, then average them to stabilize the prediction.\n\nHere is an example of `predict()` in [RegressionHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/regression_heads/regression_head.py):\n\n```Python\ndef predict(self,\n            feats: Tuple[Tensor],\n            batch_data_samples: OptSampleList,\n            test_cfg: ConfigType = {}) -> Predictions:\n    \"\"\"Predict results from outputs.\"\"\"\n\n    if test_cfg.get('flip_test', False):\n        # TTA: flip test -> feats = [orig, flipped]\n        assert isinstance(feats, list) and len(feats) == 2\n        flip_indices = batch_data_samples[0].metainfo['flip_indices']\n        input_size = batch_data_samples[0].metainfo['input_size']\n        _feats, _feats_flip = feats\n        _batch_coords = self.forward(_feats)\n        _batch_coords_flip = flip_coordinates(\n            self.forward(_feats_flip),\n            flip_indices=flip_indices,\n            shift_coords=test_cfg.get('shift_coords', True),\n            input_size=input_size)\n        batch_coords = (_batch_coords + _batch_coords_flip) * 0.5\n    else:\n        batch_coords = self.forward(feats)  # (B, K, D)\n\n    batch_coords.unsqueeze_(dim=1)  # (B, N, K, D)\n    preds = self.decode(batch_coords)\n```\n\nThe `loss()` not only performs the calculation of loss functions, but also the calculation of training-time metrics such as pose accuracy. The results are carried by a dictionary `losses`:\n\n```Python\n # calculate accuracy\n_, avg_acc, _ = keypoint_pck_accuracy(\n    pred=to_numpy(pred_coords),\n    gt=to_numpy(keypoint_labels),\n    mask=to_numpy(keypoint_weights) > 0,\n    thr=0.05,\n    norm_factor=np.ones((pred_coords.size(0), 2), dtype=np.float32))\n\nacc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\nlosses.update(acc_pose=acc_pose)\n```\n\nThe data of each batch is packaged into `batch_data_samples`. Taking the Regression-based method as an example, the normalized coordinates and keypoint weights can be obtained as follows:\n\n```Python\nkeypoint_labels = torch.cat(\n    [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\nkeypoint_weights = torch.cat([\n    d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n])\n```\n\nHere is the complete implementation of `loss()` in [RegressionHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/regression_heads/regression_head.py):\n\n```Python\ndef loss(self,\n         inputs: Tuple[Tensor],\n         batch_data_samples: OptSampleList,\n         train_cfg: ConfigType = {}) -> dict:\n    \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n    pred_outputs = self.forward(inputs)\n\n    keypoint_labels = torch.cat(\n        [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n    keypoint_weights = torch.cat([\n        d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n    ])\n\n    # calculate losses\n    losses = dict()\n    loss = self.loss_module(pred_outputs, keypoint_labels,\n                            keypoint_weights.unsqueeze(-1))\n\n    if isinstance(loss, dict):\n        losses.update(loss)\n    else:\n        losses.update(loss_kpt=loss)\n\n    # calculate accuracy\n    _, avg_acc, _ = keypoint_pck_accuracy(\n        pred=to_numpy(pred_outputs),\n        gt=to_numpy(keypoint_labels),\n        mask=to_numpy(keypoint_weights) > 0,\n        thr=0.05,\n        norm_factor=np.ones((pred_outputs.size(0), 2), dtype=np.float32))\n    acc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\n    losses.update(acc_pose=acc_pose)\n\n    return losses\n```\n\n```{note}\nIf you wish to learn more about the implementation of Model, like:\n- Head with Keypoints Visibility Prediction\n- Pose Lifting Models\n\nplease refer to [Advanced Guides - Implement New Model](./advanced_guides/implement_new_models.md) for more details.\n```\n"
  },
  {
    "path": "docs/en/index.rst",
    "content": "Welcome to MMPose's documentation!\n==================================\n\nYou can change the documentation language at the lower-left corner of the page.\n\n您可以在页面左下角切换文档语言。\n\n.. toctree::\n   :maxdepth: 1\n   :caption: Get Started\n\n   overview.md\n   installation.md\n   guide_to_framework.md\n   demos.md\n   contribution_guide.md\n   faq.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: User Guides\n\n   user_guides/inference.md\n   user_guides/configs.md\n   user_guides/prepare_datasets.md\n   user_guides/train_and_test.md\n   user_guides/how_to_deploy.md\n   user_guides/model_analysis.md\n   user_guides/dataset_tools.md\n   user_guides/mixed_datasets.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: Advanced Guides\n\n   advanced_guides/codecs.md\n   advanced_guides/dataflow.md\n   advanced_guides/implement_new_models.md\n   advanced_guides/customize_datasets.md\n   advanced_guides/customize_transforms.md\n   advanced_guides/customize_evaluation.md\n   advanced_guides/customize_optimizer.md\n   advanced_guides/customize_logging.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: Migration\n\n   migration.md\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Model Zoo\n\n   model_zoo.txt\n   model_zoo/body_2d_keypoint.md\n   model_zoo/body_3d_keypoint.md\n   model_zoo/face_2d_keypoint.md\n   model_zoo/hand_2d_keypoint.md\n   model_zoo/wholebody_2d_keypoint.md\n   model_zoo/animal_2d_keypoint.md\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Model Zoo (by paper)\n\n   model_zoo_papers/algorithms.md\n   model_zoo_papers/backbones.md\n   model_zoo_papers/techniques.md\n   model_zoo_papers/datasets.md\n\n.. toctree::\n   :maxdepth: 2\n   :caption: Dataset Zoo\n\n   dataset_zoo.md\n   dataset_zoo/2d_body_keypoint.md\n   dataset_zoo/2d_wholebody_keypoint.md\n   dataset_zoo/2d_face_keypoint.md\n   dataset_zoo/2d_hand_keypoint.md\n   dataset_zoo/2d_fashion_landmark.md\n   dataset_zoo/2d_animal_keypoint.md\n   dataset_zoo/3d_body_keypoint.md\n   dataset_zoo/3d_hand_keypoint.md\n   dataset_zoo/3d_wholebody_keypoint.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: Projects\n\n   projects/community_projects.md\n   projects/projects.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: Notes\n\n   notes/ecosystem.md\n   notes/changelog.md\n   notes/benchmark.md\n   notes/pytorch_2.md\n\n.. toctree::\n   :caption: API Reference\n\n   api.rst\n\n.. toctree::\n   :caption: Switch Language\n\n   switch_language.md\n\n\n\nIndices and tables\n==================\n\n* :ref:`genindex`\n* :ref:`search`\n"
  },
  {
    "path": "docs/en/installation.md",
    "content": "# Installation\n\nWe recommend that users follow our best practices to install MMPose. However, the whole process is highly customizable. See [Customize Installation](#customize-installation) section for more information.\n\n- [Installation](#installation)\n  - [Prerequisites](#prerequisites)\n  - [Best Practices](#best-practices)\n    - [Build MMPose from source](#build-mmpose-from-source)\n    - [Install as a Python package](#install-as-a-python-package)\n  - [Customize Installation](#customize-installation)\n    - [CUDA versions](#cuda-versions)\n    - [Install MMEngine without MIM](#install-mmengine-without-mim)\n    - [Install MMCV without MIM](#install-mmcv-without-mim)\n    - [Install on CPU-only platforms](#install-on-cpu-only-platforms)\n    - [Install on Google Colab](#install-on-google-colab)\n    - [Using MMPose with Docker](#using-mmpose-with-docker)\n  - [Verify the installation](#verify-the-installation)\n  - [Trouble shooting](#trouble-shooting)\n\n<!-- TOC -->\n\n## Prerequisites\n\nIn this section we demonstrate how to prepare an environment with PyTorch.\n\nMMPose works on Linux, Windows and macOS. It requires Python 3.7+, CUDA 9.2+ and PyTorch 1.8+.\n\nIf you are experienced with PyTorch and have already installed it, you can skip this part and jump to the [MMPose Installation](#install-mmpose). Otherwise, you can follow these steps for the preparation.\n\n**Step 0.** Download and install Miniconda from the [official website](https://docs.conda.io/en/latest/miniconda.html).\n\n**Step 1.** Create a conda environment and activate it.\n\n```shell\nconda create --name openmmlab python=3.8 -y\nconda activate openmmlab\n```\n\n**Step 2.** Install PyTorch following [official instructions](https://pytorch.org/get-started/locally/), e.g.\n\nOn GPU platforms:\n\n```shell\nconda install pytorch torchvision -c pytorch\n```\n\n```{warning}\nThis command will automatically install the latest version PyTorch and cudatoolkit, please check whether they match your environment.\n```\n\nOn CPU platforms:\n\n```shell\nconda install pytorch torchvision cpuonly -c pytorch\n```\n\n**Step 3.** Install [MMEngine](https://github.com/open-mmlab/mmengine) and [MMCV](https://github.com/open-mmlab/mmcv/tree/2.x) using [MIM](https://github.com/open-mmlab/mim).\n\n```shell\npip install -U openmim\nmim install mmengine\nmim install \"mmcv>=2.0.1\"\n```\n\nNote that some of the demo scripts in MMPose require [MMDetection](https://github.com/open-mmlab/mmdetection) (mmdet)  for human detection. If you want to run these demo scripts with mmdet, you can easily install mmdet as a dependency by running:\n\n```shell\nmim install \"mmdet>=3.1.0\"\n```\n\n```{note}\nHere are the version correspondences between mmdet, mmpose and mmcv:\n\n- mmdet 2.x <=> mmpose 0.x <=> mmcv 1.x\n- mmdet 3.x <=> mmpose 1.x <=> mmcv 2.x\n\nIf you encounter version incompatibility issues, please check the correspondence using `pip list | grep mm` and upgrade or downgrade the dependencies accordingly. Please note that `mmcv-full` is only for `mmcv 1.x`, so please uninstall it first, and then use `mim install mmcv` to install `mmcv 2.x`.\n```\n\n## Best Practices\n\n### Build MMPose from source\n\nTo develop and run mmpose directly, install it from source:\n\n```shell\ngit clone https://github.com/open-mmlab/mmpose.git\ncd mmpose\npip install -r requirements.txt\npip install -v -e .\n# \"-v\" means verbose, or more output\n# \"-e\" means installing a project in editable mode,\n# thus any local modifications made to the code will take effect without reinstallation.\n```\n\n### Install as a Python package\n\nTo use mmpose as a dependency or third-party package, install it with pip:\n\n```shell\nmim install \"mmpose>=1.1.0\"\n```\n\n## Verify the installation\n\nTo verify that MMPose is installed correctly, you can run an inference demo with the following steps.\n\n**Step 1.** We need to download config and checkpoint files.\n\n```shell\nmim download mmpose --config td-hm_hrnet-w48_8xb32-210e_coco-256x192  --dest .\n```\n\nThe downloading will take several seconds or more, depending on your network environment. When it is done, you will find two files `td-hm_hrnet-w48_8xb32-210e_coco-256x192.py` and `td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth` in your current folder.\n\n**Step 2.** Run the inference demo.\n\nOption (A). If you install mmpose from source, just run the following command under the folder `$MMPOSE`:\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    td-hm_hrnet-w48_8xb32-210e_coco-256x192.py \\\n    td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth \\\n    --out-file vis_results.jpg \\\n    --draw-heatmap\n```\n\nIf everything goes fine, you will be able to get the following visualization result from `vis_results.jpg` in your current folder, which displays the predicted keypoints and heatmaps overlaid on the person in the image.\n\n![image](https://user-images.githubusercontent.com/87690686/187824033-2cce0f55-034a-4127-82e2-52744178bc32.jpg)\n\nOption (B). If you install mmpose with pip, open you python interpreter and copy & paste the following codes.\n\n```python\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.utils import register_all_modules\n\nregister_all_modules()\n\nconfig_file = 'td-hm_hrnet-w48_8xb32-210e_coco-256x192.py'\ncheckpoint_file = 'td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth'\nmodel = init_model(config_file, checkpoint_file, device='cpu')  # or device='cuda:0'\n\n# please prepare an image with person\nresults = inference_topdown(model, 'demo.jpg')\n```\n\nThe `demo.jpg` can be downloaded from [Github](https://raw.githubusercontent.com/open-mmlab/mmpose/main/tests/data/coco/000000000785.jpg).\n\nThe inference results will be a list of `PoseDataSample`, and the predictions are in the `pred_instances`, indicating the detected keypoint locations and scores.\n\n```{note}\nMMCV version should match PyTorch version strictly. If you encounter the following issues:\n\n- No module named 'mmcv.ops'\n- No module named 'mmcv._ext'\n\nIt means that the current PyTorch version does not match the CUDA version. You can check the CUDA version using `nvidia-smi`, and it should match the `+cu1xx` in PyTorch version in `pip list | grep torch`. Otherwise, you need to uninstall PyTorch and reinstall it, then reinstall MMCV (the installation order **CAN NOT** be swapped).\n```\n\n## Customize Installation\n\n### CUDA versions\n\nWhen installing PyTorch, you need to specify the version of CUDA. If you are not clear on which to choose, follow our recommendations:\n\n- For Ampere-based NVIDIA GPUs, such as GeForce 30 series and NVIDIA A100, CUDA 11 is a must.\n- For older NVIDIA GPUs, CUDA 11 is backward compatible, but CUDA 10.2 offers better compatibility and is more lightweight.\n\nPlease make sure the GPU driver satisfies the minimum version requirements. See [this table](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions__table-cuda-toolkit-driver-versions) for more information.\n\nInstalling CUDA runtime libraries is enough if you follow our best practices, because no CUDA code will be compiled locally. However if you hope to compile MMCV from source or develop other CUDA operators, you need to install the complete CUDA toolkit from NVIDIA's [website](https://developer.nvidia.com/cuda-downloads), and its version should match the CUDA version of PyTorch. i.e., the specified version of cudatoolkit in `conda install` command.\n\n### Install MMEngine without MIM\n\nTo install MMEngine with pip instead of MIM, please follow [MMEngine installation guides](https://mmengine.readthedocs.io/zh_CN/latest/get_started/installation.html).\n\nFor example, you can install MMEngine by the following command.\n\n```shell\npip install mmengine\n```\n\n### Install MMCV without MIM\n\nMMCV contains C++ and CUDA extensions, thus depending on PyTorch in a complex way. MIM solves such dependencies automatically and makes the installation easier. However, it is not a must.\n\nTo install MMCV with pip instead of MIM, please follow [MMCV installation guides](https://mmcv.readthedocs.io/en/2.x/get_started/installation.html). This requires manually specifying a find-url based on PyTorch version and its CUDA version.\n\nFor example, the following command install mmcv built for PyTorch 1.10.x and CUDA 11.3.\n\n```shell\npip install 'mmcv>=2.0.1' -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html\n```\n\n### Install on CPU-only platforms\n\nMMPose can be built for CPU only environment. In CPU mode you can train, test or inference a model.\n\nHowever, some functionalities are missing in this mode, usually GPU-compiled ops like `Deformable Convolution`. Most models in MMPose don't depend on these ops, but if you try to train/test/infer a model containing these ops, an error will be raised.\n\n### Install on Google Colab\n\n[Google Colab](https://colab.research.google.com/) usually has PyTorch installed,\nthus we only need to install MMEngine, MMCV and MMPose with the following commands.\n\n**Step 1.** Install [MMEngine](https://github.com/open-mmlab/mmengine) and [MMCV](https://github.com/open-mmlab/mmcv/tree/2.x) using [MIM](https://github.com/open-mmlab/mim).\n\n```shell\n!pip3 install openmim\n!mim install mmengine\n!mim install \"mmcv>=2.0.1\"\n```\n\n**Step 2.** Install MMPose from the source.\n\n```shell\n!git clone https://github.com/open-mmlab/mmpose.git\n%cd mmpose\n!pip install -e .\n```\n\n**Step 3.** Verification.\n\n```python\nimport mmpose\nprint(mmpose.__version__)\n# Example output: 1.1.0\n```\n\n```{note}\nNote that within Jupyter, the exclamation mark `!` is used to call external executables and `%cd` is a [magic command](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-cd) to change the current working directory of Python.\n```\n\n### Using MMPose with Docker\n\nWe provide a [Dockerfile](https://github.com/open-mmlab/mmpose/blob/master/docker/Dockerfile) to build an image. Ensure that your [docker version](https://docs.docker.com/engine/install/) >=19.03.\n\n```shell\n# build an image with PyTorch 1.8.0, CUDA 10.1, CUDNN 7.\n# If you prefer other versions, just modified the Dockerfile\ndocker build -t mmpose docker/\n```\n\n**Important:** Make sure you've installed the [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker).\n\nRun it with\n\n```shell\ndocker run --gpus all --shm-size=8g -it -v {DATA_DIR}:/mmpose/data mmpose\n```\n\n`{DATA_DIR}` is your local folder containing all the datasets for mmpose.\n\n```{note}\nIf you encounter the error message like `permission denied`, please add `sudo` at the start of the command and try it again.\n```\n\n## Trouble shooting\n\nIf you have some issues during the installation, please first view the [FAQ](./faq.md) page.\nYou may [open an issue](https://github.com/open-mmlab/mmpose/issues/new/choose) on GitHub if no solution is found.\n"
  },
  {
    "path": "docs/en/make.bat",
    "content": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset SOURCEDIR=.\nset BUILDDIR=_build\n\nif \"%1\" == \"\" goto help\n\n%SPHINXBUILD% >NUL 2>NUL\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\ngoto end\n\n:help\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\n\n:end\npopd\n"
  },
  {
    "path": "docs/en/merge_docs.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nsed -i '$a\\\\n' ../../demo/docs/en/*_demo.md\ncat ../../demo/docs/en/*_demo.md | sed \"s/^## 2D\\(.*\\)Demo/##\\1Estimation/\" | sed \"s/md###t/html#t/g\" | sed '1i\\# Demos\\n' | sed 's=](/docs/en/=](/=g' | sed 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' >demos.md\n\n # remove /docs/ for link used in doc site\nsed -i 's=](/docs/en/=](=g' overview.md\nsed -i 's=](/docs/en/=](=g' installation.md\nsed -i 's=](/docs/en/=](=g' quick_run.md\nsed -i 's=](/docs/en/=](=g' migration.md\nsed -i 's=](/docs/en/=](=g' ./model_zoo/*.md\nsed -i 's=](/docs/en/=](=g' ./model_zoo_papers/*.md\nsed -i 's=](/docs/en/=](=g' ./user_guides/*.md\nsed -i 's=](/docs/en/=](=g' ./advanced_guides/*.md\nsed -i 's=](/docs/en/=](=g' ./dataset_zoo/*.md\nsed -i 's=](/docs/en/=](=g' ./notes/*.md\nsed -i 's=](/docs/en/=](=g' ./projects/*.md\n\n\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' overview.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' installation.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' quick_run.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' migration.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./advanced_guides/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./model_zoo/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./model_zoo_papers/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./user_guides/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./dataset_zoo/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./notes/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./projects/*.md\n"
  },
  {
    "path": "docs/en/migration.md",
    "content": "# How to Migrate MMPose 0.x Projects to MMPose 1.0\n\nMMPose 1.0 has been refactored extensively and addressed many legacy issues. Most of the code in MMPose 1.0 will not be compatible with 0.x version.\n\nTo try our best to help you migrate your code and model, here are some major changes:\n\n## Data Transformation\n\n### Translation, Rotation and Scaling\n\nThe transformation methods `TopDownRandomShiftBboxCenter` and `TopDownGetRandomScaleRotation` in old version, will be merged into `RandomBBoxTransform`.\n\n```Python\n@TRANSFORMS.register_module()\nclass RandomBBoxTransform(BaseTransform):\n    r\"\"\"Rnadomly shift, resize and rotate the bounding boxes.\n\n    Required Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Modified Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Added Keys:\n        - bbox_rotation\n\n    Args:\n        shift_factor (float): Randomly shift the bbox in range\n            :math:`[-dx, dx]` and :math:`[-dy, dy]` in X and Y directions,\n            where :math:`dx(y) = x(y)_scale \\cdot shift_factor` in pixels.\n            Defaults to 0.16\n        shift_prob (float): Probability of applying random shift. Defaults to\n            0.3\n        scale_factor (Tuple[float, float]): Randomly resize the bbox in range\n            :math:`[scale_factor[0], scale_factor[1]]`. Defaults to (0.5, 1.5)\n        scale_prob (float): Probability of applying random resizing. Defaults\n            to 1.0\n        rotate_factor (float): Randomly rotate the bbox in\n            :math:`[-rotate_factor, rotate_factor]` in degrees. Defaults\n            to 80.0\n        rotate_prob (float): Probability of applying random rotation. Defaults\n            to 0.6\n    \"\"\"\n\n    def __init__(self,\n                 shift_factor: float = 0.16,\n                 shift_prob: float = 0.3,\n                 scale_factor: Tuple[float, float] = (0.5, 1.5),\n                 scale_prob: float = 1.0,\n                 rotate_factor: float = 80.0,\n                 rotate_prob: float = 0.6) -> None:\n```\n\n### Target Generation\n\nThe old methods like:\n\n- `TopDownGenerateTarget`\n- `TopDownGenerateTargetRegression`\n- `BottomUpGenerateHeatmapTarget`\n- `BottomUpGenerateTarget`\n\nwill be merged in to `GenerateTarget`, and the actual generation methods are implemented in [Codec](./user_guides/codecs.md).\n\n```Python\n@TRANSFORMS.register_module()\nclass GenerateTarget(BaseTransform):\n    \"\"\"Encode keypoints into Target.\n\n    The generated target is usually the supervision signal of the model\n    learning, e.g. heatmaps or regression labels.\n\n    Required Keys:\n\n        - keypoints\n        - keypoints_visible\n        - dataset_keypoint_weights\n\n    Added Keys:\n\n        - The keys of the encoded items from the codec will be updated into\n            the results, e.g. ``'heatmaps'`` or ``'keypoint_weights'``. See\n            the specific codec for more details.\n\n    Args:\n        encoder (dict | list[dict]): The codec config for keypoint encoding.\n            Both single encoder and multiple encoders (given as a list) are\n            supported\n        multilevel (bool): Determine the method to handle multiple encoders.\n            If ``multilevel==True``, generate multilevel targets from a group\n            of encoders of the same type (e.g. multiple :class:`MSRAHeatmap`\n            encoders with different sigma values); If ``multilevel==False``,\n            generate combined targets from a group of different encoders. This\n            argument will have no effect in case of single encoder. Defaults\n            to ``False``\n        use_dataset_keypoint_weights (bool): Whether use the keypoint weights\n            from the dataset meta information. Defaults to ``False``\n    \"\"\"\n\n    def __init__(self,\n                 encoder: MultiConfig,\n                 multilevel: bool = False,\n                 use_dataset_keypoint_weights: bool = False) -> None:\n```\n\n### Data Normalization\n\nThe data normalization operations `NormalizeTensor` and `ToTensor` will be replaced by **DataPreprocessor** module, which will no longer be used as a preprocessing operation, but will be merged as a part of the model forward propagation.\n\nThe 3D normalization methods like\n\n- `GetRootCenteredPose`\n- `ImageCoordinateNormalization`\n- `NormalizeJointCoordinate`\n\nwill be merged into codecs, for example [`ImagePoseLifting`](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/image_pose_lifting.py#L11) and [`VideoPoseLifting`](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/video_pose_lifting.py#L13).\n\nThe data conversion and reshaping operation `PoseSequenceToTensor` will be implemented in corresponding codecs and [`PackPoseInputs`](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/formatting.py).\n\n## Compatibility of Models\n\nWe have performed compatibility with the model weights provided by model zoo to ensure that the same model weights can get a comparable accuracy in both version. But note that due to the large number of differences in processing details, the inference outputs can be slightly different(less than 0.05% difference in accuracy).\n\nFor model weights saved by training with 0.x version, we provide a `_load_state_dict_pre_hook()` method in Head to replace the old version of the `state_dict` with the new one. If you wish to make your model compatible with MMPose 1.0, you can refer to our implementation as follows.\n\n```Python\n@MODELS.register_module()\nclass YourHead(BaseHead):\ndef __init__(self):\n\n    ## omitted\n\n    # Register the hook to automatically convert old version state dicts\n    self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n```\n\n### Heatmap-based Model\n\nFor models based on `SimpleBaseline` approach, developers need to pay attention to the last convolutional layer.\n\n```Python\ndef _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                              **kwargs):\n    version = local_meta.get('version', None)\n\n    if version and version >= self._version:\n        return\n\n    # convert old-version state dict\n    keys = list(state_dict.keys())\n    for _k in keys:\n        if not _k.startswith(prefix):\n            continue\n        v = state_dict.pop(_k)\n        k = _k[len(prefix):]\n        # In old version, \"final_layer\" includes both intermediate\n        # conv layers (new \"conv_layers\") and final conv layers (new\n        # \"final_layer\").\n        #\n        # If there is no intermediate conv layer, old \"final_layer\" will\n        # have keys like \"final_layer.xxx\", which should be still\n        # named \"final_layer.xxx\";\n        #\n        # If there are intermediate conv layers, old \"final_layer\"  will\n        # have keys like \"final_layer.n.xxx\", where the weights of the last\n        # one should be renamed \"final_layer.xxx\", and others should be\n        # renamed \"conv_layers.n.xxx\"\n        k_parts = k.split('.')\n        if k_parts[0] == 'final_layer':\n            if len(k_parts) == 3:\n                assert isinstance(self.conv_layers, nn.Sequential)\n                idx = int(k_parts[1])\n                if idx < len(self.conv_layers):\n                    # final_layer.n.xxx -> conv_layers.n.xxx\n                    k_new = 'conv_layers.' + '.'.join(k_parts[1:])\n                else:\n                    # final_layer.n.xxx -> final_layer.xxx\n                    k_new = 'final_layer.' + k_parts[2]\n            else:\n                # final_layer.xxx remains final_layer.xxx\n                k_new = k\n        else:\n            k_new = k\n\n        state_dict[prefix + k_new] = v\n```\n\n### RLE-based Model\n\nFor the RLE-based models, since the loss module is renamed to `loss_module` in MMPose 1.0, and the flow model is subsumed under the loss module, changes need to be made to the keys in `state_dict`:\n\n```Python\ndef _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                              **kwargs):\n\n    version = local_meta.get('version', None)\n\n    if version and version >= self._version:\n        return\n\n    # convert old-version state dict\n    keys = list(state_dict.keys())\n    for _k in keys:\n        v = state_dict.pop(_k)\n        k = _k.lstrip(prefix)\n        # In old version, \"loss\" includes the instances of loss,\n        # now it should be renamed \"loss_module\"\n        k_parts = k.split('.')\n        if k_parts[0] == 'loss':\n            # loss.xxx -> loss_module.xxx\n            k_new = prefix + 'loss_module.' + '.'.join(k_parts[1:])\n        else:\n            k_new = _k\n\n        state_dict[k_new] = v\n```\n"
  },
  {
    "path": "docs/en/notes/benchmark.md",
    "content": "# Benchmark\n\nWe compare our results with some popular frameworks and official releases in terms of speed and accuracy.\n\n## Comparison Rules\n\nHere we compare our MMPose repo with other pose estimation toolboxes in the same data and model settings.\n\nTo ensure the fairness of the comparison, the comparison experiments were conducted under the same hardware environment and using the same dataset.\nFor each model setting, we kept the same data pre-processing methods to make sure the same feature input.\nIn addition, we also used Memcached, a distributed memory-caching system, to load the data in all the compared toolboxes.\nThis minimizes the IO time during benchmark.\n\nThe time we measured is the average training time for an iteration, including data processing and model training.\nThe training speed is measure with s/iter. The lower, the better.\n\n### Results on COCO val2017 with detector having human AP of 56.4 on COCO val2017 dataset\n\nWe demonstrate the superiority of our MMPose framework in terms of speed and accuracy on the standard COCO keypoint detection benchmark.\nThe mAP (the mean average precision) is used as the evaluation metric.\n\n| Model      | Input size | MMPose (s/iter) | HRNet (s/iter) | MMPose (mAP) | HRNet (mAP) |\n| :--------- | :--------: | :-------------: | :------------: | :----------: | :---------: |\n| resnet_50  |  256x192   |    **0.28**     |      0.64      |  **0.718**   |    0.704    |\n| resnet_50  |  384x288   |    **0.81**     |      1.24      |  **0.731**   |    0.722    |\n| resnet_101 |  256x192   |    **0.36**     |      0.84      |  **0.726**   |    0.714    |\n| resnet_101 |  384x288   |    **0.79**     |      1.53      |  **0.748**   |    0.736    |\n| resnet_152 |  256x192   |    **0.49**     |      1.00      |  **0.735**   |    0.720    |\n| resnet_152 |  384x288   |    **0.96**     |      1.65      |  **0.750**   |    0.743    |\n| hrnet_w32  |  256x192   |    **0.54**     |      1.31      |  **0.746**   |    0.744    |\n| hrnet_w32  |  384x288   |    **0.76**     |      2.00      |  **0.760**   |    0.758    |\n| hrnet_w48  |  256x192   |    **0.66**     |      1.55      |  **0.756**   |    0.751    |\n| hrnet_w48  |  384x288   |    **1.23**     |      2.20      |  **0.767**   |    0.763    |\n\n## Hardware\n\n- 8 NVIDIA Tesla V100 (32G) GPUs\n- Intel(R) Xeon(R) Gold 6148 CPU @ 2.40GHz\n\n## Software Environment\n\n- Python 3.7\n- PyTorch 1.4\n- CUDA 10.1\n- CUDNN 7.6.03\n- NCCL 2.4.08\n"
  },
  {
    "path": "docs/en/notes/changelog.md",
    "content": "# Changelog\n\n## **v1.3.2 (12/07/2024)**\n\n**New Features**\n\n- Add center alignments for draw_texts in OpencvBackendVisualizer ([#2958](https://github.com/open-mmlab/mmpose/pull/2958))\n- Add wflw2coco script ([#2961](https://github.com/open-mmlab/mmpose/pull/2961))\n- Support 300VW Dataset ([#3005](https://github.com/open-mmlab/mmpose/pull/3005))\n- Add RTMW3D for 3D wholebody pose estimation task ([#3037](https://github.com/open-mmlab/mmpose/pull/3037))\n\n**Improvements**\n\n- In browse dataset : CombinedDataset element are now browse in turn, and image saved into their dataset name folder ([#2985](https://github.com/open-mmlab/mmpose/pull/2985))\n\n**Bug Fixes**\n\n- Fix loss computation in MSPNHead ([#2993](https://github.com/open-mmlab/mmpose/pull/2993))\n- Fix bug in inferencer ([#2966](https://github.com/open-mmlab/mmpose/pull/2966))\n- Make category_id in CocoWholeBodyDataset as numpy.array ([#2963](https://github.com/open-mmlab/mmpose/pull/2963))\n\n**Documentation**\n\n- Add rtmlib examples ([#2923](https://github.com/open-mmlab/mmpose/pull/2923))\n- Fix readthedocs configuration ([#2979](https://github.com/open-mmlab/mmpose/pull/2979))\n- Add more detailed comments ([#2982](https://github.com/open-mmlab/mmpose/pull/2982))\n- Improve documentation folder structure of ExLPose ([#2977](https://github.com/open-mmlab/mmpose/pull/2977))\n\n**New Contributors**\n\n- @AntDum made their first contribution in https://github.com/open-mmlab/mmpose/pull/2958\n- @Yanyirong made their first contribution in https://github.com/open-mmlab/mmpose/pull/2961\n- @drazicmartin made their first contribution in https://github.com/open-mmlab/mmpose/pull/2977\n- @KeqiangSun made their first contribution in https://github.com/open-mmlab/mmpose/pull/3005\n- @jitrc made their first contribution in https://github.com/open-mmlab/mmpose/pull/3004\n- @zgjja made their first contribution in https://github.com/open-mmlab/mmpose/pull/2963\n- @jibranbinsaleem made their first contribution in https://github.com/open-mmlab/mmpose/pull/3027\n- @cpunion made their first contribution in https://github.com/open-mmlab/mmpose/pull/3026\n\n## **v1.3.1 (11/01/2024)**\n\nFix the bug when downloading config and checkpoint using `mim` (see [Issue #2918](https://github.com/open-mmlab/mmpose/issues/2918)).\n\n## **v1.3.0 (04/01/2024)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.3.0\n\n## **v1.2.0 (12/10/2023)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.2.0\n\n## **v1.1.0 (04/07/2023)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.1.0\n\n## **v1.0.0 (06/04/2023)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.0.0\n\n## **v1.0.0rc1 (14/10/2022)**\n\n**Highlights**\n\n- Release RTMPose, a high-performance real-time pose estimation algorithm with cross-platform deployment and inference support. See details at the [project page](/projects/rtmpose/)\n- Support several new algorithms: ViTPose (arXiv'2022), CID (CVPR'2022), DEKR (CVPR'2021)\n- Add Inferencer, a convenient inference interface that perform pose estimation and visualization on images, videos and webcam streams with only one line of code\n- Introduce *Project*, a new form for rapid and easy implementation of new algorithms and features in MMPose, which is more handy for community contributors\n\n**New Features**\n\n- Support RTMPose ([#1971](https://github.com/open-mmlab/mmpose/pull/1971), [#2024](https://github.com/open-mmlab/mmpose/pull/2024), [#2028](https://github.com/open-mmlab/mmpose/pull/2028), [#2030](https://github.com/open-mmlab/mmpose/pull/2030), [#2040](https://github.com/open-mmlab/mmpose/pull/2040), [#2057](https://github.com/open-mmlab/mmpose/pull/2057))\n- Support Inferencer ([#1969](https://github.com/open-mmlab/mmpose/pull/1969))\n- Support ViTPose ([#1876](https://github.com/open-mmlab/mmpose/pull/1876), [#2056](https://github.com/open-mmlab/mmpose/pull/2056), [#2058](https://github.com/open-mmlab/mmpose/pull/2058)， [#2065](https://github.com/open-mmlab/mmpose/pull/2065))\n- Support CID ([#1907](https://github.com/open-mmlab/mmpose/pull/1907))\n- Support DEKR ([#1834](https://github.com/open-mmlab/mmpose/pull/1834), [#1901](https://github.com/open-mmlab/mmpose/pull/1901))\n- Support training with multiple datasets ([#1767](https://github.com/open-mmlab/mmpose/pull/1767), [#1930](https://github.com/open-mmlab/mmpose/pull/1930), [#1938](https://github.com/open-mmlab/mmpose/pull/1938), [#2025](https://github.com/open-mmlab/mmpose/pull/2025))\n- Add *project* to allow rapid and easy implementation of new models and features ([#1914](https://github.com/open-mmlab/mmpose/pull/1914))\n\n**Improvements**\n\n- Improve documentation quality ([#1846](https://github.com/open-mmlab/mmpose/pull/1846), [#1858](https://github.com/open-mmlab/mmpose/pull/1858), [#1872](https://github.com/open-mmlab/mmpose/pull/1872), [#1899](https://github.com/open-mmlab/mmpose/pull/1899), [#1925](https://github.com/open-mmlab/mmpose/pull/1925), [#1945](https://github.com/open-mmlab/mmpose/pull/1945), [#1952](https://github.com/open-mmlab/mmpose/pull/1952), [#1990](https://github.com/open-mmlab/mmpose/pull/1990), [#2023](https://github.com/open-mmlab/mmpose/pull/2023), [#2042](https://github.com/open-mmlab/mmpose/pull/2042))\n- Support visualizing keypoint indices ([#2051](https://github.com/open-mmlab/mmpose/pull/2051))\n- Support OpenPose style visualization ([#2055](https://github.com/open-mmlab/mmpose/pull/2055))\n- Accelerate image transpose in data pipelines with tensor operation ([#1976](https://github.com/open-mmlab/mmpose/pull/1976))\n- Support auto-import modules from registry ([#1961](https://github.com/open-mmlab/mmpose/pull/1961))\n- Support keypoint partition metric ([#1944](https://github.com/open-mmlab/mmpose/pull/1944))\n- Support SimCC 1D-heatmap visualization ([#1912](https://github.com/open-mmlab/mmpose/pull/1912))\n- Support saving predictions and data metainfo in demos ([#1814](https://github.com/open-mmlab/mmpose/pull/1814), [#1879](https://github.com/open-mmlab/mmpose/pull/1879))\n- Support SimCC with DARK ([#1870](https://github.com/open-mmlab/mmpose/pull/1870))\n- Remove Gaussian blur for offset maps in UDP-regress ([#1815](https://github.com/open-mmlab/mmpose/pull/1815))\n- Refactor encoding interface of Codec for better extendibility and easier configuration ([#1781](https://github.com/open-mmlab/mmpose/pull/1781))\n- Support evaluating CocoMetric without annotation file ([#1722](https://github.com/open-mmlab/mmpose/pull/1722))\n- Improve unit tests ([#1765](https://github.com/open-mmlab/mmpose/pull/1765))\n\n**Bug Fixes**\n\n- Fix repeated warnings from different ranks ([#2053](https://github.com/open-mmlab/mmpose/pull/2053))\n- Avoid frequent scope switching when using mmdet inference api ([#2039](https://github.com/open-mmlab/mmpose/pull/2039))\n- Remove EMA parameters and message hub data when publishing model checkpoints ([#2036](https://github.com/open-mmlab/mmpose/pull/2036))\n- Fix metainfo copying in dataset class ([#2017](https://github.com/open-mmlab/mmpose/pull/2017))\n- Fix top-down demo bug when there is no object detected ([#2007](https://github.com/open-mmlab/mmpose/pull/2007))\n- Fix config errors ([#1882](https://github.com/open-mmlab/mmpose/pull/1882), [#1906](https://github.com/open-mmlab/mmpose/pull/1906), [#1995](https://github.com/open-mmlab/mmpose/pull/1995))\n- Fix image demo failure when GUI is unavailable ([#1968](https://github.com/open-mmlab/mmpose/pull/1968))\n- Fix bug in AdaptiveWingLoss ([#1953](https://github.com/open-mmlab/mmpose/pull/1953))\n- Fix incorrect importing of RepeatDataset which is deprecated ([#1943](https://github.com/open-mmlab/mmpose/pull/1943))\n- Fix bug in bottom-up datasets that ignores images without instances ([#1752](https://github.com/open-mmlab/mmpose/pull/1752), [#1936](https://github.com/open-mmlab/mmpose/pull/1936))\n- Fix upstream dependency issues ([#1867](https://github.com/open-mmlab/mmpose/pull/1867), [#1921](https://github.com/open-mmlab/mmpose/pull/1921))\n- Fix evaluation issues and update results ([#1763](https://github.com/open-mmlab/mmpose/pull/1763), [#1773](https://github.com/open-mmlab/mmpose/pull/1773), [#1780](https://github.com/open-mmlab/mmpose/pull/1780), [#1850](https://github.com/open-mmlab/mmpose/pull/1850), [#1868](https://github.com/open-mmlab/mmpose/pull/1868))\n- Fix local registry missing warnings ([#1849](https://github.com/open-mmlab/mmpose/pull/1849))\n- Remove deprecated scripts for model deployment ([#1845](https://github.com/open-mmlab/mmpose/pull/1845))\n- Fix a bug in input transformation in BaseHead ([#1843](https://github.com/open-mmlab/mmpose/pull/1843))\n- Fix an interface mismatch with MMDetection in webcam demo ([#1813](https://github.com/open-mmlab/mmpose/pull/1813))\n- Fix a bug in heatmap visualization that causes incorrect scale ([#1800](https://github.com/open-mmlab/mmpose/pull/1800))\n- Add model metafiles ([#1768](https://github.com/open-mmlab/mmpose/pull/1768))\n\n## **v1.0.0rc0 (14/10/2022)**\n\n**New Features**\n\n- Support 4 light-weight pose estimation algorithms: [SimCC](https://doi.org/10.48550/arxiv.2107.03332) (ECCV'2022), [Debias-IPR](https://openaccess.thecvf.com/content/ICCV2021/papers/Gu_Removing_the_Bias_of_Integral_Pose_Regression_ICCV_2021_paper.pdf) (ICCV'2021), [IPR](https://arxiv.org/abs/1711.08229) (ECCV'2018), and [DSNT](https://arxiv.org/abs/1801.07372v2) (ArXiv'2018) ([#1628](https://github.com/open-mmlab/mmpose/pull/1628))\n\n**Migrations**\n\n- Add Webcam API in MMPose 1.0 ([#1638](https://github.com/open-mmlab/mmpose/pull/1638), [#1662](https://github.com/open-mmlab/mmpose/pull/1662)) @Ben-Louis\n- Add codec for Associative Embedding (beta) ([#1603](https://github.com/open-mmlab/mmpose/pull/1603)) @ly015\n\n**Improvements**\n\n- Add a colab tutorial for MMPose 1.0 ([#1660](https://github.com/open-mmlab/mmpose/pull/1660)) @Tau-J\n- Add model index in config folder ([#1710](https://github.com/open-mmlab/mmpose/pull/1710), [#1709](https://github.com/open-mmlab/mmpose/pull/1709), [#1627](https://github.com/open-mmlab/mmpose/pull/1627)) @ly015, @Tau-J, @Ben-Louis\n- Update and improve documentation ([#1692](https://github.com/open-mmlab/mmpose/pull/1692), [#1656](https://github.com/open-mmlab/mmpose/pull/1656), [#1681](https://github.com/open-mmlab/mmpose/pull/1681), [#1677](https://github.com/open-mmlab/mmpose/pull/1677), [#1664](https://github.com/open-mmlab/mmpose/pull/1664), [#1659](https://github.com/open-mmlab/mmpose/pull/1659)) @Tau-J, @Ben-Louis, @liqikai9\n- Improve config structures and formats ([#1651](https://github.com/open-mmlab/mmpose/pull/1651)) @liqikai9\n\n**Bug Fixes**\n\n- Update mmengine version requirements ([#1715](https://github.com/open-mmlab/mmpose/pull/1715)) @Ben-Louis\n- Update dependencies of pre-commit hooks ([#1705](https://github.com/open-mmlab/mmpose/pull/1705)) @Ben-Louis\n- Fix mmcv version in DockerFile ([#1704](https://github.com/open-mmlab/mmpose/pull/1704))\n- Fix a bug in setting dataset metainfo in configs ([#1684](https://github.com/open-mmlab/mmpose/pull/1684)) @ly015\n- Fix a bug in UDP training ([#1682](https://github.com/open-mmlab/mmpose/pull/1682)) @liqikai9\n- Fix a bug in Dark decoding ([#1676](https://github.com/open-mmlab/mmpose/pull/1676)) @liqikai9\n- Fix bugs in visualization ([#1671](https://github.com/open-mmlab/mmpose/pull/1671), [#1668](https://github.com/open-mmlab/mmpose/pull/1668), [#1657](https://github.com/open-mmlab/mmpose/pull/1657)) @liqikai9, @Ben-Louis\n- Fix incorrect flops calculation ([#1669](https://github.com/open-mmlab/mmpose/pull/1669)) @liqikai9\n- Fix `tensor.tile` compatibility issue for pytorch 1.6 ([#1658](https://github.com/open-mmlab/mmpose/pull/1658)) @ly015\n- Fix compatibility with `MultilevelPixelData` ([#1647](https://github.com/open-mmlab/mmpose/pull/1647)) @liqikai9\n\n## **v1.0.0beta (1/09/2022)**\n\nWe are excited to announce the release of MMPose 1.0.0beta.\nMMPose 1.0.0beta is the first version of MMPose 1.x, a part of the OpenMMLab 2.0 projects.\nBuilt upon the new [training engine](https://github.com/open-mmlab/mmengine).\n\n**Highlights**\n\n- **New engines**. MMPose 1.x is based on [MMEngine](https://github.com/open-mmlab/mmengine), which provides a general and powerful runner that allows more flexible customizations and significantly simplifies the entrypoints of high-level interfaces.\n\n- **Unified interfaces**. As a part of the OpenMMLab 2.0 projects, MMPose 1.x unifies and refactors the interfaces and internal logics of train, testing, datasets, models, evaluation, and visualization. All the OpenMMLab 2.0 projects share the same design in those interfaces and logics to allow the emergence of multi-task/modality algorithms.\n\n- **More documentation and tutorials**. We add a bunch of documentation and tutorials to help users get started more smoothly. Read it [here](https://mmpose.readthedocs.io/en/latest/).\n\n**Breaking Changes**\n\nIn this release, we made lots of major refactoring and modifications. Please refer to the [migration guide](../migration.md) for details and migration instructions.\n\n## **v0.28.1 (28/07/2022)**\n\nThis release is meant to fix the compatibility with the latest mmcv v1.6.1\n\n## **v0.28.0 (06/07/2022)**\n\n**Highlights**\n\n- Support [TCFormer](https://openaccess.thecvf.com/content/CVPR2022/html/Zeng_Not_All_Tokens_Are_Equal_Human-Centric_Visual_Analysis_via_Token_CVPR_2022_paper.html) backbone, CVPR'2022 ([#1447](https://github.com/open-mmlab/mmpose/pull/1447), [#1452](https://github.com/open-mmlab/mmpose/pull/1452)) @zengwang430521\n\n- Add [RLE](https://arxiv.org/abs/2107.11291) models on COCO dataset ([#1424](https://github.com/open-mmlab/mmpose/pull/1424)) @Indigo6, @Ben-Louis, @ly015\n\n- Update swin models with better performance ([#1467](https://github.com/open-mmlab/mmpose/pull/1434)) @jin-s13\n\n**New Features**\n\n- Support [TCFormer](https://openaccess.thecvf.com/content/CVPR2022/html/Zeng_Not_All_Tokens_Are_Equal_Human-Centric_Visual_Analysis_via_Token_CVPR_2022_paper.html) backbone, CVPR'2022 ([#1447](https://github.com/open-mmlab/mmpose/pull/1447), [#1452](https://github.com/open-mmlab/mmpose/pull/1452)) @zengwang430521\n\n- Add [RLE](https://arxiv.org/abs/2107.11291) models on COCO dataset ([#1424](https://github.com/open-mmlab/mmpose/pull/1424)) @Indigo6, @Ben-Louis, @ly015\n\n- Support layer decay optimizer constructor and learning rate decay optimizer constructor ([#1423](https://github.com/open-mmlab/mmpose/pull/1423)) @jin-s13\n\n**Improvements**\n\n- Improve documentation quality ([#1416](https://github.com/open-mmlab/mmpose/pull/1416), [#1421](https://github.com/open-mmlab/mmpose/pull/1421), [#1423](https://github.com/open-mmlab/mmpose/pull/1423), [#1426](https://github.com/open-mmlab/mmpose/pull/1426), [#1458](https://github.com/open-mmlab/mmpose/pull/1458), [#1463](https://github.com/open-mmlab/mmpose/pull/1463)) @ly015, @liqikai9\n\n- Support installation by [mim](https://github.com/open-mmlab/mim) ([#1425](https://github.com/open-mmlab/mmpose/pull/1425)) @liqikai9\n\n- Support PAVI logger ([#1434](https://github.com/open-mmlab/mmpose/pull/1434)) @EvelynWang-0423\n\n- Add progress bar for some demos ([#1454](https://github.com/open-mmlab/mmpose/pull/1454)) @liqikai9\n\n- Webcam API supports quick device setting in terminal commands ([#1466](https://github.com/open-mmlab/mmpose/pull/1466)) @ly015\n\n- Update swin models with better performance ([#1467](https://github.com/open-mmlab/mmpose/pull/1434)) @jin-s13\n\n**Bug Fixes**\n\n- Rename `custom_hooks_config` to `custom_hooks` in configs to align with the documentation ([#1427](https://github.com/open-mmlab/mmpose/pull/1427)) @ly015\n\n- Fix deadlock issue in Webcam API ([#1430](https://github.com/open-mmlab/mmpose/pull/1430)) @ly015\n\n- Fix smoother configs in video 3D demo ([#1457](https://github.com/open-mmlab/mmpose/pull/1457)) @ly015\n\n## **v0.27.0 (07/06/2022)**\n\n**Highlights**\n\n- Support hand gesture recognition\n\n  - Try the demo for gesture recognition\n  - Learn more about the algorithm, dataset and experiment results\n\n- Major upgrade to the Webcam API\n\n  - Tutorials (EN|zh_CN)\n  - [API Reference](https://mmpose.readthedocs.io/en/latest/api.html#mmpose-apis-webcam)\n  - Demo\n\n**New Features**\n\n- Support gesture recognition algorithm [MTUT](https://openaccess.thecvf.com/content_CVPR_2019/html/Abavisani_Improving_the_Performance_of_Unimodal_Dynamic_Hand-Gesture_Recognition_With_Multimodal_CVPR_2019_paper.html) CVPR'2019 and dataset [NVGesture](https://openaccess.thecvf.com/content_cvpr_2016/html/Molchanov_Online_Detection_and_CVPR_2016_paper.html) CVPR'2016 ([#1380](https://github.com/open-mmlab/mmpose/pull/1380)) @Ben-Louis\n\n**Improvements**\n\n- Upgrade Webcam API and related documents ([#1393](https://github.com/open-mmlab/mmpose/pull/1393), [#1404](https://github.com/open-mmlab/mmpose/pull/1404), [#1413](https://github.com/open-mmlab/mmpose/pull/1413)) @ly015\n\n- Support exporting COCO inference result without the annotation file ([#1368](https://github.com/open-mmlab/mmpose/pull/1368)) @liqikai9\n\n- Replace markdownlint with mdformat in CI to avoid the dependence on ruby [#1382](https://github.com/open-mmlab/mmpose/pull/1382) @ly015\n\n- Improve documentation quality ([#1385](https://github.com/open-mmlab/mmpose/pull/1385), [#1394](https://github.com/open-mmlab/mmpose/pull/1394), [#1395](https://github.com/open-mmlab/mmpose/pull/1395), [#1408](https://github.com/open-mmlab/mmpose/pull/1408)) @chubei-oppen, @ly015, @liqikai9\n\n**Bug Fixes**\n\n- Fix xywh->xyxy bbox conversion in dataset sanity check ([#1367](https://github.com/open-mmlab/mmpose/pull/1367)) @jin-s13\n\n- Fix a bug in two-stage 3D keypoint demo ([#1373](https://github.com/open-mmlab/mmpose/pull/1373)) @ly015\n\n- Fix out-dated settings in PVT configs ([#1376](https://github.com/open-mmlab/mmpose/pull/1376)) @ly015\n\n- Fix myst settings for document compiling ([#1381](https://github.com/open-mmlab/mmpose/pull/1381)) @ly015\n\n- Fix a bug in bbox transform ([#1384](https://github.com/open-mmlab/mmpose/pull/1384)) @ly015\n\n- Fix inaccurate description of `min_keypoints` in tracking apis ([#1398](https://github.com/open-mmlab/mmpose/pull/1398)) @pallgeuer\n\n- Fix warning with `torch.meshgrid` ([#1402](https://github.com/open-mmlab/mmpose/pull/1402)) @pallgeuer\n\n- Remove redundant transformer modules from `mmpose.datasets.backbones.utils` ([#1405](https://github.com/open-mmlab/mmpose/pull/1405)) @ly015\n\n## **v0.26.0 (05/05/2022)**\n\n**Highlights**\n\n- Support [RLE (Residual Log-likelihood Estimation)](https://arxiv.org/abs/2107.11291), ICCV'2021 ([#1259](https://github.com/open-mmlab/mmpose/pull/1259)) @Indigo6, @ly015\n\n- Support [Swin Transformer](https://arxiv.org/abs/2103.14030), ICCV'2021 ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @yumendecc, @ly015\n\n- Support [PVT](https://arxiv.org/abs/2102.12122), ICCV'2021 and [PVTv2](https://arxiv.org/abs/2106.13797), CVMJ'2022 ([#1343](https://github.com/open-mmlab/mmpose/pull/1343)) @zengwang430521\n\n- Speed up inference and reduce CPU usage by optimizing the pre-processing pipeline ([#1320](https://github.com/open-mmlab/mmpose/pull/1320)) @chenxinfeng4, @liqikai9\n\n**New Features**\n\n- Support [RLE (Residual Log-likelihood Estimation)](https://arxiv.org/abs/2107.11291), ICCV'2021 ([#1259](https://github.com/open-mmlab/mmpose/pull/1259)) @Indigo6, @ly015\n\n- Support [Swin Transformer](https://arxiv.org/abs/2103.14030), ICCV'2021 ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @yumendecc, @ly015\n\n- Support [PVT](https://arxiv.org/abs/2102.12122), ICCV'2021 and [PVTv2](https://arxiv.org/abs/2106.13797), CVMJ'2022 ([#1343](https://github.com/open-mmlab/mmpose/pull/1343)) @zengwang430521\n\n- Support [FPN](https://openaccess.thecvf.com/content_cvpr_2017/html/Lin_Feature_Pyramid_Networks_CVPR_2017_paper.html), CVPR'2017 ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @yumendecc, @ly015\n\n**Improvements**\n\n- Speed up inference and reduce CPU usage by optimizing the pre-processing pipeline ([#1320](https://github.com/open-mmlab/mmpose/pull/1320)) @chenxinfeng4, @liqikai9\n\n- Video demo supports models that requires multi-frame inputs ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @liqikai9, @jin-s13\n\n- Update benchmark regression list ([#1328](https://github.com/open-mmlab/mmpose/pull/1328)) @ly015, @liqikai9\n\n- Remove unnecessary warnings in `TopDownPoseTrack18VideoDataset` ([#1335](https://github.com/open-mmlab/mmpose/pull/1335)) @liqikai9\n\n- Improve documentation quality ([#1313](https://github.com/open-mmlab/mmpose/pull/1313), [#1305](https://github.com/open-mmlab/mmpose/pull/1305)) @Ben-Louis, @ly015\n\n- Update deprecating settings in configs ([#1317](https://github.com/open-mmlab/mmpose/pull/1317)) @ly015\n\n**Bug Fixes**\n\n- Fix a bug in human skeleton grouping that may skip the matching process unexpectedly when `ignore_to_much` is True ([#1341](https://github.com/open-mmlab/mmpose/pull/1341)) @daixinghome\n\n- Fix a GPG key error that leads to CI failure ([#1354](https://github.com/open-mmlab/mmpose/pull/1354)) @ly015\n\n- Fix bugs in distributed training script ([#1338](https://github.com/open-mmlab/mmpose/pull/1338), [#1298](https://github.com/open-mmlab/mmpose/pull/1298)) @ly015\n\n- Fix an upstream bug in xtoccotools that causes incorrect AP(M) results ([#1308](https://github.com/open-mmlab/mmpose/pull/1308)) @jin-s13, @ly015\n\n- Fix indentiation errors in the colab tutorial ([#1298](https://github.com/open-mmlab/mmpose/pull/1298)) @YuanZi1501040205\n\n- Fix incompatible model weight initialization with other OpenMMLab codebases ([#1329](https://github.com/open-mmlab/mmpose/pull/1329)) @274869388\n\n- Fix HRNet FP16 checkpoints download URL ([#1309](https://github.com/open-mmlab/mmpose/pull/1309)) @YinAoXiong\n\n- Fix typos in `body3d_two_stage_video_demo.py` ([#1295](https://github.com/open-mmlab/mmpose/pull/1295)) @mucozcan\n\n**Breaking Changes**\n\n- Refactor bbox processing in datasets and pipelines ([#1311](https://github.com/open-mmlab/mmpose/pull/1311)) @ly015, @Ben-Louis\n\n- The bbox format conversion (xywh to center-scale) and random translation are moved from the dataset to the pipeline. The comparison between new and old version is as below:\n\nv0.26.0v0.25.0Dataset\n(e.g. [TopDownCOCODataset](https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py))\n\n... # Data sample only contains bbox rec.append({    'bbox': obj\\['clean_bbox\\]\\[:4\\],    ... })\n\n</td>\n\n<td  valign='top'>\n\n... # Convert bbox from xywh to center-scale center, scale = self.\\_xywh2cs(\\*obj\\['clean_bbox'\\]\\[:4\\]) # Data sample contains center and scale rec.append({    'bbox': obj\\['clean_bbox\\]\\[:4\\],    'center': center,    'scale': scale,    ... })\n\n</td>\n\n</tr>\n\n<tr>\n\n<th>Pipeline Config\n\n(e.g. [HRNet+COCO](https://github.com/open-mmlab/mmpose/blob/master/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w32_coco_256x192.py))</th>\n\n<td valign='top'>\n\n... train_pipeline = \\[    dict(type='LoadImageFromFile'),    # Convert bbox from xywh to center-scale    dict(type='TopDownGetBboxCenterScale', padding=1.25),    # Randomly shift bbox center    dict(type='TopDownRandomShiftBboxCenter', shift_factor=0.16, prob=0.3),    ... \\]\n\n</td>\n\n<td valign='top'>\n\n... train_pipeline = \\[    dict(type='LoadImageFromFile'),    ... \\]\n\n</td>\n\n</tr>\n\n<tr>\n\n<th>Advantage</th>\n\n<td valign='top'>\n\n<li>Simpler data sample content</li>\n\n<li>Flexible bbox format conversion and augmentation</li>\n\n<li>Apply bbox random translation every epoch (instead of only applying once at the annotation loading)\n\n</td>\n\n<td valign='top'>-</td>\n\n</tr>\n\n<tr>\n\n<th>BC Breaking</th>\n\n<td valign='top'>The method `_xywh2cs` of dataset base classes (e.g. [Kpt2dSviewRgbImgTopDownDataset](https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/base/kpt_2d_sview_rgb_img_top_down_dataset.py)) will be deprecated in the future. Custom datasets will need modifications to move the bbox format conversion to pipelines.</td>\n\n<td valign='top'>-</td>\n\n</tr>\n\n</tbody>\n\n</table>\n\n## **v0.25.0 (02/04/2022)**\n\n**Highlights**\n\n- Support Shelf and Campus datasets with pre-trained VoxelPose models, [\"3D Pictorial Structures for Multiple Human Pose Estimation\"](http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf), CVPR'2014 ([#1225](https://github.com/open-mmlab/mmpose/pull/1225)) @liqikai9, @wusize\n\n- Add `Smoother` module for temporal smoothing of the pose estimation with configurable filters ([#1127](https://github.com/open-mmlab/mmpose/pull/1127)) @ailingzengzzz, @ly015\n\n- Support SmoothNet for pose smoothing, [\"SmoothNet: A Plug-and-Play Network for Refining Human Poses in Videos\"](https://arxiv.org/abs/2112.13715), arXiv'2021 ([#1279](https://github.com/open-mmlab/mmpose/pull/1279)) @ailingzengzzz, @ly015\n\n- Add multiview 3D pose estimation demo ([#1270](https://github.com/open-mmlab/mmpose/pull/1270)) @wusize\n\n**New Features**\n\n- Support Shelf and Campus datasets with pre-trained VoxelPose models, [\"3D Pictorial Structures for Multiple Human Pose Estimation\"](http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf), CVPR'2014 ([#1225](https://github.com/open-mmlab/mmpose/pull/1225)) @liqikai9, @wusize\n\n- Add `Smoother` module for temporal smoothing of the pose estimation with configurable filters ([#1127](https://github.com/open-mmlab/mmpose/pull/1127)) @ailingzengzzz, @ly015\n\n- Support SmoothNet for pose smoothing, [\"SmoothNet: A Plug-and-Play Network for Refining Human Poses in Videos\"](https://arxiv.org/abs/2112.13715), arXiv'2021 ([#1279](https://github.com/open-mmlab/mmpose/pull/1279)) @ailingzengzzz, @ly015\n\n- Add multiview 3D pose estimation demo ([#1270](https://github.com/open-mmlab/mmpose/pull/1270)) @wusize\n\n- Support multi-machine distributed training ([#1248](https://github.com/open-mmlab/mmpose/pull/1248)) @ly015\n\n**Improvements**\n\n- Update HRFormer configs and checkpoints with relative position bias ([#1245](https://github.com/open-mmlab/mmpose/pull/1245)) @zengwang430521\n\n- Support using different random seed for each distributed node ([#1257](https://github.com/open-mmlab/mmpose/pull/1257), [#1229](https://github.com/open-mmlab/mmpose/pull/1229)) @ly015\n\n- Improve documentation quality ([#1275](https://github.com/open-mmlab/mmpose/pull/1275), [#1255](https://github.com/open-mmlab/mmpose/pull/1255), [#1258](https://github.com/open-mmlab/mmpose/pull/1258), [#1249](https://github.com/open-mmlab/mmpose/pull/1249), [#1247](https://github.com/open-mmlab/mmpose/pull/1247), [#1240](https://github.com/open-mmlab/mmpose/pull/1240), [#1235](https://github.com/open-mmlab/mmpose/pull/1235)) @ly015, @jin-s13, @YoniChechik\n\n**Bug Fixes**\n\n- Fix keypoint index in RHD dataset meta information ([#1265](https://github.com/open-mmlab/mmpose/pull/1265)) @liqikai9\n\n- Fix pre-commit hook unexpected behavior on Windows ([#1282](https://github.com/open-mmlab/mmpose/pull/1282)) @liqikai9\n\n- Remove python-dev installation in CI ([#1276](https://github.com/open-mmlab/mmpose/pull/1276)) @ly015\n\n- Unify hyphens in argument names in tools and demos ([#1271](https://github.com/open-mmlab/mmpose/pull/1271)) @ly015\n\n- Fix ambiguous channel size in `channel_shuffle` that may cause exporting failure (#1242) @PINTO0309\n\n- Fix a bug in Webcam API that causes single-class detectors fail ([#1239](https://github.com/open-mmlab/mmpose/pull/1239)) @674106399\n\n- Fix the issue that `custom_hook` can not be set in configs ([#1236](https://github.com/open-mmlab/mmpose/pull/1236)) @bladrome\n\n- Fix incompatible MMCV version in DockerFile ([#raykindle](https://github.com/open-mmlab/mmpose/pull/raykindle))\n\n- Skip invisible joints in visualization ([#1228](https://github.com/open-mmlab/mmpose/pull/1228)) @womeier\n\n## **v0.24.0 (07/03/2022)**\n\n**Highlights**\n\n- Support HRFormer [\"HRFormer: High-Resolution Vision Transformer for Dense Predict\"](https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html), NeurIPS'2021 ([#1203](https://github.com/open-mmlab/mmpose/pull/1203)) @zengwang430521\n\n- Support Windows installation with pip ([#1213](https://github.com/open-mmlab/mmpose/pull/1213)) @jin-s13, @ly015\n\n- Add WebcamAPI documents ([#1187](https://github.com/open-mmlab/mmpose/pull/1187)) @ly015\n\n**New Features**\n\n- Support HRFormer [\"HRFormer: High-Resolution Vision Transformer for Dense Predict\"](https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html), NeurIPS'2021 ([#1203](https://github.com/open-mmlab/mmpose/pull/1203)) @zengwang430521\n\n- Support Windows installation with pip ([#1213](https://github.com/open-mmlab/mmpose/pull/1213)) @jin-s13, @ly015\n\n- Support CPU training with mmcv \\< v1.4.4 ([#1161](https://github.com/open-mmlab/mmpose/pull/1161)) @EasonQYS, @ly015\n\n- Add \"Valentine Magic\" demo with WebcamAPI ([#1189](https://github.com/open-mmlab/mmpose/pull/1189), [#1191](https://github.com/open-mmlab/mmpose/pull/1191)) @liqikai9\n\n**Improvements**\n\n- Refactor multi-view 3D pose estimation framework towards better modularization and expansibility ([#1196](https://github.com/open-mmlab/mmpose/pull/1196)) @wusize\n\n- Add WebcamAPI documents and tutorials ([#1187](https://github.com/open-mmlab/mmpose/pull/1187)) @ly015\n\n- Refactor dataset evaluation interface to align with other OpenMMLab codebases ([#1209](https://github.com/open-mmlab/mmpose/pull/1209)) @ly015\n\n- Add deprecation message for deploy tools since [MMDeploy](https://github.com/open-mmlab/mmdeploy) has supported MMPose ([#1207](https://github.com/open-mmlab/mmpose/pull/1207)) @QwQ2000\n\n- Improve documentation quality ([#1206](https://github.com/open-mmlab/mmpose/pull/1206), [#1161](https://github.com/open-mmlab/mmpose/pull/1161)) @ly015\n\n- Switch to OpenMMLab official pre-commit-hook for copyright check ([#1214](https://github.com/open-mmlab/mmpose/pull/1214)) @ly015\n\n**Bug Fixes**\n\n- Fix hard-coded data collating and scattering in inference ([#1175](https://github.com/open-mmlab/mmpose/pull/1175)) @ly015\n\n- Fix model configs on JHMDB dataset ([#1188](https://github.com/open-mmlab/mmpose/pull/1188)) @jin-s13\n\n- Fix area calculation in pose tracking inference ([#1197](https://github.com/open-mmlab/mmpose/pull/1197)) @pallgeuer\n\n- Fix registry scope conflict of module wrapper ([#1204](https://github.com/open-mmlab/mmpose/pull/1204)) @ly015\n\n- Update MMCV installation in CI and documents ([#1205](https://github.com/open-mmlab/mmpose/pull/1205))\n\n- Fix incorrect color channel order in visualization functions ([#1212](https://github.com/open-mmlab/mmpose/pull/1212)) @ly015\n\n## **v0.23.0 (11/02/2022)**\n\n**Highlights**\n\n- Add [MMPose Webcam API](https://github.com/open-mmlab/mmpose/tree/master/tools/webcam): A simple yet powerful tools to develop interactive webcam applications with MMPose functions. ([#1178](https://github.com/open-mmlab/mmpose/pull/1178), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1143](https://github.com/open-mmlab/mmpose/pull/1143), [#1094](https://github.com/open-mmlab/mmpose/pull/1094), [#1133](https://github.com/open-mmlab/mmpose/pull/1133), [#1098](https://github.com/open-mmlab/mmpose/pull/1098), [#1160](https://github.com/open-mmlab/mmpose/pull/1160)) @ly015, @jin-s13, @liqikai9, @wusize, @luminxu, @zengwang430521 @mzr1996\n\n**New Features**\n\n- Add [MMPose Webcam API](https://github.com/open-mmlab/mmpose/tree/master/tools/webcam): A simple yet powerful tools to develop interactive webcam applications with MMPose functions. ([#1178](https://github.com/open-mmlab/mmpose/pull/1178), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1143](https://github.com/open-mmlab/mmpose/pull/1143), [#1094](https://github.com/open-mmlab/mmpose/pull/1094), [#1133](https://github.com/open-mmlab/mmpose/pull/1133), [#1098](https://github.com/open-mmlab/mmpose/pull/1098), [#1160](https://github.com/open-mmlab/mmpose/pull/1160)) @ly015, @jin-s13, @liqikai9, @wusize, @luminxu, @zengwang430521 @mzr1996\n\n- Support ConcatDataset ([#1139](https://github.com/open-mmlab/mmpose/pull/1139)) @Canwang-sjtu\n\n- Support CPU training and testing ([#1157](https://github.com/open-mmlab/mmpose/pull/1157)) @ly015\n\n**Improvements**\n\n- Add multi-processing configurations to speed up distributed training and testing ([#1146](https://github.com/open-mmlab/mmpose/pull/1146)) @ly015\n\n- Add default runtime config ([#1145](https://github.com/open-mmlab/mmpose/pull/1145))\n\n- Upgrade isort in pre-commit hook ([#1179](https://github.com/open-mmlab/mmpose/pull/1179)) @liqikai9\n\n- Update README and documents ([#1171](https://github.com/open-mmlab/mmpose/pull/1171), [#1167](https://github.com/open-mmlab/mmpose/pull/1167), [#1153](https://github.com/open-mmlab/mmpose/pull/1153), [#1149](https://github.com/open-mmlab/mmpose/pull/1149), [#1148](https://github.com/open-mmlab/mmpose/pull/1148), [#1147](https://github.com/open-mmlab/mmpose/pull/1147), [#1140](https://github.com/open-mmlab/mmpose/pull/1140)) @jin-s13, @wusize, @TommyZihao, @ly015\n\n**Bug Fixes**\n\n- Fix undeterministic behavior in pre-commit hooks ([#1136](https://github.com/open-mmlab/mmpose/pull/1136)) @jin-s13\n\n- Deprecate the support for \"python setup.py test\" ([#1179](https://github.com/open-mmlab/mmpose/pull/1179)) @ly015\n\n- Fix incompatible settings with MMCV on HSigmoid default parameters ([#1132](https://github.com/open-mmlab/mmpose/pull/1132)) @ly015\n\n- Fix albumentation installation ([#1184](https://github.com/open-mmlab/mmpose/pull/1184)) @BIGWangYuDong\n\n## **v0.22.0 (04/01/2022)**\n\n**Highlights**\n\n- Support VoxelPose [\"VoxelPose: Towards Multi-Camera 3D Human Pose Estimation in Wild Environment\"](https://arxiv.org/abs/2004.06239), ECCV'2020 ([#1050](https://github.com/open-mmlab/mmpose/pull/1050)) @wusize\n\n- Support Soft Wing loss [\"Structure-Coherent Deep Feature Learning for Robust Face Alignment\"](https://linchunze.github.io/papers/TIP21_Structure_coherent_FA.pdf), TIP'2021 ([#1077](https://github.com/open-mmlab/mmpose/pull/1077)) @jin-s13\n\n- Support Adaptive Wing loss [\"Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression\"](https://arxiv.org/abs/1904.07399), ICCV'2019 ([#1072](https://github.com/open-mmlab/mmpose/pull/1072)) @jin-s13\n\n**New Features**\n\n- Support VoxelPose [\"VoxelPose: Towards Multi-Camera 3D Human Pose Estimation in Wild Environment\"](https://arxiv.org/abs/2004.06239), ECCV'2020 ([#1050](https://github.com/open-mmlab/mmpose/pull/1050)) @wusize\n\n- Support Soft Wing loss [\"Structure-Coherent Deep Feature Learning for Robust Face Alignment\"](https://linchunze.github.io/papers/TIP21_Structure_coherent_FA.pdf), TIP'2021 ([#1077](https://github.com/open-mmlab/mmpose/pull/1077)) @jin-s13\n\n- Support Adaptive Wing loss [\"Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression\"](https://arxiv.org/abs/1904.07399), ICCV'2019 ([#1072](https://github.com/open-mmlab/mmpose/pull/1072)) @jin-s13\n\n- Add LiteHRNet-18 Checkpoints trained on COCO. ([#1120](https://github.com/open-mmlab/mmpose/pull/1120)) @jin-s13\n\n**Improvements**\n\n- Improve documentation quality ([#1115](https://github.com/open-mmlab/mmpose/pull/1115), [#1111](https://github.com/open-mmlab/mmpose/pull/1111), [#1105](https://github.com/open-mmlab/mmpose/pull/1105), [#1087](https://github.com/open-mmlab/mmpose/pull/1087), [#1086](https://github.com/open-mmlab/mmpose/pull/1086), [#1085](https://github.com/open-mmlab/mmpose/pull/1085), [#1084](https://github.com/open-mmlab/mmpose/pull/1084), [#1083](https://github.com/open-mmlab/mmpose/pull/1083), [#1124](https://github.com/open-mmlab/mmpose/pull/1124), [#1070](https://github.com/open-mmlab/mmpose/pull/1070), [#1068](https://github.com/open-mmlab/mmpose/pull/1068)) @jin-s13, @liqikai9, @ly015\n\n- Support CircleCI ([#1074](https://github.com/open-mmlab/mmpose/pull/1074)) @ly015\n\n- Skip unit tests in CI when only document files were changed ([#1074](https://github.com/open-mmlab/mmpose/pull/1074), [#1041](https://github.com/open-mmlab/mmpose/pull/1041)) @QwQ2000, @ly015\n\n- Support file_client_args in LoadImageFromFile ([#1076](https://github.com/open-mmlab/mmpose/pull/1076)) @jin-s13\n\n**Bug Fixes**\n\n- Fix a bug in Dark UDP postprocessing that causes error when the channel number is large. ([#1079](https://github.com/open-mmlab/mmpose/pull/1079), [#1116](https://github.com/open-mmlab/mmpose/pull/1116)) @X00123, @jin-s13\n\n- Fix hard-coded `sigmas` in bottom-up image demo ([#1107](https://github.com/open-mmlab/mmpose/pull/1107), [#1101](https://github.com/open-mmlab/mmpose/pull/1101)) @chenxinfeng4, @liqikai9\n\n- Fix unstable checks in unit tests ([#1112](https://github.com/open-mmlab/mmpose/pull/1112)) @ly015\n\n- Do not destroy NULL windows if `args.show==False` in demo scripts ([#1104](https://github.com/open-mmlab/mmpose/pull/1104)) @bladrome\n\n## **v0.21.0 (06/12/2021)**\n\n**Highlights**\n\n- Support [\"Learning Temporal Pose Estimation from Sparsely-Labeled Videos\"](https://arxiv.org/abs/1906.04016), NeurIPS'2019 ([#932](https://github.com/open-mmlab/mmpose/pull/932), [#1006](https://github.com/open-mmlab/mmpose/pull/1006), [#1036](https://github.com/open-mmlab/mmpose/pull/1036), [#1060](https://github.com/open-mmlab/mmpose/pull/1060)) @liqikai9\n\n- Add ViPNAS-MobileNetV3 models ([#1025](https://github.com/open-mmlab/mmpose/pull/1025)) @luminxu, @jin-s13\n\n- Add inference speed benchmark ([#1028](https://github.com/open-mmlab/mmpose/pull/1028), [#1034](https://github.com/open-mmlab/mmpose/pull/1034), [#1044](https://github.com/open-mmlab/mmpose/pull/1044)) @liqikai9\n\n**New Features**\n\n- Support [\"Learning Temporal Pose Estimation from Sparsely-Labeled Videos\"](https://arxiv.org/abs/1906.04016), NeurIPS'2019 ([#932](https://github.com/open-mmlab/mmpose/pull/932), [#1006](https://github.com/open-mmlab/mmpose/pull/1006), [#1036](https://github.com/open-mmlab/mmpose/pull/1036)) @liqikai9\n\n- Add ViPNAS-MobileNetV3 models ([#1025](https://github.com/open-mmlab/mmpose/pull/1025)) @luminxu, @jin-s13\n\n- Add light-weight top-down models for whole-body keypoint detection ([#1009](https://github.com/open-mmlab/mmpose/pull/1009), [#1020](https://github.com/open-mmlab/mmpose/pull/1020), [#1055](https://github.com/open-mmlab/mmpose/pull/1055)) @luminxu, @ly015\n\n- Add HRNet checkpoints with various settings on PoseTrack18 ([#1035](https://github.com/open-mmlab/mmpose/pull/1035)) @liqikai9\n\n**Improvements**\n\n- Add inference speed benchmark ([#1028](https://github.com/open-mmlab/mmpose/pull/1028), [#1034](https://github.com/open-mmlab/mmpose/pull/1034), [#1044](https://github.com/open-mmlab/mmpose/pull/1044)) @liqikai9\n\n- Update model metafile format ([#1001](https://github.com/open-mmlab/mmpose/pull/1001)) @ly015\n\n- Support minus output feature index in mobilenet_v3 ([#1005](https://github.com/open-mmlab/mmpose/pull/1005)) @luminxu\n\n- Improve documentation quality ([#1018](https://github.com/open-mmlab/mmpose/pull/1018), [#1026](https://github.com/open-mmlab/mmpose/pull/1026), [#1027](https://github.com/open-mmlab/mmpose/pull/1027), [#1031](https://github.com/open-mmlab/mmpose/pull/1031), [#1038](https://github.com/open-mmlab/mmpose/pull/1038), [#1046](https://github.com/open-mmlab/mmpose/pull/1046), [#1056](https://github.com/open-mmlab/mmpose/pull/1056), [#1057](https://github.com/open-mmlab/mmpose/pull/1057)) @edybk, @luminxu, @ly015, @jin-s13\n\n- Set default random seed in training initialization ([#1030](https://github.com/open-mmlab/mmpose/pull/1030)) @ly015\n\n- Skip CI when only specific files changed ([#1041](https://github.com/open-mmlab/mmpose/pull/1041), [#1059](https://github.com/open-mmlab/mmpose/pull/1059)) @QwQ2000, @ly015\n\n- Automatically cancel uncompleted action runs when new commit arrives ([#1053](https://github.com/open-mmlab/mmpose/pull/1053)) @ly015\n\n**Bug Fixes**\n\n- Update pose tracking demo to be compatible with latest mmtracking ([#1014](https://github.com/open-mmlab/mmpose/pull/1014)) @jin-s13\n\n- Fix symlink creation failure when installed in Windows environments ([#1039](https://github.com/open-mmlab/mmpose/pull/1039)) @QwQ2000\n\n- Fix AP-10K dataset sigmas ([#1040](https://github.com/open-mmlab/mmpose/pull/1040)) @jin-s13\n\n## **v0.20.0 (01/11/2021)**\n\n**Highlights**\n\n- Add AP-10K dataset for animal pose estimation ([#987](https://github.com/open-mmlab/mmpose/pull/987)) @Annbless, @AlexTheBad, @jin-s13, @ly015\n\n- Support TorchServe ([#979](https://github.com/open-mmlab/mmpose/pull/979)) @ly015\n\n**New Features**\n\n- Add AP-10K dataset for animal pose estimation ([#987](https://github.com/open-mmlab/mmpose/pull/987)) @Annbless, @AlexTheBad, @jin-s13, @ly015\n\n- Add HRNetv2 checkpoints on 300W and COFW datasets ([#980](https://github.com/open-mmlab/mmpose/pull/980)) @jin-s13\n\n- Support TorchServe ([#979](https://github.com/open-mmlab/mmpose/pull/979)) @ly015\n\n**Bug Fixes**\n\n- Fix some deprecated or risky settings in configs ([#963](https://github.com/open-mmlab/mmpose/pull/963), [#976](https://github.com/open-mmlab/mmpose/pull/976), [#992](https://github.com/open-mmlab/mmpose/pull/992)) @jin-s13, @wusize\n\n- Fix issues of default arguments of training and testing scripts ([#970](https://github.com/open-mmlab/mmpose/pull/970), [#985](https://github.com/open-mmlab/mmpose/pull/985)) @liqikai9, @wusize\n\n- Fix heatmap and tag size mismatch in bottom-up with UDP ([#994](https://github.com/open-mmlab/mmpose/pull/994)) @wusize\n\n- Fix python3.9 installation in CI ([#983](https://github.com/open-mmlab/mmpose/pull/983)) @ly015\n\n- Fix model zoo document integrity issue ([#990](https://github.com/open-mmlab/mmpose/pull/990)) @jin-s13\n\n**Improvements**\n\n- Support non-square input shape for bottom-up ([#991](https://github.com/open-mmlab/mmpose/pull/991)) @wusize\n\n- Add image and video resources for demo ([#971](https://github.com/open-mmlab/mmpose/pull/971)) @liqikai9\n\n- Use CUDA docker images to accelerate CI ([#973](https://github.com/open-mmlab/mmpose/pull/973)) @ly015\n\n- Add codespell hook and fix detected typos ([#977](https://github.com/open-mmlab/mmpose/pull/977)) @ly015\n\n## **v0.19.0 (08/10/2021)**\n\n**Highlights**\n\n- Add models for Associative Embedding with Hourglass network backbone ([#906](https://github.com/open-mmlab/mmpose/pull/906), [#955](https://github.com/open-mmlab/mmpose/pull/955)) @jin-s13, @luminxu\n\n- Support COCO-Wholebody-Face and COCO-Wholebody-Hand datasets ([#813](https://github.com/open-mmlab/mmpose/pull/813)) @jin-s13, @innerlee, @luminxu\n\n- Upgrade dataset interface ([#901](https://github.com/open-mmlab/mmpose/pull/901), [#924](https://github.com/open-mmlab/mmpose/pull/924)) @jin-s13, @innerlee, @ly015, @liqikai9\n\n- New style of documentation ([#945](https://github.com/open-mmlab/mmpose/pull/945)) @ly015\n\n**New Features**\n\n- Add models for Associative Embedding with Hourglass network backbone ([#906](https://github.com/open-mmlab/mmpose/pull/906), [#955](https://github.com/open-mmlab/mmpose/pull/955)) @jin-s13, @luminxu\n\n- Support COCO-Wholebody-Face and COCO-Wholebody-Hand datasets ([#813](https://github.com/open-mmlab/mmpose/pull/813)) @jin-s13, @innerlee, @luminxu\n\n- Add pseudo-labeling tool to generate COCO style keypoint annotations with given bounding boxes ([#928](https://github.com/open-mmlab/mmpose/pull/928)) @soltkreig\n\n- New style of documentation ([#945](https://github.com/open-mmlab/mmpose/pull/945)) @ly015\n\n**Bug Fixes**\n\n- Fix segmentation parsing in Macaque dataset preprocessing ([#948](https://github.com/open-mmlab/mmpose/pull/948)) @jin-s13\n\n- Fix dependencies that may lead to CI failure in downstream projects ([#936](https://github.com/open-mmlab/mmpose/pull/936), [#953](https://github.com/open-mmlab/mmpose/pull/953)) @RangiLyu, @ly015\n\n- Fix keypoint order in Human3.6M dataset ([#940](https://github.com/open-mmlab/mmpose/pull/940)) @ttxskk\n\n- Fix unstable image loading for Interhand2.6M ([#913](https://github.com/open-mmlab/mmpose/pull/913)) @zengwang430521\n\n**Improvements**\n\n- Upgrade dataset interface ([#901](https://github.com/open-mmlab/mmpose/pull/901), [#924](https://github.com/open-mmlab/mmpose/pull/924)) @jin-s13, @innerlee, @ly015, @liqikai9\n\n- Improve demo usability and stability ([#908](https://github.com/open-mmlab/mmpose/pull/908), [#934](https://github.com/open-mmlab/mmpose/pull/934)) @ly015\n\n- Standardize model metafile format ([#941](https://github.com/open-mmlab/mmpose/pull/941)) @ly015\n\n- Support `persistent_worker` and several other arguments in configs ([#946](https://github.com/open-mmlab/mmpose/pull/946)) @jin-s13\n\n- Use MMCV root model registry to enable cross-project module building ([#935](https://github.com/open-mmlab/mmpose/pull/935)) @RangiLyu\n\n- Improve the document quality ([#916](https://github.com/open-mmlab/mmpose/pull/916), [#909](https://github.com/open-mmlab/mmpose/pull/909), [#942](https://github.com/open-mmlab/mmpose/pull/942), [#913](https://github.com/open-mmlab/mmpose/pull/913), [#956](https://github.com/open-mmlab/mmpose/pull/956)) @jin-s13, @ly015, @bit-scientist, @zengwang430521\n\n- Improve pull request template ([#952](https://github.com/open-mmlab/mmpose/pull/952), [#954](https://github.com/open-mmlab/mmpose/pull/954)) @ly015\n\n**Breaking Changes**\n\n- Upgrade dataset interface ([#901](https://github.com/open-mmlab/mmpose/pull/901)) @jin-s13, @innerlee, @ly015\n\n## **v0.18.0 (01/09/2021)**\n\n**Bug Fixes**\n\n- Fix redundant model weight loading in pytorch-to-onnx conversion ([#850](https://github.com/open-mmlab/mmpose/pull/850)) @ly015\n\n- Fix a bug in update_model_index.py that may cause pre-commit hook failure([#866](https://github.com/open-mmlab/mmpose/pull/866)) @ly015\n\n- Fix a bug in interhand_3d_head ([#890](https://github.com/open-mmlab/mmpose/pull/890)) @zengwang430521\n\n- Fix pose tracking demo failure caused by out-of-date configs ([#891](https://github.com/open-mmlab/mmpose/pull/891))\n\n**Improvements**\n\n- Add automatic benchmark regression tools ([#849](https://github.com/open-mmlab/mmpose/pull/849), [#880](https://github.com/open-mmlab/mmpose/pull/880), [#885](https://github.com/open-mmlab/mmpose/pull/885)) @liqikai9, @ly015\n\n- Add copyright information and checking hook ([#872](https://github.com/open-mmlab/mmpose/pull/872))\n\n- Add PR template ([#875](https://github.com/open-mmlab/mmpose/pull/875)) @ly015\n\n- Add citation information ([#876](https://github.com/open-mmlab/mmpose/pull/876)) @ly015\n\n- Add python3.9 in CI ([#877](https://github.com/open-mmlab/mmpose/pull/877), [#883](https://github.com/open-mmlab/mmpose/pull/883)) @ly015\n\n- Improve the quality of the documents ([#845](https://github.com/open-mmlab/mmpose/pull/845), [#845](https://github.com/open-mmlab/mmpose/pull/845), [#848](https://github.com/open-mmlab/mmpose/pull/848), [#867](https://github.com/open-mmlab/mmpose/pull/867), [#870](https://github.com/open-mmlab/mmpose/pull/870), [#873](https://github.com/open-mmlab/mmpose/pull/873), [#896](https://github.com/open-mmlab/mmpose/pull/896)) @jin-s13, @ly015, @zhiqwang\n\n## **v0.17.0 (06/08/2021)**\n\n**Highlights**\n\n1. Support [\"Lite-HRNet: A Lightweight High-Resolution Network\"](https://arxiv.org/abs/2104.06403) CVPR'2021 ([#733](https://github.com/open-mmlab/mmpose/pull/733),[#800](https://github.com/open-mmlab/mmpose/pull/800)) @jin-s13\n\n2. Add 3d body mesh demo ([#771](https://github.com/open-mmlab/mmpose/pull/771)) @zengwang430521\n\n3. Add Chinese documentation ([#787](https://github.com/open-mmlab/mmpose/pull/787), [#798](https://github.com/open-mmlab/mmpose/pull/798), [#799](https://github.com/open-mmlab/mmpose/pull/799), [#802](https://github.com/open-mmlab/mmpose/pull/802), [#804](https://github.com/open-mmlab/mmpose/pull/804), [#805](https://github.com/open-mmlab/mmpose/pull/805), [#815](https://github.com/open-mmlab/mmpose/pull/815), [#816](https://github.com/open-mmlab/mmpose/pull/816), [#817](https://github.com/open-mmlab/mmpose/pull/817), [#819](https://github.com/open-mmlab/mmpose/pull/819), [#839](https://github.com/open-mmlab/mmpose/pull/839)) @ly015, @luminxu, @jin-s13, @liqikai9, @zengwang430521\n\n4. Add Colab Tutorial ([#834](https://github.com/open-mmlab/mmpose/pull/834)) @ly015\n\n**New Features**\n\n- Support [\"Lite-HRNet: A Lightweight High-Resolution Network\"](https://arxiv.org/abs/2104.06403) CVPR'2021 ([#733](https://github.com/open-mmlab/mmpose/pull/733),[#800](https://github.com/open-mmlab/mmpose/pull/800)) @jin-s13\n\n- Add 3d body mesh demo ([#771](https://github.com/open-mmlab/mmpose/pull/771)) @zengwang430521\n\n- Add Chinese documentation ([#787](https://github.com/open-mmlab/mmpose/pull/787), [#798](https://github.com/open-mmlab/mmpose/pull/798), [#799](https://github.com/open-mmlab/mmpose/pull/799), [#802](https://github.com/open-mmlab/mmpose/pull/802), [#804](https://github.com/open-mmlab/mmpose/pull/804), [#805](https://github.com/open-mmlab/mmpose/pull/805), [#815](https://github.com/open-mmlab/mmpose/pull/815), [#816](https://github.com/open-mmlab/mmpose/pull/816), [#817](https://github.com/open-mmlab/mmpose/pull/817), [#819](https://github.com/open-mmlab/mmpose/pull/819), [#839](https://github.com/open-mmlab/mmpose/pull/839)) @ly015, @luminxu, @jin-s13, @liqikai9, @zengwang430521\n\n- Add Colab Tutorial ([#834](https://github.com/open-mmlab/mmpose/pull/834)) @ly015\n\n- Support training for InterHand v1.0 dataset ([#761](https://github.com/open-mmlab/mmpose/pull/761)) @zengwang430521\n\n**Bug Fixes**\n\n- Fix mpii pckh@0.1 index ([#773](https://github.com/open-mmlab/mmpose/pull/773)) @jin-s13\n\n- Fix multi-node distributed test ([#818](https://github.com/open-mmlab/mmpose/pull/818)) @ly015\n\n- Fix docstring and init_weights error of ShuffleNetV1 ([#814](https://github.com/open-mmlab/mmpose/pull/814)) @Junjun2016\n\n- Fix imshow_bbox error when input bboxes is empty ([#796](https://github.com/open-mmlab/mmpose/pull/796)) @ly015\n\n- Fix model zoo doc generation ([#778](https://github.com/open-mmlab/mmpose/pull/778)) @ly015\n\n- Fix typo ([#767](https://github.com/open-mmlab/mmpose/pull/767)), ([#780](https://github.com/open-mmlab/mmpose/pull/780), [#782](https://github.com/open-mmlab/mmpose/pull/782)) @ly015, @jin-s13\n\n**Breaking Changes**\n\n- Use MMCV EvalHook ([#686](https://github.com/open-mmlab/mmpose/pull/686)) @ly015\n\n**Improvements**\n\n- Add pytest.ini and fix docstring ([#812](https://github.com/open-mmlab/mmpose/pull/812)) @jin-s13\n\n- Update MSELoss ([#829](https://github.com/open-mmlab/mmpose/pull/829)) @Ezra-Yu\n\n- Move process_mmdet_results into inference.py ([#831](https://github.com/open-mmlab/mmpose/pull/831)) @ly015\n\n- Update resource limit ([#783](https://github.com/open-mmlab/mmpose/pull/783)) @jin-s13\n\n- Use COCO 2D pose model in 3D demo examples ([#785](https://github.com/open-mmlab/mmpose/pull/785)) @ly015\n\n- Change model zoo titles in the doc from center-aligned to left-aligned ([#792](https://github.com/open-mmlab/mmpose/pull/792), [#797](https://github.com/open-mmlab/mmpose/pull/797)) @ly015\n\n- Support MIM ([#706](https://github.com/open-mmlab/mmpose/pull/706), [#794](https://github.com/open-mmlab/mmpose/pull/794)) @ly015\n\n- Update out-of-date configs ([#827](https://github.com/open-mmlab/mmpose/pull/827)) @jin-s13\n\n- Remove opencv-python-headless dependency by albumentations ([#833](https://github.com/open-mmlab/mmpose/pull/833)) @ly015\n\n- Update QQ QR code in README_CN.md ([#832](https://github.com/open-mmlab/mmpose/pull/832)) @ly015\n\n## **v0.16.0 (02/07/2021)**\n\n**Highlights**\n\n1. Support [\"ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\"](https://arxiv.org/abs/2105.10154) CVPR'2021 ([#742](https://github.com/open-mmlab/mmpose/pull/742),[#755](https://github.com/open-mmlab/mmpose/pull/755)).\n\n2. Support MPI-INF-3DHP dataset ([#683](https://github.com/open-mmlab/mmpose/pull/683),[#746](https://github.com/open-mmlab/mmpose/pull/746),[#751](https://github.com/open-mmlab/mmpose/pull/751)).\n\n3. Add webcam demo tool ([#729](https://github.com/open-mmlab/mmpose/pull/729))\n\n4. Add 3d body and hand pose estimation demo ([#704](https://github.com/open-mmlab/mmpose/pull/704), [#727](https://github.com/open-mmlab/mmpose/pull/727)).\n\n**New Features**\n\n- Support [\"ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\"](https://arxiv.org/abs/2105.10154) CVPR'2021 ([#742](https://github.com/open-mmlab/mmpose/pull/742),[#755](https://github.com/open-mmlab/mmpose/pull/755))\n\n- Support MPI-INF-3DHP dataset ([#683](https://github.com/open-mmlab/mmpose/pull/683),[#746](https://github.com/open-mmlab/mmpose/pull/746),[#751](https://github.com/open-mmlab/mmpose/pull/751))\n\n- Support Webcam demo ([#729](https://github.com/open-mmlab/mmpose/pull/729))\n\n- Support Interhand 3d demo ([#704](https://github.com/open-mmlab/mmpose/pull/704))\n\n- Support 3d pose video demo ([#727](https://github.com/open-mmlab/mmpose/pull/727))\n\n- Support H36m dataset for 2d pose estimation ([#709](https://github.com/open-mmlab/mmpose/pull/709), [#735](https://github.com/open-mmlab/mmpose/pull/735))\n\n- Add scripts to generate mim metafile ([#749](https://github.com/open-mmlab/mmpose/pull/749))\n\n**Bug Fixes**\n\n- Fix typos ([#692](https://github.com/open-mmlab/mmpose/pull/692),[#696](https://github.com/open-mmlab/mmpose/pull/696),[#697](https://github.com/open-mmlab/mmpose/pull/697),[#698](https://github.com/open-mmlab/mmpose/pull/698),[#712](https://github.com/open-mmlab/mmpose/pull/712),[#718](https://github.com/open-mmlab/mmpose/pull/718),[#728](https://github.com/open-mmlab/mmpose/pull/728))\n\n- Change model download links from `http` to `https` ([#716](https://github.com/open-mmlab/mmpose/pull/716))\n\n**Breaking Changes**\n\n- Switch to MMCV MODEL_REGISTRY ([#669](https://github.com/open-mmlab/mmpose/pull/669))\n\n**Improvements**\n\n- Refactor MeshMixDataset ([#752](https://github.com/open-mmlab/mmpose/pull/752))\n\n- Rename 'GaussianHeatMap' to 'GaussianHeatmap' ([#745](https://github.com/open-mmlab/mmpose/pull/745))\n\n- Update out-of-date configs ([#734](https://github.com/open-mmlab/mmpose/pull/734))\n\n- Improve compatibility for breaking changes ([#731](https://github.com/open-mmlab/mmpose/pull/731))\n\n- Enable to control radius and thickness in visualization ([#722](https://github.com/open-mmlab/mmpose/pull/722))\n\n- Add regex dependency ([#720](https://github.com/open-mmlab/mmpose/pull/720))\n\n## **v0.15.0 (02/06/2021)**\n\n**Highlights**\n\n1. Support 3d video pose estimation (VideoPose3D).\n\n2. Support 3d hand pose estimation (InterNet).\n\n3. Improve presentation of modelzoo.\n\n**New Features**\n\n- Support \"InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image\" (ECCV‘20) ([#624](https://github.com/open-mmlab/mmpose/pull/624))\n\n- Support \"3D human pose estimation in video with temporal convolutions and semi-supervised training\" (CVPR'19)  ([#602](https://github.com/open-mmlab/mmpose/pull/602), [#681](https://github.com/open-mmlab/mmpose/pull/681))\n\n- Support 3d pose estimation demo ([#653](https://github.com/open-mmlab/mmpose/pull/653), [#670](https://github.com/open-mmlab/mmpose/pull/670))\n\n- Support bottom-up whole-body pose estimation ([#689](https://github.com/open-mmlab/mmpose/pull/689))\n\n- Support mmcli ([#634](https://github.com/open-mmlab/mmpose/pull/634))\n\n**Bug Fixes**\n\n- Fix opencv compatibility ([#635](https://github.com/open-mmlab/mmpose/pull/635))\n\n- Fix demo with UDP ([#637](https://github.com/open-mmlab/mmpose/pull/637))\n\n- Fix bottom-up model onnx conversion ([#680](https://github.com/open-mmlab/mmpose/pull/680))\n\n- Fix `GPU_IDS` in distributed training ([#668](https://github.com/open-mmlab/mmpose/pull/668))\n\n- Fix MANIFEST.in ([#641](https://github.com/open-mmlab/mmpose/pull/641), [#657](https://github.com/open-mmlab/mmpose/pull/657))\n\n- Fix docs ([#643](https://github.com/open-mmlab/mmpose/pull/643),[#684](https://github.com/open-mmlab/mmpose/pull/684),[#688](https://github.com/open-mmlab/mmpose/pull/688),[#690](https://github.com/open-mmlab/mmpose/pull/690),[#692](https://github.com/open-mmlab/mmpose/pull/692))\n\n**Breaking Changes**\n\n- Reorganize configs by tasks, algorithms, datasets, and techniques ([#647](https://github.com/open-mmlab/mmpose/pull/647))\n\n- Rename heads and detectors ([#667](https://github.com/open-mmlab/mmpose/pull/667))\n\n**Improvements**\n\n- Add `radius` and `thickness` parameters in visualization ([#638](https://github.com/open-mmlab/mmpose/pull/638))\n\n- Add `trans_prob` parameter in `TopDownRandomTranslation` ([#650](https://github.com/open-mmlab/mmpose/pull/650))\n\n- Switch to `MMCV MODEL_REGISTRY` ([#669](https://github.com/open-mmlab/mmpose/pull/669))\n\n- Update dependencies ([#674](https://github.com/open-mmlab/mmpose/pull/674), [#676](https://github.com/open-mmlab/mmpose/pull/676))\n\n## **v0.14.0 (06/05/2021)**\n\n**Highlights**\n\n1. Support animal pose estimation with 7 popular datasets.\n\n2. Support \"A simple yet effective baseline for 3d human pose estimation\" (ICCV'17).\n\n**New Features**\n\n- Support \"A simple yet effective baseline for 3d human pose estimation\" (ICCV'17)  ([#554](https://github.com/open-mmlab/mmpose/pull/554),[#558](https://github.com/open-mmlab/mmpose/pull/558),[#566](https://github.com/open-mmlab/mmpose/pull/566),[#570](https://github.com/open-mmlab/mmpose/pull/570),[#589](https://github.com/open-mmlab/mmpose/pull/589))\n\n- Support animal pose estimation ([#559](https://github.com/open-mmlab/mmpose/pull/559),[#561](https://github.com/open-mmlab/mmpose/pull/561),[#563](https://github.com/open-mmlab/mmpose/pull/563),[#571](https://github.com/open-mmlab/mmpose/pull/571),[#603](https://github.com/open-mmlab/mmpose/pull/603),[#605](https://github.com/open-mmlab/mmpose/pull/605))\n\n- Support Horse-10 dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), MacaquePose dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), Vinegar Fly dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), Desert Locust dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), Grevy's Zebra dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), ATRW dataset ([#571](https://github.com/open-mmlab/mmpose/pull/571)), and Animal-Pose dataset ([#603](https://github.com/open-mmlab/mmpose/pull/603))\n\n- Support bottom-up pose tracking demo ([#574](https://github.com/open-mmlab/mmpose/pull/574))\n\n- Support FP16 training ([#584](https://github.com/open-mmlab/mmpose/pull/584),[#616](https://github.com/open-mmlab/mmpose/pull/616),[#626](https://github.com/open-mmlab/mmpose/pull/626))\n\n- Support NMS for bottom-up ([#609](https://github.com/open-mmlab/mmpose/pull/609))\n\n**Bug Fixes**\n\n- Fix bugs in the top-down demo, when there are no people in the images ([#569](https://github.com/open-mmlab/mmpose/pull/569)).\n\n- Fix the links in the doc ([#612](https://github.com/open-mmlab/mmpose/pull/612))\n\n**Improvements**\n\n- Speed up top-down inference ([#560](https://github.com/open-mmlab/mmpose/pull/560))\n\n- Update github CI ([#562](https://github.com/open-mmlab/mmpose/pull/562), [#564](https://github.com/open-mmlab/mmpose/pull/564))\n\n- Update Readme ([#578](https://github.com/open-mmlab/mmpose/pull/578),[#579](https://github.com/open-mmlab/mmpose/pull/579),[#580](https://github.com/open-mmlab/mmpose/pull/580),[#592](https://github.com/open-mmlab/mmpose/pull/592),[#599](https://github.com/open-mmlab/mmpose/pull/599),[#600](https://github.com/open-mmlab/mmpose/pull/600),[#607](https://github.com/open-mmlab/mmpose/pull/607))\n\n- Update Faq ([#587](https://github.com/open-mmlab/mmpose/pull/587), [#610](https://github.com/open-mmlab/mmpose/pull/610))\n\n## **v0.13.0 (31/03/2021)**\n\n**Highlights**\n\n1. Support Wingloss.\n\n2. Support RHD hand dataset.\n\n**New Features**\n\n- Support Wingloss ([#482](https://github.com/open-mmlab/mmpose/pull/482))\n\n- Support RHD hand dataset ([#523](https://github.com/open-mmlab/mmpose/pull/523), [#551](https://github.com/open-mmlab/mmpose/pull/551))\n\n- Support Human3.6m dataset for 3d keypoint detection ([#518](https://github.com/open-mmlab/mmpose/pull/518), [#527](https://github.com/open-mmlab/mmpose/pull/527))\n\n- Support TCN model for 3d keypoint detection ([#521](https://github.com/open-mmlab/mmpose/pull/521), [#522](https://github.com/open-mmlab/mmpose/pull/522))\n\n- Support Interhand3D model for 3d hand detection ([#536](https://github.com/open-mmlab/mmpose/pull/536))\n\n- Support Multi-task detector ([#480](https://github.com/open-mmlab/mmpose/pull/480))\n\n**Bug Fixes**\n\n- Fix PCKh@0.1 calculation ([#516](https://github.com/open-mmlab/mmpose/pull/516))\n\n- Fix unittest ([#529](https://github.com/open-mmlab/mmpose/pull/529))\n\n- Fix circular importing ([#542](https://github.com/open-mmlab/mmpose/pull/542))\n\n- Fix bugs in bottom-up keypoint score ([#548](https://github.com/open-mmlab/mmpose/pull/548))\n\n**Improvements**\n\n- Update config & checkpoints ([#525](https://github.com/open-mmlab/mmpose/pull/525), [#546](https://github.com/open-mmlab/mmpose/pull/546))\n\n- Fix typos ([#514](https://github.com/open-mmlab/mmpose/pull/514), [#519](https://github.com/open-mmlab/mmpose/pull/519), [#532](https://github.com/open-mmlab/mmpose/pull/532), [#537](https://github.com/open-mmlab/mmpose/pull/537), )\n\n- Speed up post processing ([#535](https://github.com/open-mmlab/mmpose/pull/535))\n\n- Update mmcv version dependency ([#544](https://github.com/open-mmlab/mmpose/pull/544))\n\n## **v0.12.0 (28/02/2021)**\n\n**Highlights**\n\n1. Support DeepPose algorithm.\n\n**New Features**\n\n- Support DeepPose algorithm ([#446](https://github.com/open-mmlab/mmpose/pull/446), [#461](https://github.com/open-mmlab/mmpose/pull/461))\n\n- Support interhand3d dataset ([#468](https://github.com/open-mmlab/mmpose/pull/468))\n\n- Support Albumentation pipeline ([#469](https://github.com/open-mmlab/mmpose/pull/469))\n\n- Support PhotometricDistortion pipeline ([#485](https://github.com/open-mmlab/mmpose/pull/485))\n\n- Set seed option for training ([#493](https://github.com/open-mmlab/mmpose/pull/493))\n\n- Add demos for face keypoint detection ([#502](https://github.com/open-mmlab/mmpose/pull/502))\n\n**Bug Fixes**\n\n- Change channel order according to configs ([#504](https://github.com/open-mmlab/mmpose/pull/504))\n\n- Fix `num_factors` in UDP encoding ([#495](https://github.com/open-mmlab/mmpose/pull/495))\n\n- Fix configs ([#456](https://github.com/open-mmlab/mmpose/pull/456))\n\n**Breaking Changes**\n\n- Refactor configs for wholebody pose estimation ([#487](https://github.com/open-mmlab/mmpose/pull/487), [#491](https://github.com/open-mmlab/mmpose/pull/491))\n\n- Rename `decode` function for heads ([#481](https://github.com/open-mmlab/mmpose/pull/481))\n\n**Improvements**\n\n- Update config & checkpoints ([#453](https://github.com/open-mmlab/mmpose/pull/453),[#484](https://github.com/open-mmlab/mmpose/pull/484),[#487](https://github.com/open-mmlab/mmpose/pull/487))\n\n- Add README in Chinese ([#462](https://github.com/open-mmlab/mmpose/pull/462))\n\n- Add tutorials about configs  ([#465](https://github.com/open-mmlab/mmpose/pull/465))\n\n- Add demo videos for various tasks ([#499](https://github.com/open-mmlab/mmpose/pull/499), [#503](https://github.com/open-mmlab/mmpose/pull/503))\n\n- Update docs about MMPose installation ([#467](https://github.com/open-mmlab/mmpose/pull/467), [#505](https://github.com/open-mmlab/mmpose/pull/505))\n\n- Rename `stat.py` to `stats.py` ([#483](https://github.com/open-mmlab/mmpose/pull/483))\n\n- Fix typos ([#463](https://github.com/open-mmlab/mmpose/pull/463), [#464](https://github.com/open-mmlab/mmpose/pull/464), [#477](https://github.com/open-mmlab/mmpose/pull/477), [#481](https://github.com/open-mmlab/mmpose/pull/481))\n\n- latex to bibtex ([#471](https://github.com/open-mmlab/mmpose/pull/471))\n\n- Update FAQ ([#466](https://github.com/open-mmlab/mmpose/pull/466))\n\n## **v0.11.0 (31/01/2021)**\n\n**Highlights**\n\n1. Support fashion landmark detection.\n\n2. Support face keypoint detection.\n\n3. Support pose tracking with MMTracking.\n\n**New Features**\n\n- Support fashion landmark detection (DeepFashion) ([#413](https://github.com/open-mmlab/mmpose/pull/413))\n\n- Support face keypoint detection (300W, AFLW, COFW, WFLW) ([#367](https://github.com/open-mmlab/mmpose/pull/367))\n\n- Support pose tracking demo with MMTracking ([#427](https://github.com/open-mmlab/mmpose/pull/427))\n\n- Support face demo ([#443](https://github.com/open-mmlab/mmpose/pull/443))\n\n- Support AIC dataset for bottom-up methods ([#438](https://github.com/open-mmlab/mmpose/pull/438), [#449](https://github.com/open-mmlab/mmpose/pull/449))\n\n**Bug Fixes**\n\n- Fix multi-batch training ([#434](https://github.com/open-mmlab/mmpose/pull/434))\n\n- Fix sigmas in AIC dataset ([#441](https://github.com/open-mmlab/mmpose/pull/441))\n\n- Fix config file ([#420](https://github.com/open-mmlab/mmpose/pull/420))\n\n**Breaking Changes**\n\n- Refactor Heads ([#382](https://github.com/open-mmlab/mmpose/pull/382))\n\n**Improvements**\n\n- Update readme ([#409](https://github.com/open-mmlab/mmpose/pull/409), [#412](https://github.com/open-mmlab/mmpose/pull/412), [#415](https://github.com/open-mmlab/mmpose/pull/415), [#416](https://github.com/open-mmlab/mmpose/pull/416), [#419](https://github.com/open-mmlab/mmpose/pull/419), [#421](https://github.com/open-mmlab/mmpose/pull/421), [#422](https://github.com/open-mmlab/mmpose/pull/422), [#424](https://github.com/open-mmlab/mmpose/pull/424), [#425](https://github.com/open-mmlab/mmpose/pull/425), [#435](https://github.com/open-mmlab/mmpose/pull/435), [#436](https://github.com/open-mmlab/mmpose/pull/436), [#437](https://github.com/open-mmlab/mmpose/pull/437), [#444](https://github.com/open-mmlab/mmpose/pull/444), [#445](https://github.com/open-mmlab/mmpose/pull/445))\n\n- Add GAP (global average pooling) neck ([#414](https://github.com/open-mmlab/mmpose/pull/414))\n\n- Speed up ([#411](https://github.com/open-mmlab/mmpose/pull/411), [#423](https://github.com/open-mmlab/mmpose/pull/423))\n\n- Support COCO test-dev test ([#433](https://github.com/open-mmlab/mmpose/pull/433))\n\n## **v0.10.0 (31/12/2020)**\n\n**Highlights**\n\n1. Support more human pose estimation methods.\n\n   1. [UDP](https://arxiv.org/abs/1911.07524)\n\n2. Support pose tracking.\n\n3. Support multi-batch inference.\n\n4. Add some useful tools, including `analyze_logs`, `get_flops`, `print_config`.\n\n5. Support more backbone networks.\n\n   1. [ResNest](https://arxiv.org/pdf/2004.08955.pdf)\n   2. [VGG](https://arxiv.org/abs/1409.1556)\n\n**New Features**\n\n- Support UDP ([#353](https://github.com/open-mmlab/mmpose/pull/353), [#371](https://github.com/open-mmlab/mmpose/pull/371), [#402](https://github.com/open-mmlab/mmpose/pull/402))\n\n- Support multi-batch inference ([#390](https://github.com/open-mmlab/mmpose/pull/390))\n\n- Support MHP dataset ([#386](https://github.com/open-mmlab/mmpose/pull/386))\n\n- Support pose tracking demo ([#380](https://github.com/open-mmlab/mmpose/pull/380))\n\n- Support mpii-trb demo ([#372](https://github.com/open-mmlab/mmpose/pull/372))\n\n- Support mobilenet for hand pose estimation ([#377](https://github.com/open-mmlab/mmpose/pull/377))\n\n- Support ResNest backbone ([#370](https://github.com/open-mmlab/mmpose/pull/370))\n\n- Support VGG backbone ([#370](https://github.com/open-mmlab/mmpose/pull/370))\n\n- Add some useful tools, including `analyze_logs`, `get_flops`, `print_config` ([#324](https://github.com/open-mmlab/mmpose/pull/324))\n\n**Bug Fixes**\n\n- Fix bugs in pck evaluation ([#328](https://github.com/open-mmlab/mmpose/pull/328))\n\n- Fix model download links in README ([#396](https://github.com/open-mmlab/mmpose/pull/396), [#397](https://github.com/open-mmlab/mmpose/pull/397))\n\n- Fix CrowdPose annotations and update benchmarks ([#384](https://github.com/open-mmlab/mmpose/pull/384))\n\n- Fix modelzoo stat ([#354](https://github.com/open-mmlab/mmpose/pull/354), [#360](https://github.com/open-mmlab/mmpose/pull/360), [#362](https://github.com/open-mmlab/mmpose/pull/362))\n\n- Fix config files for aic datasets ([#340](https://github.com/open-mmlab/mmpose/pull/340))\n\n**Breaking Changes**\n\n- Rename `image_thr` to `det_bbox_thr` for top-down methods.\n\n**Improvements**\n\n- Organize the readme files ([#398](https://github.com/open-mmlab/mmpose/pull/398), [#399](https://github.com/open-mmlab/mmpose/pull/399), [#400](https://github.com/open-mmlab/mmpose/pull/400))\n\n- Check linting for markdown ([#379](https://github.com/open-mmlab/mmpose/pull/379))\n\n- Add faq.md ([#350](https://github.com/open-mmlab/mmpose/pull/350))\n\n- Remove PyTorch 1.4 in CI ([#338](https://github.com/open-mmlab/mmpose/pull/338))\n\n- Add pypi badge in readme ([#329](https://github.com/open-mmlab/mmpose/pull/329))\n\n## **v0.9.0 (30/11/2020)**\n\n**Highlights**\n\n1. Support more human pose estimation methods.\n\n   1. [MSPN](https://arxiv.org/abs/1901.00148)\n   2. [RSN](https://arxiv.org/abs/2003.04030)\n\n2. Support video pose estimation datasets.\n\n   1. [sub-JHMDB](http://jhmdb.is.tue.mpg.de/dataset)\n\n3. Support Onnx model conversion.\n\n**New Features**\n\n- Support MSPN ([#278](https://github.com/open-mmlab/mmpose/pull/278))\n\n- Support RSN ([#221](https://github.com/open-mmlab/mmpose/pull/221), [#318](https://github.com/open-mmlab/mmpose/pull/318))\n\n- Support new post-processing method for MSPN & RSN ([#288](https://github.com/open-mmlab/mmpose/pull/288))\n\n- Support sub-JHMDB dataset ([#292](https://github.com/open-mmlab/mmpose/pull/292))\n\n- Support urls for pre-trained models in config files ([#232](https://github.com/open-mmlab/mmpose/pull/232))\n\n- Support Onnx ([#305](https://github.com/open-mmlab/mmpose/pull/305))\n\n**Bug Fixes**\n\n- Fix model download links in README ([#255](https://github.com/open-mmlab/mmpose/pull/255), [#315](https://github.com/open-mmlab/mmpose/pull/315))\n\n**Breaking Changes**\n\n- `post_process=True|False` and `unbiased_decoding=True|False` are deprecated, use `post_process=None|default|unbiased` etc. instead ([#288](https://github.com/open-mmlab/mmpose/pull/288))\n\n**Improvements**\n\n- Enrich the model zoo ([#256](https://github.com/open-mmlab/mmpose/pull/256), [#320](https://github.com/open-mmlab/mmpose/pull/320))\n\n- Set the default map_location as 'cpu' to reduce gpu memory cost ([#227](https://github.com/open-mmlab/mmpose/pull/227))\n\n- Support return heatmaps and backbone features for bottom-up models ([#229](https://github.com/open-mmlab/mmpose/pull/229))\n\n- Upgrade mmcv maximum & minimum version ([#269](https://github.com/open-mmlab/mmpose/pull/269), [#313](https://github.com/open-mmlab/mmpose/pull/313))\n\n- Automatically add modelzoo statistics to readthedocs ([#252](https://github.com/open-mmlab/mmpose/pull/252))\n\n- Fix Pylint issues ([#258](https://github.com/open-mmlab/mmpose/pull/258), [#259](https://github.com/open-mmlab/mmpose/pull/259), [#260](https://github.com/open-mmlab/mmpose/pull/260), [#262](https://github.com/open-mmlab/mmpose/pull/262), [#265](https://github.com/open-mmlab/mmpose/pull/265), [#267](https://github.com/open-mmlab/mmpose/pull/267), [#268](https://github.com/open-mmlab/mmpose/pull/268), [#270](https://github.com/open-mmlab/mmpose/pull/270), [#271](https://github.com/open-mmlab/mmpose/pull/271), [#272](https://github.com/open-mmlab/mmpose/pull/272), [#273](https://github.com/open-mmlab/mmpose/pull/273), [#275](https://github.com/open-mmlab/mmpose/pull/275), [#276](https://github.com/open-mmlab/mmpose/pull/276), [#283](https://github.com/open-mmlab/mmpose/pull/283), [#285](https://github.com/open-mmlab/mmpose/pull/285), [#293](https://github.com/open-mmlab/mmpose/pull/293), [#294](https://github.com/open-mmlab/mmpose/pull/294), [#295](https://github.com/open-mmlab/mmpose/pull/295))\n\n- Improve README ([#226](https://github.com/open-mmlab/mmpose/pull/226), [#257](https://github.com/open-mmlab/mmpose/pull/257), [#264](https://github.com/open-mmlab/mmpose/pull/264), [#280](https://github.com/open-mmlab/mmpose/pull/280), [#296](https://github.com/open-mmlab/mmpose/pull/296))\n\n- Support PyTorch 1.7 in CI ([#274](https://github.com/open-mmlab/mmpose/pull/274))\n\n- Add docs/tutorials for running demos ([#263](https://github.com/open-mmlab/mmpose/pull/263))\n\n## **v0.8.0 (31/10/2020)**\n\n**Highlights**\n\n1. Support more human pose estimation datasets.\n\n   1. [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose)\n   2. [PoseTrack18](https://posetrack.net/)\n\n2. Support more 2D hand keypoint estimation datasets.\n\n   1. [InterHand2.6](https://github.com/facebookresearch/InterHand2.6M)\n\n3. Support adversarial training for 3D human shape recovery.\n\n4. Support multi-stage losses.\n\n5. Support mpii demo.\n\n**New Features**\n\n- Support [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose) dataset ([#195](https://github.com/open-mmlab/mmpose/pull/195))\n\n- Support [PoseTrack18](https://posetrack.net/) dataset ([#220](https://github.com/open-mmlab/mmpose/pull/220))\n\n- Support [InterHand2.6](https://github.com/facebookresearch/InterHand2.6M) dataset ([#202](https://github.com/open-mmlab/mmpose/pull/202))\n\n- Support adversarial training for 3D human shape recovery ([#192](https://github.com/open-mmlab/mmpose/pull/192))\n\n- Support multi-stage losses ([#204](https://github.com/open-mmlab/mmpose/pull/204))\n\n**Bug Fixes**\n\n- Fix config files ([#190](https://github.com/open-mmlab/mmpose/pull/190))\n\n**Improvements**\n\n- Add mpii demo ([#216](https://github.com/open-mmlab/mmpose/pull/216))\n\n- Improve README ([#181](https://github.com/open-mmlab/mmpose/pull/181), [#183](https://github.com/open-mmlab/mmpose/pull/183), [#208](https://github.com/open-mmlab/mmpose/pull/208))\n\n- Support return heatmaps and backbone features ([#196](https://github.com/open-mmlab/mmpose/pull/196), [#212](https://github.com/open-mmlab/mmpose/pull/212))\n\n- Support different return formats of mmdetection models ([#217](https://github.com/open-mmlab/mmpose/pull/217))\n\n## **v0.7.0 (30/9/2020)**\n\n**Highlights**\n\n1. Support HMR for 3D human shape recovery.\n\n2. Support WholeBody human pose estimation.\n\n   1. [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody)\n\n3. Support more 2D hand keypoint estimation datasets.\n\n   1. [Frei-hand](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\n   2. [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html)\n\n4. Add more popular backbones & enrich the [modelzoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html)\n\n   1. ShuffleNetv2\n\n5. Support hand demo and whole-body demo.\n\n**New Features**\n\n- Support HMR for 3D human shape recovery ([#157](https://github.com/open-mmlab/mmpose/pull/157), [#160](https://github.com/open-mmlab/mmpose/pull/160), [#161](https://github.com/open-mmlab/mmpose/pull/161), [#162](https://github.com/open-mmlab/mmpose/pull/162))\n\n- Support [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody) dataset ([#133](https://github.com/open-mmlab/mmpose/pull/133))\n\n- Support [Frei-hand](https://lmb.informatik.uni-freiburg.de/projects/freihand/) dataset ([#125](https://github.com/open-mmlab/mmpose/pull/125))\n\n- Support [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html) dataset ([#144](https://github.com/open-mmlab/mmpose/pull/144))\n\n- Support H36M dataset ([#159](https://github.com/open-mmlab/mmpose/pull/159))\n\n- Support ShuffleNetv2 ([#139](https://github.com/open-mmlab/mmpose/pull/139))\n\n- Support saving best models based on key indicator ([#127](https://github.com/open-mmlab/mmpose/pull/127))\n\n**Bug Fixes**\n\n- Fix typos in docs ([#121](https://github.com/open-mmlab/mmpose/pull/121))\n\n- Fix assertion ([#142](https://github.com/open-mmlab/mmpose/pull/142))\n\n**Improvements**\n\n- Add tools to transform .mat format to .json format ([#126](https://github.com/open-mmlab/mmpose/pull/126))\n\n- Add hand demo ([#115](https://github.com/open-mmlab/mmpose/pull/115))\n\n- Add whole-body demo ([#163](https://github.com/open-mmlab/mmpose/pull/163))\n\n- Reuse mmcv utility function and update version files ([#135](https://github.com/open-mmlab/mmpose/pull/135), [#137](https://github.com/open-mmlab/mmpose/pull/137))\n\n- Enrich the modelzoo ([#147](https://github.com/open-mmlab/mmpose/pull/147), [#169](https://github.com/open-mmlab/mmpose/pull/169))\n\n- Improve docs ([#174](https://github.com/open-mmlab/mmpose/pull/174), [#175](https://github.com/open-mmlab/mmpose/pull/175), [#178](https://github.com/open-mmlab/mmpose/pull/178))\n\n- Improve README ([#176](https://github.com/open-mmlab/mmpose/pull/176))\n\n- Improve version.py ([#173](https://github.com/open-mmlab/mmpose/pull/173))\n\n## **v0.6.0 (31/8/2020)**\n\n**Highlights**\n\n1. Add more popular backbones & enrich the [modelzoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html)\n\n   1. ResNext\n   2. SEResNet\n   3. ResNetV1D\n   4. MobileNetv2\n   5. ShuffleNetv1\n   6. CPM (Convolutional Pose Machine)\n\n2. Add more popular datasets:\n\n   1. [AIChallenger](https://arxiv.org/abs/1711.06475?context=cs.CV)\n   2. [MPII](http://human-pose.mpi-inf.mpg.de/)\n   3. [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body)\n   4. [OCHuman](http://www.liruilong.cn/projects/pose2seg/index.html)\n\n3. Support 2d hand keypoint estimation.\n\n   1. [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\n\n4. Support bottom-up inference.\n\n**New Features**\n\n- Support [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) dataset ([#52](https://github.com/open-mmlab/mmpose/pull/52))\n\n- Support [MPII](http://human-pose.mpi-inf.mpg.de/) dataset ([#55](https://github.com/open-mmlab/mmpose/pull/55))\n\n- Support [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) dataset ([#19](https://github.com/open-mmlab/mmpose/pull/19), [#47](https://github.com/open-mmlab/mmpose/pull/47), [#48](https://github.com/open-mmlab/mmpose/pull/48))\n\n- Support [OCHuman](http://www.liruilong.cn/projects/pose2seg/index.html) dataset ([#70](https://github.com/open-mmlab/mmpose/pull/70))\n\n- Support [AIChallenger](https://arxiv.org/abs/1711.06475?context=cs.CV) dataset ([#87](https://github.com/open-mmlab/mmpose/pull/87))\n\n- Support multiple backbones ([#26](https://github.com/open-mmlab/mmpose/pull/26))\n\n- Support CPM model ([#56](https://github.com/open-mmlab/mmpose/pull/56))\n\n**Bug Fixes**\n\n- Fix configs for MPII & MPII-TRB datasets ([#93](https://github.com/open-mmlab/mmpose/pull/93))\n\n- Fix the bug of missing `test_pipeline` in configs ([#14](https://github.com/open-mmlab/mmpose/pull/14))\n\n- Fix typos ([#27](https://github.com/open-mmlab/mmpose/pull/27), [#28](https://github.com/open-mmlab/mmpose/pull/28), [#50](https://github.com/open-mmlab/mmpose/pull/50), [#53](https://github.com/open-mmlab/mmpose/pull/53), [#63](https://github.com/open-mmlab/mmpose/pull/63))\n\n**Improvements**\n\n- Update benchmark ([#93](https://github.com/open-mmlab/mmpose/pull/93))\n\n- Add Dockerfile ([#44](https://github.com/open-mmlab/mmpose/pull/44))\n\n- Improve unittest coverage and minor fix ([#18](https://github.com/open-mmlab/mmpose/pull/18))\n\n- Support CPUs for train/val/demo ([#34](https://github.com/open-mmlab/mmpose/pull/34))\n\n- Support bottom-up demo ([#69](https://github.com/open-mmlab/mmpose/pull/69))\n\n- Add tools to publish model ([#62](https://github.com/open-mmlab/mmpose/pull/62))\n\n- Enrich the modelzoo ([#64](https://github.com/open-mmlab/mmpose/pull/64), [#68](https://github.com/open-mmlab/mmpose/pull/68), [#82](https://github.com/open-mmlab/mmpose/pull/82))\n\n## **v0.5.0 (21/7/2020)**\n\n**Highlights**\n\n- MMPose is released.\n\n**Main Features**\n\n- Support both top-down and bottom-up pose estimation approaches.\n\n- Achieve higher training efficiency and higher accuracy than other popular codebases (e.g. AlphaPose, HRNet)\n\n- Support various backbone models: ResNet, HRNet, SCNet, Houglass and HigherHRNet.\n"
  },
  {
    "path": "docs/en/notes/ecosystem.md",
    "content": "# Ecosystem\n\nComing soon.\n"
  },
  {
    "path": "docs/en/notes/pytorch_2.md",
    "content": "# PyTorch 2.0 Compatibility and Benchmarks\n\nMMPose 1.0.0 is now compatible with PyTorch 2.0, ensuring that users can leverage the latest features and performance improvements offered by the PyTorch 2.0 framework when using MMPose. With the integration of inductor, users can expect faster model speeds. The table below shows several example models:\n\n| Model     |     Training Speed      |    Memory     |\n| :-------- | :---------------------: | :-----------: |\n| ViTPose-B | 29.6% ↑ (0.931 → 0.655) | 10586 → 10663 |\n| ViTPose-S | 33.7% ↑ (0.563 → 0.373) |  6091 → 6170  |\n| HRNet-w32 | 12.8% ↑ (0.553 → 0.482) | 9849 → 10145  |\n| HRNet-w48 | 37.1% ↑ (0.437 → 0.275) |  7319 → 7394  |\n| RTMPose-t | 6.3% ↑ (1.533 → 1.437)  |  6292 → 6489  |\n| RTMPose-s | 13.1% ↑ (1.645 → 1.430) |  9013 → 9208  |\n\n- Pytorch 2.0 test, add projects doc and refactor by @LareinaM in [PR#2136](https://github.com/open-mmlab/mmpose/pull/2136)\n"
  },
  {
    "path": "docs/en/overview.md",
    "content": "# Overview\n\nThis chapter will introduce you to the overall framework of MMPose and provide links to detailed tutorials.\n\n## What is MMPose\n\n![overview](https://user-images.githubusercontent.com/13503330/191004511-508d3ec6-9ead-4c52-a522-4d9aa1f26027.png)\n\nMMPose is a Pytorch-based pose estimation open-source toolkit, a member of the [OpenMMLab Project](https://github.com/open-mmlab). It contains a rich set of algorithms for 2d multi-person human pose estimation, 2d hand pose estimation, 2d face landmark detection, 133 keypoint whole-body human pose estimation, fashion landmark detection and animal pose estimation as well as related components and modules, below is its overall framework.\n\nMMPose consists of **8** main components:\n\n- **apis** provides high-level APIs for model inference\n- **structures** provides data structures like bbox, keypoint and PoseDataSample\n- **datasets** supports various datasets for pose estimation\n  - **transforms** contains a lot of useful data augmentation transforms\n- **codecs** provides pose encoders and decoders: an encoder encodes poses (mostly keypoints) into learning targets (e.g. heatmaps), and a decoder decodes model outputs into pose predictions\n- **models** provides all components of pose estimation models in a modular structure\n  - **pose_estimators** defines all pose estimation model classes\n  - **data_preprocessors** is for preprocessing the input data of the model\n  - **backbones** provides a collection of backbone networks\n  - **necks** contains various neck modules\n  - **heads** contains various prediction heads that perform pose estimation\n  - **losses** contains various loss functions\n- **engine** provides runtime components related to pose estimation\n  - **hooks** provides various hooks of the runner\n- **evaluation** provides metrics for evaluating model performance\n- **visualization** is for visualizing skeletons, heatmaps and other information\n\n## How to Use this Guide\n\nWe have prepared detailed guidelines for all types of users:\n\n1. For installation instrunctions:\n\n   - [Installation](./installation.md)\n\n2. For the basic usage of MMPose:\n\n   - [A 20-minute Tour to MMPose](./guide_to_framework.md)\n   - [Demos](./demos.md)\n   - [Inference](./user_guides/inference.md)\n   - [Configs](./user_guides/configs.md)\n   - [Prepare Datasets](./user_guides/prepare_datasets.md)\n   - [Train and Test](./user_guides/train_and_test.md)\n   - [Deployment](./user_guides/how_to_deploy.md)\n   - [Model Analysis](./user_guides/model_analysis.md)\n   - [Dataset Annotation and Preprocessing](./user_guides/dataset_tools.md)\n\n3. For developers who wish to develop based on MMPose:\n\n   - [Learn about Codecs](./advanced_guides/codecs.md)\n   - [Dataflow in MMPose](./advanced_guides/dataflow.md)\n   - [Implement New Models](./advanced_guides/implement_new_models.md)\n   - [Customize Datasets](./advanced_guides/customize_datasets.md)\n   - [Customize Data Transforms](./advanced_guides/customize_transforms.md)\n   - [Customize Optimizer](./advanced_guides/customize_optimizer.md)\n   - [Customize Logging](./advanced_guides/customize_logging.md)\n   - [Migration Guide](./migration.md)\n\n4. For researchers and developers who are willing to contribute to MMPose:\n\n   - [Contribution Guide](./contribution_guide.md)\n\n5. For some common issues, we provide a FAQ list:\n\n   - [FAQ](./faq.md)\n"
  },
  {
    "path": "docs/en/projects/projects.md",
    "content": "# Projects based on MMPose\n\nThere are many projects built upon MMPose. We list some of them as examples of how to extend MMPose for your own projects. As the page might not be completed, please feel free to create a PR to update this page.\n\n## Projects as an extension\n\nSome projects extend the boundary of MMPose for deployment or other research fields. They reveal the potential of what MMPose can do. We list several of them as below.\n\n- [Anime Face Detector](https://github.com/hysts/anime-face-detector): An anime face landmark detection toolbox.\n- [PosePipeline](https://github.com/peabody124/PosePipeline): Open-Source Human Pose Estimation Pipeline for Clinical Research\n\n## Projects of papers\n\nThere are also projects released with papers. Some of the papers are published in top-tier conferences (CVPR, ICCV, and ECCV), the others are also highly influential. We list some of these works as a reference for the community to develop and compare new pose estimation algorithms. Methods already supported and maintained by MMPose are not listed.\n\n- Pose for Everything: Towards Category-Agnostic Pose Estimation, ECCV 2022. [\\[paper\\]](https://arxiv.org/abs/2207.10387)[\\[github\\]](https://github.com/luminxu/Pose-for-Everything)\n- UniFormer: Unified Transformer for Efficient Spatiotemporal Representation Learning, ICLR 2022. [\\[paper\\]](https://arxiv.org/abs/2201.04676)[\\[github\\]](https://github.com/Sense-X/UniFormer)\n- Poseur:Direct Human Pose Regression with Transformers, ECCV 2022. [\\[paper\\]](https://arxiv.org/abs/2201.07412)[\\[github\\]](https://github.com/aim-uofa/Poseur)\n- ViTAEv2: Vision Transformer Advanced by Exploring Inductive Bias for Image Recognition and Beyond, NeurIPS 2022. [\\[paper\\]](https://arxiv.org/abs/2106.03348)[\\[github\\]](https://github.com/ViTAE-Transformer/ViTAE-Transformer)\n- Dite-HRNet:Dynamic Lightweight High-Resolution Network for Human Pose Estimation, IJCAI-ECAI 2021. [\\[paper\\]](https://arxiv.org/abs/2204.10762)[\\[github\\]](https://github.com/ZiyiZhang27/Dite-HRNet)\n"
  },
  {
    "path": "docs/en/quick_run.md",
    "content": "# Quick Run\n\nThis page provides a basic tutorial about the usage of MMPose.\n\nWe will walk you through the 7 key steps of a typical MMPose workflow by training a top-down residual log-likelihood algorithm based on resnet50 on COCO dataset:\n\n1. Inference with a pretrained model\n2. Prepare the dataset\n3. Prepare a config\n4. Browse the transformed images\n5. Training\n6. Testing\n7. Visualization\n\n## Installation\n\nFor installation instructions, please refer to [Installation](./installation.md).\n\n## Get Started\n\n### Inference with a pretrained model\n\nWe provide a useful script to perform pose estimation with a pretrained model:\n\n```Bash\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_coco_256x192_rle-2ea9bb4a_20220616.pth\n```\n\nIf MMPose is properly installed, you will get the visualized result as follows:\n\n![inference_demo](https://user-images.githubusercontent.com/13503330/187112344-0c5062f2-689c-445c-a259-d5d4311e2497.png)\n\n```{note}\nMore demo and full instructions can be found in [Inference](./user_guides/inference.md).\n```\n\n### Prepare the dataset\n\nMMPose supports multiple tasks. We provide the corresponding guidelines for data preparation.\n\n- [2D Body Keypoint Detection](./dataset_zoo/2d_body_keypoint.md)\n\n- [3D Body Keypoint Detection](./dataset_zoo/3d_body_keypoint.md)\n\n- [2D Hand Keypoint Detection](./dataset_zoo/2d_hand_keypoint.md)\n\n- [3D Hand Keypoint Detection](./dataset_zoo/3d_hand_keypoint.md)\n\n- [2D Face Keypoint Detection](./dataset_zoo/2d_face_keypoint.md)\n\n- [2D WholeBody Keypoint Detection](./dataset_zoo/2d_wholebody_keypoint.md)\n\n- [2D Fashion Landmark Detection](./dataset_zoo/2d_fashion_landmark.md)\n\n- [2D Animal Keypoint Detection](./dataset_zoo/2d_animal_keypoint.md)\n\nYou can refer to \\[2D Body Keypoint Detection\\] > \\[COCO\\] for COCO dataset preparation.\n\n```{note}\nIn MMPose, we suggest placing the data under `$MMPOSE/data`.\n```\n\n### Prepare a config\n\nMMPose is equipped with a powerful config system to conduct various experiments conveniently. A config file organizes the settings of:\n\n- **General**: basic configurations non-related to training or testing, such as Timer, Logger, Visualizer and other Hooks, as well as distributed-related environment settings\n\n- **Data**: dataset, dataloader and data augmentation\n\n- **Training**: resume, weights loading, optimizer, learning rate scheduling, epochs and valid interval etc.\n\n- **Model**: structure, module and loss function etc.\n\n- **Evaluation**: metrics\n\nWe provide a bunch of well-prepared configs under `$MMPOSE/configs` so that you can directly use or modify.\n\nGoing back to our example, we  will use the prepared config:\n\n```Bash\n$MMPOSE/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py\n```\n\nYou can set the path of the COCO dataset by modifying `data_root` in the config：\n\n```Python\ndata_root = 'data/coco'\n```\n\n```{note}\nIf you wish to learn more about our config system, please refer to [Configs](./user_guides/configs.md).\n```\n\n### Browse the transformed images\n\nBefore training, we can browse the transformed training data to check if the images are augmented properly:\n\n```Bash\npython tools/misc/browse_dastaset.py \\\n    configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py \\\n    --mode transformed\n```\n\n![transformed_training_img](https://user-images.githubusercontent.com/13503330/187112376-e604edcb-46cc-4995-807b-e8f204f991b0.png)\n\n### Training\n\nUse the following command to train with a single GPU:\n\n```Bash\npython tools/train.py configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py\n```\n\n```{note}\nMMPose automates many useful training tricks and functions including:\n\n- Learning rate warmup and scheduling\n\n- ImageNet pretrained models\n\n- Automatic learning rate scaling\n\n- Multi-GPU and Multi-Node training support\n\n- Various Data backend support, e.g. HardDisk, LMDB, Petrel, HTTP etc.\n\n- Mixed precision training support\n\n- TensorBoard\n```\n\n### Testing\n\nCheckpoints and logs will be saved under `$MMPOSE/work_dirs` by default. The best model is under `$MMPOSE/work_dir/best_coco`.\n\nUse the following command to evaluate the model on COCO dataset:\n\n```Bash\npython tools/test.py \\\n    configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py \\\n    work_dir/best_coco/AP_epoch_20.pth\n```\n\nHere is an example of evaluation results：\n\n```Bash\n Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets= 20 ] =  0.704\n Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets= 20 ] =  0.883\n Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets= 20 ] =  0.777\n Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets= 20 ] =  0.667\n Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets= 20 ] =  0.769\n Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 20 ] =  0.751\n Average Recall     (AR) @[ IoU=0.50      | area=   all | maxDets= 20 ] =  0.920\n Average Recall     (AR) @[ IoU=0.75      | area=   all | maxDets= 20 ] =  0.815\n Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets= 20 ] =  0.709\n Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets= 20 ] =  0.811\n08/23 12:04:42 - mmengine - INFO - Epoch(test) [3254/3254]  coco/AP: 0.704168  coco/AP .5: 0.883134  coco/AP .75: 0.777015  coco/AP (M): 0.667207  coco/AP (L): 0.768644  coco/AR: 0.750913  coco/AR .5: 0.919710  coco/AR .75: 0.815334  coco/AR (M): 0.709232  coco/AR (L): 0.811334\n```\n\n```{note}\nIf you want to perform evaluation on other datasets, please refer to [Train & Test](./user_guides/train_and_test.md).\n```\n\n### Visualization\n\nIn addition to the visualization of the keypoint skeleton, MMPose also supports the visualization of Heatmaps by setting `output_heatmap=True` in confg:\n\n```Python\nmodel = dict(\n    ## omitted\n    test_cfg = dict(\n        ## omitted\n        output_heatmaps=True\n    )\n)\n```\n\nor add `--cfg-options='model.test_cfg.output_heatmaps=True'` at the end of your command.\n\nVisualization result (top: decoded keypoints; bottom: predicted heatmap):\n\n![vis_pred](https://user-images.githubusercontent.com/26127467/187578902-30ef7bb0-9a93-4e03-bae0-02aeccf7f689.jpg)\n\n```{note}\nIf you wish to apply MMPose to your own projects, we have prepared a detailed [Migration guide](./migration.md).\n```\n"
  },
  {
    "path": "docs/en/stats.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport functools as func\nimport glob\nimport re\nfrom os.path import basename, splitext\n\nimport numpy as np\nimport titlecase\n\n\ndef anchor(name):\n    return re.sub(r'-+', '-', re.sub(r'[^a-zA-Z0-9]', '-',\n                                     name.strip().lower())).strip('-')\n\n\n# Count algorithms\n\nfiles = sorted(glob.glob('model_zoo/*.md'))\n\nstats = []\n\nfor f in files:\n    with open(f, 'r') as content_file:\n        content = content_file.read()\n\n    # title\n    title = content.split('\\n')[0].replace('#', '')\n\n    # count papers\n    papers = set(\n        (papertype, titlecase.titlecase(paper.lower().strip()))\n        for (papertype, paper) in re.findall(\n            r'<!--\\s*\\[([A-Z]*?)\\]\\s*-->\\s*\\n.*?\\btitle\\s*=\\s*{(.*?)}',\n            content, re.DOTALL))\n    # paper links\n    revcontent = '\\n'.join(list(reversed(content.splitlines())))\n    paperlinks = {}\n    for _, p in papers:\n        # print(p)\n        paperlinks[p] = ', '.join(\n            ((f'[{paperlink} ⇨]'\n              f'(model_zoo/{splitext(basename(f))[0]}.html#'\n              f'{anchor(paperlink)})') for paperlink in re.findall(\n                  rf'\\btitle\\s*=\\s*{{\\s*{p}\\s*}}.*?\\n### (.*?)\\s*[,;]?\\s*\\n',\n                  revcontent, re.DOTALL | re.IGNORECASE)))\n        # print('   ', paperlinks[p])\n    paperlist = '\\n'.join(\n        sorted(f'    - [{t}] {x} ({paperlinks[x]})' for t, x in papers))\n    # count configs\n    configs = set(x.lower().strip()\n                  for x in re.findall(r'.*configs/.*\\.py', content))\n\n    # count ckpts\n    ckpts = set(x.lower().strip()\n                for x in re.findall(r'https://download.*\\.pth', content)\n                if 'mmpose' in x)\n\n    statsmsg = f\"\"\"\n## [{title}]({f})\n\n* Number of checkpoints: {len(ckpts)}\n* Number of configs: {len(configs)}\n* Number of papers: {len(papers)}\n{paperlist}\n\n    \"\"\"\n\n    stats.append((papers, configs, ckpts, statsmsg))\n\nallpapers = func.reduce(lambda a, b: a.union(b), [p for p, _, _, _ in stats])\nallconfigs = func.reduce(lambda a, b: a.union(b), [c for _, c, _, _ in stats])\nallckpts = func.reduce(lambda a, b: a.union(b), [c for _, _, c, _ in stats])\n\n# Summarize\n\nmsglist = '\\n'.join(x for _, _, _, x in stats)\npapertypes, papercounts = np.unique([t for t, _ in allpapers],\n                                    return_counts=True)\ncountstr = '\\n'.join(\n    [f'   - {t}: {c}' for t, c in zip(papertypes, papercounts)])\n\nmodelzoo = f\"\"\"\n# Overview\n\n* Number of checkpoints: {len(allckpts)}\n* Number of configs: {len(allconfigs)}\n* Number of papers: {len(allpapers)}\n{countstr}\n\nFor supported datasets, see [datasets overview](dataset_zoo.md).\n\n{msglist}\n\n\"\"\"\n\nwith open('model_zoo.md', 'w') as f:\n    f.write(modelzoo)\n\n# Count datasets\n\nfiles = sorted(glob.glob('model_zoo/*.md'))\n# files = sorted(glob.glob('docs/tasks/*.md'))\n\ndatastats = []\n\nfor f in files:\n    with open(f, 'r') as content_file:\n        content = content_file.read()\n\n    # title\n    title = content.split('\\n')[0].replace('#', '')\n\n    # count papers\n    papers = set(\n        (papertype, titlecase.titlecase(paper.lower().strip()))\n        for (papertype, paper) in re.findall(\n            r'<!--\\s*\\[([A-Z]*?)\\]\\s*-->\\s*\\n.*?\\btitle\\s*=\\s*{(.*?)}',\n            content, re.DOTALL))\n    # paper links\n    revcontent = '\\n'.join(list(reversed(content.splitlines())))\n    paperlinks = {}\n    for _, p in papers:\n        # print(p)\n        paperlinks[p] = ', '.join(\n            (f'[{p} ⇨](model_zoo/{splitext(basename(f))[0]}.html#'\n             f'{anchor(p)})' for p in re.findall(\n                 rf'\\btitle\\s*=\\s*{{\\s*{p}\\s*}}.*?\\n## (.*?)\\s*[,;]?\\s*\\n',\n                 revcontent, re.DOTALL | re.IGNORECASE)))\n        # print('   ', paperlinks[p])\n    paperlist = '\\n'.join(\n        sorted(f'    - [{t}] {x} ({paperlinks[x]})' for t, x in papers))\n    # count configs\n    configs = set(x.lower().strip()\n                  for x in re.findall(r'https.*configs/.*\\.py', content))\n\n    # count ckpts\n    ckpts = set(x.lower().strip()\n                for x in re.findall(r'https://download.*\\.pth', content)\n                if 'mmpose' in x)\n\n    statsmsg = f\"\"\"\n## [{title}]({f})\n\n* Number of papers: {len(papers)}\n{paperlist}\n\n    \"\"\"\n\n    datastats.append((papers, configs, ckpts, statsmsg))\n\nalldatapapers = func.reduce(lambda a, b: a.union(b),\n                            [p for p, _, _, _ in datastats])\n\n# Summarize\n\nmsglist = '\\n'.join(x for _, _, _, x in stats)\ndatamsglist = '\\n'.join(x for _, _, _, x in datastats)\npapertypes, papercounts = np.unique([t for t, _ in alldatapapers],\n                                    return_counts=True)\ncountstr = '\\n'.join(\n    [f'   - {t}: {c}' for t, c in zip(papertypes, papercounts)])\n\ndataset_zoo = f\"\"\"\n# Overview\n\n* Number of papers: {len(alldatapapers)}\n{countstr}\n\nFor supported pose algorithms, see [modelzoo overview](model_zoo.md).\n\n{datamsglist}\n\"\"\"\n\nwith open('dataset_zoo.md', 'w') as f:\n    f.write(dataset_zoo)\n"
  },
  {
    "path": "docs/en/switch_language.md",
    "content": "## <a href='https://mmpose.readthedocs.io/en/latest/'>English</a>\n\n## <a href='https://mmpose.readthedocs.io/zh_CN/latest/'>简体中文</a>\n"
  },
  {
    "path": "docs/en/user_guides/configs.md",
    "content": "# Configs\n\nWe use python files as configs and incorporate modular and inheritance design into our config system, which is convenient to conduct various experiments.\n\n## Structure\n\nThe file structure of configs is as follows:\n\n```shell\nconfigs\n|----_base_\n     |----datasets\n     |----default_runtime.py\n|----animal_2d_keypoint\n|----body_2d_keypoint\n|----body_3d_keypoint\n|----face_2d_keypoint\n|----fashion_2d_keypoint\n|----hand_2d_keypoint\n|----hand_3d_keypoint\n|----wholebody_2d_keypoint\n```\n\n## Introduction\n\nMMPose is equipped with a powerful config system. Cooperating with Registry, a config file can organize all the configurations in the form of python dictionaries and create instances of the corresponding modules.\n\nHere is a simple example of vanilla Pytorch module definition to show how the config system works:\n\n```Python\n# Definition of Loss_A in loss_a.py\nClass Loss_A(nn.Module):\n    def __init__(self, param1, param2):\n        self.param1 = param1\n        self.param2 = param2\n    def forward(self, x):\n        return x\n\n# Init the module\nloss = Loss_A(param1=1.0, param2=True)\n```\n\nAll you need to do is just to register the module to the pre-defined Registry `MODELS`:\n\n```Python\n# Definition of Loss_A in loss_a.py\nfrom mmpose.registry import MODELS\n\n@MODELS.register_module() # register the module to MODELS\nClass Loss_A(nn.Module):\n    def __init__(self, param1, param2):\n        self.param1 = param1\n        self.param2 = param2\n    def forward(self, x):\n        return x\n```\n\nAnd import the new module in `__init__.py` in the corresponding directory:\n\n```Python\n# __init__.py of mmpose/models/losses\nfrom .loss_a.py import Loss_A\n\n__all__ = ['Loss_A']\n```\n\nThen you can define the module anywhere you want：\n\n```Python\n# config_file.py\nloss_cfg = dict(\n    type='Loss_A', # specify your registered module via `type`\n    param1=1.0,    # pass parameters to __init__() of the module\n    param2=True\n)\n\n# Init the module\nloss = MODELS.build(loss_cfg) # equals to `loss = Loss_A(param1=1.0, param2=True)`\n```\n\n```{note}\nNote that all new modules need to be registered using `Registry` and imported in `__init__.py` in the corresponding directory before we can create their instances from configs.\n```\n\nHere is a list of pre-defined registries in MMPose:\n\n- `DATASETS`: data-related modules\n- `TRANSFORMS`: data transformations\n- `MODELS`: all kinds of modules inheriting `nn.Module` (Backbone, Neck, Head, Loss, etc.)\n- `VISUALIZERS`: visualization tools\n- `VISBACKENDS`: visualizer backend\n- `METRICS`: all kinds of evaluation metrics\n- `KEYPOINT_CODECS`: keypoint encoder/decoder\n- `HOOKS`: all kinds of hooks like `CheckpointHook`\n\nAll registries are defined in `$MMPOSE/mmpose/registry.py`.\n\n## Config System\n\nIt is best practice to layer your configs in five sections:\n\n- **General**: basic configurations non-related to training or testing, such as Timer, Logger, Visualizer and other Hooks, as well as distributed-related environment settings\n\n- **Data**: dataset, dataloader and data augmentation\n\n- **Training**: resume, weights loading, optimizer, learning rate scheduling, epochs and valid interval etc.\n\n- **Model**: structure, module and loss function etc.\n\n- **Evaluation**: metrics\n\nYou can find all the provided configs under `$MMPOSE/configs`. A config can inherit contents from another config.To keep a config file simple and easy to read, we store some necessary but unremarkable configurations to `$MMPOSE/configs/_base_`.You can inspect the complete configurations by：\n\n```Bash\npython tools/analysis_tools/print_config.py /PATH/TO/CONFIG\n```\n\n### General\n\nGeneral configuration refers to the necessary configuration non-related to training or testing, mainly including:\n\n- **Default Hooks**: time statistics, training logs, checkpoints etc.\n\n- **Environment**: distributed backend, cudnn, multi-processing etc.\n\n- **Visualizer**: visualization backend and strategy\n\n- **Log**: log level, format, printing and recording interval etc.\n\nHere is the description of General configuration:\n\n```Python\n# General\ndefault_scope = 'mmpose'\ndefault_hooks = dict(\n    # time the data processing and model inference\n    timer=dict(type='IterTimerHook'),\n    # interval to print logs，50 iters by default\n    logger=dict(type='LoggerHook', interval=50),\n    # update lr according to the lr scheduler\n    param_scheduler=dict(type='ParamSchedulerHook'),\n    checkpoint=dict(\n        # interval to save ckpt\n        # e.g.\n        # save_best='coco/AP' means save the best ckpt according to coco/AP of CocoMetric\n        # save_best='PCK' means save the best ckpt according to PCK of PCKAccuracy\n        type='CheckpointHook', interval=1, save_best='coco/AP',\n\n        # rule to judge the metric\n        # 'greater' means the larger the better\n        # 'less' means the smaller the better\n        rule='greater'), # rule to judge the metric\n    sampler_seed=dict(type='DistSamplerSeedHook')) # set the distributed seed\nenv_cfg = dict(\n    cudnn_benchmark=False, # cudnn benchmark flag\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0), # num of opencv threads\n    dist_cfg=dict(backend='nccl')) # distributed training backend\nvis_backends = [dict(type='LocalVisBackend')] # visualizer backend\nvisualizer = dict( # Config of visualizer\n    type='PoseLocalVisualizer',\n    vis_backends=[dict(type='LocalVisBackend')],\n    name='visualizer')\nlog_processor = dict( # Format, interval to log\n    type='LogProcessor', window_size=50, by_epoch=True, num_digits=6)\nlog_level = 'INFO' # The level of logging\n```\n\n```{note}\nWe now support two visualizer backends: LocalVisBackend and TensorboardVisBackend, the former is for local visualization and the latter is for Tensorboard visualization. You can choose according to your needs. See [Train and Test](./train_and_test.md) for details.\n```\n\nGeneral configuration is stored alone in the `$MMPOSE/configs/_base_`, and inherited by doing:\n\n```Python\n_base_ = ['../../../_base_/default_runtime.py'] # take the config file as the starting point of the relative path\n```\n\n### Data\n\nData configuration refers to the data processing related settings, mainly including:\n\n- **File Client**: data storage backend, default is `disk`, we also support `LMDB`, `S3 Bucket` etc.\n\n- **Dataset**: image and annotation file path\n\n- **Dataloader**: loading configuration, batch size etc.\n\n- **Pipeline**: data augmentation\n\n- **Input Encoder**: encoding the annotation into specific form of target\n\nHere is the description of Data configuration:\n\n```Python\nbackend_args = dict(backend='local') # data storage backend\ndataset_type = 'CocoDataset' # name of dataset\ndata_mode = 'topdown' # type of the model\ndata_root = 'data/coco/' # root of the dataset\n # config of codec，to generate targets and decode preds into coordinates\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\ntrain_pipeline = [ # data aug in training\n    dict(type='LoadImage', backend_args=backend_args, # image loading\n    dict(type='GetBBoxCenterScale'), # calculate center and scale of bbox\n    dict(type='RandomBBoxTransform'), # config of scaling, rotation and shifing\n    dict(type='RandomFlip', direction='horizontal'), # config of random flipping\n    dict(type='RandomHalfBody'), # config of half-body aug\n    dict(type='TopdownAffine', input_size=codec['input_size']), # update inputs via transform matrix\n    dict(\n        type='GenerateTarget', # generate targets via transformed inputs\n        # typeof targets\n        encoder=codec, # get encoder from codec\n    dict(type='PackPoseInputs') # pack targets\n]\ntest_pipeline = [ # data aug in testing\n    dict(type='LoadImage', backend_args=backend_args), # image loading\n    dict(type='GetBBoxCenterScale'), # calculate center and scale of bbox\n    dict(type='TopdownAffine', input_size=codec['input_size']), # update inputs via transform matrix\n    dict(type='PackPoseInputs') # pack targets\n]\ntrain_dataloader = dict(\n    batch_size=64, # batch size of each single GPU during training\n    num_workers=2, # workers to pre-fetch data for each single GPU\n    persistent_workers=True, # workers will stay around (with their state) waiting for another call into that dataloader.\n    sampler=dict(type='DefaultSampler', shuffle=True), # data sampler, shuffle in traning\n    dataset=dict(\n        type=dataset_type , # name of dataset\n        data_root=data_root, # root of dataset\n        data_mode=data_mode, # type of the model\n        ann_file='annotations/person_keypoints_train2017.json', # path to annotation file\n        data_prefix=dict(img='train2017/'), # path to images\n        pipeline=train_pipeline\n    ))\nval_dataloader = dict(\n    batch_size=32, # batch size of each single GPU during validation\n    num_workers=2, # workers to pre-fetch data for each single GPU\n    persistent_workers=True, # workers will stay around (with their state) waiting for another call into that dataloader.\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False), # data sampler\n    dataset=dict(\n        type=dataset_type , # name of dataset\n        data_root=data_root, # root of dataset\n        data_mode=data_mode, # type of the model\n        ann_file='annotations/person_keypoints_val2017.json', # path to annotation file\n        bbox_file=\n        'data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json', # bbox file use for evaluation\n        data_prefix=dict(img='val2017/'), # path to images\n        test_mode=True,\n        pipeline=test_pipeline\n    ))\ntest_dataloader = val_dataloader # use val as test by default\n```\n\n```{note}\nCommon Usages:\n- [Resume training](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/train_and_test.html#resume-training)\n- [Automatic mixed precision (AMP) training](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/train_and_test.html#automatic-mixed-precision-amp-training)\n- [Set the random seed](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/train_and_test.html#set-the-random-seed)\n```\n\n### Training\n\nTraining configuration refers to the training related settings including:\n\n- Resume training\n\n- Model weights loading\n\n- Epochs of training and interval to validate\n\n- Learning rate adjustment strategies like warm-up, scheduling etc.\n\n- Optimizer and initial learning rate\n\n- Advanced tricks like auto learning rate scaling\n\nHere is the description of Training configuration:\n\n```Python\nresume = False # resume checkpoints from a given path, the training will be resumed from the epoch when the checkpoint's is saved\nload_from = None # load models as a pre-trained model from a given path\ntrain_cfg = dict(by_epoch=True, max_epochs=210, val_interval=10) # max epochs of training, interval to validate\nparam_scheduler = [\n    dict( # warmup strategy\n        type='LinearLR', begin=0, end=500, start_factor=0.001, by_epoch=False),\n    dict( # scheduler\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=0.0005)) # optimizer and initial lr\nauto_scale_lr = dict(base_batch_size=512) # auto scale the lr according to batch size\n```\n\n### Model\n\nModel configuration refers to model training and inference related settings including:\n\n- Model Structure\n\n- Loss Function\n\n- Output Decoding\n\n- Test-time augmentation\n\nHere is the description of Model configuration, which defines a Top-down Heatmap-based HRNetx32:\n\n```Python\n# config of codec, if already defined in data configuration section, no need to define again\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\nmodel = dict(\n    type='TopdownPoseEstimator', # Macro model structure\n    data_preprocessor=dict( # data normalization and channel transposition\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict( # config of backbone\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained', # load pretrained weights to backbone\n            checkpoint='https://download.openmmlab.com/mmpose'\n            '/pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict( # config of head\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True), # config of loss function\n        decoder=codec), # get decoder from codec\n    test_cfg=dict(\n        flip_test=True, # flag of flip test\n        flip_mode='heatmap', # heatmap flipping\n        shift_heatmap=True,  # shift the flipped heatmap several pixels to get a better performance\n    ))\n```\n\n### Evaluation\n\nEvaluation configuration refers to metrics commonly used by public datasets for keypoint detection tasks, mainly including:\n\n- AR, AP and mAP\n\n- PCK, PCKh, tPCK\n\n- AUC\n\n- EPE\n\n- NME\n\nHere is the description of Evaluation configuration, which defines a COCO metric evaluator:\n\n```Python\nval_evaluator = dict(\n    type='CocoMetric', # coco AP\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json') # path to annotation file\ntest_evaluator = val_evaluator # use val as test by default\n```\n\n## Config File Naming Convention\n\nMMPose follow the style below to name config files：\n\n```Python\n{{algorithm info}}_{{module info}}_{{training info}}_{{data info}}.py\n```\n\nThe filename is divided into four parts:\n\n- **Algorithm Information**: the name of algorithm, such as `topdown-heatmap`, `topdown-rle`\n\n- **Module Information**: list of intermediate modules in the forward order, such as `res101`, `hrnet-w48`\n\n- **Training Information**: settings of training(e.g. `batch_size`, `scheduler`), such as `8xb64-210e`\n\n- **Data Information**: the name of dataset, the reshape of input data, such as `ap10k-256x256`, `zebra-160x160`\n\nWords between different parts are connected by `'_'`, and those from the same part are connected by `'-'`.\n\nTo avoid a too long filename, some strong related modules in `{{module info}}` will be omitted, such as `gap` in `RLE` algorithm, `deconv` in `Heatmap-based` algorithm\n\nContributors are advised to follow the same style.\n\n## Common Usage\n\n### Inheritance\n\nThis is often used to inherit configurations from other config files. Let's assume two configs like:\n\n`optimizer_cfg.py`:\n\n```Python\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\n```\n\n`resnet50.py`:\n\n```Python\n_base_ = ['optimizer_cfg.py']\nmodel = dict(type='ResNet', depth=50)\n```\n\nAlthough we did not define `optimizer` in `resnet50.py`, all configurations in `optimizer.py` will be inherited by setting `_base_ = ['optimizer_cfg.py']`\n\n```Python\ncfg = Config.fromfile('resnet50.py')\ncfg.optimizer  # ConfigDict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\n```\n\n### Modification\n\nFor configurations already set in previous configs, you can directly modify arguments specific to that module.\n\n`resnet50_lr0.01.py`:\n\n```Python\n_base_ = ['optimizer_cfg.py']\nmodel = dict(type='ResNet', depth=50)\noptimizer = dict(lr=0.01) # modify specific filed\n```\n\nNow only `lr` is modified:\n\n```Python\ncfg = Config.fromfile('resnet50_lr0.01.py')\ncfg.optimizer  # ConfigDict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)\n```\n\n### Delete\n\nFor configurations already set in previous configs, if you wish to modify some specific argument and delete the remainders(in other words, discard the previous and redefine the module), you can set `_delete_=True`.\n\n`resnet50.py`:\n\n```Python\n_base_ = ['optimizer_cfg.py', 'runtime_cfg.py']\nmodel = dict(type='ResNet', depth=50)\noptimizer = dict(_delete_=True, type='SGD', lr=0.01) # discard the previous and redefine the module\n```\n\nNow only `type` and `lr` are kept:\n\n```Python\ncfg = Config.fromfile('resnet50_lr0.01.py')\ncfg.optimizer  # ConfigDict(type='SGD', lr=0.01)\n```\n\n```{note}\nIf you wish to learn more about advanced usages of the config system, please refer to [MMEngine Config](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/config.html).\n```\n"
  },
  {
    "path": "docs/en/user_guides/dataset_tools.md",
    "content": "# Dataset Annotation and Format Conversion\n\nThis guide will help you tackle your datasets to get them ready for training and testing.\n\n## Dataset Annotation\n\nFor users of [Label Studio](https://github.com/heartexlabs/label-studio/), please follow the instructions in the [Label Studio to COCO document](./label_studio.md) to annotate and export the results as a Label Studio `.json` file. And save the `Code` from the `Labeling Interface` as an `.xml` file.\n\n```{note}\nMMPose **DOSE NOT** impose any restrictions on the annotation tools used by users. As long as the final annotated results meet MMPose's data format requirements, they are acceptable. We warmly welcome community users to contribute more tutorials and conversion scripts for using various dataset annotation tools.\n```\n\n## Browse Dataset\n\nMMPose provides a useful tool to browse the dataset. You can visualize the raw annotations and the transformed annotations after data augmentation, which is helpful for debugging.\n\nPlease refer to [this document](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/prepare_datasets.html#browse-dataset) for more details.\n\n## Download Open-source Datasets via MIM\n\nBy using [OpenXLab](https://openxlab.org.cn/datasets), you can obtain free formatted datasets in various fields. Through the search function of the platform, you may address the dataset they look for quickly and easily. Using the formatted datasets from the platform, you can efficiently conduct tasks across datasets.\n\nWe recommend you check out this [how-to guide](https://mmpose.readthedocs.io/en/dev-1.x/user_guides/prepare_datasets.html#download-dataset-via-mim) to learn more details.\n\n## Format Conversion Scripts\n\nWe provide some scripts to convert the raw annotations into the format compatible with MMPose (namely, COCO style).\n\n### Animal Pose\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n\nFor [Animal-Pose](https://sites.google.com/view/animal-pose/) dataset, the images and annotations can be downloaded from [official website](https://sites.google.com/view/animal-pose/). The script `tools/dataset_converters/parse_animalpose_dataset.py` converts raw annotations into the format compatible with MMPose. The pre-processed [annotation files](https://download.openmmlab.com/mmpose/datasets/animalpose_annotations.tar) are available. If you would like to generate the annotations by yourself, please follow:\n\n1. Download the raw images and annotations and extract them under `$MMPOSE/data`. Make them look like this:\n\n   ```text\n   mmpose\n   ├── mmpose\n   ├── docs\n   ├── tests\n   ├── tools\n   ├── configs\n   `── data\n       │── animalpose\n           │\n           │-- VOC2012\n           │   │-- Annotations\n           │   │-- ImageSets\n           │   │-- JPEGImages\n           │   │-- SegmentationClass\n           │   │-- SegmentationObject\n           │\n           │-- animalpose_image_part2\n           │   │-- cat\n           │   │-- cow\n           │   │-- dog\n           │   │-- horse\n           │   │-- sheep\n           │\n           │-- PASCAL2011_animal_annotation\n           │   │-- cat\n           │   │   |-- 2007_000528_1.xml\n           │   │   |-- 2007_000549_1.xml\n           │   │   │-- ...\n           │   │-- cow\n           │   │-- dog\n           │   │-- horse\n           │   │-- sheep\n           │\n           │-- annimalpose_anno2\n           │   │-- cat\n           │   │   |-- ca1.xml\n           │   │   |-- ca2.xml\n           │   │   │-- ...\n           │   │-- cow\n           │   │-- dog\n           │   │-- horse\n           │   │-- sheep\n   ```\n\n2. Run command\n\n   ```bash\n   python tools/dataset_converters/parse_animalpose_dataset.py\n   ```\n\n   The generated annotation files are put in `$MMPOSE/data/animalpose/annotations`.\n\nThe official dataset does not provide the official train/val/test set split.\nWe choose the images from PascalVOC for train & val. In total, we have 3608 images and 5117 annotations for train+val, where\n2798 images with 4000 annotations are used for training, and 810 images with 1117 annotations are used for validation.\nThose images from other sources (1000 images with 1000 annotations) are used for testing.\n\n### COFW\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2013/html/Burgos-Artizzu_Robust_Face_Landmark_2013_ICCV_paper.html\">COFW (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{burgos2013robust,\n  title={Robust face landmark estimation under occlusion},\n  author={Burgos-Artizzu, Xavier P and Perona, Pietro and Doll{\\'a}r, Piotr},\n  booktitle={Proceedings of the IEEE international conference on computer vision},\n  pages={1513--1520},\n  year={2013}\n}\n```\n\n</details>\n\nFor COFW data, please download from [COFW Dataset (Color Images)](https://data.caltech.edu/records/20099).\nMove `COFW_train_color.mat` and `COFW_test_color.mat` to `$MMPOSE/data/cofw/` and make them look like:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n```\n\nRun `pip install h5py` first to install the dependency, then run the following script under `$MMPOSE`:\n\n```bash\npython tools/dataset_converters/parse_cofw_dataset.py\n```\n\nAnd you will get\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n        |── annotations\n        |   |── cofw_train.json\n        |   |── cofw_test.json\n        |── images\n            |── 000001.jpg\n            |── 000002.jpg\n```\n\n### DeepposeKit\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Desert Locust (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\nFor [Vinegar Fly](https://github.com/jgraving/DeepPoseKit-Data), [Desert Locust](https://github.com/jgraving/DeepPoseKit-Data), and [Grévy’s Zebra](https://github.com/jgraving/DeepPoseKit-Data) dataset, the annotations files can be downloaded from [DeepPoseKit-Data](https://github.com/jgraving/DeepPoseKit-Data). The script `tools/dataset_converters/parse_deepposekit_dataset.py` converts raw annotations into the format compatible with MMPose. The pre-processed annotation files are available at [vinegar_fly_annotations](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_annotations.tar), [locust_annotations](https://download.openmmlab.com/mmpose/datasets/locust_annotations.tar), and [zebra_annotations](https://download.openmmlab.com/mmpose/datasets/zebra_annotations.tar). If you would like to generate the annotations by yourself, please follows:\n\n1. Download the raw images and annotations and extract them under `$MMPOSE/data`. Make them look like this:\n\n   ```text\n   mmpose\n   ├── mmpose\n   ├── docs\n   ├── tests\n   ├── tools\n   ├── configs\n   `── data\n       |\n       |── DeepPoseKit-Data\n       |   `── datasets\n       |       |── fly\n       |       |   |── annotation_data_release.h5\n       |       |   |── skeleton.csv\n       |       |   |── ...\n       |       |\n       |       |── locust\n       |       |   |── annotation_data_release.h5\n       |       |   |── skeleton.csv\n       |       |   |── ...\n       |       |\n       |       `── zebra\n       |           |── annotation_data_release.h5\n       |           |── skeleton.csv\n       |           |── ...\n       |\n       │── fly\n           `-- images\n               │-- 0.jpg\n               │-- 1.jpg\n               │-- ...\n   ```\n\n   Note that the images can be downloaded from [vinegar_fly_images](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_images.tar), [locust_images](https://download.openmmlab.com/mmpose/datasets/locust_images.tar), and [zebra_images](https://download.openmmlab.com/mmpose/datasets/zebra_images.tar).\n\n2. Run command\n\n   ```bash\n   python tools/dataset_converters/parse_deepposekit_dataset.py\n   ```\n\n   The generated annotation files are put in `$MMPOSE/data/fly/annotations`, `$MMPOSE/data/locust/annotations`, and `$MMPOSE/data/zebra/annotations`.\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation.\n\n### Macaque\n\n<details>\n<summary align=\"right\"><a href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/pmc7874091/\">MacaquePose (bioRxiv'2020)</a></summary>\n\n```bibtex\n@article{labuguen2020macaquepose,\n  title={MacaquePose: A novel ‘in the wild’macaque monkey pose dataset for markerless motion capture},\n  author={Labuguen, Rollyn and Matsumoto, Jumpei and Negrete, Salvador and Nishimaru, Hiroshi and Nishijo, Hisao and Takada, Masahiko and Go, Yasuhiro and Inoue, Ken-ichi and Shibata, Tomohiro},\n  journal={bioRxiv},\n  year={2020},\n  publisher={Cold Spring Harbor Laboratory}\n}\n```\n\n</details>\n\nFor [MacaquePose](http://www2.ehub.kyoto-u.ac.jp/datasets/macaquepose/index.html) dataset, images and annotations can be downloaded from [download](http://www2.ehub.kyoto-u.ac.jp/datasets/macaquepose/index.html). The script `tools/dataset_converters/parse_macaquepose_dataset.py` converts raw annotations into the format compatible with MMPose. The pre-processed [macaque_annotations](https://download.openmmlab.com/mmpose/datasets/macaque_annotations.tar) are available. If you would like to generate the annotations by yourself, please follows:\n\n1. Download the raw images and annotations and extract them under `$MMPOSE/data`. Make them look like this:\n\n   ```text\n   mmpose\n   ├── mmpose\n   ├── docs\n   ├── tests\n   ├── tools\n   ├── configs\n   `── data\n       │── macaque\n           │-- annotations.csv\n           │-- images\n           │   │-- 01418849d54b3005.jpg\n           │   │-- 0142d1d1a6904a70.jpg\n           │   │-- 01ef2c4c260321b7.jpg\n           │   │-- 020a1c75c8c85238.jpg\n           │   │-- 020b1506eef2557d.jpg\n           │   │-- ...\n   ```\n\n2. Run command\n\n   ```bash\n   python tools/dataset_converters/parse_macaquepose_dataset.py\n   ```\n\n   The generated annotation files are put in `$MMPOSE/data/macaque/annotations`.\n\nSince the official dataset does not provide the test set, we randomly select 12500 images for training, and the rest for evaluation.\n\n### Human3.6M\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\nFor [Human3.6M](http://vision.imar.ro/human3.6m/description.php), please download from the official website and place the files under `$MMPOSE/data/h36m`.\nThen run the [preprocessing script](/tools/dataset_converters/preprocess_h36m.py):\n\n```bash\npython tools/dataset_converters/preprocess_h36m.py --metadata {path to metadata.xml} --original data/h36m\n```\n\nThis will extract camera parameters and pose annotations at full framerate (50 FPS) and downsampled framerate (10 FPS). The processed data should have the following structure:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── h36m\n        ├── annotation_body3d\n        |   ├── cameras.pkl\n        |   ├── fps50\n        |   |   ├── h36m_test.npz\n        |   |   ├── h36m_train.npz\n        |   |   ├── joint2d_rel_stats.pkl\n        |   |   ├── joint2d_stats.pkl\n        |   |   ├── joint3d_rel_stats.pkl\n        |   |   `── joint3d_stats.pkl\n        |   `── fps10\n        |       ├── h36m_test.npz\n        |       ├── h36m_train.npz\n        |       ├── joint2d_rel_stats.pkl\n        |       ├── joint2d_stats.pkl\n        |       ├── joint3d_rel_stats.pkl\n        |       `── joint3d_stats.pkl\n        `── images\n            ├── S1\n            |   ├── S1_Directions_1.54138969\n            |   |   ├── S1_Directions_1.54138969_00001.jpg\n            |   |   ├── S1_Directions_1.54138969_00002.jpg\n            |   |   ├── ...\n            |   ├── ...\n            ├── S5\n            ├── S6\n            ├── S7\n            ├── S8\n            ├── S9\n            `── S11\n```\n\nAfter that, the annotations need to be transformed into COCO format which is compatible with MMPose. Please run:\n\n```bash\npython tools/dataset_converters/h36m_to_coco.py\n```\n\n### MPII\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\nDuring training and inference for [MPII](http://human-pose.mpi-inf.mpg.de/), the prediction result will be saved as '.mat' format by default. We also provide a tool to convert this `.mat` to more readable `.json` format.\n\n```shell\npython tools/dataset_converters/mat2json ${PRED_MAT_FILE} ${GT_JSON_FILE} ${OUTPUT_PRED_JSON_FILE}\n```\n\nFor example,\n\n```shell\npython tools/dataset/mat2json work_dirs/res50_mpii_256x256/pred.mat data/mpii/annotations/mpii_val.json pred.json\n```\n\n## Label Studio\n\n<details>\n<summary align=\"right\"><a href=\"https://github.com/heartexlabs/label-studio/\">Label Studio</a></summary>\n\n```bibtex\n@misc{Label Studio,\n  title={{Label Studio}: Data labeling software},\n  url={https://github.com/heartexlabs/label-studio},\n  note={Open source software available from https://github.com/heartexlabs/label-studio},\n  author={\n    Maxim Tkachenko and\n    Mikhail Malyuk and\n    Andrey Holmanyuk and\n    Nikolai Liubimov},\n  year={2020-2022},\n}\n```\n\n</details>\n\nFor users of [Label Studio](https://github.com/heartexlabs/label-studio/), please follow the instructions in the [Label Studio to COCO document](./label_studio.md) to annotate and export the results as a Label Studio `.json` file. And save the `Code` from the `Labeling Interface` as an `.xml` file.\n\nWe provide a script to convert Label Studio `.json` annotation file to COCO `.json` format file. It can be used by running the following command:\n\n```shell\npython tools/dataset_converters/labelstudio2coco.py ${LS_JSON_FILE} ${LS_XML_FILE} ${OUTPUT_COCO_JSON_FILE}\n```\n\nFor example,\n\n```shell\npython tools/dataset_converters/labelstudio2coco.py config.xml project-1-at-2023-05-13-09-22-91b53efa.json output/result.json\n```\n\n### UBody2D\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2303.16160\">UBody (CVPR'2023)</a></summary>\n\n```bibtex\n@article{lin2023one,\n  title={One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer},\n  author={Lin, Jing and Zeng, Ailing and Wang, Haoqian and Zhang, Lei and Li, Yu},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  year={2023},\n}\n```\n\n</details>\n\nFor [Ubody](https://github.com/IDEA-Research/OSX) dataset, videos and annotations can be downloaded from [OSX homepage](https://github.com/IDEA-Research/OSX).\n\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── UBody\n        ├── annotations\n        │   ├── ConductMusic\n        │   ├── Entertainment\n        │   ├── Fitness\n        │   ├── Interview\n        │   ├── LiveVlog\n        │   ├── Magic_show\n        │   ├── Movie\n        │   ├── Olympic\n        │   ├── Online_class\n        │   ├── SignLanguage\n        │   ├── Singing\n        │   ├── Speech\n        │   ├── TVShow\n        │   ├── TalkShow\n        │   └── VideoConference\n        ├── splits\n        │   ├── inter_scene_test_list.npy\n        │   └── intra_scene_test_list.npy\n        ├── videos\n        │   ├── ConductMusic\n        │   ├── Entertainment\n        │   ├── Fitness\n        │   ├── Interview\n        │   ├── LiveVlog\n        │   ├── Magic_show\n        │   ├── Movie\n        │   ├── Olympic\n        │   ├── Online_class\n        │   ├── SignLanguage\n        │   ├── Singing\n        │   ├── Speech\n        │   ├── TVShow\n        │   ├── TalkShow\n        │   └── VideoConference\n```\n\nWe provide a script to convert vidoes to images and split annotations to train/val sets. It can be used by running the following command:\n\n```shell\npython tools/dataset_converters/ubody_kpts_to_coco.py --data-root ${UBODY_DATA_ROOT}\n```\n\nFor example,\n\n```shell\npython tools/dataset_converters/ubody_kpts_to_coco.py --data-root data/UBody\n```\n"
  },
  {
    "path": "docs/en/user_guides/how_to_deploy.md",
    "content": "# Publish Model and Deployment\n\nThis chapter will introduce how to export and deploy models trained with MMPose. It includes the following sections:\n\n- [Model Simplification](#model-simplification)\n- [Deployment with MMDeploy](#deployment-with-mmdeploy)\n  - [Introduction to MMDeploy](#introduction-to-mmdeploy)\n  - [Supported Models](#supported-models)\n  - [Installation](#installation)\n  - [Model Conversion](#model-conversion)\n    - [How to Find the Deployment Configuration File for an MMPose Model](#how-to-find-the-deployment-configuration-file-for-an-mmpose-model)\n    - [RTMPose Model Export Example](#rtmpose-model-export-example)\n    - [ONNX](#onnx)\n    - [TensorRT](#tensorrt)\n    - [Advanced Settings](#advanced-settings)\n  - [Model Profiling](#model-profiling)\n  - [Accuracy Validation](#accuracy-validation)\n\n## Publish Model\n\nBy default, the checkpoint file saved during MMPose training contains all the information about the model, including the model structure, weights, optimizer states, etc. This information is redundant for model deployment. Therefore, we need to simplify the model. The simplified `.pth` file can even be less than half the size of the original.\n\nMMPose provides the [tools/misc/publish_model.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tools/misc/publish_model.py) script for model simplification, which can be used as follows:\n\n```shell\npython tools/misc/publish_model.py ${IN_FILE} ${OUT_FILE}\n```\n\nFor example:\n\n```shell\npython tools/misc/publish_model.py ./epoch_10.pth ./epoch_10_publish.pth\n```\n\nThe script will automatically simplify the model, save the simplified model to the specified path, and add a timestamp to the filename, for example, `./epoch_10_publish-21815b2c_20230726.pth`.\n\n## Deployment with MMDeploy\n\n### Introduction to MMDeploy\n\nMMDeploy is the OpenMMLab model deployment toolbox, providing a unified deployment experience for various algorithm libraries. With MMDeploy, developers can easily generate SDKs tailored to specific hardware from MMPose, saving a lot of adaptation time.\n\n- You can directly download SDK versions of models (ONNX, TensorRT, ncnn, etc.) from the [ OpenMMLab Deploee](https://platform.openmmlab.com/deploee).\n- We also support [Online Model Conversion](https://platform.openmmlab.com/deploee/task-convert-list), so you don't need to install MMDeploy locally.\n\nFor more information and usage guidelines, see the [MMDeploy documentation](https://mmdeploy.readthedocs.io/en/latest/get_started.html).\n\n### Supported Models\n\n| Model                                                                                                     | Task          | ONNX Runtime | TensorRT | ncnn | PPLNN | OpenVINO | CoreML | TorchScript |\n| :-------------------------------------------------------------------------------------------------------- | :------------ | :----------: | :------: | :--: | :---: | :------: | :----: | :---------: |\n| [HRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#hrnet-cvpr-2019)          | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [MSPN](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#mspn-arxiv-2019)           | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [LiteHRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#litehrnet-cvpr-2021)  | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [Hourglass](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#hourglass-eccv-2016) | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [SimCC](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#simcc-eccv-2022)         | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [RTMPose](https://github.com/open-mmlab/mmpose/tree/main/projects/rtmpose)                                | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [YoloX-Pose](https://github.com/open-mmlab/mmpose/tree/main/projects/yolox_pose)                          | PoseDetection |      Y       |    Y     |  N   |   N   |    Y     |   Y    |      Y      |\n\n### Installation\n\nBefore starting the deployment, you need to make sure that MMPose, MMDetection, and MMDeploy are correctly installed. Please follow the installation instructions below:\n\n- [Installation of MMPose and MMDetection](../installation.md)\n- [Installation of MMDeploy](https://mmdeploy.readthedocs.io/en/latest/04-supported-codebases/mmpose.html)\n\nDepending on the backend you choose for deployment, some backends require **compilation of custom operators** supported by MMDeploy. Please refer to the corresponding documentation to ensure that the environment is set up correctly:\n\n- [ONNX](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/onnxruntime.html)\n- [TensorRT](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/tensorrt.html)\n- [OpenVINO](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/openvino.html)\n- [ncnn](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/ncnn.html)\n- [TorchScript](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/torchscript.html)\n- [More](https://github.com/open-mmlab/mmdeploy/tree/main/docs/en/05-supported-backends)\n\n### Model Conversion\n\nAfter completing the installation, you can start model deployment. You can use the provided [tools/deploy.py](https://github.com/open-mmlab/mmdeploy/blob/main/tools/deploy.py) script in MMDeploy to easily convert MMPose models to different deployment backends.\n\nHere's how you can use it:\n\n```shell\npython ./tools/deploy.py \\\n    ${DEPLOY_CFG_PATH} \\\n    ${MODEL_CFG_PATH} \\\n    ${MODEL_CHECKPOINT_PATH} \\\n    ${INPUT_IMG} \\\n    --test-img ${TEST_IMG} \\\n    --work-dir ${WORK_DIR} \\\n    --calib-dataset-cfg ${CALIB_DATA_CFG} \\\n    --device ${DEVICE} \\\n    --log-level INFO \\\n    --show \\\n    --dump-info\n```\n\nParameter descriptions:\n\n- `deploy_cfg`: Deployment configuration specific to mmdeploy, including inference framework type, quantization, and whether the input shape is dynamic or static. The configuration files may have reference relationships, and `configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py` is an example.\n\n- `model_cfg`: Model configuration specific to the mm algorithm library, e.g., `mmpose/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-256x192.py`, independent of mmdeploy path.\n\n- `checkpoint`: Path to the torch model. It can be a local file path or a download link (e.g., `http/https`).\n\n- `img`: Path to the test image or point cloud file used for model conversion.\n\n- `--test-img`: Path to the image file used to test the model. Default is set to `None`.\n\n- `--work-dir`: Working directory to save logs and model files.\n\n- `--calib-dataset-cfg`: This parameter only takes effect in `int8` mode and is used for the calibration dataset configuration file. If not provided in `int8` mode, the script will automatically use the 'val' dataset from the model configuration file for calibration.\n\n- `--device`: Device used for model conversion. Default is `cpu`, but for trt, you can use `cuda:0`, for example.\n\n- `--log-level`: Set the log level, with options including 'CRITICAL', 'FATAL', 'ERROR', 'WARN', 'WARNING', 'INFO', 'DEBUG', and 'NOTSET'. Default is `INFO`.\n\n- `--show`: Whether to display the detection results.\n\n- `--dump-info`: Whether to output SDK information.\n\n#### How to Find the Deployment Configuration File for an MMPose Model\n\n1. All deployment configuration files related to MMPose are stored in the [configs/mmpose/](https://github.com/open-mmlab/mmdeploy/tree/main/configs/mmpose) directory.\n2. The naming convention for deployment configuration files is `{Task}_{Algorithm}_{Backend}_{Dynamic/Static}_{Input Size}`.\n\n#### RTMPose Model Export Example\n\nIn this section, we demonstrate how to export the RTMPose model in ONNX and TensorRT formats. For more information, refer to the [MMDeploy documentation](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/convert_model.html).\n\n- ONNX Configuration\n\n  - [pose-detection_simcc_onnxruntime_dynamic.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py)\n\n- TensorRT Configuration\n\n  - [pose-detection_simcc_tensorrt_dynamic-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py)\n\n- More\n\n  |  Backend  | Config                                                                                                                                                               |\n  | :-------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n  | ncnn-fp16 | [pose-detection_simcc_ncnn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_ncnn-fp16_static-256x192.py) |\n  |  CoreML   | [pose-detection_simcc_coreml_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_coreml_static-256x192.py)       |\n  | OpenVINO  | [pose-detection_simcc_openvino_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_openvino_static-256x192.py)   |\n  |   RKNN    | [pose-detection_simcc_rknn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_rknn-fp16_static-256x192.py) |\n\nIf you need to modify the deployment configuration, please refer to the [MMDeploy config tutorial](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/write_config.html).\n\nThe file structure used in this tutorial is as follows:\n\n```shell\n|----mmdeploy\n|----mmpose\n```\n\n##### ONNX\n\nRun the following command:\n\n```shell\n# Go to the mmdeploy directory\ncd ${PATH_TO_MMDEPLOY}\n\n# Convert RTMPose\n# The input model path can be a local path or a download link.\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmpose-m \\\n    --device cpu \\\n    --show \\\n    --dump-info   # Export SDK info\n```\n\nThe default exported model file is `{work-dir}/end2end.onnx`\n\n##### TensorRT\n\nRun the following command:\n\n```shell\n# Go to the mmdeploy directory\ncd ${PATH_TO_MMDEPLOY}\n\n# Convert RTMPose\n# The input model path can be a local path or a download link.\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-trt/rtmpose-m \\\n    --device cuda:0 \\\n    --show \\\n    --dump-info   # Export SDK info\n```\n\nThe default exported model file is `{work-dir}/end2end.engine`\n\nIf the model is successfully exported, you will see the detection results on the sample image:\n\n![convert_models](https://user-images.githubusercontent.com/13503330/217726963-7815dd01-561a-4605-b0c6-07b6fe1956c3.png)\n\n###### Advanced Settings\n\nIf you want to use TensorRT-FP16, you can enable it by modifying the following MMDeploy configuration:\n\n```Python\n# in MMDeploy config\nbackend_config = dict(\n    type='tensorrt',\n    common_config=dict(\n        fp16_mode=True  # Enable FP16\n    ))\n```\n\n### Model Profiling\n\nIf you want to test the inference speed of the model in the deployment framework, MMDeploy provides a convenient script called `tools/profiler.py`.\n\nYou need to prepare a folder containing test images named `./test_images`, and the profiler will randomly extract images from this directory for model profiling.\n\n```shell\n# Go to the mmdeploy directory\ncd ${PATH_TO_MMDEPLOY}\n\npython tools/profiler.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    ../test_images \\\n    --model {WORK_DIR}/end2end.onnx \\\n    --shape 256x192 \\\n    --device cpu \\\n    --warmup 50 \\\n    --num-iter 200\n```\n\nThe profiling results will be displayed as follows:\n\n```shell\n01/30 15:06:35 - mmengine - INFO - [onnxruntime]-70 times per count: 8.73 ms, 114.50 FPS\n01/30 15:06:36 - mmengine - INFO - [onnxruntime]-90 times per count: 9.05 ms, 110.48 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-110 times per count: 9.87 ms, 101.32 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-130 times per count: 9.99 ms, 100.10 FPS\n01/30 15:06:38 - mmengine - INFO - [onnxruntime]-150 times per count: 10.39 ms, 96.29 FPS\n01/30 15:06:39 - mmengine - INFO - [onnxruntime]-170 times per count: 10.77 ms, 92.86 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-190 times per count: 10.98 ms, 91.05 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-210 times per count: 11.19 ms, 89.33 FPS\n01/30 15:06:41 - mmengine - INFO - [onnxruntime]-230 times per count: 11.16 ms, 89.58 FPS\n01/30 15:06:42 - mmengine - INFO - [onnxruntime]-250 times per count: 11.06 ms, 90.41 FPS\n----- Settings:\n+------------+---------+\n| batch size |    1    |\n|   shape    | 256x192 |\n| iterations |   200   |\n|   warmup   |    50   |\n+------------+---------+\n----- Results:\n+--------+------------+---------+\n| Stats  | Latency/ms |   FPS   |\n+--------+------------+---------+\n|  Mean  |   11.060   |  90.412 |\n| Median |   11.852   |  84.375 |\n|  Min   |   7.812    | 128.007 |\n|  Max   |   13.690   |  73.044 |\n+--------+------------+---------+\n```\n\n```{note}\nIf you want to learn more about profiler and its more parameter settings and functionality, you can refer to the [Profiler documentation](https://mmdeploy.readthedocs.io/en/main/02-how-to-run/useful_tools.html#profiler).\n```\n\n### Model Accuracy Testing\n\nIf you want to test the inference accuracy of the model in the deployment framework, MMDeploy provides a convenient script called `tools/test.py`.\n\n```shell\n# Go to the mmdeploy directory\ncd ${PATH_TO_MMDEPLOY}\n\npython tools/test.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ./mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    --model {PATH_TO_MODEL}/rtmpose_m.pth \\\n    --device cpu\n```\n\n```{note}\nFor more detailed content, please refer to the [MMDeploy documentation](https://github.com/open-mmlab/mmdeploy/blob/main/docs/en/02-how-to-run/profile_model.md).\n```\n\nWith this, you have covered the steps for model simplification and deployment using MMDeploy for MMPose models. It includes converting models to different formats (ONNX, TensorRT, etc.), testing inference speed, and accuracy in the deployment framework.\n"
  },
  {
    "path": "docs/en/user_guides/inference.md",
    "content": "# Inference with existing models\n\nMMPose provides a wide variety of pre-trained models for pose estimation, which can be found in the [Model Zoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html).\nThis guide will demonstrate **how to perform inference**, or running pose estimation on provided images or videos using trained models.\n\nFor instructions on testing existing models on standard datasets, refer to this [guide](./train_and_test.md#test).\n\nIn MMPose, we provide two ways to perform inference:\n\n1. Inferencer: a Unified Inference Interface\n2. Python API: more flexible and customizable\n\n## Inferencer: a Unified Inference Interface\n\nMMPose offers a comprehensive API for inference, known as [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24). This API enables users to perform inference on both images and videos using all the models supported by MMPose. Furthermore, the API provides automatic visualization of inference results and allows for the convenient saving of predictions.\n\n### Basic Usage\n\nThe [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) can be used in any Python program to perform pose estimation. Below is an example of inference on a given image using the pre-trained human pose estimator within the Python shell.\n\n```python\nfrom mmpose.apis import MMPoseInferencer\n\nimg_path = 'tests/data/coco/000000000785.jpg'   # replace this with your own image path\n\n# instantiate the inferencer using the model alias\ninferencer = MMPoseInferencer('human')\n\n# The MMPoseInferencer API employs a lazy inference approach,\n# creating a prediction generator when given input\nresult_generator = inferencer(img_path, show=True)\nresult = next(result_generator)\n```\n\nIf everything works fine, you will see the following image in a new window:\n![inferencer_result_coco](https://user-images.githubusercontent.com/26127467/220008302-4a57fd44-0978-408e-8351-600e5513316a.jpg)\n\nThe `result` variable is a dictionary comprising two keys, `'visualization'` and `'predictions'`.\n\n- `'visualization'` holds a list which:\n\n  - contains visualization results, such as the input image, markers of the estimated poses, and optional predicted heatmaps.\n  - remains empty if the `return_vis` argument is not specified.\n\n- `'predictions'` stores:\n\n  - a list of estimated keypoints for each identified instance.\n\nThe structure of the `result` dictionary is as follows:\n\n```python\nresult = {\n    'visualization': [\n        # number of elements: batch_size (defaults to 1)\n        vis_image_1,\n        ...\n    ],\n    'predictions': [\n        # pose estimation result of each image\n        # number of elements: batch_size (defaults to 1)\n        [\n            # pose information of each detected instance\n            # number of elements: number of detected instances\n            {'keypoints': ...,  # instance 1\n            'keypoint_scores': ...,\n            ...\n            },\n            {'keypoints': ...,  # instance 2\n            'keypoint_scores': ...,\n            ...\n            },\n        ]\n    ...\n    ]\n}\n\n```\n\nA **command-line interface (CLI)** tool for the inferencer is also available: `demo/inferencer_demo.py`. This tool allows users to perform inference using the same model and inputs with the following command:\n\n```bash\npython demo/inferencer_demo.py 'tests/data/coco/000000000785.jpg' \\\n    --pose2d 'human' --show --pred-out-dir 'predictions'\n```\n\nThe predictions will be save in `predictions/000000000785.json`. The argument names correspond with the [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24), which serves as an API.\n\nThe inferencer is capable of processing a range of input types, which includes the following:\n\n- A path to an image\n- A path to a video\n- A path to a folder (which will cause all images in that folder to be inferred)\n- An image array (NA for CLI tool)\n- A list of image arrays (NA for CLI tool)\n- A webcam (in which case the `input` parameter should be set to either `'webcam'` or `'webcam:{CAMERA_ID}'`)\n\nPlease note that when the input corresponds to multiple images, such as when the input is a video or a folder path, the inference process needs to iterate over the results generator in order to perform inference on all the frames or images within the folder. Here's an example in Python:\n\n```python\nfolder_path = 'tests/data/coco'\n\nresult_generator = inferencer(folder_path, show=True)\nresults = [result for result in result_generator]\n```\n\nIn this example, the `inferencer` takes the `folder_path` as input and returns a generator object (`result_generator`) that produces inference results. By iterating over the `result_generator` and storing each result in the `results` list, you can obtain the inference results for all the frames or images within the folder.\n\n### Custom Pose Estimation Models\n\nThe inferencer provides several methods that can be used to customize the models employed:\n\n```python\n\n# build the inferencer with model alias\ninferencer = MMPoseInferencer('human')\n\n# build the inferencer with model config name\ninferencer = MMPoseInferencer('td-hm_hrnet-w32_8xb64-210e_coco-256x192')\n\n# build the inferencer with model config path and checkpoint path/URL\ninferencer = MMPoseInferencer(\n    pose2d='configs/body_2d_keypoint/topdown_heatmap/coco/' \\\n           'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py',\n    pose2d_weights='https://download.openmmlab.com/mmpose/top_down/' \\\n                   'hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth'\n)\n```\n\nThe complete list of model alias can be found in the [Model Alias](#model-alias) section.\n\n**Custom Inferencer for 3D Pose Estimation Models**\n\nThe code shown above provides examples for creating 2D pose estimator inferencers. You can similarly construct a 3D model inferencer by using the `pose3d` argument:\n\n```python\n# build the inferencer with 3d model alias\ninferencer = MMPoseInferencer(pose3d=\"human3d\")\n\n# build the inferencer with 3d model config name\ninferencer = MMPoseInferencer(pose3d=\"motionbert_dstformer-ft-243frm_8xb32-120e_h36m\")\n\n# build the inferencer with 3d model config path and checkpoint path/URL\ninferencer = MMPoseInferencer(\n    pose3d='configs/body_3d_keypoint/motionbert/h36m/' \\\n           'motionbert_dstformer-ft-243frm_8xb32-120e_h36m.py',\n    pose3d_weights='https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/' \\\n                   'pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth'\n)\n```\n\n**Custom Object Detector for Top-down Pose Estimation Models**\n\nIn addition, top-down pose estimators also require an object detection model. The inferencer is capable of inferring the instance type for models trained with datasets supported in MMPose, and subsequently constructing the necessary object detection model. Alternatively, users may also manually specify the detection model using the following methods:\n\n```python\n\n# specify detection model by alias\n# the available aliases include 'human', 'hand', 'face', 'animal',\n# as well as any additional aliases defined in mmdet\ninferencer = MMPoseInferencer(\n    # suppose the pose estimator is trained on custom dataset\n    pose2d='custom_human_pose_estimator.py',\n    pose2d_weights='custom_human_pose_estimator.pth',\n    det_model='human'\n)\n\n# specify detection model with model config name\ninferencer = MMPoseInferencer(\n    pose2d='human',\n    det_model='yolox_l_8x8_300e_coco',\n    det_cat_ids=[0],  # the category id of 'human' class\n)\n\n# specify detection model with config path and checkpoint path/URL\ninferencer = MMPoseInferencer(\n    pose2d='human',\n    det_model=f'{PATH_TO_MMDET}/configs/yolox/yolox_l_8x8_300e_coco.py',\n    det_weights='https://download.openmmlab.com/mmdetection/v2.0/' \\\n                'yolox/yolox_l_8x8_300e_coco/' \\\n                'yolox_l_8x8_300e_coco_20211126_140236-d3bd2b23.pth',\n    det_cat_ids=[0],  # the category id of 'human' class\n)\n```\n\nTo perform top-down pose estimation on cropped images containing a single object, users can set `det_model='whole_image'`. This bypasses the object detector initialization, creating a bounding box that matches the input image size and directly sending the entire image to the top-down pose estimator.\n\n### Dump Results\n\nAfter performing pose estimation, you might want to save the results for further analysis or processing. This section will guide you through saving the predicted keypoints and visualizations to your local machine.\n\nTo save the predictions in a JSON file, use the `pred_out_dir` argument when running the inferencer:\n\n```python\nresult_generator = inferencer(img_path, pred_out_dir='predictions')\nresult = next(result_generator)\n```\n\nThe predictions will be saved in the `predictions/` folder in JSON format, with each file named after the corresponding input image or video.\n\nFor more advanced scenarios, you can also access the predictions directly from the `result` dictionary returned by the inferencer. The key `'predictions'` contains a list of predicted keypoints for each individual instance in the input image or video. You can then manipulate or store these results using your preferred method.\n\nKeep in mind that if you want to save both the visualization images and the prediction files in a single folder, you can use the `out_dir` argument:\n\n```python\nresult_generator = inferencer(img_path, out_dir='output')\nresult = next(result_generator)\n```\n\nIn this case, the visualization images will be saved in the `output/visualization/` folder, while the predictions will be stored in the `output/predictions/` folder.\n\n### Visualization\n\nThe inferencer can automatically draw predictions on input images or videos. Visualization results can be displayed in a new window and saved locally.\n\nTo view the visualization results in a new window, use the following code:\n\n```python\nresult_generator = inferencer(img_path, show=True)\nresult = next(result_generator)\n```\n\nNotice that:\n\n- If the input video comes from a webcam, displaying the visualization results in a new window will be enabled by default, allowing users to see the inputs.\n- If there is no GUI on the platform, this step may become stuck.\n\nTo save the visualization results locally, specify the `vis_out_dir` argument like this:\n\n```python\nresult_generator = inferencer(img_path, vis_out_dir='vis_results')\nresult = next(result_generator)\n```\n\nThe input images or videos with predicted poses will be saved in the `vis_results/` folder.\n\nAs seen in the above image, the visualization of estimated poses consists of keypoints (depicted by solid circles) and skeletons (represented by lines). The default size of these visual elements might not produce satisfactory results. Users can adjust the circle size and line thickness using the `radius` and `thickness` arguments, as shown below:\n\n```python\nresult_generator = inferencer(img_path, show=True, radius=4, thickness=2)\nresult = next(result_generator)\n```\n\n### Arguments of Inferencer\n\nThe [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) offers a variety of arguments for customizing pose estimation, visualization, and saving predictions. Below is a list of the arguments available when initializing the inferencer and their descriptions:\n\n| Argument         | Description                                                                                                      |\n| ---------------- | ---------------------------------------------------------------------------------------------------------------- |\n| `pose2d`         | Specifies the model alias, configuration file name, or configuration file path for the 2D pose estimation model. |\n| `pose2d_weights` | Specifies the URL or local path to the 2D pose estimation model's checkpoint file.                               |\n| `pose3d`         | Specifies the model alias, configuration file name, or configuration file path for the 3D pose estimation model. |\n| `pose3d_weights` | Specifies the URL or local path to the 3D pose estimation model's checkpoint file.                               |\n| `det_model`      | Specifies the model alias, configuration file name, or configuration file path for the object detection model.   |\n| `det_weights`    | Specifies the URL or local path to the object detection model's checkpoint file.                                 |\n| `det_cat_ids`    | Specifies the list of category IDs corresponding to the object classes to be detected.                           |\n| `device`         | The device to perform the inference. If left `None`, the Inferencer will select the most suitable one.           |\n| `scope`          | The namespace where the model modules are defined.                                                               |\n\nThe inferencer is designed for both visualization and saving predictions. The table below presents the list of arguments available when using the [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) for inference, along with their compatibility with 2D and 3D inferencing:\n\n| Argument                  | Description                                                                                                                                                       | 2D  | 3D  |\n| ------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------- | --- | --- |\n| `show`                    | Controls the display of the image or video in a pop-up window.                                                                                                    | ✔️  | ✔️  |\n| `radius`                  | Sets the visualization keypoint radius.                                                                                                                           | ✔️  | ✔️  |\n| `thickness`               | Determines the link thickness for visualization.                                                                                                                  | ✔️  | ✔️  |\n| `kpt_thr`                 | Sets the keypoint score threshold. Keypoints with scores exceeding this threshold will be displayed.                                                              | ✔️  | ✔️  |\n| `draw_bbox`               | Decides whether to display the bounding boxes of instances.                                                                                                       | ✔️  | ✔️  |\n| `draw_heatmap`            | Decides if the predicted heatmaps should be drawn.                                                                                                                | ✔️  | ❌  |\n| `black_background`        | Decides whether the estimated poses should be displayed on a black background.                                                                                    | ✔️  | ❌  |\n| `skeleton_style`          | Sets the skeleton style. Options include 'mmpose' (default) and 'openpose'.                                                                                       | ✔️  | ❌  |\n| `use_oks_tracking`        | Decides whether to use OKS as a similarity measure in tracking.                                                                                                   | ❌  | ✔️  |\n| `tracking_thr`            | Sets the similarity threshold for tracking.                                                                                                                       | ❌  | ✔️  |\n| `disable_norm_pose_2d`    | Decides whether to scale the bounding box to the dataset's average bounding box scale and relocate the bounding box to the dataset's average bounding box center. | ❌  | ✔️  |\n| `disable_rebase_keypoint` | Decides whether to set the lowest keypoint with height 0.                                                                                                         | ❌  | ✔️  |\n| `num_instances`           | Sets the number of instances to visualize in the results. If set to a negative number, all detected instances will be visualized.                                 | ❌  | ✔️  |\n| `return_vis`              | Decides whether to include visualization images in the results.                                                                                                   | ✔️  | ✔️  |\n| `vis_out_dir`             | Defines the folder path to save the visualization images. If unset, the visualization images will not be saved.                                                   | ✔️  | ✔️  |\n| `return_datasamples`      | Determines if the prediction should be returned in the `PoseDataSample` format.                                                                                   | ✔️  | ✔️  |\n| `pred_out_dir`            | Specifies the folder path to save the predictions. If unset, the predictions will not be saved.                                                                   | ✔️  | ✔️  |\n| `out_dir`                 | If `vis_out_dir` or `pred_out_dir` is unset, these will be set to `f'{out_dir}/visualization'` or `f'{out_dir}/predictions'`, respectively.                       | ✔️  | ✔️  |\n\n### Model Alias\n\nThe MMPose library has predefined aliases for several frequently used models. These aliases can be utilized as a shortcut when initializing the [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24), as an alternative to providing the full model configuration name. Here are the available 2D model aliases and their corresponding configuration names:\n\n| Alias     | Configuration Name                                 | Task                            | Pose Estimator | Detector            |\n| --------- | -------------------------------------------------- | ------------------------------- | -------------- | ------------------- |\n| animal    | rtmpose-m_8xb64-210e_ap10k-256x256                 | Animal pose estimation          | RTMPose-m      | RTMDet-m            |\n| human     | rtmpose-m_8xb256-420e_body8-256x192                | Human pose estimation           | RTMPose-m      | RTMDet-m            |\n| body26    | rtmpose-m_8xb512-700e_body8-halpe26-256x192        | Human pose estimation           | RTMPose-m      | RTMDet-m            |\n| face      | rtmpose-m_8xb256-120e_face6-256x256                | Face keypoint detection         | RTMPose-m      | yolox-s             |\n| hand      | rtmpose-m_8xb256-210e_hand5-256x256                | Hand keypoint detection         | RTMPose-m      | ssdlite_mobilenetv2 |\n| wholebody | rtmpose-m_8xb64-270e_coco-wholebody-256x192        | Human wholebody pose estimation | RTMPose-m      | RTMDet-m            |\n| vitpose   | td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192  | Human pose estimation           | ViTPose-base   | RTMDet-m            |\n| vitpose-s | td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192 | Human pose estimation           | ViTPose-small  | RTMDet-m            |\n| vitpose-b | td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192  | Human pose estimation           | ViTPose-base   | RTMDet-m            |\n| vitpose-l | td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192 | Human pose estimation           | ViTPose-large  | RTMDet-m            |\n| vitpose-h | td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192  | Human pose estimation           | ViTPose-huge   | RTMDet-m            |\n\nThe following table lists the available 3D model aliases and their corresponding configuration names:\n\n| Alias   | Configuration Name                           | Task                     | 3D Pose Estimator | 2D Pose Estimator | Detector    |\n| ------- | -------------------------------------------- | ------------------------ | ----------------- | ----------------- | ----------- |\n| human3d | vid_pl_motionbert_8xb32-120e_h36m            | Human 3D pose estimation | MotionBert        | RTMPose-m         | RTMDet-m    |\n| hand3d  | internet_res50_4xb16-20e_interhand3d-256x256 | Hand 3D pose estimation  | InterNet          | -                 | whole image |\n\nIn addition, users can utilize the CLI tool to display all available aliases with the following command:\n\n```shell\npython demo/inferencer_demo.py --show-alias\n```\n\n## Python API: more flexible and customizable\n\nMMPose provides a separate Python API for inference, which is more flexible but requires users to handle inputs and outputs themselves. Therefore, this API is suitable for users who are **familiar with MMPose**.\n\nThe Python inference interface provided by MMPose is located in [$MMPOSE/mmpose/apis](https://github.com/open-mmlab/mmpose/tree/dev-1.x/mmpose/apis) directory. Here is an example of building a topdown model and performing inference:\n\n### Build a model\n\n```python\nfrom mmcv.image import imread\n\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import merge_data_samples\n\nmodel_cfg = 'configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py'\n\nckpt = 'https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.pth'\n\ndevice = 'cuda'\n\n# init model\nmodel = init_model(model_cfg, ckpt, device=device)\n```\n\n### Inference\n\n```python\nimg_path = 'tests/data/coco/000000000785.jpg'\n\n# inference on a single image\nbatch_results = inference_topdown(model, img_path)\n```\n\nThe inference interface returns a list of PoseDataSample, each of which corresponds to the inference result of an image. The structure of PoseDataSample is as follows:\n\n```python\n[\n    <PoseDataSample(\n\n        ori_shape: (425, 640)\n        img_path: 'tests/data/coco/000000000785.jpg'\n        input_size: (192, 256)\n        flip_indices: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]\n        img_shape: (425, 640)\n\n        gt_instances: <InstanceData(\n                bboxes: array([[  0.,   0., 640., 425.]], dtype=float32)\n                bbox_centers: array([[320. , 212.5]], dtype=float32)\n                bbox_scales: array([[ 800.    , 1066.6666]], dtype=float32)\n                bbox_scores: array([1.], dtype=float32)\n            )>\n\n        gt_instance_labels: <InstanceData()>\n\n        pred_instances: <InstanceData(\n                keypoints: array([[[365.83333333,  87.50000477],\n                            [372.08333333,  79.16667175],\n                            [361.66666667,  81.25000501],\n                            [384.58333333,  85.41667151],\n                            [357.5       ,  85.41667151],\n                            [407.5       , 112.50000381],\n                            [363.75      , 125.00000334],\n                            [438.75      , 150.00000238],\n                            [347.08333333, 158.3333354 ],\n                            [451.25      , 170.83333492],\n                            [305.41666667, 177.08333468],\n                            [432.5       , 214.58333325],\n                            [401.25      , 218.74999976],\n                            [430.41666667, 285.41666389],\n                            [370.        , 274.99999762],\n                            [470.        , 356.24999452],\n                            [403.33333333, 343.74999499]]])\n                bbox_scores: array([1.], dtype=float32)\n                bboxes: array([[  0.,   0., 640., 425.]], dtype=float32)\n                keypoint_scores: array([[0.8720184 , 0.9068178 , 0.89255375, 0.94684595, 0.83111566,\n                            0.9929208 , 1.0862956 , 0.9265839 , 0.9781244 , 0.9008082 ,\n                            0.9043166 , 1.0150217 , 1.1122335 , 1.0207931 , 1.0099326 ,\n                            1.0480015 , 1.0897669 ]], dtype=float32)\n                keypoints_visible: array([[0.8720184 , 0.9068178 , 0.89255375, 0.94684595, 0.83111566,\n                            0.9929208 , 1.0862956 , 0.9265839 , 0.9781244 , 0.9008082 ,\n                            0.9043166 , 1.0150217 , 1.1122335 , 1.0207931 , 1.0099326 ,\n                            1.0480015 , 1.0897669 ]], dtype=float32)\n            )>\n    )>\n]\n```\n\nYou can obtain the predicted keypoints via `.`:\n\n```python\npred_instances = batch_results[0].pred_instances\n\npred_instances.keypoints\n# array([[[365.83333333,  87.50000477],\n#         [372.08333333,  79.16667175],\n#         [361.66666667,  81.25000501],\n#         [384.58333333,  85.41667151],\n#         [357.5       ,  85.41667151],\n#         [407.5       , 112.50000381],\n#         [363.75      , 125.00000334],\n#         [438.75      , 150.00000238],\n#         [347.08333333, 158.3333354 ],\n#         [451.25      , 170.83333492],\n#         [305.41666667, 177.08333468],\n#         [432.5       , 214.58333325],\n#         [401.25      , 218.74999976],\n#         [430.41666667, 285.41666389],\n#         [370.        , 274.99999762],\n#         [470.        , 356.24999452],\n#         [403.33333333, 343.74999499]]])\n```\n\n### Visualization\n\nIn MMPose, most visualizations are implemented based on visualizers. A visualizer is a class that takes a data sample and visualizes it.\n\nMMPose provides a visualizer registry, which users can instantiate using `VISUALIZERS`. Here is an example of using a visualizer to visualize the inference results:\n\n```python\n# merge results as a single data sample\nresults = merge_data_samples(batch_results)\n\n# build the visualizer\nvisualizer = VISUALIZERS.build(model.cfg.visualizer)\n\n# set skeleton, colormap and joint connection rule\nvisualizer.set_dataset_meta(model.dataset_meta)\n\nimg = imread(img_path, channel_order='rgb')\n\n# visualize the results\nvisualizer.add_datasample(\n    'result',\n    img,\n    data_sample=results,\n    show=True)\n```\n\nMMPose also provides a simpler interface for visualization:\n\n```python\nfrom mmpose.apis import visualize\n\npred_instances = batch_results[0].pred_instances\n\nkeypoints = pred_instances.keypoints\nkeypoint_scores = pred_instances.keypoint_scores\n\nmetainfo = 'config/_base_/datasets/coco.py'\n\nvisualize(\n    img_path,\n    keypoints,\n    keypoint_scores,\n    metainfo=metainfo,\n    show=True)\n```\n"
  },
  {
    "path": "docs/en/user_guides/label_studio.md",
    "content": "# Label Studio Annotations to COCO Script\n\n[Label Studio](https://labelstud.io/) is a popular deep learning annotation tool that can be used for annotating various tasks. However, for keypoint annotation, Label Studio can not directly export to the COCO format required by MMPose. This article will explain how to use Label Studio to annotate keypoint data and convert it into the required COCO format using the [labelstudio2coco.py](../../../tools/dataset_converters/labelstudio2coco.py) tool.\n\n## Label Studio Annotation Requirements\n\nAccording to the COCO format requirements, each annotated instance needs to include information about keypoints, segmentation, and bounding box (bbox). However, Label Studio scatters this information across different instances during annotation. Therefore, certain rules need to be followed during annotation to ensure proper usage with the subsequent scripts.\n\n1. Label Interface Setup\n\nFor a newly created Label Studio project, the label interface needs to be set up. There should be three types of annotations: `KeyPointLabels`, `PolygonLabels`, and `RectangleLabels`, which correspond to `keypoints`, `segmentation`, and `bbox` in the COCO format, respectively. The following is an example of a label interface. You can find the `Labeling Interface` in the project's `Settings`, click on `Code`, and paste the following example.\n\n```xml\n<View>\n  <KeyPointLabels name=\"kp-1\" toName=\"img-1\">\n      <Label value=\"person\" background=\"#D4380D\"/>\n  </KeyPointLabels>\n  <PolygonLabels name=\"polygonlabel\" toName=\"img-1\">\n      <Label value=\"person\" background=\"#0DA39E\"/>\n  </PolygonLabels>\n  <RectangleLabels name=\"label\" toName=\"img-1\">\n      <Label value=\"person\" background=\"#DDA0EE\"/>\n  </RectangleLabels>\n  <Image name=\"img-1\" value=\"$img\"/>\n</View>\n```\n\n2. Annotation Order\n\nSince it is necessary to combine annotations of different types into one instance, a specific order of annotation is required to determine whether the annotations belong to the same instance. Annotations should be made in the order of `KeyPointLabels` -> `PolygonLabels`/`RectangleLabels`. The order and number of `KeyPointLabels` should match the order and number of keypoints specified in the `dataset_info` in MMPose configuration file. The annotation order of `PolygonLabels` and `RectangleLabels` can be interchangeable, and only one of them needs to be annotated. The annotation should be within one instance starts with keypoints and ends with non-keypoints. The following image shows an annotation example:\n\n*Note: The bbox and area will be calculated based on the later PolygonLabels/RectangleLabels. If you annotate PolygonLabels first, the bbox will be based on the range of the later RectangleLabels, and the area will be equal to the area of the rectangle. Conversely, they will be based on the minimum bounding rectangle of the polygon and the area of the polygon.*\n\n![image](https://github.com/open-mmlab/mmpose/assets/15847281/b2d004d0-8361-42c5-9180-cfbac0373a94)\n\n3. Exporting Annotations\n\nOnce the annotations are completed as described above, they need to be exported. Select the `Export` button on the project interface, choose the `JSON` format, and click `Export` to download the JSON file containing the labels.\n\n*Note: The exported file only contains the labels and does not include the original images. Therefore, the corresponding annotated images need to be provided separately. It is not recommended to use directly uploaded files because Label Studio truncates long filenames. Instead, use the export COCO format tool available in the `Export` functionality, which includes a folder with the image files within the downloaded compressed package.*\n\n![image](https://github.com/open-mmlab/mmpose/assets/15847281/9f54ca3d-8cdd-4d7f-8ed6-494badcfeaf2)\n\n## Usage of the Conversion Tool Script\n\nThe conversion tool script is located at `tools/dataset_converters/labelstudio2coco.py`and can be used as follows:\n\n```bash\npython tools/dataset_converters/labelstudio2coco.py config.xml project-1-at-2023-05-13-09-22-91b53efa.json output/result.json\n```\n\nWhere `config.xml` contains the code from the Labeling Interface mentioned earlier, `project-1-at-2023-05-13-09-22-91b53efa.json` is the JSON file exported from Label Studio, and `output/result.json` is the path to the resulting JSON file in COCO format. If the path does not exist, the script will create it automatically.\n\nAfterward, place the image folder in the output directory to complete the conversion of the COCO dataset. The directory structure can be as follows:\n\n```bash\n.\n├── images\n│   ├── 38b480f2.jpg\n│   └── aeb26f04.jpg\n└── result.json\n\n```\n\nIf you want to use this dataset in MMPose, you can make modifications like the following example:\n\n```python\ndataset=dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='result.json',\n    data_prefix=dict(img='images/'),\n    pipeline=train_pipeline,\n)\n```\n"
  },
  {
    "path": "docs/en/user_guides/mixed_datasets.md",
    "content": "# Use Mixed Datasets for Training\n\nMMPose offers a convenient and versatile solution for training with mixed datasets through its [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) tool. Acting as a wrapper, it allows for the inclusion of multiple datasets and seamlessly reads and converts data from varying sources into a unified format for model training. The data processing pipeline utilizing [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) is illustrated in the following figure.\n\n![combined_dataset_pipeline](https://user-images.githubusercontent.com/26127467/223333154-fb88e511-810a-423c-b755-c791d296bc43.jpg)\n\nThe following section will provide a detailed description of how to configure [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) with an example that combines the COCO and AI Challenger (AIC) datasets.\n\n## COCO & AIC example\n\nThe COCO and AIC datasets are both human 2D pose datasets, but they differ in the number and order of keypoints. Here are two instances from the respective datasets.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223335806-748498af-8da4-4666-a6d3-337e4a8996f0.png\" height=\"300px\" alt><br>\n\nSome keypoints, such as \"left hand\", are defined in both datasets, but they have different indices. Specifically, the index for the \"left hand\" keypoint is 9 in the COCO dataset and 5 in the AIC dataset. Furthermore, each dataset contains unique keypoints that are not present in the counterpart dataset. For instance, the facial keypoints (with indices 0~4) are only defined in the COCO dataset, whereas the \"head top\" (with index 12) and \"neck\" (with index 13) keypoints are exclusive to the AIC dataset. The relationship between the keypoints in both datasets is illustrated in the following Venn diagram.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223338755-d838dd39-901b-4e7d-af8b-b94b5f5f9ef3.png\" height=\"200px\" alt><br>\n\nNext, we will discuss two methods of mixing datasets.\n\n- [Merge](#merge-aic-into-coco)\n- [Combine](#combine-aic-and-coco)\n\n### Merge AIC into COCO\n\nIf users aim to enhance their model's performance on the COCO dataset or other similar datasets, they can use the AIC dataset as an auxiliary source. To do so, they should select only the keypoints in AIC dataset that are shared with COCO datasets and ignore the rest. Moreover, the indices of these chosen keypoints in the AIC dataset should be transformed to match the corresponding indices in the COCO dataset.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223348541-d1f9e3b7-7e60-41b5-bf68-22e61b34bb2b.png\" height=\"200px\" alt><br>\n\nIn this scenario, no data conversion is required for the elements from the COCO dataset. To configure the COCO dataset, use the following code:\n\n```python\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root='data/coco/',\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[], # Leave the `pipeline` empty, as no conversion is needed\n)\n```\n\nFor AIC dataset, the order of the keypoints needs to be transformed. MMPose provides a [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11) transform to achieve this. Here's an example of how to configure the AIC sub dataset:\n\n```python\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,  # same as COCO dataset\n            mapping=[  # includes index pairs for corresponding keypoints\n                (0, 6),  # index 0 (in AIC) -> index 6 (in COCO)\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n```\n\nBy using the [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11), the indices of keypoints with indices 0 to 11 will be transformed to corresponding indices among 5 to 16. Meanwhile, the keypoints with indices 12 and 13 will be removed. For the target keypoints with indices 0 to 4, which are not defined in the `mapping` argument, they will be set as invisible and won't be used in training.\n\nOnce the sub datasets are configured, the [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) wrapper can be defined as follows:\n\n```python\ndataset = dict(\n    type='CombinedDataset',\n    # Since the combined dataset has the same data format as COCO,\n    # it should use the same meta information for the dataset\n    metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n    datasets=[dataset_coco, dataset_aic],\n    # The pipeline includes typical transforms, such as loading the\n    # image and data augmentation\n    pipeline=train_pipeline,\n    # The sample_ratio_factor controls the sampling ratio of\n    # each dataset in the combined dataset. The length of sample_ratio_factor\n    # should match the number of datasets. Each factor indicates the sampling\n    # ratio of the corresponding dataset relative to its original length.\n    sample_ratio_factor=[1.0, 0.5]\n)\n```\n\nA complete, ready-to-use [config file](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py) that merges the AIC dataset into the COCO dataset is also available. Users can refer to it for more details and use it as a template to build their own custom dataset.\n\n### Combine AIC and COCO\n\nThe previously mentioned method discards some annotations in the AIC dataset. If users want to use all the information from both datasets, they can combine the two datasets. This means taking the union set of keypoints in both datasets.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223356617-075e0ab1-0ed3-426d-bc88-4f16be93f0ba.png\" height=\"200px\" alt><br>\n\nIn this scenario, both COCO and AIC datasets need to adjust the keypoint indices using [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11):\n\n```python\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root='data/coco/',\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,  # the size of union keypoint set\n            mapping=[\n                (0, 0),\n                (1, 1),\n                # omitted\n                (16, 16),\n            ])\n    ])\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,  # the size of union keypoint set\n            mapping=[\n                (0, 6),\n                # omitted\n                (12, 17),\n                (13, 18),\n            ])\n    ],\n)\n```\n\nTo account for the fact that the combined dataset has 19 keypoints, which is different from either COCO or AIC dataset, a new dataset meta information file is needed to describe the new dataset. An example of such a file is [coco_aic.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/_base_/datasets/coco_aic.py), which is based on [coco.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/_base_/datasets/coco.py) but includes several updates:\n\n- The paper information of AIC dataset has been added.\n- The 'head_top' and 'neck' keypoints, which are unique in AIC, have been added to the `keypoint_info`.\n- A skeleton link between 'head_top' and 'neck' has been added.\n- The `joint_weights` and `sigmas` have been extended for the newly added keypoints.\n\nFinally, the combined dataset can be configured as:\n\n```python\ndataset = dict(\n    type='CombinedDataset',\n    # using new dataset meta information file\n    metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n    datasets=[dataset_coco, dataset_aic],\n    # The pipeline includes typical transforms, such as loading the\n    # image and data augmentation\n    pipeline=train_pipeline,\n)\n```\n\nAdditionally, the output channel number of the model should be adjusted as the number of keypoints changes. If the users aim to evaluate the model on the COCO dataset, a subset of model outputs must be chosen. This subset can be customized using the `output_keypoint_indices` argument in `test_cfg`. Users can refer to the [config file](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py), which combines the COCO and AIC dataset, for more details and use it as a template to create their custom dataset.\n\n## Sampling Strategy for Mixed Datasets\n\nWhen training with mixed datasets, users often encounter the problem of inconsistent data distributions between different datasets. To address this issue, we provide two different sampling strategies:\n\n1. Adjust the sampling ratio of each sub dataset\n2. Adjust the ratio of each sub dataset in each batch\n\n### Adjust the sampling ratio of each sub dataset\n\nIn [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15), we provide the `sample_ratio_factor` argument to adjust the sampling ratio of each sub dataset.\n\nFor example:\n\n- If `sample_ratio_factor` is `[1.0, 0.5]`, then all data from the first sub dataset will be included in the training, and the second sub dataset will be sampled at a ratio of 0.5.\n- If `sample_ratio_factor` is `[1.0, 2.0]`, then all data from the first sub dataset will be included in the training, and the second sub dataset will be sampled at a ratio of 2 times its total number.\n\n### Adjust the ratio of each sub dataset in each batch\n\nIn [$MMPOSE/datasets/samplers.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/samplers.py) we provide [MultiSourceSampler](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/samplers.py#L15) to adjust the ratio of each sub dataset in each batch.\n\nFor example:\n\n- If `sample_ratio_factor` is `[1.0, 0.5]`, then the data volume of the first sub dataset in each batch will be `1.0 / (1.0 + 0.5) = 66.7%`, and the data volume of the second sub dataset will be `0.5 / (1.0 + 0.5) = 33.3%`. That is, the first sub dataset will be twice as large as the second sub dataset in each batch.\n\nUsers can set the `sampler` argument in the configuration file:\n\n```python\n# data loaders\ntrain_bs = 256\ntrain_dataloader = dict(\n    batch_size=train_bs,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(\n        type='MultiSourceSampler',\n        batch_size=train_bs,\n        # ratio of sub datasets in each batch\n        source_ratio=[1.0, 0.5],\n        shuffle=True,\n        round_up=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        # set sub datasets\n        datasets=[sub_dataset1, sub_dataset2],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n```\n"
  },
  {
    "path": "docs/en/user_guides/model_analysis.md",
    "content": "# Model Analysis\n\n## Get Model Params & FLOPs\n\nMMPose provides [tools/analysis_tools/get_flops.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tools/analysis_tools/get_flops.py) to get model parameters and FLOPs.\n\n```shell\npython tools/analysis_tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}] [--cfg-options ${CFG_OPTIONS}]\n```\n\nDescription of all arguments:\n\n`CONFIG_FILE` : The path of a model config file.\n\n`--shape`: The input shape to the model.\n\n`--input-constructor`: If specified as batch, it will generate a batch tensor to calculate FLOPs.\n\n`--batch-size`：If `--input-constructor` is specified as batch, it will generate a random tensor with shape `(batch_size, 3, **input_shape)` to calculate FLOPs.\n\n`--cfg-options`: If specified, the key-value pair optional `cfg` will be merged into config file.\n\nExample:\n\n```shell\npython tools/analysis_tools/get_flops.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py\n```\n\nWe will get the following results:\n\n```text\n==============================\nInput shape: (1, 3, 256, 192)\nFlops: 7.7 GFLOPs\nParams: 28.54 M\n==============================\n```\n\n```{note}\nThis tool is still experimental and we do not guarantee that the number is absolutely correct. Some operators are not counted into FLOPs like GN and custom operators.\n```\n\n## Log Analysis\n\nMMPose provides [tools/analysis_tools/analyze_logs.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tools/analysis_tools/analyze_logs.py) to analyze the training log. The log file can be either a json file or a text file. The json file is recommended, because it is more convenient to parse and visualize.\n\nCurrently, the following functions are supported:\n\n- Plot loss/accuracy curves\n- Calculate training time\n\n### Plot Loss/Accuracy Curves\n\nThe function depends on `seaborn`, please install it first by running `pip install seaborn`.\n\n![log_curve](https://user-images.githubusercontent.com/87690686/188538215-5d985aaa-59f8-44cf-b6f9-10890d599e9c.png)\n\n```shell\npython tools/analysis_tools/analyze_logs.py plot_curve ${JSON_LOGS} [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]\n```\n\nExamples:\n\n- Plot loss curve\n\n  ```shell\n  python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_kpt --legend loss_kpt\n  ```\n\n- Plot accuracy curve and export to PDF file\n\n  ```shell\n  python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys acc_pose --out results.pdf\n  ```\n\n- Plot multiple log files on the same figure\n\n  ```shell\n  python tools/analysis_tools/analyze_logs.py plot_curve log1.json log2.json --keys loss_kpt --legend run1 run2 --title loss_kpt --out loss_kpt.png\n  ```\n\n### Calculate Training Time\n\n```shell\npython tools/analysis_tools/analyze_logs.py cal_train_time ${JSON_LOGS} [--include-outliers]\n```\n\nExamples:\n\n```shell\npython tools/analysis_tools/analyze_logs.py cal_train_time log.json\n```\n\nThe result is as follows:\n\n```text\n-----Analyze train time of hrnet_w32_256x192.json-----\nslowest epoch 56, average time is 0.6924\nfastest epoch 1, average time is 0.6502\ntime std over epochs is 0.0085\naverage iter time: 0.6688 s/iter\n```\n"
  },
  {
    "path": "docs/en/user_guides/prepare_datasets.md",
    "content": "# Prepare Datasets\n\nIn this document, we will give a guide on the process of preparing datasets for the MMPose. Various aspects of dataset preparation will be discussed, including using built-in datasets, creating custom datasets, combining datasets for training, browsing and downloading the datasets.\n\n## Use built-in datasets\n\n**Step 1**: Prepare Data\n\nMMPose supports multiple tasks and corresponding datasets. You can find them in [dataset zoo](https://mmpose.readthedocs.io/en/latest/dataset_zoo.html). To properly prepare your data, please follow the guidelines associated with your chosen dataset.\n\n**Step 2**: Configure Dataset Settings in the Config File\n\nBefore training or evaluating models, you must configure the dataset settings. Take [`td-hm_hrnet-w32_8xb64-210e_coco-256x192.py`](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) for example, which can be used to train or evaluate the HRNet pose estimator on COCO dataset. We will go through the dataset configuration.\n\n- Basic Dataset Arguments\n\n  ```python\n  # base dataset settings\n  dataset_type = 'CocoDataset'\n  data_mode = 'topdown'\n  data_root = 'data/coco/'\n  ```\n\n  - `dataset_type` specifies the class name of the dataset. Users can refer to [Datasets APIs](https://mmpose.readthedocs.io/en/latest/api.html#datasets) to find the class name of their desired dataset.\n  - `data_mode` determines the output format of the dataset, with two options available: `'topdown'` and `'bottomup'`. If `data_mode='topdown'`, the data element represents a single instance with its pose; otherwise, the data element is an entire image containing multiple instances and poses.\n  - `data_root` designates the root directory of the dataset.\n\n- Data Processing Pipelines\n\n  ```python\n  # pipelines\n  train_pipeline = [\n      dict(type='LoadImage'),\n      dict(type='GetBBoxCenterScale'),\n      dict(type='RandomFlip', direction='horizontal'),\n      dict(type='RandomHalfBody'),\n      dict(type='RandomBBoxTransform'),\n      dict(type='TopdownAffine', input_size=codec['input_size']),\n      dict(type='GenerateTarget', encoder=codec),\n      dict(type='PackPoseInputs')\n  ]\n  val_pipeline = [\n      dict(type='LoadImage'),\n      dict(type='GetBBoxCenterScale'),\n      dict(type='TopdownAffine', input_size=codec['input_size']),\n      dict(type='PackPoseInputs')\n  ]\n  ```\n\n  The `train_pipeline` and `val_pipeline` define the steps to process data elements during the training and evaluation phases, respectively. In addition to loading images and packing inputs, the `train_pipeline` primarily consists of data augmentation techniques and target generator, while the `val_pipeline` focuses on transforming data elements into a unified format.\n\n- Data Loaders\n\n  ```python\n  # data loaders\n  train_dataloader = dict(\n      batch_size=64,\n      num_workers=2,\n      persistent_workers=True,\n      sampler=dict(type='DefaultSampler', shuffle=True),\n      dataset=dict(\n          type=dataset_type,\n          data_root=data_root,\n          data_mode=data_mode,\n          ann_file='annotations/person_keypoints_train2017.json',\n          data_prefix=dict(img='train2017/'),\n          pipeline=train_pipeline,\n      ))\n  val_dataloader = dict(\n      batch_size=32,\n      num_workers=2,\n      persistent_workers=True,\n      drop_last=False,\n      sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n      dataset=dict(\n          type=dataset_type,\n          data_root=data_root,\n          data_mode=data_mode,\n          ann_file='annotations/person_keypoints_val2017.json',\n          bbox_file='data/coco/person_detection_results/'\n          'COCO_val2017_detections_AP_H_56_person.json',\n          data_prefix=dict(img='val2017/'),\n          test_mode=True,\n          pipeline=val_pipeline,\n      ))\n  test_dataloader = val_dataloader\n  ```\n\n  This section is crucial for configuring the dataset in the config file. In addition to the basic dataset arguments and pipelines discussed earlier, other important parameters are defined here. The `batch_size` determines the batch size per GPU; the `ann_file` indicates the annotation file for the dataset; and `data_prefix` specifies the image folder. The `bbox_file`, which supplies detected bounding box information, is only used in the val/test data loader for top-down datasets.\n\nWe recommend copying the dataset configuration from provided config files that use the same dataset, rather than writing it from scratch, in order to minimize potential errors. By doing so, users can simply make the necessary modifications as needed, ensuring a more reliable and efficient setup process.\n\n## Use a custom dataset\n\nThe [Customize Datasets](../advanced_guides/customize_datasets.md) guide provides detailed information on how to build a custom dataset. In this section, we will highlight some key tips for using and configuring custom datasets.\n\n- Determine the dataset class name. If you reorganize your dataset into the COCO format, you can simply use `CocoDataset` as the value for `dataset_type`. Otherwise, you will need to use the name of the custom dataset class you added.\n\n- Specify the meta information config file. Suppose the path of the annotation file is `aaa/annotations/xxx.json`, and the path of imgs is `aaa/train/c.jpg`, you should specify the meta information config file as follows:\n\n  ```python\n  train_dataloader = dict(\n      ...\n      dataset=dict(\n          type=dataset_type,\n          data_root='aaa',\n          # ann file is stored at {data_root}/{ann_file}\n          # e.g. aaa/annotations/xxx.json\n          ann_file='annotations/xxx.json',\n          # img is stored at {data_root}/{img}/\n          # e.g. aaa/train/c.jpg\n          data_prefix=dict(img='train'),\n          # specify dataset meta information\n          metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n          ...),\n  )\n  ```\n\n  Note that the argument `metainfo` must be specified in the val/test data loaders as well.\n\n## Use mixed datasets for training\n\nMMPose offers a convenient and versatile solution for training with mixed datasets. Please refer to [Use Mixed Datasets for Training](./mixed_datasets.md).\n\n## Browse dataset\n\n`tools/analysis_tools/browse_dataset.py` helps the user to browse a pose dataset visually, or save the image to a designated directory.\n\n```shell\npython tools/misc/browse_dataset.py ${CONFIG} [-h] [--output-dir ${OUTPUT_DIR}] [--max-item-per-dataset ${MAX_ITEM_PER_DATASET}] [--not-show] [--phase ${PHASE}] [--mode ${MODE}] [--show-interval ${SHOW_INTERVAL}]\n```\n\n| ARGS                             | Description                                                                                                                                          |\n| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG`                         | The path to the config file.                                                                                                                         |\n| `--output-dir OUTPUT_DIR`        | The target folder to save visualization results. If not specified, the visualization results will not be saved.                                      |\n| `--not-show`                     | Do not show the visualization results in an external window.                                                                                         |\n| `--phase {train, val, test}`     | Options for dataset.                                                                                                                                 |\n| `--mode {original, transformed}` | Specify the type of visualized images. `original` means to show images without pre-processing; `transformed` means to show images are pre-processed. |\n| `--show-interval SHOW_INTERVAL`  | Time interval between visualizing two images.                                                                                                        |\n| `--max-item-per-dataset`         | Define the maximum item processed per dataset, default to 50                                                                                         |\n\nFor instance, users who want to visualize images and annotations in COCO dataset use:\n\n```shell\npython tools/misc/browse_dataset.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-e210_coco-256x192.py --mode original\n```\n\nThe bounding boxes and keypoints will be plotted on the original image. Following is an example:\n![original_coco](https://user-images.githubusercontent.com/26127467/187383698-7e518f21-b4cc-4712-9e97-99ddd8f0e437.jpg)\n\nThe original images need to be processed before being fed into models. To visualize pre-processed images and annotations, users need to modify the argument `mode`  to `transformed`. For example:\n\n```shell\npython tools/misc/browse_dataset.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-e210_coco-256x192.py --mode transformed\n```\n\nHere is a processed sample\n\n![transformed_coco](https://user-images.githubusercontent.com/26127467/187386652-bd47335d-797c-4e8c-b823-2a4915f9812f.jpg)\n\nThe heatmap target will be visualized together if it is generated in the pipeline.\n\n## Download dataset via MIM\n\nBy using [OpenXLab](https://openxlab.org.cn/datasets), you can obtain free formatted datasets in various fields. Through the search function of the platform, you may address the dataset they look for quickly and easily. Using the formatted datasets from the platform, you can efficiently conduct tasks across datasets.\n\nIf you use MIM to download, make sure that the version is greater than v0.3.8. You can use the following command to update, install, login and download the dataset:\n\n```shell\n# upgrade your MIM\npip install -U openmim\n\n# install OpenXLab CLI tools\npip install -U openxlab\n# log in OpenXLab\nopenxlab login\n\n# download coco2017 and preprocess by MIM\nmim download mmpose --dataset coco2017\n```\n\n### Supported datasets\n\nHere is the list of supported datasets, we will continue to update it in the future.\n\n#### Body\n\n| Dataset name  | Download command                          |\n| ------------- | ----------------------------------------- |\n| COCO 2017     | `mim download mmpose --dataset coco2017`  |\n| MPII          | `mim download mmpose --dataset mpii`      |\n| AI Challenger | `mim download mmpose --dataset aic`       |\n| CrowdPose     | `mim download mmpose --dataset crowdpose` |\n\n#### Face\n\n| Dataset name | Download command                     |\n| ------------ | ------------------------------------ |\n| LaPa         | `mim download mmpose --dataset lapa` |\n| 300W         | `mim download mmpose --dataset 300w` |\n| WFLW         | `mim download mmpose --dataset wflw` |\n\n#### Hand\n\n| Dataset name | Download command                           |\n| ------------ | ------------------------------------------ |\n| OneHand10K   | `mim download mmpose --dataset onehand10k` |\n| FreiHand     | `mim download mmpose --dataset freihand`   |\n| HaGRID       | `mim download mmpose --dataset hagrid`     |\n\n#### Whole Body\n\n| Dataset name | Download command                      |\n| ------------ | ------------------------------------- |\n| Halpe        | `mim download mmpose --dataset halpe` |\n\n#### Animal\n\n| Dataset name | Download command                      |\n| ------------ | ------------------------------------- |\n| AP-10K       | `mim download mmpose --dataset ap10k` |\n\n#### Fashion\n\nComing Soon\n"
  },
  {
    "path": "docs/en/user_guides/train_and_test.md",
    "content": "# Training and Testing\n\n## Launch training\n\n### Train with your PC\n\nYou can use `tools/train.py` to train a model on a single machine with a CPU and optionally a GPU.\n\nHere is the full usage of the script:\n\n```shell\npython tools/train.py ${CONFIG_FILE} [ARGS]\n```\n\n```{note}\nBy default, MMPose prefers GPU to CPU. If you want to train a model on CPU, please empty `CUDA_VISIBLE_DEVICES` or set it to -1 to make GPU invisible to the program.\n```\n\n```shell\nCUDA_VISIBLE_DEVICES=-1 python tools/train.py ${CONFIG_FILE} [ARGS]\n```\n\n| ARGS                                  | Description                                                                                                                                                         |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG_FILE`                         | The path to the config file.                                                                                                                                        |\n| `--work-dir WORK_DIR`                 | The target folder to save logs and checkpoints. Defaults to a folder with the same name as the config file under `./work_dirs`.                                     |\n| `--resume [RESUME]`                   | Resume training. If specify a path, resume from it, while if not specify, try to auto resume from the latest checkpoint.                                            |\n| `--amp`                               | Enable automatic-mixed-precision training.                                                                                                                          |\n| `--no-validate`                       | **Not suggested**. Disable checkpoint evaluation during training.                                                                                                   |\n| `--auto-scale-lr`                     | Automatically rescale the learning rate according to the actual batch size and the original batch size.                                                             |\n| `--cfg-options CFG_OPTIONS`           | Override some settings in the used config, the key-value pair in xxx=yyy format will be merged into the config file. If the value to be overwritten is a list, it should be of the form of either `key=\"[a,b]\"` or `key=a,b`. The argument also allows nested list/tuple values, e.g. `key=\"[(a,b),(c,d)]\"`. Note that quotation marks are necessary and that **no white space is allowed**. |\n| `--show-dir SHOW_DIR`                 | The directory to save the result visualization images generated during validation.                                                                                  |\n| `--show`                              | Visualize the prediction result in a window.                                                                                                                        |\n| `--interval INTERVAL`                 | The interval of samples to visualize.                                                                                                                               |\n| `--wait-time WAIT_TIME`               | The display time of every window (in seconds). Defaults to 1.                                                                                                       |\n| `--launcher {none,pytorch,slurm,mpi}` | Options for job launcher.                                                                                                                                           |\n\n### Train with multiple GPUs\n\nWe provide a shell script to start a multi-GPUs task with `torch.distributed.launch`.\n\n```shell\nbash ./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\n| ARGS          | Description                                                                        |\n| ------------- | ---------------------------------------------------------------------------------- |\n| `CONFIG_FILE` | The path to the config file.                                                       |\n| `GPU_NUM`     | The number of GPUs to be used.                                                     |\n| `[PYARGS]`    | The other optional arguments of `tools/train.py`, see [here](#train-with-your-pc). |\n\nYou can also specify extra arguments of the launcher by environment variables. For example, change the\ncommunication port of the launcher to 29666 by the below command:\n\n```shell\nPORT=29666 bash ./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\nIf you want to startup multiple training jobs and use different GPUs, you can launch them by specifying\ndifferent port and visible devices.\n\n```shell\nCUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 bash ./tools/dist_train.sh ${CONFIG_FILE1} 4 [PY_ARGS]\nCUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 bash ./tools/dist_train.sh ${CONFIG_FILE2} 4 [PY_ARGS]\n```\n\n### Train with multiple machines\n\n#### Multiple machines in the same network\n\nIf you launch a training job with multiple machines connected with ethernet, you can run the following commands:\n\nOn the first machine:\n\n```shell\nNNODES=2 NODE_RANK=0 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_train.sh $CONFIG $GPUS\n```\n\nOn the second machine:\n\n```shell\nNNODES=2 NODE_RANK=1 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_train.sh $CONFIG $GPUS\n```\n\nCompared with multi-GPUs in a single machine, you need to specify some extra environment variables:\n\n| ENV_VARS      | Description                                                                  |\n| ------------- | ---------------------------------------------------------------------------- |\n| `NNODES`      | The total number of machines.                                                |\n| `NODE_RANK`   | The index of the local machine.                                              |\n| `PORT`        | The communication port, it should be the same in all machines.               |\n| `MASTER_ADDR` | The IP address of the master machine, it should be the same in all machines. |\n\nUsually, it is slow if you do not have high-speed networking like InfiniBand.\n\n#### Multiple machines managed with slurm\n\nIf you run MMPose on a cluster managed with [slurm](https://slurm.schedmd.com/), you can use the script `slurm_train.sh`.\n\n```shell\n[ENV_VARS] ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR} [PY_ARGS]\n```\n\nHere are the arguments description of the script.\n\n| ARGS          | Description                                                                        |\n| ------------- | ---------------------------------------------------------------------------------- |\n| `PARTITION`   | The partition to use in your cluster.                                              |\n| `JOB_NAME`    | The name of your job, you can name it as you like.                                 |\n| `CONFIG_FILE` | The path to the config file.                                                       |\n| `WORK_DIR`    | The target folder to save logs and checkpoints.                                    |\n| `[PYARGS]`    | The other optional arguments of `tools/train.py`, see [here](#train-with-your-pc). |\n\nHere are the environment variables that can be used to configure the slurm job.\n\n| ENV_VARS        | Description                                                                                                |\n| --------------- | ---------------------------------------------------------------------------------------------------------- |\n| `GPUS`          | The total number of GPUs to be used. Defaults to 8.                                                        |\n| `GPUS_PER_NODE` | The number of GPUs to be allocated per node. Defaults to 8.                                                |\n| `CPUS_PER_TASK` | The number of CPUs to be allocated per task (Usually one GPU corresponds to one task). Defaults to 5.      |\n| `SRUN_ARGS`     | The other arguments of `srun`. Available options can be found [here](https://slurm.schedmd.com/srun.html). |\n\n## Resume training\n\nResume training means to continue training from the state saved from one of the previous trainings, where the state includes the model weights, the state of the optimizer and the optimizer parameter adjustment strategy.\n\n### Automatically resume training\n\nUsers can add `--resume` to the end of the training command to resume training. The program will automatically load the latest weight file from `work_dirs` to resume training. If there is a latest `checkpoint` in `work_dirs` (e.g. the training was interrupted during the previous training), the training will be resumed from the `checkpoint`. Otherwise (e.g. the previous training did not save `checkpoint` in time or a new training task was started), the training will be restarted.\n\nHere is an example of resuming training:\n\n```shell\npython tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py --resume\n```\n\n### Specify the checkpoint to resume training\n\nYou can also specify the `checkpoint` path for `--resume`. MMPose will automatically read the `checkpoint` and resume training from it. The command is as follows:\n\n```shell\npython tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py \\\n    --resume work_dirs/td-hm_res50_8xb64-210e_coco-256x192/latest.pth\n```\n\nIf you hope to manually specify the `checkpoint` path in the config file, in addition to setting `resume=True`, you also need to set the `load_from`.\n\nIt should be noted that if only `load_from` is set without setting `resume=True`, only the weights in the `checkpoint` will be loaded and the training will be restarted from scratch, instead of continuing from the previous state.\n\nThe following example is equivalent to the example above that specifies the `--resume` parameter:\n\n```python\nresume = True\nload_from = 'work_dirs/td-hm_res50_8xb64-210e_coco-256x192/latest.pth'\n# model settings\nmodel = dict(\n    ## omitted ##\n    )\n```\n\n## Freeze partial parameters during training\n\nIn some scenarios, it might be desirable to freeze certain parameters of a model during training to fine-tune specific parts or to prevent overfitting. In MMPose, you can set different hyperparameters for any module in the model by setting custom_keys in `paramwise_cfg`. This allows you to control the learning rate and decay coefficient for specific parts of the model.\n\nFor example, if you want to freeze the parameters in `backbone.layer0` and `backbone.layer1`, you can modify the optimizer wrapper in the config file as:\n\n```python\noptim_wrapper = dict(\n    optimizer=dict(...),\n    paramwise_cfg=dict(\n        custom_keys={\n            'backbone.layer0': dict(lr_mult=0, decay_mult=0),\n            'backbone.layer0': dict(lr_mult=0, decay_mult=0),\n        }))\n```\n\nThis configuration will freeze the parameters in `backbone.layer0` and `backbone.layer1` by setting their learning rate and decay coefficient to 0. By using this approach, you can effectively control the training process and fine-tune specific parts of your model as needed.\n\n## Automatic Mixed Precision (AMP) training\n\nMixed precision training can reduce training time and storage requirements without changing the model or reducing the model training accuracy, thus supporting larger batch sizes, larger models, and larger input sizes.\n\nTo enable Automatic Mixing Precision (AMP) training, add `--amp` to the end of the training command, which is as follows:\n\n```shell\npython tools/train.py ${CONFIG_FILE} --amp\n```\n\nSpecific examples are as follows:\n\n```shell\npython tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py  --amp\n```\n\n## Set the random seed\n\nIf you want to specify the random seed during training, you can use the following command:\n\n```shell\npython ./tools/train.py \\\n    ${CONFIG} \\                               # config file\n    --cfg-options randomness.seed=2023 \\      # set the random seed = 2023\n    [randomness.diff_rank_seed=True] \\        # Set different seeds according to rank.\n    [randomness.deterministic=True]           # Set the cuDNN backend deterministic option to True\n# `[]` stands for optional parameters, when actually entering the command line, you do not need to enter `[]`\n```\n\n`randomness` has three parameters that can be set, with the following meanings.\n\n- `randomness.seed=2023`, set the random seed to `2023`.\n\n- `randomness.diff_rank_seed=True`, set different seeds according to global `rank`. Defaults to `False`.\n\n- `randomness.deterministic=True`, set the deterministic option for `cuDNN` backend, i.e., set `torch.backends.cudnn.deterministic` to `True` and `torch.backends.cudnn.benchmark` to `False`. Defaults to `False`. See [Pytorch Randomness](https://pytorch.org/docs/stable/notes/randomness.html) for more details.\n\n## Training Log\n\nDuring training, the training log will be printed in the console as follows:\n\n```shell\n07/14 08:26:50 - mmengine - INFO - Epoch(train) [38][ 6/38]  base_lr: 5.148343e-04 lr: 5.148343e-04  eta: 0:15:34  time: 0.540754  data_time: 0.394292  memory: 3141  loss: 0.006220  loss_kpt: 0.006220  acc_pose: 1.000000\n```\n\nThe training log contains the following information:\n\n- `07/14 08:26:50`: The current time.\n- `mmengine`: The name of the program.\n- `INFO` or `WARNING`: The log level.\n- `Epoch(train)`: The current training stage. `train` means the training stage, `val` means the validation stage.\n- `[38][ 6/38]`: The current epoch and the current iteration.\n- `base_lr`: The base learning rate.\n- `lr`: The current (real) learning rate.\n- `eta`: The estimated time of arrival.\n- `time`: The elapsed time (minutes) of the current iteration.\n- `data_time`: The elapsed time (minutes) of data processing (i/o and transforms).\n- `memory`: The GPU memory (MB) allocated by the program.\n- `loss`: The total loss value of the current iteration.\n- `loss_kpt`: The loss value you passed in head module.\n- `acc_pose`: The accuracy value you passed in head module.\n\n## Visualize training process\n\nMonitoring the training process is essential for understanding the performance of your model and making necessary adjustments. In this section, we will introduce two methods to visualize the training process of your MMPose model: TensorBoard and the MMEngine Visualizer.\n\n### TensorBoard\n\nTensorBoard is a powerful tool that allows you to visualize the changes in losses during training. To enable TensorBoard visualization, you may need to:\n\n1. Install TensorBoard environment\n\n   ```shell\n   pip install tensorboard\n   ```\n\n2. Enable TensorBoard in the config file\n\n   ```python\n   visualizer = dict(vis_backends=[\n       dict(type='LocalVisBackend'),\n       dict(type='TensorboardVisBackend'),\n   ])\n   ```\n\nThe event file generated by TensorBoard will be save under the experiment log folder `${WORK_DIR}`, which defaults to `work_dir/${CONFIG}` or can be specified using the `--work-dir` option. To visualize the training process, use the following command:\n\n```shell\ntensorboard --logdir ${WORK_DIR}/${TIMESTAMP}/vis_data\n```\n\n### MMEngine visualizer\n\nMMPose also supports visualizing model inference results during validation. To activate this function, please use the `--show` option or set `--show-dir` when launching training. This feature provides an effective way to analyze the model's performance on specific examples and make any necessary adjustments.\n\n## Test your model\n\n### Test with your PC\n\nYou can use `tools/test.py` to test a model on a single machine with a CPU and optionally a GPU.\n\nHere is the full usage of the script:\n\n```shell\npython tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [ARGS]\n```\n\n```{note}\nBy default, MMPose prefers GPU to CPU. If you want to test a model on CPU, please empty `CUDA_VISIBLE_DEVICES` or set it to -1 to make GPU invisible to the program.\n```\n\n```shell\nCUDA_VISIBLE_DEVICES=-1 python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [ARGS]\n```\n\n| ARGS                                  | Description                                                                                                                                                         |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG_FILE`                         | The path to the config file.                                                                                                                                        |\n| `CHECKPOINT_FILE`                     | The path to the checkpoint file (It can be a http link, and you can find checkpoints [here](https://MMPose.readthedocs.io/en/latest/model_zoo.html)).               |\n| `--work-dir WORK_DIR`                 | The directory to save the file containing evaluation metrics.                                                                                                       |\n| `--out OUT`                           | The path to save the file containing evaluation metrics.                                                                                                            |\n| `--dump DUMP`                         | The path to dump all outputs of the model for offline evaluation.                                                                                                   |\n| `--cfg-options CFG_OPTIONS`           | Override some settings in the used config, the key-value pair in xxx=yyy format will be merged into the config file. If the value to be overwritten is a list, it should be of the form of either `key=\"[a,b]\"` or `key=a,b`. The argument also allows nested list/tuple values, e.g. `key=\"[(a,b),(c,d)]\"`. Note that quotation marks are necessary and that no white space is allowed. |\n| `--show-dir SHOW_DIR`                 | The directory to save the result visualization images.                                                                                                              |\n| `--show`                              | Visualize the prediction result in a window.                                                                                                                        |\n| `--interval INTERVAL`                 | The interval of samples to visualize.                                                                                                                               |\n| `--wait-time WAIT_TIME`               | The display time of every window (in seconds). Defaults to 1.                                                                                                       |\n| `--launcher {none,pytorch,slurm,mpi}` | Options for job launcher.                                                                                                                                           |\n\n### Test with multiple GPUs\n\nWe provide a shell script to start a multi-GPUs task with `torch.distributed.launch`.\n\n```shell\nbash ./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\n| ARGS              | Description                                                                                                                                           |\n| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG_FILE`     | The path to the config file.                                                                                                                          |\n| `CHECKPOINT_FILE` | The path to the checkpoint file (It can be a http link, and you can find checkpoints [here](https://mmpose.readthedocs.io/en/latest/model_zoo.html)). |\n| `GPU_NUM`         | The number of GPUs to be used.                                                                                                                        |\n| `[PYARGS]`        | The other optional arguments of `tools/test.py`, see [here](#test-with-your-pc).                                                                      |\n\nYou can also specify extra arguments of the launcher by environment variables. For example, change the\ncommunication port of the launcher to 29666 by the below command:\n\n```shell\nPORT=29666 bash ./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\nIf you want to startup multiple test jobs and use different GPUs, you can launch them by specifying\ndifferent port and visible devices.\n\n```shell\nCUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 bash ./tools/dist_test.sh ${CONFIG_FILE1} ${CHECKPOINT_FILE} 4 [PY_ARGS]\nCUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 bash ./tools/dist_test.sh ${CONFIG_FILE2} ${CHECKPOINT_FILE} 4 [PY_ARGS]\n```\n\n### Test with multiple machines\n\n#### Multiple machines in the same network\n\nIf you launch a test job with multiple machines connected with ethernet, you can run the following commands:\n\nOn the first machine:\n\n```shell\nNNODES=2 NODE_RANK=0 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_test.sh $CONFIG $CHECKPOINT_FILE $GPUS\n```\n\nOn the second machine:\n\n```shell\nNNODES=2 NODE_RANK=1 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_test.sh $CONFIG $CHECKPOINT_FILE $GPUS\n```\n\nCompared with multi-GPUs in a single machine, you need to specify some extra environment variables:\n\n| ENV_VARS      | Description                                                                  |\n| ------------- | ---------------------------------------------------------------------------- |\n| `NNODES`      | The total number of machines.                                                |\n| `NODE_RANK`   | The index of the local machine.                                              |\n| `PORT`        | The communication port, it should be the same in all machines.               |\n| `MASTER_ADDR` | The IP address of the master machine, it should be the same in all machines. |\n\nUsually, it is slow if you do not have high-speed networking like InfiniBand.\n\n#### Multiple machines managed with slurm\n\nIf you run MMPose on a cluster managed with [slurm](https://slurm.schedmd.com/), you can use the script `slurm_test.sh`.\n\n```shell\n[ENV_VARS] ./tools/slurm_test.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${CHECKPOINT_FILE} [PY_ARGS]\n```\n\nHere are the argument descriptions of the script.\n\n| ARGS              | Description                                                                                                                                           |\n| ----------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `PARTITION`       | The partition to use in your cluster.                                                                                                                 |\n| `JOB_NAME`        | The name of your job, you can name it as you like.                                                                                                    |\n| `CONFIG_FILE`     | The path to the config file.                                                                                                                          |\n| `CHECKPOINT_FILE` | The path to the checkpoint file (It can be a http link, and you can find checkpoints [here](https://MMPose.readthedocs.io/en/latest/model_zoo.html)). |\n| `[PYARGS]`        | The other optional arguments of `tools/test.py`, see [here](#test-with-your-pc).                                                                      |\n\nHere are the environment variables that can be used to configure the slurm job.\n\n| ENV_VARS        | Description                                                                                                |\n| --------------- | ---------------------------------------------------------------------------------------------------------- |\n| `GPUS`          | The total number of GPUs to be used. Defaults to 8.                                                        |\n| `GPUS_PER_NODE` | The number of GPUs to be allocated per node. Defaults to 8.                                                |\n| `CPUS_PER_TASK` | The number of CPUs to be allocated per task (Usually one GPU corresponds to one task). Defaults to 5.      |\n| `SRUN_ARGS`     | The other arguments of `srun`. Available options can be found [here](https://slurm.schedmd.com/srun.html). |\n\n## Custom Testing Features\n\n### Test with Custom Metrics\n\nIf you're looking to assess models using unique metrics not already supported by MMPose, you'll need to code these metrics yourself and include them in your config file. For guidance on how to accomplish this, check out our [customized evaluation guide](https://mmpose.readthedocs.io/en/latest/advanced_guides/customize_evaluation.html).\n\n### Evaluating Across Multiple Datasets\n\nMMPose offers a handy tool known as `MultiDatasetEvaluator` for streamlined assessment across multiple datasets. Setting up this evaluator in your config file is a breeze. Below is a quick example demonstrating how to evaluate a model using both the COCO and AIC datasets:\n\n```python\n# Set up validation datasets\ncoco_val = dict(type='CocoDataset', ...)\naic_val = dict(type='AicDataset', ...)\nval_dataset = dict(\n        type='CombinedDataset',\n        datasets=[coco_val, aic_val],\n        pipeline=val_pipeline,\n        ...)\n\n# configurate the evaluator\nval_evaluator = dict(\n    type='MultiDatasetEvaluator',\n    metrics=[  # metrics for each dataset\n        dict(type='CocoMetric',\n             ann_file='data/coco/annotations/person_keypoints_val2017.json'),\n        dict(type='CocoMetric',\n            ann_file='data/aic/annotations/aic_val.json',\n            use_area=False,\n            prefix='aic')\n    ],\n    # the number and order of datasets must align with metrics\n    datasets=[coco_val, aic_val],\n    )\n```\n\nKeep in mind that different datasets, like COCO and AIC, have various keypoint definitions. Yet, the model's output keypoints are standardized. This results in a discrepancy between the model outputs and the actual ground truth. To address this, you can employ `KeypointConverter` to align the keypoint configurations between different datasets. Here’s a full example that shows how to leverage `KeypointConverter` to align AIC keypoints with COCO keypoints:\n\n```python\naic_to_coco_converter = dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n\n# val datasets\ncoco_val = dict(\n    type='CocoDataset',\n    data_root='data/coco/',\n    data_mode='topdown',\n    ann_file='annotations/person_keypoints_val2017.json',\n    bbox_file='data/coco/person_detection_results/'\n    'COCO_val2017_detections_AP_H_56_person.json',\n    data_prefix=dict(img='val2017/'),\n    test_mode=True,\n    pipeline=[],\n)\n\naic_val = dict(\n        type='AicDataset',\n        data_root='data/aic/',\n        data_mode=data_mode,\n        ann_file='annotations/aic_val.json',\n        data_prefix=dict(img='ai_challenger_keypoint_validation_20170911/'\n                         'keypoint_validation_images_20170911/'),\n        test_mode=True,\n        pipeline=[],\n    )\n\nval_dataset = dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[coco_val, aic_val],\n        pipeline=val_pipeline,\n        test_mode=True,\n    )\n\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=val_dataset)\n\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='MultiDatasetEvaluator',\n    metrics=[\n        dict(type='CocoMetric',\n             ann_file=data_root + 'annotations/person_keypoints_val2017.json'),\n        dict(type='CocoMetric',\n            ann_file='data/aic/annotations/aic_val.json',\n            use_area=False,\n            gt_converter=aic_to_coco_converter,\n            prefix='aic')\n    ],\n    datasets=val_dataset['datasets'],\n    )\n\ntest_evaluator = val_evaluator\n```\n\nFor further clarification on converting AIC keypoints to COCO keypoints, please consult [this guide](https://mmpose.readthedocs.io/en/latest/user_guides/mixed_datasets.html#merge-aic-into-coco).\n\n### Evaluating Top-down Models with Custom Detector\n\nTo evaluate top-down models, you can use either ground truth or pre-detected bounding boxes. The `bbox_file` provides these boxes, generated by a specific detector. For instance, `COCO_val2017_detections_AP_H_56_person.json` contains bounding boxes for the COCO val2017 dataset, generated using a detector with a human AP of 56.4. To create your own `bbox_file` using a custom detector supported by MMDetection, run the following command:\n\n```sh\npython tools/misc/generate_bbox_file.py \\\n    ${DET_CONFIG} ${DET_WEIGHT} ${OUTPUT_FILE_NAME} \\\n    [--pose-config ${POSE_CONFIG}] \\\n    [--score-thr ${SCORE_THRESHOLD}] [--nms-thr ${NMS_THRESHOLD}]\n```\n\nHere, the `DET_CONFIG` and `DET_WEIGHT` initialize the detector. `POSE_CONFIG` specifies the test dataset requiring bounding box detection, while  `SCORE_THRESHOLD` and `NMS_THRESHOLD` arguments are used for bounding box filtering.\n"
  },
  {
    "path": "docs/en/visualization.md",
    "content": "# Visualization\n\n- [Single Image](#single-image)\n- [Browse Dataset](#browse-dataset)\n- [Visualizer Hook](#visualizer-hook)\n\n## Single Image\n\n`demo/image_demo.py` helps the user to visualize the prediction result of a single image, including the skeleton and heatmaps.\n\n```shell\npython demo/image_demo.py ${IMG} ${CONFIG} ${CHECKPOINT} [-h] [--out-file OUT_FILE] [--device DEVICE] [--draw-heatmap]\n```\n\n| ARGS                  | Description                      |\n| --------------------- | -------------------------------- |\n| `IMG`                 | The path to the test image.      |\n| `CONFIG`              | The path to the config file.     |\n| `CHECKPOINT`          | The path to the checkpoint file. |\n| `--out-file OUT_FILE` | Path to output file.             |\n| `--device DEVICE`     | Device used for inference.       |\n| `--draw-heatmap`      | Visualize the predicted heatmap. |\n\nHere is an example of Heatmap visualization:\n\n![000000196141](https://user-images.githubusercontent.com/13503330/222373580-88d93603-e00e-45e9-abdd-f504a62b4ca5.jpg)\n\n## Browse Dataset\n\n`tools/analysis_tools/browse_dataset.py` helps the user to browse a pose dataset visually, or save the image to a designated directory.\n\n```shell\npython tools/misc/browse_dataset.py ${CONFIG} [-h] [--output-dir ${OUTPUT_DIR}] [--not-show] [--phase ${PHASE}] [--mode ${MODE}] [--show-interval ${SHOW_INTERVAL}]\n```\n\n| ARGS                             | Description                                                                                                                                          |\n| -------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG`                         | The path to the config file.                                                                                                                         |\n| `--output-dir OUTPUT_DIR`        | The target folder to save visualization results. If not specified, the visualization results will not be saved.                                      |\n| `--not-show`                     | Do not show the visualization results in an external window.                                                                                         |\n| `--phase {train, val, test}`     | Options for dataset.                                                                                                                                 |\n| `--mode {original, transformed}` | Specify the type of visualized images. `original` means to show images without pre-processing; `transformed` means to show images are pre-processed. |\n| `--show-interval SHOW_INTERVAL`  | Time interval between visualizing two images.                                                                                                        |\n\nFor instance, users who want to visualize images and annotations in COCO dataset use:\n\n```shell\npython tools/misc/browse_dataset.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-e210_coco-256x192.py --mode original\n```\n\nThe bounding boxes and keypoints will be plotted on the original image. Following is an example:\n![original_coco](https://user-images.githubusercontent.com/26127467/187383698-7e518f21-b4cc-4712-9e97-99ddd8f0e437.jpg)\n\nThe original images need to be processed before being fed into models. To visualize pre-processed images and annotations, users need to modify the argument `mode`  to `transformed`. For example:\n\n```shell\npython tools/misc/browse_dataset.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-e210_coco-256x192.py --mode transformed\n```\n\nHere is a processed sample\n\n![transformed_coco](https://user-images.githubusercontent.com/26127467/187386652-bd47335d-797c-4e8c-b823-2a4915f9812f.jpg)\n\nThe heatmap target will be visualized together if it is generated in the pipeline.\n\n## Visualizer Hook\n\nDuring validation and testing, users can specify certain arguments to visualize the output of trained models.\n\nTo visualize in external window during testing:\n\n```shell\npython tools/test.py ${CONFIG} ${CHECKPOINT} --show\n```\n\nDuring validation:\n\n```shell\npython tools/train.py ${CONFIG} --work-dir ${WORK_DIR} --show --interval ${INTERVAL}\n```\n\nIt is suggested to use large `INTERVAL` (e.g., 50) if users want to visualize during validation, since the wait time for each visualized instance will make the validation process very slow.\n\nTo save visualization results in `SHOW_DIR` during testing:\n\n```shell\npython tools/test.py ${CONFIG} ${CHECKPOINT} --show-dir=${SHOW_DIR}\n```\n\nDuring validation:\n\n```shell\npython tools/train.py ${CONFIG} --work-dir ${WORK_DIR} --show-dir=${SHOW_DIR}\n```\n\nMore details about visualization arguments can be found in [train_and_test](./train_and_test.md).\n\nIf you use a heatmap-based method and want to visualize predicted heatmaps, you can manually specify `output_heatmaps=True` for `model.test_cfg` in config file. Another way is to add `--cfg-options='model.test_cfg.output_heatmaps=True'` at the end of your command.\n\nVisualization example (top: decoded keypoints; bottom: predicted heatmap):\n![vis_pred](https://user-images.githubusercontent.com/26127467/187578902-30ef7bb0-9a93-4e03-bae0-02aeccf7f689.jpg)\n\nFor top-down models, each sample only contains one instance. So there will be multiple visualization results for each image.\n"
  },
  {
    "path": "docs/src/papers/algorithms/associative_embedding.md",
    "content": "# Associative embedding: End-to-end learning for joint detection and grouping (AE)\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1611.05424\">Associative Embedding (NIPS'2017)</a></summary>\n\n```bibtex\n@inproceedings{newell2017associative,\n  title={Associative embedding: End-to-end learning for joint detection and grouping},\n  author={Newell, Alejandro and Huang, Zhiao and Deng, Jia},\n  booktitle={Advances in neural information processing systems},\n  pages={2277--2287},\n  year={2017}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe introduce associative embedding, a novel method for supervising convolutional neural networks for the task of detection and grouping. A number of computer vision problems can be framed in this manner including multi-person pose estimation, instance segmentation, and multi-object tracking. Usually the grouping of detections is achieved with multi-stage pipelines, instead we propose an approach that teaches a network to simultaneously output detections and group assignments. This technique can be easily integrated into any state-of-the-art network architecture that produces pixel-wise predictions. We show how to apply this method to both multi-person pose estimation and instance segmentation and report state-of-the-art performance for multi-person pose on the MPII and MS-COCO datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146514181-84f22623-6b73-4656-89b8-9e7f551e9cc0.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/awingloss.md",
    "content": "# Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/1904.07399.pdf\">AdaptiveWingloss (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{wang2019adaptive,\n  title={Adaptive wing loss for robust face alignment via heatmap regression},\n  author={Wang, Xinyao and Bo, Liefeng and Fuxin, Li},\n  booktitle={Proceedings of the IEEE/CVF international conference on computer vision},\n  pages={6971--6981},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHeatmap regression with a deep network has become one of the mainstream approaches to localize facial landmarks. However, the loss function for heatmap regression is rarely studied. In this paper, we analyze the ideal loss function properties for heatmap regression in face alignment problems. Then we propose a novel loss function, named Adaptive Wing loss, that is able to adapt its shape to different types of ground truth heatmap pixels. This adaptability penalizes loss more on foreground pixels while less on background pixels. To address the imbalance between foreground and background pixels, we also propose Weighted Loss Map, which assigns high weights on foreground and difficult background pixels to help training process focus more on pixels that are crucial to landmark localization. To further improve face alignment accuracy, we introduce boundary prediction and CoordConv with boundary coordinates. Extensive experiments on different benchmarks, including COFW, 300W and WFLW, show our approach outperforms the state-of-the-art by a significant margin on\nvarious evaluation metrics. Besides, the Adaptive Wing loss also helps other heatmap regression tasks.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/148007960-a06a34d8-8090-49e1-80db-6bbe4a7e7e8d.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/cid.md",
    "content": "# Contextual Instance Decoupling for Robust Multi-Person Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/CVPR2022/html/Wang_Contextual_Instance_Decoupling_for_Robust_Multi-Person_Pose_Estimation_CVPR_2022_paper.html\">CID (CVPR'2022)</a></summary>\n\n```bibtex\n@InProceedings{Wang_2022_CVPR,\n    author    = {Wang, Dongkai and Zhang, Shiliang},\n    title     = {Contextual Instance Decoupling for Robust Multi-Person Pose Estimation},\n    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n    month     = {June},\n    year      = {2022},\n    pages     = {11060-11068}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nCrowded scenes make it challenging to differentiate persons and locate their pose keypoints. This paper proposes the Contextual Instance Decoupling (CID), which presents a new pipeline for multi-person pose estimation. Instead of relying on person bounding boxes to spatially differentiate persons, CID decouples persons in an image into multiple instance-aware feature maps. Each of those feature maps is hence adopted to infer keypoints for a specific person. Compared with bounding box detection, CID is differentiable and robust to detection errors. Decoupling persons into different feature maps allows to isolate distractions from other persons, and explore context cues at scales larger than the bounding box size. Experiments show that CID outperforms previous multi-person pose estimation pipelines on crowded scenes pose estimation benchmarks in both accuracy and efficiency. For instance, it achieves 71.3% AP on CrowdPose, outperforming the recent single-stage DEKR by 5.6%, the bottom-up CenterAttention by 3.7%, and the top-down JCSPPE by 5.3%. This advantage sustains on the commonly used COCO benchmark.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://github.com/kennethwdk/CID/raw/main/img/framework.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/cpm.md",
    "content": "# Convolutional pose machines\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Wei_Convolutional_Pose_Machines_CVPR_2016_paper.html\">CPM (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{wei2016convolutional,\n  title={Convolutional pose machines},\n  author={Wei, Shih-En and Ramakrishna, Varun and Kanade, Takeo and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={4724--4732},\n  year={2016}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe introduce associative embedding, a novel method for supervising convolutional neural networks for the task of detection and grouping. A number of computer vision problems can be framed in this manner including multi-person pose estimation, instance segmentation, and multi-object tracking. Usually the grouping of detections is achieved with multi-stage pipelines, instead we propose an approach that teaches a network to simultaneously output detections and group assignments. This technique can be easily integrated into any state-of-the-art network architecture that produces pixel-wise predictions. We show how to apply this method to both multi-person pose estimation and instance segmentation and report state-of-the-art performance for multi-person pose on the MPII and MS-COCO datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146514331-a599580b-69a5-4ee4-9aaf-4a72f9c25c9a.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/dark.md",
    "content": "# Distribution-aware coordinate representation for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWhile being the de facto standard coordinate representation for human pose estimation, heatmap has not been investigated in-depth. This work fills this gap. For the first time, we find that the process of decoding the predicted heatmaps into the final joint coordinates in the original image space is surprisingly significant for the performance. We further probe the design limitations of the standard coordinate decoding method, and propose a more principled distributionaware decoding method. Also, we improve the standard coordinate encoding process (i.e. transforming ground-truth coordinates to heatmaps) by generating unbiased/accurate heatmaps. Taking the two together, we formulate a novel Distribution-Aware coordinate Representation of Keypoints (DARK) method. Serving as a model-agnostic plug-in, DARK brings about significant performance boost to existing human pose estimation models. Extensive experiments show that DARK yields the best results on two common benchmarks, MPII and COCO. Besides, DARK achieves the 2nd place entry in the ICCV 2019 COCO Keypoints Challenge. The code is available online.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146514732-1d53614b-e5b7-4a1c-a39f-6fc726217d81.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/debias_ipr.md",
    "content": "# Removing the Bias of Integral Pose Regression\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/ICCV2021/papers/Gu_Removing_the_Bias_of_Integral_Pose_Regression_ICCV_2021_paper.pdf\">Debias IPR (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{gu2021removing,\n    title={Removing the Bias of Integral Pose Regression},\n    author={Gu, Kerui and Yang, Linlin and Yao, Angela},\n    booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n    pages={11067--11076},\n    year={2021}\n  }\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHeatmap-based detection methods are dominant for 2D human pose estimation even though regression is more intuitive. The introduction of the integral regression method, which, architecture-wise uses an implicit heatmap, brings the two approaches even closer together. This begs the question -- does detection really outperform regression? In this paper, we investigate the difference in supervision between the heatmap-based detection and integral regression, as this is the key remaining difference between the two approaches. In the process, we discover an underlying bias behind integral pose regression that arises from taking the expectation after the softmax function. To counter the bias, we present a compensation method which we find to improve integral regression accuracy on all 2D pose estimation benchmarks. We further propose a simple combined detection and bias-compensated regression method that considerably outperforms state-of-the-art baselines with few added components.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/189810184-159432bb-32a1-403c-8150-e90edce1a5bb.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/deeppose.md",
    "content": "# DeepPose: Human pose estimation via deep neural networks\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Toshev_DeepPose_Human_Pose_2014_CVPR_paper.html\">DeepPose (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{toshev2014deeppose,\n  title={Deeppose: Human pose estimation via deep neural networks},\n  author={Toshev, Alexander and Szegedy, Christian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1653--1660},\n  year={2014}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe propose a method for human pose estimation based on Deep Neural Networks (DNNs). The pose estimation is formulated as a DNN-based regression problem towards body joints. We present a cascade of such DNN regressors which results in high precision pose estimates. The approach has the advantage of reasoning about pose in a holistic fashion and has a simple but yet powerful formulation which capitalizes on recent advances in Deep Learning. We present a detailed empirical analysis with state-of-art or better performance on four academic benchmarks of diverse real-world images.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515040-a82a8a29-d6bc-42f1-a2ab-7dfa610ce363.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/dekr.md",
    "content": "# Bottom-up Human Pose Estimation via Disentangled Keypoint Regression\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.02300\">DEKR (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{geng2021bottom,\n  title={Bottom-up human pose estimation via disentangled keypoint regression},\n  author={Geng, Zigang and Sun, Ke and Xiao, Bin and Zhang, Zhaoxiang and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={14676--14686},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we are interested in the bottom-up paradigm of estimating human poses from an image. We study the dense keypoint regression framework that is previously inferior to the keypoint detection and grouping framework. Our motivation is that regressing keypoint positions accurately needs to learn representations that focus on the keypoint regions.\nWe present a simple yet effective approach, named disentangled keypoint regression (DEKR). We adopt adaptive convolutions through pixel-wise spatial transformer to activate the pixels in the keypoint regions and accordingly learn representations from them. We use a multi-branch structure for separate regression: each branch learns a representation with dedicated adaptive convolutions and regresses one keypoint. The resulting disentangled representations are able to attend to the keypoint regions, respectively, and thus the keypoint regression is spatially more accurate. We empirically show that the proposed direct regression method outperforms keypoint detection and grouping methods and achieves superior bottom-up pose estimation results on two benchmark datasets, COCO and CrowdPose. The code and models are available at [this https URL](https://github.com/HRNet/DEKR).\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/26127467/192512411-1f8e66c1-4ba2-4db6-a66a-31c0f7c13882.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/dsnt.md",
    "content": "# Numerical Coordinate Regression with Convolutional Neural Networks\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1801.07372v2\">DSNT (2018)</a></summary>\n\n```bibtex\n@article{nibali2018numerical,\n  title={Numerical Coordinate Regression with Convolutional Neural Networks},\n  author={Nibali, Aiden and He, Zhen and Morgan, Stuart and Prendergast, Luke},\n  journal={arXiv preprint arXiv:1801.07372},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe study deep learning approaches to inferring numerical coordinates for points of interest in an input image. Existing convolutional neural network-based solutions to this problem either take a heatmap matching approach or regress to coordinates with a fully connected output layer. Neither of these approaches is ideal, since the former is not entirely differentiable, and the latter lacks inherent spatial generalization. We propose our differentiable spatial to numerical transform (DSNT) to fill this gap. The DSNT layer adds no trainable parameters, is fully differentiable, and exhibits good spatial generalization. Unlike heatmap matching, DSNT works well with low heatmap resolutions, so it can be dropped in as an output layer for a wide range of existing fully convolutional architectures. Consequently, DSNT offers a better trade-off between inference speed and prediction accuracy compared to existing techniques. When used to replace the popular heatmap matching approach used in almost all state-of-the-art methods for pose estimation, DSNT gives better prediction accuracy for all model architectures tested.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/189809838-1f313583-e73b-4843-b396-70b4c979ea77.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/dwpose.md",
    "content": "# Effective Whole-body Pose Estimation with Two-stages Distillation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2307.15880\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@article{yang2023effective,\n  title={Effective Whole-body Pose Estimation with Two-stages Distillation},\n  author={Yang, Zhendong and Zeng, Ailing and Yuan, Chun and Li, Yu},\n  journal={arXiv preprint arXiv:2307.15880},\n  year={2023}\n}\n\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWhole-body pose estimation localizes the human body, hand, face, and foot keypoints in an image. This task is challenging due to multi-scale body parts, fine-grained localization for low-resolution regions, and data scarcity. Meanwhile, applying a highly efficient and accurate pose estimator to widely human-centric understanding and generation tasks is urgent. In this work, we present a two-stage pose **D**istillation for **W**hole-body **P**ose estimators, named **DWPose**, to improve their effectiveness and efficiency. The first-stage distillation designs a weight-decay strategy while utilizing a teacher's intermediate feature and final logits with both visible and invisible keypoints to supervise the student from scratch. The second stage distills the student model itself to further improve performance. Different from the previous self-knowledge distillation, this stage finetunes the student's head with only 20% training time as a plug-and-play training strategy. For data limitations, we explore the UBody dataset that contains diverse facial expressions and hand gestures for real-life applications. Comprehensive experiments show the superiority of our proposed simple yet effective methods. We achieve new state-of-the-art performance on COCO-WholeBody, significantly boosting the whole-body AP of RTMPose-l from 64.8% to 66.5%, even surpassing RTMPose-x teacher with 65.3% AP. We release a series of models with different sizes, from tiny to large, for satisfying various downstream tasks. Our code and models are available at https://github.com/IDEA-Research/DWPose.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/54797851/262253853-5f820730-260b-4685-b6c0-1a9257fb6265.jpg\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/edpose.md",
    "content": "# Explicit Box Detection Unifies End-to-End Multi-Person Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/2302.01593.pdf\">ED-Pose (ICLR'2023)</a></summary>\n\n```bibtex\n@inproceedings{\nyang2023explicit,\ntitle={Explicit Box Detection Unifies End-to-End Multi-Person Pose Estimation},\nauthor={Jie Yang and Ailing Zeng and Shilong Liu and Feng Li and Ruimao Zhang and Lei Zhang},\nbooktitle={International Conference on Learning Representations},\nyear={2023},\nurl={https://openreview.net/forum?id=s4WVupnJjmX}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nThis paper presents a novel end-to-end framework with Explicit box Detection for multi-person Pose estimation, called ED-Pose, where it unifies the contextual learning between human-level (global) and keypoint-level (local) information. Different from previous one-stage methods, ED-Pose re-considers this task as two explicit box detection processes with a unified representation and regression supervision. First, we introduce a human detection decoder from encoded tokens to extract global features. It can provide a good initialization for the latter keypoint detection, making the training process converge fast. Second, to bring in contextual information near keypoints, we regard pose estimation as a keypoint box detection problem to learn both box positions and contents for each keypoint. A human-to-keypoint detection decoder adopts an interactive learning strategy between human and keypoint features to further enhance global and local feature aggregation. In general, ED-Pose is conceptually simple without post-processing and dense heatmap supervision. It demonstrates its effectiveness and efficiency compared with both two-stage and one-stage methods. Notably, explicit box detection boosts the pose estimation performance by 4.5 AP on COCO and 9.9 AP on CrowdPose. For the first time, as a fully end-to-end framework with a L1 regression loss, ED-Pose surpasses heatmap-based Top-down methods under the same backbone by 1.2 AP on COCO and achieves the state-of-the-art with 76.6 AP on CrowdPose without bells and whistles. Code is available at https://github.com/IDEA-Research/ED-Pose.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://github.com/IDEA-Research/ED-Pose/raw/master/figs/edpose_git.jpg\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/higherhrnet.md",
    "content": "# HigherHRNet: Scale-Aware Representation Learning for Bottom-Up Human Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Cheng_HigherHRNet_Scale-Aware_Representation_Learning_for_Bottom-Up_Human_Pose_Estimation_CVPR_2020_paper.html\">HigherHRNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{cheng2020higherhrnet,\n  title={HigherHRNet: Scale-Aware Representation Learning for Bottom-Up Human Pose Estimation},\n  author={Cheng, Bowen and Xiao, Bin and Wang, Jingdong and Shi, Honghui and Huang, Thomas S and Zhang, Lei},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={5386--5395},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nBottom-up human pose estimation methods have difficulties in predicting the correct pose for small persons due to challenges in scale variation. In this paper, we present HigherHRNet: a novel bottom-up human pose estimation method for learning scale-aware representations using high-resolution feature pyramids. Equipped with multi-resolution supervision for training and multi-resolution aggregation for inference, the proposed approach is able to solve the scale variation challenge in bottom-up multi-person pose estimation and localize keypoints more precisely, especially for small person. The feature pyramid in HigherHRNet consists of feature map outputs from HRNet and upsampled higher-resolution outputs through a transposed convolution. HigherHRNet outperforms the previous best bottom-up method by 2.5% AP for medium person on COCO test-dev, showing its effectiveness in handling scale variation. Furthermore, HigherHRNet achieves new state-of-the-art result on COCO test-dev (70.5% AP) without using refinement or other post-processing techniques, surpassing all existing bottom-up methods. HigherHRNet even surpasses all top-down methods on CrowdPose test (67.6% AP), suggesting its robustness in crowded scene.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515482-975050d6-57da-469a-8dda-201675a404e7.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/hmr.md",
    "content": "# End-to-end Recovery of Human Shape and Pose\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Kanazawa_End-to-End_Recovery_of_CVPR_2018_paper.html\">HMR (CVPR'2018)</a></summary>\n\n```bibtex\n@inProceedings{kanazawaHMR18,\n  title={End-to-end Recovery of Human Shape and Pose},\n  author = {Angjoo Kanazawa\n  and Michael J. Black\n  and David W. Jacobs\n  and Jitendra Malik},\n  booktitle={Computer Vision and Pattern Recognition (CVPR)},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe describe Human Mesh Recovery (HMR), an end-to-end framework for reconstructing a full 3D mesh of a human body from a single RGB image. In contrast to most current methods that compute 2D or 3D joint locations, we produce a richer and more useful mesh representation that is parameterized by shape and 3D joint angles. The main objective is to minimize the reprojection loss of keypoints, which allows our model to be trained using in-the-wild images that only have ground truth 2D annotations. However, the reprojection loss alone is highly underconstrained. In this work we address this problem by introducing an adversary trained to tell whether human body shape and pose are real or not using a large database of 3D human meshes. We show that HMR can be trained with and without using any paired 2D-to-3D supervision. We do not rely on intermediate 2D keypoint detections and infer 3D pose and shape parameters directly from image pixels. Our model runs in real-time given a bounding box containing the person. We demonstrate our approach on various images in-the-wild and out-perform previous optimization-based methods that output 3D meshes and show competitive results on tasks such as 3D joint location estimation and part segmentation.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515822-a271ec4d-4045-4456-a7cb-740018317053.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/hourglass.md",
    "content": "# Stacked hourglass networks for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\">Hourglass (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{newell2016stacked,\n  title={Stacked hourglass networks for human pose estimation},\n  author={Newell, Alejandro and Yang, Kaiyu and Deng, Jia},\n  booktitle={European conference on computer vision},\n  pages={483--499},\n  year={2016},\n  organization={Springer}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nThis work introduces a novel convolutional network architecture for the task of human pose estimation. Features are processed across all scales and consolidated to best capture the various spatial relationships associated with the body. We show how repeated bottom-up, top-down processing used in conjunction with intermediate supervision is critical to improving the performance of the network. We refer to the architecture as a \"stacked hourglass\" network based on the successive steps of pooling and upsampling that are done to produce a final set of predictions. State-of-the-art results are achieved on the FLIC and MPII benchmarks outcompeting all recent methods.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146516901-cee086aa-6b7c-4f79-82bd-1168f03ea63b.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/hrnet.md",
    "content": "# Deep high-resolution representation learning for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we are interested in the human pose estimation problem with a focus on learning reliable highresolution representations. Most existing methods recover high-resolution representations from low-resolution representations produced by a high-to-low resolution network. Instead, our proposed network maintains high-resolution representations through the whole process. We start from a high-resolution subnetwork as the first stage, gradually add high-to-low resolution subnetworks one by one to form more stages, and connect the mutliresolution subnetworks in parallel. We conduct repeated multi-scale fusions such that each of the high-to-low resolution representations receives information from other parallel representations over and over, leading to rich highresolution representations. As a result, the predicted keypoint heatmap is potentially more accurate and spatially more precise. We empirically demonstrate the effectiveness\nof our network through the superior pose estimation results over two benchmark datasets: the COCO keypoint detection\ndataset and the MPII Human Pose dataset. In addition, we show the superiority of our network in pose tracking on the PoseTrack dataset.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146518010-9c1d6078-dd9c-4610-94a9-cbcb60aa87c0.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/hrnetv2.md",
    "content": "# Deep high-resolution representation learning for visual recognition\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHigh-resolution representations are essential for position-sensitive vision problems, such as human pose estimation, semantic segmentation, and object detection. Existing state-of-the-art frameworks first encode the input image as a low-resolution representation through a subnetwork that is formed by connecting high-to-low resolution convolutions in series (e.g., ResNet, VGGNet), and then recover the high-resolution representation from the encoded low-resolution representation. Instead, our proposed network, named as High-Resolution Network (HRNet), maintains high-resolution representations through the whole process. There are two key characteristics: (i) Connect the high-to-low resolution convolution streams in parallel and (ii) repeatedly exchange the information across resolutions. The benefit is that the resulting representation is semantically richer and spatially more precise. We show the superiority of the proposed HRNet in a wide range of applications, including human pose estimation, semantic segmentation, and object detection, suggesting that the HRNet is a stronger backbone for computer vision problems.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146519239-b3416e9a-0f3a-493a-9cc5-2d257b7fae01.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/internet.md",
    "content": "# InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterNet (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nAnalysis of hand-hand interactions is a crucial step towards better understanding human behavior. However, most researches in 3D hand pose estimation have focused on the isolated single hand case. Therefore, we firstly propose (1) a large-scale dataset, InterHand2.6M, and (2) a baseline network, InterNet, for 3D interacting hand pose estimation from a single RGB image. The proposed InterHand2.6M consists of 2.6 M labeled single and interacting hand frames under various poses from multiple subjects. Our InterNet simultaneously performs 3D single and interacting hand pose estimation. In our experiments, we demonstrate big gains in 3D interacting hand pose estimation accuracy when leveraging the interacting hand data in InterHand2.6M. We also report the accuracy of InterNet on InterHand2.6M, which serves as a strong baseline for this new dataset. Finally, we show 3D interacting hand pose estimation results from general images.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146519040-dfd5662d-a769-4e63-bff8-cd70877e1acb.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/ipr.md",
    "content": "# Integral Human Pose Regression\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.08229\">IPR (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{sun2018integral,\n  title={Integral human pose regression},\n  author={Sun, Xiao and Xiao, Bin and Wei, Fangyin and Liang, Shuang and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={529--545},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nState-of-the-art human pose estimation methods are based on heat map representation. In spite of the good performance, the representation has a few issues in nature, such as not differentiable and quantization error. This work shows that a simple integral operation relates and unifies the heat map representation and joint regression, thus avoiding the above issues. It is differentiable, efficient, and compatible with any heat map based methods. Its effectiveness is convincingly validated via comprehensive ablation experiments under various settings, specifically on 3D pose estimation, for the first time.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/189809459-026c7a9b-2260-4676-bc64-de92ce8784ce.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/litehrnet.md",
    "content": "# Lite-HRNet: A Lightweight High-Resolution Network\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.06403\">LiteHRNet (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{Yulitehrnet21,\n  title={Lite-HRNet: A Lightweight High-Resolution Network},\n  author={Yu, Changqian and Xiao, Bin and Gao, Changxin and Yuan, Lu and Zhang, Lei and Sang, Nong and Wang, Jingdong},\n  booktitle={CVPR},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present an efficient high-resolution network, Lite-HRNet, for human pose estimation. We start by simply applying the efficient shuffle block in ShuffleNet to HRNet (high-resolution network), yielding stronger performance over popular lightweight networks, such as MobileNet, ShuffleNet, and Small HRNet.\nWe find that the heavily-used pointwise (1x1) convolutions in shuffle blocks become the computational bottleneck. We introduce a lightweight unit, conditional channel weighting, to replace costly pointwise (1x1) convolutions in shuffle blocks. The complexity of channel weighting is linear w.r.t the number of channels and lower than the quadratic time complexity for pointwise convolutions. Our solution learns the weights from all the channels and over multiple resolutions that are readily available in the parallel branches in HRNet. It uses the weights as the bridge to exchange information across channels and resolutions, compensating the role played by the pointwise (1x1) convolution. Lite-HRNet demonstrates superior results on human pose estimation over popular lightweight networks. Moreover, Lite-HRNet can be easily applied to semantic segmentation task in the same lightweight manner.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146520579-3e86e3af-a8b2-4071-94da-916e0ce90464.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/motionbert.md",
    "content": "# MotionBERT: Unified Pretraining for Human Motion Analysis\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2210.06551\">MotionBERT (ICCV'2023)</a></summary>\n\n```bibtex\n @misc{Zhu_Ma_Liu_Liu_Wu_Wang_2022,\n title={Learning Human Motion Representations: A Unified Perspective},\n author={Zhu, Wentao and Ma, Xiaoxuan and Liu, Zhaoyang and Liu, Libin and Wu, Wayne and Wang, Yizhou},\n year={2022},\n month={Oct},\n language={en-US}\n }\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present MotionBERT, a unified pretraining framework, to tackle different sub-tasks of human motion analysis including 3D pose estimation, skeleton-based action recognition, and mesh recovery. The proposed framework is capable of utilizing all kinds of human motion data resources, including motion capture data and in-the-wild videos. During pretraining, the pretext task requires the motion encoder to recover the underlying 3D motion from noisy partial 2D observations. The pretrained motion representation thus acquires geometric, kinematic, and physical knowledge about human motion and therefore can be easily transferred to multiple downstream tasks. We implement the motion encoder with a novel Dual-stream Spatio-temporal Transformer (DSTformer) neural network. It could capture long-range spatio-temporal relationships among the skeletal joints comprehensively and adaptively, exemplified by the lowest 3D pose estimation error so far when trained from scratch. More importantly, the proposed framework achieves state-of-the-art performance on all three downstream tasks by simply finetuning the pretrained motion encoder with 1-2 linear layers, which demonstrates the versatility of the learned motion representations.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/877d47ee-b821-476c-a805-f39ca656913c\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/mspn.md",
    "content": "# Rethinking on multi-stage networks for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1901.00148\">MSPN (ArXiv'2019)</a></summary>\n\n```bibtex\n@article{li2019rethinking,\n  title={Rethinking on Multi-Stage Networks for Human Pose Estimation},\n  author={Li, Wenbo and Wang, Zhicheng and Yin, Binyi and Peng, Qixiang and Du, Yuming and Xiao, Tianzi and Yu, Gang and Lu, Hongtao and Wei, Yichen and Sun, Jian},\n  journal={arXiv preprint arXiv:1901.00148},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nExisting pose estimation approaches fall into two categories: single-stage and multi-stage methods. While multi-stage methods are seemingly more suited for the task, their performance in current practice is not as good as single-stage methods. This work studies this issue. We argue that the current multi-stage methods' unsatisfactory performance comes from the insufficiency in various design choices. We propose several improvements, including the single-stage module design, cross stage feature aggregation, and coarse-to-fine supervision. The resulting method establishes the new state-of-the-art on both MS COCO and MPII Human Pose dataset, justifying the effectiveness of a multi-stage architecture. The source code is publicly available for further research.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146520722-74c1ef85-9fa3-4b96-8cbf-4a2c86a80adc.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/posewarper.md",
    "content": "# Learning Temporal Pose Estimation from Sparsely-Labeled Videos\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1906.04016\">PoseWarper (NeurIPS'2019)</a></summary>\n\n```bibtex\n@inproceedings{NIPS2019_gberta,\ntitle = {Learning Temporal Pose Estimation from Sparsely Labeled Videos},\nauthor = {Bertasius, Gedas and Feichtenhofer, Christoph, and Tran, Du and Shi, Jianbo, and Torresani, Lorenzo},\nbooktitle = {Advances in Neural Information Processing Systems 33},\nyear = {2019},\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nModern approaches for multi-person pose estimation in video require large amounts of dense annotations. However, labeling every frame in a video is costly and labor intensive. To reduce the need for dense annotations, we propose a PoseWarper network that leverages training videos with sparse annotations (every k frames) to learn to perform dense temporal pose propagation and estimation. Given a pair of video frames---a labeled Frame A and an unlabeled Frame B---we train our model to predict human pose in Frame A using the features from Frame B by means of deformable convolutions to implicitly learn the pose warping between A and B. We demonstrate that we can leverage our trained PoseWarper for several applications. First, at inference time we can reverse the application direction of our network in order to propagate pose information from manually annotated frames to unlabeled frames. This makes it possible to generate pose annotations for the entire video given only a few manually-labeled frames. Compared to modern label propagation methods based on optical flow, our warping mechanism is much more compact (6M vs 39M parameters), and also more accurate (88.7% mAP vs 83.8% mAP). We also show that we can improve the accuracy of a pose estimator by training it on an augmented dataset obtained by adding our propagated poses to the original manual labels. Lastly, we can use our PoseWarper to aggregate temporal pose information from neighboring frames during inference. This allows our system to achieve state-of-the-art pose detection results on the PoseTrack2017 and PoseTrack2018 datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146521380-97f7c23c-4960-454c-bd93-426a9cca175c.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/rle.md",
    "content": "# Human pose regression with residual log-likelihood estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.11291\">RLE (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{li2021human,\n  title={Human pose regression with residual log-likelihood estimation},\n  author={Li, Jiefeng and Bian, Siyuan and Zeng, Ailing and Wang, Can and Pang, Bo and Liu, Wentao and Lu, Cewu},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={11025--11034},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHeatmap-based methods dominate in the field of human pose estimation by modelling the output distribution through likelihood heatmaps. In contrast, regressionbased methods are more efficient but suffer from inferior performance. In this work, we explore maximum likelihood estimation (MLE) to develop an efficient and effective regression-based methods. From the perspective of MLE, adopting different regression losses is making different assumptions about the output density function. A density function closer to the true distribution leads to a better regression performance. In light of this, we propose a novel regression paradigm with Residual Log-likelihood Estimation (RLE) to capture the underlying output distribution. Concretely, RLE learns the change of the distribution instead of the unreferenced underlying distribution to facilitate the training process. With the proposed reparameterization design, our method is compatible with offthe-shelf flow models. The proposed method is effective, efficient and flexible. We show its potential in various human pose estimation tasks with comprehensive experiments. Compared to the conventional regression paradigm, regression with RLE bring 12.4 mAP improvement on MSCOCO without any test-time overhead. Moreover, for the first time, especially on multi-person pose estimation, our regression method is superior to the heatmap-based methods.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/166661858-e1149715-02cf-4393-b948-81c8e39f247d.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/rsn.md",
    "content": "# Learning delicate local representations for multi-person pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RSN (ECCV'2020)</a></summary>\n\n```bibtex\n@misc{cai2020learning,\n    title={Learning Delicate Local Representations for Multi-Person Pose Estimation},\n    author={Yuanhao Cai and Zhicheng Wang and Zhengxiong Luo and Binyi Yin and Angang Du and Haoqian Wang and Xinyu Zhou and Erjin Zhou and Xiangyu Zhang and Jian Sun},\n    year={2020},\n    eprint={2003.04030},\n    archivePrefix={arXiv},\n    primaryClass={cs.CV}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we propose a novel method called Residual Steps Network (RSN). RSN aggregates features with the same spatial size (Intra-level features) efficiently to obtain delicate local representations, which retain rich low-level spatial information and result in precise keypoint localization. Additionally, we observe the output features contribute differently to final performance. To tackle this problem, we propose an efficient attention mechanism - Pose Refine Machine (PRM) to make a trade-off between local and global representations in output features and further refine the keypoint locations. Our approach won the 1st place of COCO Keypoint Challenge 2019 and achieves state-of-the-art results on both COCO and MPII benchmarks, without using extra training data and pretrained model. Our single model achieves 78.6 on COCO test-dev, 93.0 on MPII test dataset. Ensembled models achieve 79.2 on COCO test-dev, 77.1 on COCO test-challenge dataset.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522226-5041d16e-41cb-4d31-ae53-dbe21314a697.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/rtmo.md",
    "content": "# RTMO: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2312.07526\">RTMO</a></summary>\n\n```bibtex\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nReal-time multi-person pose estimation presents significant challenges in balancing speed and precision. While two-stage top-down methods slow down as the number of people in the image increases, existing one-stage methods often fail to simultaneously deliver high accuracy and real-time performance. This paper introduces RTMO, a one-stage pose estimation framework that seamlessly integrates coordinate classification by representing keypoints using dual 1-D heatmaps within the YOLO architecture, achieving accuracy comparable to top-down methods while maintaining high speed. We propose a dynamic coordinate classifier and a tailored loss function for heatmap learning, specifically designed to address the incompatibilities between coordinate classification and dense prediction models. RTMO outperforms state-of-the-art one-stage pose estimators, achieving 1.1% higher AP on COCO while operating about 9 times faster with the same backbone. Our largest model, RTMO-l, attains 74.8% AP on COCO val2017 and 141 FPS on a single V100 GPU, demonstrating its efficiency and accuracy.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/ad94c097-7d51-4b91-b885-d8605e22a0e6\" height=\"360px\" alt><br>\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/rtmpose.md",
    "content": "# RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RTMPose (arXiv'2023)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency. In order to bridge this gap, we empirically explore key factors in pose estimation including paradigm, model architecture, training strategy, and deployment, and present a high-performance real-time multi-person pose estimation framework, RTMPose, based on MMPose. Our RTMPose-m achieves 75.8% AP on COCO with 90+ FPS on an Intel i7-11700 CPU and 430+ FPS on an NVIDIA GTX 1660 Ti GPU, and RTMPose-l achieves 67.0% AP on COCO-WholeBody with 130+ FPS. To further evaluate RTMPose’s capability in critical real-time applications, we also report the performance after deploying on the mobile device. Our RTMPoses achieves 72.2% AP on COCO with 70+ FPS on a Snapdragon 865 chip, outperforming existing open-source libraries. Code and models are released at https://github.com/open-mmlab/mmpose/tree/main/projects/rtmpose.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/225237680-6e3640c1-7b03-4cd9-9bb2-ca28adb8710d.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/scnet.md",
    "content": "# Improving Convolutional Networks with Self-Calibrated Convolutions\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Liu_Improving_Convolutional_Networks_With_Self-Calibrated_Convolutions_CVPR_2020_paper.html\">SCNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020improving,\n  title={Improving Convolutional Networks with Self-Calibrated Convolutions},\n  author={Liu, Jiang-Jiang and Hou, Qibin and Cheng, Ming-Ming and Wang, Changhu and Feng, Jiashi},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={10096--10105},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nRecent advances on CNNs are mostly devoted to designing more complex architectures to enhance their representation learning capacity. In this paper, we consider how to improve the basic convolutional feature transformation process of CNNs without tuning the model architectures. To this end, we present a novel self-calibrated convolutions that explicitly expand fields-of-view of each convolutional layers through internal communications and hence enrich the output features. In particular, unlike the standard convolutions that fuse spatial and channel-wise information using small kernels (e.g., 3x3), self-calibrated convolutions adaptively build long-range spatial and inter-channel dependencies around each spatial location through a novel self-calibration operation. Thus, it can help CNNs generate more discriminative representations by explicitly incorporating richer information. Our self-calibrated convolution design is simple and generic, and can be easily applied to augment standard convolutional layers without introducing extra parameters and complexity. Extensive experiments demonstrate that when applying self-calibrated convolutions into different backbones, our networks can significantly improve the baseline models in a variety of vision tasks, including image recognition, object detection, instance segmentation, and keypoint detection, with no need to change the network architectures. We hope this work could provide a promising way for future research in designing novel convolutional feature transformations for improving convolutional networks. Code is available on the project page.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522623-fdc88996-1a8f-4b0a-bdee-fc284dfd7348.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/simcc.md",
    "content": "# SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.03332\">SimCC (ECCV'2022)</a></summary>\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2107.03332,\n  title={SimCC: a Simple Coordinate Classification Perspective for Human Pose Estimation},\n  author={Li, Yanjie and Yang, Sen and Liu, Peidong and Zhang, Shoukui and Wang, Yunxiao and Wang, Zhicheng and Yang, Wankou and Xia, Shu-Tao},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nThe 2D heatmap-based approaches have dominated Human Pose Estimation (HPE) for years due to high performance. However, the long-standing quantization error problem in the 2D heatmap-based methods leads to several well-known drawbacks: 1) The performance for the low-resolution inputs is limited; 2) To improve the feature map resolution for higher localization precision, multiple costly upsampling layers are required; 3) Extra post-processing is adopted to reduce the quantization error. To address these issues, we aim to explore a brand new scheme, called \\\\textit{SimCC}, which reformulates HPE as two classification tasks for horizontal and vertical coordinates. The proposed SimCC uniformly divides each pixel into several bins, thus achieving \\\\emph{sub-pixel} localization precision and low quantization error. Benefiting from that, SimCC can omit additional refinement post-processing and exclude upsampling layers under certain settings, resulting in a more simple and effective pipeline for HPE. Extensive experiments conducted over COCO, CrowdPose, and MPII datasets show that SimCC outperforms heatmap-based counterparts, especially in low-resolution settings by a large margin.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/189811385-6395d118-055b-4bad-89e8-f84ffa2c2aa6.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/simplebaseline2d.md",
    "content": "# Simple baselines for human pose estimation and tracking\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Bin_Xiao_Simple_Baselines_for_ECCV_2018_paper.html\">SimpleBaseline2D (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{xiao2018simple,\n  title={Simple baselines for human pose estimation and tracking},\n  author={Xiao, Bin and Wu, Haiping and Wei, Yichen},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={466--481},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nThere has been significant progress on pose estimation and increasing interests on pose tracking in recent years. At the same time, the overall algorithm and system complexity increases as well, making the algorithm analysis and comparison more difficult. This work provides simple and effective baseline methods. They are helpful for inspiring and evaluating new ideas for the field. State-of-the-art results are achieved on challenging benchmarks.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522977-5f355832-e9c1-442f-a34f-9d24fb0aefa8.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/simplebaseline3d.md",
    "content": "# A simple yet effective baseline for 3d human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2017/html/Martinez_A_Simple_yet_ICCV_2017_paper.html\">SimpleBaseline3D (ICCV'2017)</a></summary>\n\n```bibtex\n@inproceedings{martinez_2017_3dbaseline,\n  title={A simple yet effective baseline for 3d human pose estimation},\n  author={Martinez, Julieta and Hossain, Rayat and Romero, Javier and Little, James J.},\n  booktitle={ICCV},\n  year={2017}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nFollowing the success of deep convolutional networks, state-of-the-art methods for 3d human pose estimation have focused on deep end-to-end systems that predict 3d joint locations given raw image pixels. Despite their excellent performance, it is often not easy to understand whether their remaining error stems from a limited 2d pose (visual) understanding, or from a failure to map 2d poses into 3-dimensional positions. With the goal of understanding these sources of error, we set out to build a system that given 2d joint locations predicts 3d positions. Much to our surprise, we have found that, with current technology, \"lifting\" ground truth 2d joint locations to 3d space is a task that can be solved with a remarkably low error rate: a relatively simple deep feed-forward network outperforms the best reported result by about 30% on Human3.6M, the largest publicly available 3d pose estimation benchmark. Furthermore, training our system on the output of an off-the-shelf state-of-the-art 2d detector (i.e., using images as input) yields state of the art results -- this includes an array of systems that have been trained end-to-end specifically for this task. Our results indicate that a large portion of the error of modern deep 3d pose estimation systems stems from their visual analysis, and suggests directions to further advance the state of the art in 3d human pose estimation.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146523402-1b2a6c14-a5f4-4266-b2b4-19c0738cd434.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/softwingloss.md",
    "content": "# Structure-Coherent Deep Feature Learning for Robust Face Alignment\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/document/9442331/\">SoftWingloss (TIP'2021)</a></summary>\n\n```bibtex\n@article{lin2021structure,\n  title={Structure-Coherent Deep Feature Learning for Robust Face Alignment},\n  author={Lin, Chunze and Zhu, Beier and Wang, Quan and Liao, Renjie and Qian, Chen and Lu, Jiwen and Zhou, Jie},\n  journal={IEEE Transactions on Image Processing},\n  year={2021},\n  publisher={IEEE}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we propose a structure-coherent deep feature learning method for face alignment. Unlike most existing face alignment methods which overlook the facial structure cues, we explicitly exploit the relation among facial landmarks to make the detector robust to hard cases such as occlusion and large pose. Specifically, we leverage a landmark-graph relational network to enforce the structural relationships among landmarks. We consider the facial landmarks as structural graph nodes and carefully design the neighborhood to passing features among the most related nodes. Our method dynamically adapts the weights of node neighborhood to eliminate distracted information from noisy nodes, such as occluded landmark point. Moreover, different from most previous works which only tend to penalize the landmarks absolute position during the training, we propose a relative location loss to enhance the information of relative location of landmarks. This relative location supervision further regularizes the facial structure. Our approach considers the interactions among facial landmarks and can be easily implemented on top of any convolutional backbone to boost the performance. Extensive experiments on three popular benchmarks, including WFLW, COFW and 300W, demonstrate the effectiveness of the proposed method. In particular, due to explicit structure modeling, our approach is especially robust to challenging cases resulting in impressive low failure rate on COFW and WFLW datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/148036579-b128fb21-3a2d-4894-bb54-4223a4cdf856.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/udp.md",
    "content": "# The Devil is in the Details: Delving into Unbiased Data Processing for Human Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nRecently, the leading performance of human pose estimation is dominated by top-down methods. Being a fundamental component in training and inference, data processing has not been systematically considered in pose estimation community, to the best of our knowledge. In this paper, we focus on this problem and find that the devil of top-down pose estimator is in the biased data processing. Specifically, by investigating the standard data processing in state-of-the-art approaches mainly including data transformation and encoding-decoding, we find that the results obtained by common flipping strategy are unaligned with the original ones in inference. Moreover, there is statistical error in standard encoding-decoding during both training and inference. Two problems couple together and significantly degrade the pose estimation performance. Based on quantitative analyses, we then formulate a principled way to tackle this dilemma. Data is processed in continuous space based on unit length (the intervals between pixels) instead of in discrete space with pixel, and a combined classification and regression approach is adopted to perform encoding-decoding. The Unbiased Data Processing (UDP) for human pose estimation can be achieved by combining the two together. UDP not only boosts the performance of existing methods by a large margin but also plays a important role in result reproducing and future exploration. As a model-agnostic approach, UDP promotes SimpleBaseline-ResNet50-256x192 by 1.5 AP (70.2 to 71.7) and HRNet-W32-256x192 by 1.7 AP (73.5 to 75.2) on COCO test-dev set. The HRNet-W48-384x288 equipped with UDP achieves 76.5 AP and sets a new state-of-the-art for human pose estimation. The source code is publicly available for further research.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146524686-ddfe1356-77bd-46a0-a6cd-7ff418f65675.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/videopose3d.md",
    "content": "# 3D human pose estimation in video with temporal convolutions and semi-supervised training\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Pavllo_3D_Human_Pose_Estimation_in_Video_With_Temporal_Convolutions_and_CVPR_2019_paper.html\">VideoPose3D (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{pavllo20193d,\n  title={3d human pose estimation in video with temporal convolutions and semi-supervised training},\n  author={Pavllo, Dario and Feichtenhofer, Christoph and Grangier, David and Auli, Michael},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7753--7762},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this work, we demonstrate that 3D poses in video can be effectively estimated with a fully convolutional model based on dilated temporal convolutions over 2D keypoints. We also introduce back-projection, a simple and effective semi-supervised training method that leverages unlabeled video data. We start with predicted 2D keypoints for unlabeled video, then estimate 3D poses and finally back-project to the input 2D keypoints. In the supervised setting, our fully-convolutional model outperforms the previous best result from the literature by 6 mm mean per-joint position error on Human3.6M, corresponding to an error reduction of 11%, and the model also shows significant improvements on HumanEva-I. Moreover, experiments with back-projection show that it comfortably outperforms previous state-of-the-art results in semi-supervised settings where labeled data is scarce.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146525184-34a14153-5cab-4fe0-8500-018c99a5f647.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/vipnas.md",
    "content": "# ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2105.10154\">ViPNAS (CVPR'2021)</a></summary>\n\n```bibtex\n@article{xu2021vipnas,\n  title={ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search},\n  author={Xu, Lumin and Guan, Yingda and Jin, Sheng and Liu, Wentao and Qian, Chen and Luo, Ping and Ouyang, Wanli and Wang, Xiaogang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHuman pose estimation has achieved significant progress in recent years. However, most of the recent methods focus on improving accuracy using complicated models and ignoring real-time efficiency. To achieve a better trade-off between accuracy and efficiency, we propose a novel neural architecture search (NAS) method, termed ViPNAS, to search networks in both spatial and temporal levels for fast online video pose estimation. In the spatial level, we carefully design the search space with five different dimensions including network depth, width, kernel size, group number, and attentions. In the temporal level, we search from a series of temporal feature fusions to optimize the total accuracy and speed across multiple video frames. To the best of our knowledge, we are the first to search for the temporal feature fusion and automatic computation allocation in videos. Extensive experiments demonstrate the effectiveness of our approach on the challenging COCO2017 and PoseTrack2018 datasets. Our discovered model family, S-ViPNAS and T-ViPNAS, achieve significantly higher inference speed (CPU real-time) without sacrificing the accuracy compared to the previous state-of-the-art methods.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146527709-b8e55e40-426c-4958-8a35-b8d259e69efa.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/vitpose.md",
    "content": "# ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.12484\">ViTPose (NeurIPS'2022)</a></summary>\n\n```bibtex\n@inproceedings{\n  xu2022vitpose,\n  title={ViTPose: Simple Vision Transformer Baselines for Human Pose Estimation},\n  author={Yufei Xu and Jing Zhang and Qiming Zhang and Dacheng Tao},\n  booktitle={Advances in Neural Information Processing Systems},\n  year={2022},\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nAlthough no specific domain knowledge is considered in the design, plain vision transformers have shown excellent performance in visual recognition tasks. However, little effort has been made to reveal the potential of such simple structures for pose estimation tasks. In this paper, we show the surprisingly good capabilities of plain vision transformers for pose estimation from various aspects, namely simplicity in model structure, scalability in model size, flexibility in training paradigm, and transferability of knowledge between models, through a simple baseline model called ViTPose. Specifically, ViTPose employs plain and non-hierarchical vision transformers as backbones to extract features for a given person instance and a lightweight decoder for pose estimation. It can be scaled up from 100M to 1B parameters by taking the advantages of the scalable model capacity and high parallelism of transformers, setting a new Pareto front between throughput and performance. Besides, ViTPose is very flexible regarding the attention type, input resolution, pre-training and finetuning strategy, as well as dealing with multiple pose tasks. We also empirically demonstrate that the knowledge of large ViTPose models can be easily transferred to small ones via a simple knowledge token. Experimental results show that our basic ViTPose model outperforms representative methods on the challenging MS COCO Keypoint Detection benchmark, while the largest model sets a new state-of-the-art.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/26127467/224964357-d3d000fc-768b-4087-96d6-9291c86a3e8a.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/voxelpose.md",
    "content": "# VoxelPose: Towards Multi-Camera 3D Human Pose Estimation in Wild Environment\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.ecva.net/papers/eccv_2020/papers_ECCV/papers/123460188.pdf\">VoxelPose (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{tumultipose,\n  title={VoxelPose: Towards Multi-Camera 3D Human Pose Estimation in Wild Environment},\n  author={Tu, Hanyue and Wang, Chunyu and Zeng, Wenjun},\n  booktitle={ECCV},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present VoxelPose to estimate 3D poses of multiple people from multiple camera views. In contrast to the previous efforts which require to establish cross-view correspondence based on noisy and incomplete 2D pose estimates, VoxelPose directly operates in the 3D space therefore avoids making incorrect decisions in each camera view. To achieve this goal, features in all camera views are aggregated in the 3D voxel space and fed into Cuboid Proposal Network (CPN) to localize all people. Then we propose Pose Regression Network (PRN) to estimate a detailed 3D pose for each proposal. The approach is robust to occlusion which occurs frequently in practice. Without bells and whistles, it outperforms the previous methods on several public datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/148036780-b73a878c-7244-480b-b56e-ac739396856b.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/wingloss.md",
    "content": "# Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Feng_Wing_Loss_for_CVPR_2018_paper.html\">Wingloss (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{feng2018wing,\n  title={Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks},\n  author={Feng, Zhen-Hua and Kittler, Josef and Awais, Muhammad and Huber, Patrik and Wu, Xiao-Jun},\n  booktitle={Computer Vision and Pattern Recognition (CVPR), 2018 IEEE Conference on},\n  year={2018},\n  pages ={2235-2245},\n  organization={IEEE}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present a new loss function, namely Wing loss, for robust facial landmark localisation with Convolutional Neural Networks (CNNs). We first compare and analyse different loss functions including L2, L1 and smooth L1. The analysis of these loss functions suggests that, for the training of a CNN-based localisation model, more attention should be paid to small and medium range errors. To this end, we design a piece-wise loss function. The new loss amplifies the impact of errors from the interval (-w, w) by switching from L1 loss to a modified logarithm function. To address the problem of under-representation of samples with large out-of-plane head rotations in the training set, we propose a simple but effective boosting strategy, referred to as pose-based data balancing. In particular, we deal with the data imbalance problem by duplicating the minority training samples and perturbing them by injecting random image rotation, bounding box translation and other data augmentation approaches. Last, the proposed approach is extended to create a two-stage framework for robust facial landmark localisation. The experimental results obtained on AFLW and 300W demonstrate the merits of the Wing loss function, and prove the superiority of the proposed method over the state-of-the-art approaches.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146528473-f3228f69-b60e-4807-9c4b-b45997fbc530.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/algorithms/yolopose.md",
    "content": "# YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.06806\">YOLO-Pose (CVPRW'2022)</a></summary>\n\n```bibtex\n@inproceedings{maji2022yolo,\n  title={Yolo-pose: Enhancing yolo for multi person pose estimation using object keypoint similarity loss},\n  author={Maji, Debapriya and Nagori, Soyeb and Mathew, Manu and Poddar, Deepak},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={2637--2646},\n  year={2022}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe introduce YOLO-pose, a novel heatmap-free approach for joint detection, and 2D multi-person pose estimation in an image based on the popular YOLO object detection framework. Existing heatmap based two-stage approaches are sub-optimal as they are not end-to-end trainable and training relies on a surrogate L1 loss that is not equivalent to maximizing the evaluation metric, i.e. Object Keypoint Similarity (OKS). Our framework allows us to train the model end-to-end and optimize the OKS metric itself. The proposed model learns to jointly detect bounding boxes for multiple persons and their corresponding 2D poses in a single forward pass and thus bringing in the best of both top-down and bottom-up approaches. Proposed approach doesn't require the postprocessing of bottom-up approaches to group detected keypoints into a skeleton as each bounding box has an associated pose, resulting in an inherent grouping of the keypoints. Unlike top-down approaches, multiple forward passes are done away with since all persons are localized along with their pose in a single inference. YOLO-pose achieves new state-of-the-art results on COCO validation (90.2% AP50) and test-dev set (90.3% AP50), surpassing all existing bottom-up approaches in a single forward pass without flip test, multi-scale testing, or any other test time augmentation. All experiments and results reported in this paper are without any test time augmentation, unlike traditional approaches that use flip-test and multi-scale testing to boost performance.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/63b9ba0c-3d28-4d5f-80b6-03f58cfb26c2\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/alexnet.md",
    "content": "# Imagenet classification with deep convolutional neural networks\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://proceedings.neurips.cc/paper/4824-imagenet-classification-with-deep-convolutional-neural-networks.pdf\">AlexNet (NeurIPS'2012)</a></summary>\n\n```bibtex\n@inproceedings{krizhevsky2012imagenet,\n  title={Imagenet classification with deep convolutional neural networks},\n  author={Krizhevsky, Alex and Sutskever, Ilya and Hinton, Geoffrey E},\n  booktitle={Advances in neural information processing systems},\n  pages={1097--1105},\n  year={2012}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe trained a large, deep convolutional neural network to classify the 1.2 million high-resolution images in the ImageNet LSVRC-2010 contest into the 1000 different classes. On the test data, we achieved top-1 and top-5 error rates of 37.5% and 17.0% which is considerably better than the previous state-of-the-art. The neural network, which has 60 million parameters and 650,000 neurons, consists of five convolutional layers, some of which are followed by max-pooling layers, and three fully-connected layers with a final 1000-way softmax. To make training faster, we used non-saturating neurons and a very efficient GPU implementation of the convolution operation. To reduce overfitting in the fully-connected layers we employed a recently-developed regularization method called \"dropout\" that proved to be very effective. We also entered a variant of this model in the ILSVRC-2012 competition and achieved a winning top-5 test error rate of 15.3%, compared to 26.2% achieved by the second-best entry\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146537150-39cd128e-185e-48eb-9d6b-7e9a187d2ae5.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/cpm.md",
    "content": "# Convolutional pose machines\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Wei_Convolutional_Pose_Machines_CVPR_2016_paper.html\">CPM (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{wei2016convolutional,\n  title={Convolutional pose machines},\n  author={Wei, Shih-En and Ramakrishna, Varun and Kanade, Takeo and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={4724--4732},\n  year={2016}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe introduce associative embedding, a novel method for supervising convolutional neural networks for the task of detection and grouping. A number of computer vision problems can be framed in this manner including multi-person pose estimation, instance segmentation, and multi-object tracking. Usually the grouping of detections is achieved with multi-stage pipelines, instead we propose an approach that teaches a network to simultaneously output detections and group assignments. This technique can be easily integrated into any state-of-the-art network architecture that produces pixel-wise predictions. We show how to apply this method to both multi-person pose estimation and instance segmentation and report state-of-the-art performance for multi-person pose on the MPII and MS-COCO datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146514331-a599580b-69a5-4ee4-9aaf-4a72f9c25c9a.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/higherhrnet.md",
    "content": "# HigherHRNet: Scale-Aware Representation Learning for Bottom-Up Human Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Cheng_HigherHRNet_Scale-Aware_Representation_Learning_for_Bottom-Up_Human_Pose_Estimation_CVPR_2020_paper.html\">HigherHRNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{cheng2020higherhrnet,\n  title={HigherHRNet: Scale-Aware Representation Learning for Bottom-Up Human Pose Estimation},\n  author={Cheng, Bowen and Xiao, Bin and Wang, Jingdong and Shi, Honghui and Huang, Thomas S and Zhang, Lei},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={5386--5395},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nBottom-up human pose estimation methods have difficulties in predicting the correct pose for small persons due to challenges in scale variation. In this paper, we present HigherHRNet: a novel bottom-up human pose estimation method for learning scale-aware representations using high-resolution feature pyramids. Equipped with multi-resolution supervision for training and multi-resolution aggregation for inference, the proposed approach is able to solve the scale variation challenge in bottom-up multi-person pose estimation and localize keypoints more precisely, especially for small person. The feature pyramid in HigherHRNet consists of feature map outputs from HRNet and upsampled higher-resolution outputs through a transposed convolution. HigherHRNet outperforms the previous best bottom-up method by 2.5% AP for medium person on COCO test-dev, showing its effectiveness in handling scale variation. Furthermore, HigherHRNet achieves new state-of-the-art result on COCO test-dev (70.5% AP) without using refinement or other post-processing techniques, surpassing all existing bottom-up methods. HigherHRNet even surpasses all top-down methods on CrowdPose test (67.6% AP), suggesting its robustness in crowded scene.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146515482-975050d6-57da-469a-8dda-201675a404e7.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/hourglass.md",
    "content": "# Stacked hourglass networks for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46484-8_29\">Hourglass (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{newell2016stacked,\n  title={Stacked hourglass networks for human pose estimation},\n  author={Newell, Alejandro and Yang, Kaiyu and Deng, Jia},\n  booktitle={European conference on computer vision},\n  pages={483--499},\n  year={2016},\n  organization={Springer}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nThis work introduces a novel convolutional network architecture for the task of human pose estimation. Features are processed across all scales and consolidated to best capture the various spatial relationships associated with the body. We show how repeated bottom-up, top-down processing used in conjunction with intermediate supervision is critical to improving the performance of the network. We refer to the architecture as a \"stacked hourglass\" network based on the successive steps of pooling and upsampling that are done to produce a final set of predictions. State-of-the-art results are achieved on the FLIC and MPII benchmarks outcompeting all recent methods.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146516901-cee086aa-6b7c-4f79-82bd-1168f03ea63b.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/hrformer.md",
    "content": "# HRFormer: High-Resolution Vision Transformer for Dense Predict\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html\">HRFormer (NIPS'2021)</a></summary>\n\n```bibtex\n@article{yuan2021hrformer,\n  title={HRFormer: High-Resolution Vision Transformer for Dense Predict},\n  author={Yuan, Yuhui and Fu, Rao and Huang, Lang and Lin, Weihong and Zhang, Chao and Chen, Xilin and Wang, Jingdong},\n  journal={Advances in Neural Information Processing Systems},\n  volume={34},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present a High-Resolution Transformer (HRFormer) that learns high-resolution representations for dense\nprediction tasks, in contrast to the original Vision Transformer that produces low-resolution representations\nand has high memory and computational cost. We take advantage of the multi-resolution parallel design\nintroduced in high-resolution convolutional networks (HRNet), along with local-window self-attention\nthat performs self-attention over small non-overlapping image windows, for improving the memory and\ncomputation efficiency. In addition, we introduce a convolution into the FFN to exchange information\nacross the disconnected image windows. We demonstrate the effectiveness of the HighResolution Transformer\non both human pose estimation and semantic segmentation tasks, e.g., HRFormer outperforms Swin\ntransformer by 1.3 AP on COCO pose estimation with 50% fewer parameters and 30% fewer FLOPs.\nCode is available at: https://github.com/HRNet/HRFormer\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/28900607/155838218-a6aa12b5-5855-45ed-922e-1cfe74f63027.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/hrnet.md",
    "content": "# Deep high-resolution representation learning for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Sun_Deep_High-Resolution_Representation_Learning_for_Human_Pose_Estimation_CVPR_2019_paper.html\">HRNet (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{sun2019deep,\n  title={Deep high-resolution representation learning for human pose estimation},\n  author={Sun, Ke and Xiao, Bin and Liu, Dong and Wang, Jingdong},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={5693--5703},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we are interested in the human pose estimation problem with a focus on learning reliable highresolution representations. Most existing methods recover high-resolution representations from low-resolution representations produced by a high-to-low resolution network. Instead, our proposed network maintains high-resolution representations through the whole process. We start from a high-resolution subnetwork as the first stage, gradually add high-to-low resolution subnetworks one by one to form more stages, and connect the mutliresolution subnetworks in parallel. We conduct repeated multi-scale fusions such that each of the high-to-low resolution representations receives information from other parallel representations over and over, leading to rich highresolution representations. As a result, the predicted keypoint heatmap is potentially more accurate and spatially more precise. We empirically demonstrate the effectiveness\nof our network through the superior pose estimation results over two benchmark datasets: the COCO keypoint detection\ndataset and the MPII Human Pose dataset. In addition, we show the superiority of our network in pose tracking on the PoseTrack dataset.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146518010-9c1d6078-dd9c-4610-94a9-cbcb60aa87c0.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/hrnetv2.md",
    "content": "# Deep high-resolution representation learning for visual recognition\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/9052469/\">HRNetv2 (TPAMI'2019)</a></summary>\n\n```bibtex\n@article{WangSCJDZLMTWLX19,\n  title={Deep High-Resolution Representation Learning for Visual Recognition},\n  author={Jingdong Wang and Ke Sun and Tianheng Cheng and\n          Borui Jiang and Chaorui Deng and Yang Zhao and Dong Liu and Yadong Mu and\n          Mingkui Tan and Xinggang Wang and Wenyu Liu and Bin Xiao},\n  journal={TPAMI},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHigh-resolution representations are essential for position-sensitive vision problems, such as human pose estimation, semantic segmentation, and object detection. Existing state-of-the-art frameworks first encode the input image as a low-resolution representation through a subnetwork that is formed by connecting high-to-low resolution convolutions in series (e.g., ResNet, VGGNet), and then recover the high-resolution representation from the encoded low-resolution representation. Instead, our proposed network, named as High-Resolution Network (HRNet), maintains high-resolution representations through the whole process. There are two key characteristics: (i) Connect the high-to-low resolution convolution streams in parallel and (ii) repeatedly exchange the information across resolutions. The benefit is that the resulting representation is semantically richer and spatially more precise. We show the superiority of the proposed HRNet in a wide range of applications, including human pose estimation, semantic segmentation, and object detection, suggesting that the HRNet is a stronger backbone for computer vision problems.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146519239-b3416e9a-0f3a-493a-9cc5-2d257b7fae01.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/litehrnet.md",
    "content": "# Lite-HRNet: A Lightweight High-Resolution Network\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2104.06403\">LiteHRNet (CVPR'2021)</a></summary>\n\n```bibtex\n@inproceedings{Yulitehrnet21,\n  title={Lite-HRNet: A Lightweight High-Resolution Network},\n  author={Yu, Changqian and Xiao, Bin and Gao, Changxin and Yuan, Lu and Zhang, Lei and Sang, Nong and Wang, Jingdong},\n  booktitle={CVPR},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present an efficient high-resolution network, Lite-HRNet, for human pose estimation. We start by simply applying the efficient shuffle block in ShuffleNet to HRNet (high-resolution network), yielding stronger performance over popular lightweight networks, such as MobileNet, ShuffleNet, and Small HRNet.\nWe find that the heavily-used pointwise (1x1) convolutions in shuffle blocks become the computational bottleneck. We introduce a lightweight unit, conditional channel weighting, to replace costly pointwise (1x1) convolutions in shuffle blocks. The complexity of channel weighting is linear w.r.t the number of channels and lower than the quadratic time complexity for pointwise convolutions. Our solution learns the weights from all the channels and over multiple resolutions that are readily available in the parallel branches in HRNet. It uses the weights as the bridge to exchange information across channels and resolutions, compensating the role played by the pointwise (1x1) convolution. Lite-HRNet demonstrates superior results on human pose estimation over popular lightweight networks. Moreover, Lite-HRNet can be easily applied to semantic segmentation task in the same lightweight manner.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146520579-3e86e3af-a8b2-4071-94da-916e0ce90464.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/mobilenetv2.md",
    "content": "# Mobilenetv2: Inverted residuals and linear bottlenecks\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Sandler_MobileNetV2_Inverted_Residuals_CVPR_2018_paper.html\">MobilenetV2 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{sandler2018mobilenetv2,\n  title={Mobilenetv2: Inverted residuals and linear bottlenecks},\n  author={Sandler, Mark and Howard, Andrew and Zhu, Menglong and Zhmoginov, Andrey and Chen, Liang-Chieh},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={4510--4520},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper we describe a new mobile architecture, mbox{MobileNetV2}, that improves the state of the art performance of mobile models on multiple tasks and benchmarks as well as across a spectrum of different model sizes. We also describe efficient ways of applying these mobile models to object detection in a novel framework we call mbox{SSDLite}. Additionally, we demonstrate how to build mobile semantic segmentation models through a reduced form of mbox{DeepLabv3} which we call Mobile mbox{DeepLabv3}. is based on an inverted residual structure where the shortcut connections are between the thin bottleneck layers. The intermediate expansion layer uses lightweight depthwise convolutions to filter features as a source of non-linearity. Additionally, we find that it is important to remove non-linearities in the narrow layers in order to maintain representational power. We demonstrate that this improves performance and provide an intuition that led to this design. Finally, our approach allows decoupling of the input/output domains from the expressiveness of the transformation, which provides a convenient framework for further analysis. We measure our performance on mbox{ImageNet}~cite{Russakovsky:2015:ILS:2846547.2846559} classification, COCO object detection cite{COCO}, VOC image segmentation cite{PASCAL}. We evaluate the trade-offs between accuracy, and number of operations measured by multiply-adds (MAdd), as well as actual latency, and the number of parameters.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146537871-75c22a93-72ef-4a24-9ce9-0c2823381961.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/mspn.md",
    "content": "# Rethinking on multi-stage networks for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1901.00148\">MSPN (ArXiv'2019)</a></summary>\n\n```bibtex\n@article{li2019rethinking,\n  title={Rethinking on Multi-Stage Networks for Human Pose Estimation},\n  author={Li, Wenbo and Wang, Zhicheng and Yin, Binyi and Peng, Qixiang and Du, Yuming and Xiao, Tianzi and Yu, Gang and Lu, Hongtao and Wei, Yichen and Sun, Jian},\n  journal={arXiv preprint arXiv:1901.00148},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nExisting pose estimation approaches fall into two categories: single-stage and multi-stage methods. While multi-stage methods are seemingly more suited for the task, their performance in current practice is not as good as single-stage methods. This work studies this issue. We argue that the current multi-stage methods' unsatisfactory performance comes from the insufficiency in various design choices. We propose several improvements, including the single-stage module design, cross stage feature aggregation, and coarse-to-fine supervision. The resulting method establishes the new state-of-the-art on both MS COCO and MPII Human Pose dataset, justifying the effectiveness of a multi-stage architecture. The source code is publicly available for further research.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146520722-74c1ef85-9fa3-4b96-8cbf-4a2c86a80adc.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/pvt.md",
    "content": "# Pyramid Vision Transformer: A Versatile Backbone for Dense Prediction without Convolutions\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2102.12122\">PVT (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{wang2021pyramid,\n  title={Pyramid vision transformer: A versatile backbone for dense prediction without convolutions},\n  author={Wang, Wenhai and Xie, Enze and Li, Xiang and Fan, Deng-Ping and Song, Kaitao and Liang, Ding and Lu, Tong and Luo, Ping and Shao, Ling},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={568--578},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nAlthough using convolutional neural networks (CNNs) as backbones achieves great\nsuccesses in computer vision, this work investigates a simple backbone network\nuseful for many dense prediction tasks without convolutions. Unlike the\nrecently-proposed Transformer model (e.g., ViT) that is specially designed for\nimage classification, we propose Pyramid Vision Transformer~(PVT), which overcomes\nthe difficulties of porting Transformer to various dense prediction tasks.\nPVT has several merits compared to prior arts. (1) Different from ViT that\ntypically has low-resolution outputs and high computational and memory cost,\nPVT can be not only trained on dense partitions of the image to achieve high\noutput resolution, which is important for dense predictions but also using a\nprogressive shrinking pyramid to reduce computations of large feature maps.\n(2) PVT inherits the advantages from both CNN and Transformer, making it a\nunified backbone in various vision tasks without convolutions by simply replacing\nCNN backbones. (3) We validate PVT by conducting extensive experiments, showing\nthat it boosts the performance of many downstream tasks, e.g., object detection,\nsemantic, and instance segmentation. For example, with a comparable number of\nparameters, RetinaNet+PVT achieves 40.4 AP on the COCO dataset, surpassing\nRetinNet+ResNet50 (36.3 AP) by 4.1 absolute AP. We hope PVT could serve as an\nalternative and useful backbone for pixel-level predictions and facilitate future\nresearches. Code is available at https://github.com/whai362/PVT .\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/28900607/166134407-d455c57e-4ec3-4951-be9e-730cb9d9c213.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/pvtv2.md",
    "content": "# PVTv2: Improved Baselines with Pyramid Vision Transformer\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2106.13797\">PVTV2 (CVMJ'2022)</a></summary>\n\n```bibtex\n@article{wang2022pvt,\n  title={PVT v2: Improved baselines with Pyramid Vision Transformer},\n  author={Wang, Wenhai and Xie, Enze and Li, Xiang and Fan, Deng-Ping and Song, Kaitao and Liang, Ding and Lu, Tong and Luo, Ping and Shao, Ling},\n  journal={Computational Visual Media},\n  pages={1--10},\n  year={2022},\n  publisher={Springer}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nTransformer recently has presented encouraging progress in computer vision.\nIn this work, we present new baselines by improving the original Pyramid\nVision Transformer (PVTv1) by adding three designs, including (1) linear\ncomplexity attention layer, (2) overlapping patch embedding, and (3)\nconvolutional feed-forward network. With these modifications, PVTv2 reduces\nthe computational complexity of PVTv1 to linear and achieves significant\nimprovements on fundamental vision tasks such as classification, detection,\nand segmentation. Notably, the proposed PVTv2 achieves comparable or better\nperformances than recent works such as Swin Transformer. We hope this work\nwill facilitate state-of-the-art Transformer researches in computer vision.\nCode is available at https://github.com/whai362/PVT .\n"
  },
  {
    "path": "docs/src/papers/backbones/resnest.md",
    "content": "# ResNeSt: Split-Attention Networks\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2004.08955\">ResNeSt (ArXiv'2020)</a></summary>\n\n```bibtex\n@article{zhang2020resnest,\n  title={ResNeSt: Split-Attention Networks},\n  author={Zhang, Hang and Wu, Chongruo and Zhang, Zhongyue and Zhu, Yi and Zhang, Zhi and Lin, Haibin and Sun, Yue and He, Tong and Muller, Jonas and Manmatha, R. and Li, Mu and Smola, Alexander},\n  journal={arXiv preprint arXiv:2004.08955},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIt is well known that featuremap attention and multi-path representation are important for visual recognition. In this paper, we present a modularized architecture, which applies the channel-wise attention on different network branches to leverage their success in capturing cross-feature interactions and learning diverse representations. Our design results in a simple and unified computation block, which can be parameterized using only a few variables. Our model, named ResNeSt, outperforms EfficientNet in accuracy and latency trade-off on image classification. In addition, ResNeSt has achieved superior transfer learning results on several public benchmarks serving as the backbone, and has been adopted by the winning entries of COCO-LVIS challenge. The source code for complete system and pretrained models are publicly available.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146538001-387b40dc-886c-48c5-8621-1dc287fa2ae3.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/resnet.md",
    "content": "# Deep residual learning for image recognition\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/He_Deep_Residual_Learning_CVPR_2016_paper.html\">ResNet (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{he2016deep,\n  title={Deep residual learning for image recognition},\n  author={He, Kaiming and Zhang, Xiangyu and Ren, Shaoqing and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={770--778},\n  year={2016}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nDeeper neural networks are more difficult to train. We present a residual learning framework to ease the training of networks that are substantially deeper than those used previously. We explicitly reformulate the layers as learning residual functions with reference to the layer inputs, instead of learning unreferenced functions. We provide comprehensive empirical evidence showing that these residual networks are easier to optimize, and can gain accuracy from\nconsiderably increased depth. On the ImageNet dataset we evaluate residual nets with a depth of up to 152 layers—8× deeper than VGG nets but still having lower complexity. An ensemble of these residual nets achieves 3.57% error on the ImageNet test set. This result won the 1st place on the ILSVRC 2015 classification task. We also present analysis on CIFAR-10 with 100 and 1000 layers. The depth of representations is of central importance for many visual recognition tasks. Solely due to our extremely deep representations, we obtain a 28% relative improvement on the COCO object detection dataset. Deep residual nets are foundations of our submissions to ILSVRC\n& COCO 2015 competitions1 , where we also won the 1st places on the tasks of ImageNet detection, ImageNet localization, COCO detection, and COCO segmentation.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146538539-d635ee57-200c-40f5-93cf-a34a5b416feb.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/resnetv1d.md",
    "content": "# Bag of tricks for image classification with convolutional neural networks\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/He_Bag_of_Tricks_for_Image_Classification_with_Convolutional_Neural_Networks_CVPR_2019_paper.html\">ResNetV1D (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{he2019bag,\n  title={Bag of tricks for image classification with convolutional neural networks},\n  author={He, Tong and Zhang, Zhi and Zhang, Hang and Zhang, Zhongyue and Xie, Junyuan and Li, Mu},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={558--567},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nMuch of the recent progress made in image classification research can be credited to training procedure refinements, such as changes in data augmentations and optimization methods. In the literature, however, most refinements are either briefly mentioned as implementation details or only visible in source code. In this paper, we will examine a collection of such refinements and empirically evaluate their impact on the final model accuracy through ablation study. We will show that, by combining these refinements together, we are able to improve various CNN models significantly. For example, we raise ResNet-50’s top-1 validation accuracy from 75.3% to 79.29% on ImageNet. We will also demonstrate that improvement on image classification accuracy leads to better transfer learning performance in other application domains such as object detection and semantic\nsegmentation.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146539869-6deeea09-8f28-4b19-8737-2d9b0d080189.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/resnext.md",
    "content": "# Aggregated residual transformations for deep neural networks\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2017/html/Xie_Aggregated_Residual_Transformations_CVPR_2017_paper.html\">ResNext (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{xie2017aggregated,\n  title={Aggregated residual transformations for deep neural networks},\n  author={Xie, Saining and Girshick, Ross and Doll{\\'a}r, Piotr and Tu, Zhuowen and He, Kaiming},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={1492--1500},\n  year={2017}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present a simple, highly modularized network architecture for image classification. Our network is constructed by repeating a building block that aggregates a set of transformations with the same topology. Our simple design results in a homogeneous, multi-branch architecture that has only a few hyper-parameters to set. This strategy exposes a new dimension, which we call \"cardinality\" (the size of the set of transformations), as an essential factor in addition to the dimensions of depth and width. On the ImageNet-1K dataset, we empirically show that even under the restricted condition of maintaining complexity, increasing cardinality is able to improve classification accuracy. Moreover, increasing cardinality is more effective than going deeper or wider when we increase the capacity. Our models, named ResNeXt, are the foundations of our entry to the ILSVRC 2016 classification task in which we secured 2nd place. We further investigate ResNeXt on an ImageNet-5K set and the COCO detection set, also showing better results than its ResNet counterpart. The code and models are publicly available online.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146540039-cd3950dd-a6d2-4836-9af2-f7f990e98f77.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/rsn.md",
    "content": "# Learning delicate local representations for multi-person pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RSN (ECCV'2020)</a></summary>\n\n```bibtex\n@misc{cai2020learning,\n    title={Learning Delicate Local Representations for Multi-Person Pose Estimation},\n    author={Yuanhao Cai and Zhicheng Wang and Zhengxiong Luo and Binyi Yin and Angang Du and Haoqian Wang and Xinyu Zhou and Erjin Zhou and Xiangyu Zhang and Jian Sun},\n    year={2020},\n    eprint={2003.04030},\n    archivePrefix={arXiv},\n    primaryClass={cs.CV}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we propose a novel method called Residual Steps Network (RSN). RSN aggregates features with the same spatial size (Intra-level features) efficiently to obtain delicate local representations, which retain rich low-level spatial information and result in precise keypoint localization. Additionally, we observe the output features contribute differently to final performance. To tackle this problem, we propose an efficient attention mechanism - Pose Refine Machine (PRM) to make a trade-off between local and global representations in output features and further refine the keypoint locations. Our approach won the 1st place of COCO Keypoint Challenge 2019 and achieves state-of-the-art results on both COCO and MPII benchmarks, without using extra training data and pretrained model. Our single model achieves 78.6 on COCO test-dev, 93.0 on MPII test dataset. Ensembled models achieve 79.2 on COCO test-dev, 77.1 on COCO test-challenge dataset.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522226-5041d16e-41cb-4d31-ae53-dbe21314a697.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/scnet.md",
    "content": "# Improving Convolutional Networks with Self-Calibrated Convolutions\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Liu_Improving_Convolutional_Networks_With_Self-Calibrated_Convolutions_CVPR_2020_paper.html\">SCNet (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020improving,\n  title={Improving Convolutional Networks with Self-Calibrated Convolutions},\n  author={Liu, Jiang-Jiang and Hou, Qibin and Cheng, Ming-Ming and Wang, Changhu and Feng, Jiashi},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={10096--10105},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nRecent advances on CNNs are mostly devoted to designing more complex architectures to enhance their representation learning capacity. In this paper, we consider how to improve the basic convolutional feature transformation process of CNNs without tuning the model architectures. To this end, we present a novel self-calibrated convolutions that explicitly expand fields-of-view of each convolutional layers through internal communications and hence enrich the output features. In particular, unlike the standard convolutions that fuse spatial and channel-wise information using small kernels (e.g., 3x3), self-calibrated convolutions adaptively build long-range spatial and inter-channel dependencies around each spatial location through a novel self-calibration operation. Thus, it can help CNNs generate more discriminative representations by explicitly incorporating richer information. Our self-calibrated convolution design is simple and generic, and can be easily applied to augment standard convolutional layers without introducing extra parameters and complexity. Extensive experiments demonstrate that when applying self-calibrated convolutions into different backbones, our networks can significantly improve the baseline models in a variety of vision tasks, including image recognition, object detection, instance segmentation, and keypoint detection, with no need to change the network architectures. We hope this work could provide a promising way for future research in designing novel convolutional feature transformations for improving convolutional networks. Code is available on the project page.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146522623-fdc88996-1a8f-4b0a-bdee-fc284dfd7348.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/seresnet.md",
    "content": "# Squeeze-and-excitation networks\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Hu_Squeeze-and-Excitation_Networks_CVPR_2018_paper\">SEResNet (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{hu2018squeeze,\n  title={Squeeze-and-excitation networks},\n  author={Hu, Jie and Shen, Li and Sun, Gang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={7132--7141},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nConvolutional neural networks are built upon the convolution operation, which extracts informative features by fusing spatial and channel-wise information together within local receptive fields. In order to boost the representational power of a network, several recent approaches have shown the benefit of enhancing spatial encoding. In this work, we focus on the channel relationship and propose a novel architectural unit, which we term the \"Squeeze-and-Excitation\" (SE) block, that adaptively recalibrates channel-wise feature responses by explicitly modelling interdependencies between channels. We demonstrate that by stacking these blocks together, we can construct SENet architectures that generalise extremely well across challenging datasets. Crucially, we find that SE blocks produce significant performance improvements for existing state-of-the-art deep architectures at minimal additional computational cost. SENets formed the foundation of our ILSVRC 2017 classification submission which won first place and significantly reduced the top-5 error to 2.251%, achieving a ∼25% relative improvement over the winning entry of 2016. Code and models are available at https: //github.com/hujie-frank/SENet.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146540423-a7e8ae12-3b3e-447e-848b-682c06c1126e.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/shufflenetv1.md",
    "content": "# Shufflenet: An extremely efficient convolutional neural network for mobile devices\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Zhang_ShuffleNet_An_Extremely_CVPR_2018_paper.html\">ShufflenetV1 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{zhang2018shufflenet,\n  title={Shufflenet: An extremely efficient convolutional neural network for mobile devices},\n  author={Zhang, Xiangyu and Zhou, Xinyu and Lin, Mengxiao and Sun, Jian},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={6848--6856},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe introduce an extremely computation-efficient CNN architecture named ShuffleNet, which is designed specially for mobile devices with very limited computing power (e.g., 10-150 MFLOPs). The new architecture utilizes two new operations, pointwise group convolution and channel shuffle, to greatly reduce computation cost while maintaining accuracy. Experiments on ImageNet classification and MS COCO object detection demonstrate the superior performance of ShuffleNet over other structures, e.g. lower top-1 error (absolute 7.8%) than recent MobileNet~cite{howard2017mobilenets} on ImageNet classification task, under the computation budget of 40 MFLOPs. On an ARM-based mobile device, ShuffleNet achieves $sim$13$ imes$ actual speedup over AlexNet while maintaining comparable accuracy.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146540601-7ed2ac24-aa7d-44b1-a7e0-be03bde0e098.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/shufflenetv2.md",
    "content": "# Shufflenet v2: Practical guidelines for efficient cnn architecture design\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ECCV_2018/html/Ningning_Light-weight_CNN_Architecture_ECCV_2018_paper.html\">ShufflenetV2 (ECCV'2018)</a></summary>\n\n```bibtex\n@inproceedings{ma2018shufflenet,\n  title={Shufflenet v2: Practical guidelines for efficient cnn architecture design},\n  author={Ma, Ningning and Zhang, Xiangyu and Zheng, Hai-Tao and Sun, Jian},\n  booktitle={Proceedings of the European conference on computer vision (ECCV)},\n  pages={116--131},\n  year={2018}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nCurrent network architecture design is mostly guided by the indirect metric of computation complexity, i.e., FLOPs. However, the direct metric, such as speed, also depends on the other factors such as memory access cost and platform characterics. Taking these factors into account, this work proposes practical guidelines for efficient network de- sign. Accordingly, a new architecture called ShuffleNet V2 is presented. Comprehensive experiments verify that it is the state-of-the-art in both speed and accuracy.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146540752-993df527-7ec3-475c-ba12-3791bf8b3a0c.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/swin.md",
    "content": "# Swin transformer: Hierarchical vision transformer using shifted windows\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2103.14030\">Swin (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{liu2021swin,\n  title={Swin transformer: Hierarchical vision transformer using shifted windows},\n  author={Liu, Ze and Lin, Yutong and Cao, Yue and Hu, Han and Wei, Yixuan and Zhang, Zheng and Lin, Stephen and Guo, Baining},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={10012--10022},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nThis paper presents a new vision Transformer, called Swin Transformer, that capably serves as a general-purpose backbone for computer vision. Challenges in adapting Transformer from language to vision arise from differences between the two domains, such as large variations in the scale of visual entities and the high resolution of pixels in images compared to words in text. To address these differences, we propose a hierarchical Transformer whose representation is computed with Shifted windows. The shifted windowing scheme brings greater efficiency by limiting self-attention computation to non-overlapping local windows while also allowing for cross-window connection. This hierarchical architecture has the flexibility to model at various scales and has linear computational complexity with respect to image size. These qualities of Swin Transformer make it compatible with a broad range of vision tasks, including image classification (87.3 top-1 accuracy on ImageNet-1K) and dense prediction tasks such as object detection (58.7 box AP and 51.1 mask AP on COCO testdev) and semantic segmentation (53.5 mIoU on ADE20K val). Its performance surpasses the previous state-of-theart by a large margin of +2.7 box AP and +2.6 mask AP on COCO, and +3.2 mIoU on ADE20K, demonstrating the potential of Transformer-based models as vision backbones. The hierarchical design and the shifted window approach also prove beneficial for all-MLP architectures.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/40661020/143999551-6a527048-de38-485c-a1b6-3133ffa5bfaa.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/vgg.md",
    "content": "# Very Deep Convolutional Networks for Large-Scale Image Recognition\n\n<!-- [BACKBONE] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1409.1556\">VGG (ICLR'2015)</a></summary>\n\n```bibtex\n@article{simonyan2014very,\n  title={Very deep convolutional networks for large-scale image recognition},\n  author={Simonyan, Karen and Zisserman, Andrew},\n  journal={arXiv preprint arXiv:1409.1556},\n  year={2014}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this work we investigate the effect of the convolutional network depth on its accuracy in the large-scale image recognition setting. Our main contribution is a thorough evaluation of networks of increasing depth using an architecture with very small (3x3) convolution filters, which shows that a significant improvement on the prior-art configurations can be achieved by pushing the depth to 16-19 weight layers. These findings were the basis of our ImageNet Challenge 2014 submission, where our team secured the first and the second places in the localisation and classification tracks respectively. We also show that our representations generalise well to other datasets, where they achieve state-of-the-art results. We have made our two best-performing ConvNet models publicly available to facilitate further research on the use of deep visual representations in computer vision.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146540877-b0fc7823-efe2-4b5c-8168-3b3a9d7e93ac.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/backbones/vipnas.md",
    "content": "# ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2105.10154\">ViPNAS (CVPR'2021)</a></summary>\n\n```bibtex\n@article{xu2021vipnas,\n  title={ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search},\n  author={Xu, Lumin and Guan, Yingda and Jin, Sheng and Liu, Wentao and Qian, Chen and Luo, Ping and Ouyang, Wanli and Wang, Xiaogang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHuman pose estimation has achieved significant progress in recent years. However, most of the recent methods focus on improving accuracy using complicated models and ignoring real-time efficiency. To achieve a better trade-off between accuracy and efficiency, we propose a novel neural architecture search (NAS) method, termed ViPNAS, to search networks in both spatial and temporal levels for fast online video pose estimation. In the spatial level, we carefully design the search space with five different dimensions including network depth, width, kernel size, group number, and attentions. In the temporal level, we search from a series of temporal feature fusions to optimize the total accuracy and speed across multiple video frames. To the best of our knowledge, we are the first to search for the temporal feature fusion and automatic computation allocation in videos. Extensive experiments demonstrate the effectiveness of our approach on the challenging COCO2017 and PoseTrack2018 datasets. Our discovered model family, S-ViPNAS and T-ViPNAS, achieve significantly higher inference speed (CPU real-time) without sacrificing the accuracy compared to the previous state-of-the-art methods.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146527709-b8e55e40-426c-4958-8a35-b8d259e69efa.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/datasets/300vw.md",
    "content": "# 300 faces in-the-wild challenge: Database and results\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2015_workshops/w25/papers/Shen_The_First_Facial_ICCV_2015_paper.pdf\">300VW (ICCVW'2015)</a></summary>\n\n```bibtex\n@inproceedings{shen2015first,\n  title={The first facial landmark tracking in-the-wild challenge: Benchmark and results},\n  author={Shen, Jie and Zafeiriou, Stefanos and Chrysos, Grigoris G and Kossaifi, Jean and Tzimiropoulos, Georgios and Pantic, Maja},\n  booktitle={Proceedings of the IEEE international conference on computer vision workshops},\n  pages={50--58},\n  year={2015}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/300w.md",
    "content": "# 300 faces in-the-wild challenge: Database and results\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.sciencedirect.com/science/article/pii/S0262885616000147\">300W (IMAVIS'2016)</a></summary>\n\n```bibtex\n@article{sagonas2016300,\n  title={300 faces in-the-wild challenge: Database and results},\n  author={Sagonas, Christos and Antonakos, Epameinondas and Tzimiropoulos, Georgios and Zafeiriou, Stefanos and Pantic, Maja},\n  journal={Image and vision computing},\n  volume={47},\n  pages={3--18},\n  year={2016},\n  publisher={Elsevier}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/300wlp.md",
    "content": "# **Face Alignment Across Large Poses: A 3D Solution**\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://www.cbsr.ia.ac.cn/users/xiangyuzhu/projects/3DDFA/main.htm\">300WLP (IEEE'2017)</a></summary>\n\n```bibtex\n@article{zhu2017face,\n  title={Face alignment in full pose range: A 3d total solution},\n  author={Zhu, Xiangyu and Liu, Xiaoming and Lei, Zhen and Li, Stan Z},\n  journal={IEEE transactions on pattern analysis and machine intelligence},\n  year={2017},\n  publisher={IEEE}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/aflw.md",
    "content": "# Annotated facial landmarks in the wild: A large-scale, real-world database for facial landmark localization\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6130513/\">AFLW (ICCVW'2011)</a></summary>\n\n```bibtex\n@inproceedings{koestinger2011annotated,\n  title={Annotated facial landmarks in the wild: A large-scale, real-world database for facial landmark localization},\n  author={Koestinger, Martin and Wohlhart, Paul and Roth, Peter M and Bischof, Horst},\n  booktitle={2011 IEEE international conference on computer vision workshops (ICCV workshops)},\n  pages={2144--2151},\n  year={2011},\n  organization={IEEE}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/aic.md",
    "content": "# Ai challenger: A large-scale dataset for going deeper in image understanding\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/animalkingdom.md",
    "content": "# Animal Kingdom: A Large and Diverse Dataset for Animal Behavior Understanding\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.08129\">Animal Kingdom (CVPR'2022)</a></summary>\n\n```bibtex\n@InProceedings{Ng_2022_CVPR,\n    author    = {Ng, Xun Long and Ong, Kian Eng and Zheng, Qichen and Ni, Yun and Yeo, Si Yong and Liu, Jun},\n    title     = {Animal Kingdom: A Large and Diverse Dataset for Animal Behavior Understanding},\n    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n    month     = {June},\n    year      = {2022},\n    pages     = {19023-19034}\n }\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/animalpose.md",
    "content": "# Cross-Domain Adaptation for Animal Pose Estimation\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/ap10k.md",
    "content": "# AP-10K: A Benchmark for Animal Pose Estimation in the Wild\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/atrw.md",
    "content": "# ATRW: A Benchmark for Amur Tiger Re-identification in the Wild\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1906.05586\">ATRW (ACM MM'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020atrw,\n  title={ATRW: A Benchmark for Amur Tiger Re-identification in the Wild},\n  author={Li, Shuyuan and Li, Jianguo and Tang, Hanlin and Qian, Rui and Lin, Weiyao},\n  booktitle={Proceedings of the 28th ACM International Conference on Multimedia},\n  pages={2590--2598},\n  year={2020}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/campus_and_shelf.md",
    "content": "# 3D Pictorial Structures for Multiple Human Pose Estimation\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf\">Campus and Shelf (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings {belagian14multi,\n    title = {{3D} Pictorial Structures for Multiple Human Pose Estimation},\n    author = {Belagiannis, Vasileios and Amin, Sikandar and Andriluka, Mykhaylo and Schiele, Bernt and Navab\n    Nassir and Ilic, Slobodan},\n    booktitle = {IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR)},\n    year = {2014},\n    month = {June},\n    organization={IEEE}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/coco.md",
    "content": "# Microsoft coco: Common objects in context\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/coco_wholebody.md",
    "content": "# Whole-Body Human Pose Estimation in the Wild\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/coco_wholebody_face.md",
    "content": "# Whole-Body Human Pose Estimation in the Wild\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/coco_wholebody_hand.md",
    "content": "# Whole-Body Human Pose Estimation in the Wild\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/cofw.md",
    "content": "# Robust face landmark estimation under occlusion\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2013/html/Burgos-Artizzu_Robust_Face_Landmark_2013_ICCV_paper.html\">COFW (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{burgos2013robust,\n  title={Robust face landmark estimation under occlusion},\n  author={Burgos-Artizzu, Xavier P and Perona, Pietro and Doll{\\'a}r, Piotr},\n  booktitle={Proceedings of the IEEE international conference on computer vision},\n  pages={1513--1520},\n  year={2013}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/crowdpose.md",
    "content": "# CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/deepfashion.md",
    "content": "# DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Liu_DeepFashion_Powering_Robust_CVPR_2016_paper.html\">DeepFashion (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuLQWTcvpr16DeepFashion,\n author = {Liu, Ziwei and Luo, Ping and Qiu, Shi and Wang, Xiaogang and Tang, Xiaoou},\n title = {DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations},\n booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n month = {June},\n year = {2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46475-6_15\">DeepFashion (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuYLWTeccv16FashionLandmark,\n author = {Liu, Ziwei and Yan, Sijie and Luo, Ping and Wang, Xiaogang and Tang, Xiaoou},\n title = {Fashion Landmark Detection in the Wild},\n booktitle = {European Conference on Computer Vision (ECCV)},\n month = {October},\n year = {2016}\n }\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/exlpose.md",
    "content": "# Human Pose Estimation in Extremely Low-Light Conditions\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://cg.postech.ac.kr/research/ExLPose/\">ExLPose (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ExLPose_2023_CVPR,\n title={Human Pose Estimation in Extremely Low-Light Conditions},\n author={Sohyun Lee, Jaesung Rim, Boseung Jeong, Geonu Kim, ByungJu Woo, Haechan Lee, Sunghyun Cho, Suha Kwak},\n booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n year={2023}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/fly.md",
    "content": "# Fast animal pose estimation using deep neural networks\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.nature.com/articles/s41592-018-0234-5\">Vinegar Fly (Nature Methods'2019)</a></summary>\n\n```bibtex\n@article{pereira2019fast,\n  title={Fast animal pose estimation using deep neural networks},\n  author={Pereira, Talmo D and Aldarondo, Diego E and Willmore, Lindsay and Kislin, Mikhail and Wang, Samuel S-H and Murthy, Mala and Shaevitz, Joshua W},\n  journal={Nature methods},\n  volume={16},\n  number={1},\n  pages={117--125},\n  year={2019},\n  publisher={Nature Publishing Group}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/freihand.md",
    "content": "# Freihand: A dataset for markerless capture of hand pose and shape from single rgb images\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Zimmermann_FreiHAND_A_Dataset_for_Markerless_Capture_of_Hand_Pose_and_ICCV_2019_paper.html\">FreiHand (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{zimmermann2019freihand,\n  title={Freihand: A dataset for markerless capture of hand pose and shape from single rgb images},\n  author={Zimmermann, Christian and Ceylan, Duygu and Yang, Jimei and Russell, Bryan and Argus, Max and Brox, Thomas},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={813--822},\n  year={2019}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/h36m.md",
    "content": "# Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/halpe.md",
    "content": "# PaStaNet: Toward Human Activity Knowledge Engine\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2004.00945\">Halpe (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020pastanet,\n  title={PaStaNet: Toward Human Activity Knowledge Engine},\n  author={Li, Yong-Lu and Xu, Liang and Liu, Xinpeng and Huang, Xijie and Xu, Yue and Wang, Shiyi and Fang, Hao-Shu and Ma, Ze and Chen, Mingyang and Lu, Cewu},\n  booktitle={CVPR},\n  year={2020}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/horse10.md",
    "content": "# Pretraining boosts out-of-domain robustness for pose estimation\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/WACV2021/html/Mathis_Pretraining_Boosts_Out-of-Domain_Robustness_for_Pose_Estimation_WACV_2021_paper.html\">Horse-10 (WACV'2021)</a></summary>\n\n```bibtex\n@inproceedings{mathis2021pretraining,\n  title={Pretraining boosts out-of-domain robustness for pose estimation},\n  author={Mathis, Alexander and Biasi, Thomas and Schneider, Steffen and Yuksekgonul, Mert and Rogers, Byron and Bethge, Matthias and Mathis, Mackenzie W},\n  booktitle={Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision},\n  pages={1859--1868},\n  year={2021}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/human_art.md",
    "content": "# Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://idea-research.github.io/HumanArt/\">Human-Art (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ju2023humanart,\n    title={Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes},\n    author={Ju, Xuan and Zeng, Ailing and Jianan, Wang and Qiang, Xu and Lei, Zhang},\n    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR),\n    year={2023}}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/interhand.md",
    "content": "# InterHand2.6M: A dataset and baseline for 3D interacting hand pose estimation from a single RGB image\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterHand2.6M (ECCV'2020)</a></summary>\n\n```bibtex\n@article{moon2020interhand2,\n  title={InterHand2.6M: A dataset and baseline for 3D interacting hand pose estimation from a single RGB image},\n  author={Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\n  journal={arXiv preprint arXiv:2008.09309},\n  year={2020},\n  publisher={Springer}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/jhmdb.md",
    "content": "# Towards understanding action recognition\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2013/html/Jhuang_Towards_Understanding_Action_2013_ICCV_paper.html\">JHMDB (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{Jhuang:ICCV:2013,\n  title = {Towards understanding action recognition},\n  author = {H. Jhuang and J. Gall and S. Zuffi and C. Schmid and M. J. Black},\n  booktitle = {International Conf. on Computer Vision (ICCV)},\n  month = Dec,\n  pages = {3192-3199},\n  year = {2013}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/lapa.md",
    "content": "# A New Dataset and Boundary-Attention Semantic Segmentation for Face Parsing\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://aaai.org/ojs/index.php/AAAI/article/view/6832/6686\">LaPa (AAAI'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020new,\n  title={A New Dataset and Boundary-Attention Semantic Segmentation for Face Parsing.},\n  author={Liu, Yinglu and Shi, Hailin and Shen, Hao and Si, Yue and Wang, Xiaobo and Mei, Tao},\n  booktitle={AAAI},\n  pages={11637--11644},\n  year={2020}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/locust.md",
    "content": "# DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Desert Locust (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/macaque.md",
    "content": "# MacaquePose: A novel ‘in the wild’macaque monkey pose dataset for markerless motion capture\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/pmc7874091/\">MacaquePose (bioRxiv'2020)</a></summary>\n\n```bibtex\n@article{labuguen2020macaquepose,\n  title={MacaquePose: A novel ‘in the wild’macaque monkey pose dataset for markerless motion capture},\n  author={Labuguen, Rollyn and Matsumoto, Jumpei and Negrete, Salvador and Nishimaru, Hiroshi and Nishijo, Hisao and Takada, Masahiko and Go, Yasuhiro and Inoue, Ken-ichi and Shibata, Tomohiro},\n  journal={bioRxiv},\n  year={2020},\n  publisher={Cold Spring Harbor Laboratory}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/mhp.md",
    "content": "# Understanding humans in crowded scenes: Deep nested adversarial learning and a new benchmark for multi-human parsing\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://dl.acm.org/doi/abs/10.1145/3240508.3240509\">MHP (ACM MM'2018)</a></summary>\n\n```bibtex\n@inproceedings{zhao2018understanding,\n  title={Understanding humans in crowded scenes: Deep nested adversarial learning and a new benchmark for multi-human parsing},\n  author={Zhao, Jian and Li, Jianshu and Cheng, Yu and Sim, Terence and Yan, Shuicheng and Feng, Jiashi},\n  booktitle={Proceedings of the 26th ACM international conference on Multimedia},\n  pages={792--800},\n  year={2018}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/mpi_inf_3dhp.md",
    "content": "# Monocular 3D Human Pose Estimation In The Wild Using Improved CNN Supervision\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8374605/\">MPI-INF-3DHP (3DV'2017)</a></summary>\n\n```bibtex\n@inproceedings{mono-3dhp2017,\n  author = {Mehta, Dushyant and Rhodin, Helge and Casas, Dan and Fua, Pascal and Sotnychenko, Oleksandr and Xu, Weipeng and Theobalt, Christian},\n  title = {Monocular 3D Human Pose Estimation In The Wild Using Improved CNN Supervision},\n  booktitle = {3D Vision (3DV), 2017 Fifth International Conference on},\n  url = {http://gvv.mpi-inf.mpg.de/3dhp_dataset},\n  year = {2017},\n  organization={IEEE},\n  doi={10.1109/3dv.2017.00064},\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/mpii.md",
    "content": "# 2D Human Pose Estimation: New Benchmark and State of the Art Analysis\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/mpii_trb.md",
    "content": "# TRB: A Novel Triplet Representation for Understanding 2D Human Body\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Duan_TRB_A_Novel_Triplet_Representation_for_Understanding_2D_Human_Body_ICCV_2019_paper.html\">MPII-TRB (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{duan2019trb,\n  title={TRB: A Novel Triplet Representation for Understanding 2D Human Body},\n  author={Duan, Haodong and Lin, Kwan-Yee and Jin, Sheng and Liu, Wentao and Qian, Chen and Ouyang, Wanli},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={9479--9488},\n  year={2019}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/ochuman.md",
    "content": "# Pose2seg: Detection free human instance segmentation\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Zhang_Pose2Seg_Detection_Free_Human_Instance_Segmentation_CVPR_2019_paper.html\">OCHuman (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{zhang2019pose2seg,\n  title={Pose2seg: Detection free human instance segmentation},\n  author={Zhang, Song-Hai and Li, Ruilong and Dong, Xin and Rosin, Paul and Cai, Zixi and Han, Xi and Yang, Dingcheng and Huang, Haozhi and Hu, Shi-Min},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={889--898},\n  year={2019}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/onehand10k.md",
    "content": "# Mask-pose cascaded cnn for 2d hand pose estimation from single color image\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/panoptic.md",
    "content": "# Hand keypoint detection in single images using multiview bootstrapping\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2017/html/Simon_Hand_Keypoint_Detection_CVPR_2017_paper.html\">CMU Panoptic HandDB (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{simon2017hand,\n  title={Hand keypoint detection in single images using multiview bootstrapping},\n  author={Simon, Tomas and Joo, Hanbyul and Matthews, Iain and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={1145--1153},\n  year={2017}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/panoptic_body3d.md",
    "content": "# Panoptic Studio: A Massively Multiview System for Social Motion Capture\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content_iccv_2015/html/Joo_Panoptic_Studio_A_ICCV_2015_paper.html\">CMU Panoptic (ICCV'2015)</a></summary>\n\n```bibtex\n@Article = {joo_iccv_2015,\nauthor = {Hanbyul Joo, Hao Liu, Lei Tan, Lin Gui, Bart Nabbe, Iain Matthews, Takeo Kanade, Shohei Nobuhara, and Yaser Sheikh},\ntitle = {Panoptic Studio: A Massively Multiview System for Social Motion Capture},\nbooktitle = {ICCV},\nyear = {2015}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/posetrack18.md",
    "content": "# Posetrack: A benchmark for human pose estimation and tracking\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Andriluka_PoseTrack_A_Benchmark_CVPR_2018_paper.html\">PoseTrack18 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{andriluka2018posetrack,\n  title={Posetrack: A benchmark for human pose estimation and tracking},\n  author={Andriluka, Mykhaylo and Iqbal, Umar and Insafutdinov, Eldar and Pishchulin, Leonid and Milan, Anton and Gall, Juergen and Schiele, Bernt},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={5167--5176},\n  year={2018}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/rhd.md",
    "content": "# Learning to Estimate 3D Hand Pose from Single RGB Images\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/ubody.md",
    "content": "# One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2303.16160\">UBody (CVPR'2023)</a></summary>\n\n```bibtex\n@article{lin2023one,\n  title={One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer},\n  author={Lin, Jing and Zeng, Ailing and Wang, Haoqian and Zhang, Lei and Li, Yu},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  year={2023},\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/wflw.md",
    "content": "# Look at boundary: A boundary-aware face alignment algorithm\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/datasets/zebra.md",
    "content": "# DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Grévy’s Zebra (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/techniques/albumentations.md",
    "content": "# Albumentations: fast and flexible image augmentations\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.mdpi.com/649002\">Albumentations (Information'2020)</a></summary>\n\n```bibtex\n@article{buslaev2020albumentations,\n  title={Albumentations: fast and flexible image augmentations},\n  author={Buslaev, Alexander and Iglovikov, Vladimir I and Khvedchenya, Eugene and Parinov, Alex and Druzhinin, Mikhail and Kalinin, Alexandr A},\n  journal={Information},\n  volume={11},\n  number={2},\n  pages={125},\n  year={2020},\n  publisher={Multidisciplinary Digital Publishing Institute}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/techniques/awingloss.md",
    "content": "# Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/1904.07399.pdf\">AdaptiveWingloss (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{wang2019adaptive,\n  title={Adaptive wing loss for robust face alignment via heatmap regression},\n  author={Wang, Xinyao and Bo, Liefeng and Fuxin, Li},\n  booktitle={Proceedings of the IEEE/CVF international conference on computer vision},\n  pages={6971--6981},\n  year={2019}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHeatmap regression with a deep network has become one of the mainstream approaches to localize facial landmarks. However, the loss function for heatmap regression is rarely studied. In this paper, we analyze the ideal loss function properties for heatmap regression in face alignment problems. Then we propose a novel loss function, named Adaptive Wing loss, that is able to adapt its shape to different types of ground truth heatmap pixels. This adaptability penalizes loss more on foreground pixels while less on background pixels. To address the imbalance between foreground and background pixels, we also propose Weighted Loss Map, which assigns high weights on foreground and difficult background pixels to help training process focus more on pixels that are crucial to landmark localization. To further improve face alignment accuracy, we introduce boundary prediction and CoordConv with boundary coordinates. Extensive experiments on different benchmarks, including COFW, 300W and WFLW, show our approach outperforms the state-of-the-art by a significant margin on\nvarious evaluation metrics. Besides, the Adaptive Wing loss also helps other heatmap regression tasks.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/148007960-a06a34d8-8090-49e1-80db-6bbe4a7e7e8d.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/dark.md",
    "content": "# Distribution-aware coordinate representation for human pose estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Zhang_Distribution-Aware_Coordinate_Representation_for_Human_Pose_Estimation_CVPR_2020_paper.html\">DarkPose (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{zhang2020distribution,\n  title={Distribution-aware coordinate representation for human pose estimation},\n  author={Zhang, Feng and Zhu, Xiatian and Dai, Hanbin and Ye, Mao and Zhu, Ce},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={7093--7102},\n  year={2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWhile being the de facto standard coordinate representation for human pose estimation, heatmap has not been investigated in-depth. This work fills this gap. For the first time, we find that the process of decoding the predicted heatmaps into the final joint coordinates in the original image space is surprisingly significant for the performance. We further probe the design limitations of the standard coordinate decoding method, and propose a more principled distributionaware decoding method. Also, we improve the standard coordinate encoding process (i.e. transforming ground-truth coordinates to heatmaps) by generating unbiased/accurate heatmaps. Taking the two together, we formulate a novel Distribution-Aware coordinate Representation of Keypoints (DARK) method. Serving as a model-agnostic plug-in, DARK brings about significant performance boost to existing human pose estimation models. Extensive experiments show that DARK yields the best results on two common benchmarks, MPII and COCO. Besides, DARK achieves the 2nd place entry in the ICCV 2019 COCO Keypoints Challenge. The code is available online.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146514732-1d53614b-e5b7-4a1c-a39f-6fc726217d81.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/fp16.md",
    "content": "# Mixed Precision Training\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1710.03740\">FP16 (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{micikevicius2017mixed,\n  title={Mixed precision training},\n  author={Micikevicius, Paulius and Narang, Sharan and Alben, Jonah and Diamos, Gregory and Elsen, Erich and Garcia, David and Ginsburg, Boris and Houston, Michael and Kuchaiev, Oleksii and Venkatesh, Ganesh and others},\n  journal={arXiv preprint arXiv:1710.03740},\n  year={2017}\n}\n```\n\n</details>\n"
  },
  {
    "path": "docs/src/papers/techniques/fpn.md",
    "content": "# Feature pyramid networks for object detection\n\n<!-- [OTHERS] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content_cvpr_2017/html/Lin_Feature_Pyramid_Networks_CVPR_2017_paper.html\">FPN (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{lin2017feature,\n  title={Feature pyramid networks for object detection},\n  author={Lin, Tsung-Yi and Doll{\\'a}r, Piotr and Girshick, Ross and He, Kaiming and Hariharan, Bharath and Belongie, Serge},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2117--2125},\n  year={2017}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nFeature pyramids are a basic component in recognition systems for detecting objects at different scales. But recent deep learning object detectors have avoided pyramid representations, in part because they are compute and memory intensive. In this paper, we exploit the inherent multi-scale, pyramidal hierarchy of deep convolutional networks to construct feature pyramids with marginal extra cost. A topdown architecture with lateral connections is developed for building high-level semantic feature maps at all scales. This architecture, called a Feature Pyramid Network (FPN), shows significant improvement as a generic feature extractor in several applications. Using FPN in a basic Faster R-CNN system, our method achieves state-of-the-art singlemodel results on the COCO detection benchmark without bells and whistles, surpassing all existing single-model entries including those from the COCO 2016 challenge winners. In addition, our method can run at 6 FPS on a GPU and thus is a practical and accurate solution to multi-scale object detection. Code will be made publicly available.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146524686-ddfe1356-77bd-46a0-a6cd-7ff418f65675.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/rle.md",
    "content": "# Human pose regression with residual log-likelihood estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2107.11291\">RLE (ICCV'2021)</a></summary>\n\n```bibtex\n@inproceedings{li2021human,\n  title={Human pose regression with residual log-likelihood estimation},\n  author={Li, Jiefeng and Bian, Siyuan and Zeng, Ailing and Wang, Can and Pang, Bo and Liu, Wentao and Lu, Cewu},\n  booktitle={Proceedings of the IEEE/CVF International Conference on Computer Vision},\n  pages={11025--11034},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nHeatmap-based methods dominate in the field of human pose estimation by modelling the output distribution through likelihood heatmaps. In contrast, regressionbased methods are more efficient but suffer from inferior performance. In this work, we explore maximum likelihood estimation (MLE) to develop an efficient and effective regression-based methods. From the perspective of MLE, adopting different regression losses is making different assumptions about the output density function. A density function closer to the true distribution leads to a better regression performance. In light of this, we propose a novel regression paradigm with Residual Log-likelihood Estimation (RLE) to capture the underlying output distribution. Concretely, RLE learns the change of the distribution instead of the unreferenced underlying distribution to facilitate the training process. With the proposed reparameterization design, our method is compatible with offthe-shelf flow models. The proposed method is effective, efficient and flexible. We show its potential in various human pose estimation tasks with comprehensive experiments. Compared to the conventional regression paradigm, regression with RLE bring 12.4 mAP improvement on MSCOCO without any test-time overhead. Moreover, for the first time, especially on multi-person pose estimation, our regression method is superior to the heatmap-based methods.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/166661858-e1149715-02cf-4393-b948-81c8e39f247d.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/smoothnet.md",
    "content": "# SmoothNet: A Plug-and-Play Network for Refining Human Poses in Videos\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2112.13715\">SmoothNet (arXiv'2021)</a></summary>\n\n```bibtex\n@article{zeng2021smoothnet,\n  title={SmoothNet: A Plug-and-Play Network for Refining Human Poses in Videos},\n  author={Zeng, Ailing and Yang, Lei and Ju, Xuan and Li, Jiefeng and Wang, Jianyi and Xu, Qiang},\n  journal={arXiv preprint arXiv:2112.13715},\n  year={2021}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWhen analyzing human motion videos, the output jitters from existing pose estimators are highly-unbalanced. Most frames only suffer from slight jitters, while significant jitters occur in those frames with occlusion or poor image quality. Such complex poses often persist in videos, leading to consecutive frames with poor estimation results and large jitters. Existing pose smoothing solutions based on temporal convolutional networks, recurrent neural networks, or low-pass filters cannot deal with such a long-term jitter problem without considering the significant and persistent errors within the jittering video segment. Motivated by the above observation, we propose a novel plug-and-play refinement network, namely SMOOTHNET, which can be attached to any existing pose estimators to improve its temporal smoothness and enhance its per-frame precision simultaneously. Especially, SMOOTHNET is a simple yet effective data-driven fully-connected network with large receptive fields, effectively mitigating the impact of long-term jitters with unreliable estimation results. We conduct extensive experiments on twelve backbone networks with seven datasets across 2D and 3D pose estimation, body recovery, and downstream tasks. Our results demonstrate that the proposed SMOOTHNET consistently outperforms existing solutions, especially on those clips with high errors and long-term jitters.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/161272519-0165c0e2-f0e8-45ad-88dd-ddb49fc81bda.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/softwingloss.md",
    "content": "# Structure-Coherent Deep Feature Learning for Robust Face Alignment\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/document/9442331/\">SoftWingloss (TIP'2021)</a></summary>\n\n```bibtex\n@article{lin2021structure,\n  title={Structure-Coherent Deep Feature Learning for Robust Face Alignment},\n  author={Lin, Chunze and Zhu, Beier and Wang, Quan and Liao, Renjie and Qian, Chen and Lu, Jiwen and Zhou, Jie},\n  journal={IEEE Transactions on Image Processing},\n  year={2021},\n  publisher={IEEE}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nIn this paper, we propose a structure-coherent deep feature learning method for face alignment. Unlike most existing face alignment methods which overlook the facial structure cues, we explicitly exploit the relation among facial landmarks to make the detector robust to hard cases such as occlusion and large pose. Specifically, we leverage a landmark-graph relational network to enforce the structural relationships among landmarks. We consider the facial landmarks as structural graph nodes and carefully design the neighborhood to passing features among the most related nodes. Our method dynamically adapts the weights of node neighborhood to eliminate distracted information from noisy nodes, such as occluded landmark point. Moreover, different from most previous works which only tend to penalize the landmarks absolute position during the training, we propose a relative location loss to enhance the information of relative location of landmarks. This relative location supervision further regularizes the facial structure. Our approach considers the interactions among facial landmarks and can be easily implemented on top of any convolutional backbone to boost the performance. Extensive experiments on three popular benchmarks, including WFLW, COFW and 300W, demonstrate the effectiveness of the proposed method. In particular, due to explicit structure modeling, our approach is especially robust to challenging cases resulting in impressive low failure rate on COFW and WFLW datasets.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/148036579-b128fb21-3a2d-4894-bb54-4223a4cdf856.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/udp.md",
    "content": "# The Devil is in the Details: Delving into Unbiased Data Processing for Human Pose Estimation\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2020/html/Huang_The_Devil_Is_in_the_Details_Delving_Into_Unbiased_Data_CVPR_2020_paper.html\">UDP (CVPR'2020)</a></summary>\n\n```bibtex\n@InProceedings{Huang_2020_CVPR,\n  author = {Huang, Junjie and Zhu, Zheng and Guo, Feng and Huang, Guan},\n  title = {The Devil Is in the Details: Delving Into Unbiased Data Processing for Human Pose Estimation},\n  booktitle = {The IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n  month = {June},\n  year = {2020}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nRecently, the leading performance of human pose estimation is dominated by top-down methods. Being a fundamental component in training and inference, data processing has not been systematically considered in pose estimation community, to the best of our knowledge. In this paper, we focus on this problem and find that the devil of top-down pose estimator is in the biased data processing. Specifically, by investigating the standard data processing in state-of-the-art approaches mainly including data transformation and encoding-decoding, we find that the results obtained by common flipping strategy are unaligned with the original ones in inference. Moreover, there is statistical error in standard encoding-decoding during both training and inference. Two problems couple together and significantly degrade the pose estimation performance. Based on quantitative analyses, we then formulate a principled way to tackle this dilemma. Data is processed in continuous space based on unit length (the intervals between pixels) instead of in discrete space with pixel, and a combined classification and regression approach is adopted to perform encoding-decoding. The Unbiased Data Processing (UDP) for human pose estimation can be achieved by combining the two together. UDP not only boosts the performance of existing methods by a large margin but also plays a important role in result reproducing and future exploration. As a model-agnostic approach, UDP promotes SimpleBaseline-ResNet50-256x192 by 1.5 AP (70.2 to 71.7) and HRNet-W32-256x192 by 1.7 AP (73.5 to 75.2) on COCO test-dev set. The HRNet-W48-384x288 equipped with UDP achieves 76.5 AP and sets a new state-of-the-art for human pose estimation. The source code is publicly available for further research.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146524686-ddfe1356-77bd-46a0-a6cd-7ff418f65675.png\">\n</div>\n"
  },
  {
    "path": "docs/src/papers/techniques/wingloss.md",
    "content": "# Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks\n\n<!-- [ALGORITHM] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Feng_Wing_Loss_for_CVPR_2018_paper.html\">Wingloss (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{feng2018wing,\n  title={Wing Loss for Robust Facial Landmark Localisation with Convolutional Neural Networks},\n  author={Feng, Zhen-Hua and Kittler, Josef and Awais, Muhammad and Huber, Patrik and Wu, Xiao-Jun},\n  booktitle={Computer Vision and Pattern Recognition (CVPR), 2018 IEEE Conference on},\n  year={2018},\n  pages ={2235-2245},\n  organization={IEEE}\n}\n```\n\n</details>\n\n## Abstract\n\n<!-- [ABSTRACT] -->\n\nWe present a new loss function, namely Wing loss, for robust facial landmark localisation with Convolutional Neural Networks (CNNs). We first compare and analyse different loss functions including L2, L1 and smooth L1. The analysis of these loss functions suggests that, for the training of a CNN-based localisation model, more attention should be paid to small and medium range errors. To this end, we design a piece-wise loss function. The new loss amplifies the impact of errors from the interval (-w, w) by switching from L1 loss to a modified logarithm function. To address the problem of under-representation of samples with large out-of-plane head rotations in the training set, we propose a simple but effective boosting strategy, referred to as pose-based data balancing. In particular, we deal with the data imbalance problem by duplicating the minority training samples and perturbing them by injecting random image rotation, bounding box translation and other data augmentation approaches. Last, the proposed approach is extended to create a two-stage framework for robust facial landmark localisation. The experimental results obtained on AFLW and 300W demonstrate the merits of the Wing loss function, and prove the superiority of the proposed method over the state-of-the-art approaches.\n\n<!-- [IMAGE] -->\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/15977946/146528473-f3228f69-b60e-4807-9c4b-b45997fbc530.png\">\n</div>\n"
  },
  {
    "path": "docs/zh_cn/.readthedocs.yaml",
    "content": "version: 2\n\nformats:\n  - epub\n\nbuild:\n  os: ubuntu-22.04\n  tools:\n    python: \"3.8\"\n\nsphinx:\n  configuration: docs/zh_cn/conf.py\n\npython:\n  install:\n    - requirements: requirements/docs.txt\n    - requirements: requirements/readthedocs.txt\n"
  },
  {
    "path": "docs/zh_cn/Makefile",
    "content": "# Minimal makefile for Sphinx documentation\n#\n\n# You can set these variables from the command line, and also\n# from the environment for the first two.\nSPHINXOPTS    ?=\nSPHINXBUILD   ?= sphinx-build\nSOURCEDIR     = .\nBUILDDIR      = _build\n\n# Put it first so that \"make\" without argument is like \"make help\".\nhelp:\n\t@$(SPHINXBUILD) -M help \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n\n.PHONY: help Makefile\n\n# Catch-all target: route all unknown targets to Sphinx using the new\n# \"make mode\" option.  $(O) is meant as a shortcut for $(SPHINXOPTS).\n%: Makefile\n\t@$(SPHINXBUILD) -M $@ \"$(SOURCEDIR)\" \"$(BUILDDIR)\" $(SPHINXOPTS) $(O)\n"
  },
  {
    "path": "docs/zh_cn/_static/css/readthedocs.css",
    "content": ".header-logo {\n    background-image: url(\"../images/mmpose-logo.png\");\n    background-size: 120px 50px;\n    height: 50px;\n    width: 120px;\n}\n\ntable.autosummary td {\n    width: 35%\n}\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/codecs.md",
    "content": "# 编解码器\n\n在关键点检测任务中，根据算法的不同，需要利用标注信息，生成不同格式的训练目标，比如归一化的坐标值、一维向量、高斯热图等。同样的，对于模型输出的结果，也需要经过处理转换成标注信息格式。我们一般将标注信息到训练目标的处理过程称为编码，模型输出到标注信息的处理过程称为解码。\n\n编码和解码是一对紧密相关的互逆处理过程。在 MMPose 早期版本中，编码和解码过程往往分散在不同模块里，使其不够直观和统一，增加了学习和维护成本。\n\nMMPose 1.0 中引入了新模块 **编解码器（Codec）** ，将关键点数据的编码和解码过程进行集成，以增加代码的友好度和复用性。\n\n编解码器在工作流程中所处的位置如下所示：\n\n![pose_estimator_cn](https://github.com/open-mmlab/mmpose/assets/13503330/0c048f66-b889-4268-937f-71b8753b505f)\n\n## 基本概念\n\n一个编解码器主要包含两个部分：\n\n- 编码器\n- 解码器\n\n### 编码器\n\n编码器主要负责将处于输入图片尺度的坐标值，编码为模型训练所需要的目标格式，主要包括：\n\n- 归一化的坐标值：用于 Regression-based 方法\n- 一维向量：用于 SimCC-based 方法\n- 高斯热图：用于 Heatmap-based 方法\n\n以 Regression-based 方法的编码器为例：\n\n```Python\ndef encode(self,\n           keypoints: np.ndarray,\n           keypoints_visible: Optional[np.ndarray] = None) -> dict:\n    \"\"\"Encoding keypoints from input image space to normalized space.\n\n    Args:\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n\n    Returns:\n        dict:\n        - keypoint_labels (np.ndarray): The normalized regression labels in\n            shape (N, K, D) where D is 2 for 2d coordinates\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (N, K)\n    \"\"\"\n    if keypoints_visible is None:\n        keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n    w, h = self.input_size\n    valid = ((keypoints >= 0) &\n             (keypoints <= [w - 1, h - 1])).all(axis=-1) & (\n                 keypoints_visible > 0.5)\n\n    keypoint_labels = (keypoints / np.array([w, h])).astype(np.float32)\n    keypoint_weights = np.where(valid, 1., 0.).astype(np.float32)\n\n    encoded = dict(\n        keypoint_labels=keypoint_labels, keypoint_weights=keypoint_weights)\n\n    return encoded\n```\n\n编码后的数据会在 `PackPoseInputs` 中被转换为 Tensor 格式，并封装到 `data_sample.gt_instance_labels` 中供模型调用，默认包含以下的字段：\n\n- `keypoint_labels`\n- `keypoint_weights`\n- `keypoints_visible_weights`\n\n如要指定要打包的数据字段，可以在编解码器中定义 `label_mapping_table` 属性。例如，在 `VideoPoseLifting` 中：\n\n```Python\nlabel_mapping_table = dict(\n        trajectory_weights='trajectory_weights',\n        lifting_target_label='lifting_target_label',\n        lifting_target_weight='lifting_target_weight',\n)\n```\n\n`data_sample.gt_instance_labels` 一般主要用于 loss 计算，下面以 `RegressionHead` 中的 `loss()` 为例：\n\n```Python\ndef loss(self,\n         inputs: Tuple[Tensor],\n         batch_data_samples: OptSampleList,\n         train_cfg: ConfigType = {}) -> dict:\n    \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n    pred_outputs = self.forward(inputs)\n\n    keypoint_labels = torch.cat(\n        [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n    keypoint_weights = torch.cat([\n        d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n    ])\n\n    # calculate losses\n    losses = dict()\n    loss = self.loss_module(pred_outputs, keypoint_labels,\n                            keypoint_weights.unsqueeze(-1))\n\n    losses.update(loss_kpt=loss)\n    ### 后续内容省略 ###\n```\n\n```{note}\n解码器亦会定义封装在 `data_sample.gt_instances` 和 `data_sample.gt_fields` 中的字段。修改编码器中的 `instance_mapping_table` 和 `field_mapping_table` 的值将分别指定封装的字段，其中默认值定义在 [BaseKeypointCodec](https://github.com/open-mmlab/mmpose/blob/main/mmpose/codecs/base.py) 中。\n```\n\n### 解码器\n\n解码器主要负责将模型的输出解码为输入图片尺度的坐标值，处理过程与编码器相反。\n\n以 Regression-based 方法的解码器为例：\n\n```Python\ndef decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Decode keypoint coordinates from normalized space to input image\n    space.\n\n    Args:\n        encoded (np.ndarray): Coordinates in shape (N, K, D)\n\n    Returns:\n        tuple:\n        - keypoints (np.ndarray): Decoded coordinates in shape (N, K, D)\n        - scores (np.ndarray): The keypoint scores in shape (N, K).\n            It usually represents the confidence of the keypoint prediction\n\n    \"\"\"\n\n    if encoded.shape[-1] == 2:\n        N, K, _ = encoded.shape\n        normalized_coords = encoded.copy()\n        scores = np.ones((N, K), dtype=np.float32)\n    elif encoded.shape[-1] == 4:\n        # split coords and sigma if outputs contain output_sigma\n        normalized_coords = encoded[..., :2].copy()\n        output_sigma = encoded[..., 2:4].copy()\n        scores = (1 - output_sigma).mean(axis=-1)\n    else:\n        raise ValueError(\n            'Keypoint dimension should be 2 or 4 (with sigma), '\n            f'but got {encoded.shape[-1]}')\n\n    w, h = self.input_size\n    keypoints = normalized_coords * np.array([w, h])\n\n    return keypoints, scores\n```\n\n默认情况下，`decode()` 方法只提供单个目标数据的解码过程，你也可以通过 `batch_decode()` 来实现批量解码提升执行效率。\n\n## 常见用法\n\n在 MMPose 配置文件中，主要有三处涉及编解码器：\n\n- 定义编解码器\n- 生成训练目标\n- 模型头部\n\n### 定义编解码器\n\n以回归方法生成归一化的坐标值为例，在配置文件中，我们通过如下方式定义编解码器：\n\n```Python\ncodec = dict(type='RegressionLabel', input_size=(192, 256))\n```\n\n### 生成训练目标\n\n在数据处理阶段生成训练目标时，需要传入编解码器用于编码：\n\n```Python\ndict(type='GenerateTarget', encoder=codec)\n```\n\n### 模型头部\n\n在 MMPose 中，我们在模型头部对模型的输出进行解码，需要传入编解码器用于解码：\n\n```Python\nhead=dict(\n    type='RLEHead',\n    in_channels=2048,\n    num_joints=17,\n    loss=dict(type='RLELoss', use_target_weight=True),\n    decoder=codec\n)\n```\n\n它们在配置文件中的具体位置如下:\n\n```Python\n\n# codec settings\ncodec = dict(type='RegressionLabel', input_size=(192, 256))                     ## 定义 ##\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='ResNet',\n        depth=50,\n        init_cfg=dict(type='Pretrained', checkpoint='torchvision://resnet50'),\n    ),\n    neck=dict(type='GlobalAveragePooling'),\n    head=dict(\n        type='RLEHead',\n        in_channels=2048,\n        num_joints=17,\n        loss=dict(type='RLELoss', use_target_weight=True),\n        decoder=codec),                                                         ## 模型头部 ##\n    test_cfg=dict(\n        flip_test=True,\n        shift_coords=True,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),   ## 生成训练目标 ##\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n```\n\n## 已支持编解码器列表\n\n编解码器相关的代码位于 [$MMPOSE/mmpose/codecs/](https://github.com/open-mmlab/mmpose/tree/dev-1.x/mmpose/codecs)。目前 MMPose 已支持的编解码器如下所示：\n\n- [RegressionLabel](#RegressionLabel)\n- [IntegralRegressionLabel](#IntegralRegressionLabel)\n- [MSRAHeatmap](#MSRAHeatmap)\n- [UDPHeatmap](#UDPHeatmap)\n- [MegviiHeatmap](#MegviiHeatmap)\n- [SPR](#SPR)\n- [SimCC](#SimCC)\n- [DecoupledHeatmap](#DecoupledHeatmap)\n- [ImagePoseLifting](#ImagePoseLifting)\n- [VideoPoseLifting](#VideoPoseLifting)\n- [MotionBERTLabel](#MotionBERTLabel)\n\n### RegressionLabel\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/regression_label.py#L12)\n\nRegressionLabel 编解码器主要用于 Regression-based 方法，适用于直接把坐标值作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为**归一化**的坐标值，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的归一化坐标值解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [DeepPose](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#deeppose-cvpr-2014)\n- [RLE](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#rle-iccv-2021)\n\n### IntegralRegressionLabel\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/integral_regression_label.py)\n\nIntegralRegressionLabel 编解码器主要用于 Integral Regression-based 方法，适用于把坐标值作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为**归一化**的坐标值，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的归一化坐标值解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [IPR](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#ipr-eccv-2018)\n- [DSNT](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#dsnt-2018)\n- [Debias IPR](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#debias-ipr-iccv-2021)\n\n### MSRAHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/msra_heatmap.py)\n\nMSRAHeatmap 编解码器主要用于 Heatmap-based 方法，适用于把高斯热图作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为 2D 离散高斯分布，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 2D 高斯分布解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [SimpleBaseline2D](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#simplebaseline2d-eccv-2018)\n- [CPM](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#cpm-cvpr-2016)\n- [HRNet](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#hrnet-cvpr-2019)\n- [DARK](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#darkpose-cvpr-2020)\n\n### UDPHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/udp_heatmap.py)\n\nUDPHeatmap 编解码器主要用于 Heatmap-based 方法，适用于把高斯热图作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为 2D 离散高斯分布，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 2D 高斯分布解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [UDP](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#udp-cvpr-2020)\n\n### MegviiHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/megvii_heatmap.py)\n\nMegviiHeatmap 编解码器主要用于 Megvii 提出的 Heatmap-based 方法，适用于把高斯热图作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为 2D 离散高斯分布，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 2D 高斯分布解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [MSPN](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#mspn-arxiv-2019)\n- [RSN](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#rsn-eccv-2020)\n\n### SPR\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/spr.py)\n\nSPR 编解码器主要用于 DEKR 方法，适用于同时使用中心 Heatmap 和偏移坐标值作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的中心关键点坐标值编码为 2D 离散高斯分布，以及相对于中心的偏移，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 2D 高斯分布与偏移进行组合，解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [DEKR](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#dekr-cvpr-2021)\n\n### SimCC\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/simcc_label.py)\n\nSimCC 编解码器主要用于 SimCC-based 方法，适用于两个 1D 离散分布表征的 x 和 y 坐标作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为水平和竖直方向 1D 离散分布，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 1D 离散分布解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [SimCC](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#simcc-eccv-2022)\n- [RTMPose](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#rtmpose-arxiv-2023)\n\n### DecoupledHeatmap\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/decoupled_heatmap.py)\n\nDecoupledHeatmap 编解码器主要用于 CID 方法，适用于把高斯热图作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的人体中心坐标值和关键点坐标值编码为 2D 离散高斯分布，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的人体中心与关键点 2D 高斯分布解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [CID](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#cid-cvpr-2022)\n\n### ImagePoseLifting\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/image_pose_lifting.py)\n\nImagePoseLifting 编解码器主要用于 2D-to-3D pose lifting 方法，适用于把单张图片的 2D 坐标值作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为 3D 坐标空间归一化的坐标值，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 3D 坐标空间归一化的坐标值解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [SimpleBaseline3D](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#simplebaseline3d-iccv-2017)\n\n### VideoPoseLifting\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/video_pose_lifting.py)\n\nVideoPoseLifting 编解码器主要用于 2D-to-3D pose lifting 方法，适用于把视频中一组 2D 坐标值作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为 3D 坐标空间归一化的坐标值，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 3D 坐标空间归一化的坐标值解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [VideoPose3D](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo_papers/algorithms.html#videopose3d-cvpr-2019)\n\n### MotionBERTLabel\n\n[\\[Github\\]](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/motionbert_label.py)\n\nMotionBERTLabel 编解码器主要用于 2D-to-3D pose lifting 方法，适用于把视频中一组 2D 坐标值作为训练目标的场景。\n\n**输入：**\n\n- 将**输入图片尺度**的坐标值编码为 3D 坐标空间归一化的坐标值，用于训练目标的生成。\n\n**输出：**\n\n- 将模型输出的 3D 坐标空间归一化的坐标值解码为**输入图片尺度**的坐标值。\n\n常见的使用此编解码器的算法有：\n\n- [MotionBERT](https://mmpose.readthedocs.io/zh_CN/dev-1.x/model_zoo/body_3d_keypoint.html#pose-lift-motionbert-on-h36m)\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/customize_datasets.md",
    "content": "# 自定义数据集\n\nMMPose 目前已支持了多个任务和相应的数据集。您可以在 [数据集](https://mmpose.readthedocs.io/zh_CN/latest/dataset_zoo.html) 找到它们。请按照相应的指南准备数据。\n\n<!-- TOC -->\n\n- [自定义数据集-将数据组织为 COCO 格式](#自定义数据集-将数据组织为-coco-格式)\n- [创建自定义数据集的元信息文件](#创建自定义数据集的元信息文件)\n- [创建自定义数据集类](#创建自定义数据集类)\n- [创建自定义配置文件](#创建自定义配置文件)\n- [数据集封装](#数据集封装)\n\n<!-- TOC -->\n\n## 将数据组织为 COCO 格式\n\n最简单的使用自定义数据集的方法是将您的注释格式转换为 COCO 数据集格式。\n\nCOCO 格式的注释 JSON 文件具有以下必要键：\n\n```python\n'images': [\n    {\n        'file_name': '000000001268.jpg',\n        'height': 427,\n        'width': 640,\n        'id': 1268\n    },\n    ...\n],\n'annotations': [\n    {\n        'segmentation': [[426.36,\n            ...\n            424.34,\n            223.3]],\n        'keypoints': [0,0,0,\n            0,0,0,\n            0,0,0,\n            427,220,2,\n            443,222,2,\n            414,228,2,\n            449,232,2,\n            408,248,1,\n            454,261,2,\n            0,0,0,\n            0,0,0,\n            411,287,2,\n            431,287,2,\n            0,0,0,\n            458,265,2,\n            0,0,0,\n            466,300,1],\n        'num_keypoints': 10,\n        'area': 3894.5826,\n        'iscrowd': 0,\n        'image_id': 1268,\n        'bbox': [402.34, 205.02, 65.26, 88.45],\n        'category_id': 1,\n        'id': 215218\n    },\n    ...\n],\n'categories': [\n    {'id': 1, 'name': 'person'},\n ]\n```\n\nJSON 标注文件中有三个关键词是必需的：\n\n- `images`：包含所有图像信息的列表，每个图像都有一个 `file_name`、`height`、`width` 和 `id` 键。\n- `annotations`：包含所有实例标注信息的列表，每个实例都有一个 `segmentation`、`keypoints`、`num_keypoints`、`area`、`iscrowd`、`image_id`、`bbox`、`category_id` 和 `id` 键。\n- `categories`：包含所有类别信息的列表，每个类别都有一个 `id` 和 `name` 键。以人体姿态估计为例，`id` 为 1，`name` 为 `person`。\n\n如果您的数据集已经是 COCO 格式的，那么您可以直接使用 `CocoDataset` 类来读取该数据集。\n\n## 创建自定义数据集的元信息文件\n\n对于一个新的数据集而言，您需要创建一个新的数据集元信息文件。该文件包含了数据集的基本信息，如关键点个数、排列顺序、可视化颜色、骨架连接关系等。元信息文件通常存放在 `config/_base_/datasets/` 目录下，例如：\n\n```\nconfig/_base_/datasets/custom.py\n```\n\n元信息文件中需要包含以下信息：\n\n- `keypoint_info`：每个关键点的信息：\n  1. `name`: 关键点名称，必须是唯一的，例如 `nose`、`left_eye` 等。\n  2. `id`: 关键点 ID，必须是唯一的，从 0 开始。\n  3. `color`: 关键点可视化时的颜色，以 (\\[B, G, R\\]) 格式组织起来，用于可视化。\n  4. `type`: 关键点类型，可以是 `upper`、`lower` 或 `''`，用于数据增强 [RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/b225a773d168fc2afd48cde5f76c0202d1ba2f52/mmpose/datasets/transforms/common_transforms.py#L263)。\n  5. `swap`: 关键点交换关系，用于水平翻转数据增强 [RandomFlip](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L94)。\n- `skeleton_info`：骨架连接关系，用于可视化。\n- `joint_weights`：每个关键点的权重，用于损失函数计算。\n- `sigma`：标准差，用于计算 OKS 分数，详细信息请参考 [keypoints-eval](https://cocodataset.org/#keypoints-eval)。\n\n下面是一个简化版本的元信息文件（[完整版](/configs/_base_/datasets/coco.py)）：\n\n```python\ndataset_info = dict(\n    dataset_name='coco',\n    paper_info=dict(\n        author='Lin, Tsung-Yi and Maire, Michael and '\n        'Belongie, Serge and Hays, James and '\n        'Perona, Pietro and Ramanan, Deva and '\n        r'Doll{\\'a}r, Piotr and Zitnick, C Lawrence',\n        title='Microsoft coco: Common objects in context',\n        container='European conference on computer vision',\n        year='2014',\n        homepage='http://cocodataset.org/',\n    ),\n    keypoint_info={\n        0:\n        dict(name='nose', id=0, color=[51, 153, 255], type='upper', swap=''),\n        1:\n        dict(\n            name='left_eye',\n            id=1,\n            color=[51, 153, 255],\n            type='upper',\n            swap='right_eye'),\n        ...\n        16:\n        dict(\n            name='right_ankle',\n            id=16,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle')\n    },\n    skeleton_info={\n        0:\n        dict(link=('left_ankle', 'left_knee'), id=0, color=[0, 255, 0]),\n        ...\n        18:\n        dict(\n            link=('right_ear', 'right_shoulder'), id=18, color=[51, 153, 255])\n    },\n    joint_weights=[\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ],\n    sigmas=[\n        0.026, 0.025, 0.025, 0.035, 0.035, 0.079, 0.079, 0.072, 0.072, 0.062,\n        0.062, 0.107, 0.107, 0.087, 0.087, 0.089, 0.089\n    ])\n```\n\n## 创建自定义数据集类\n\n如果标注信息不是用 COCO 格式存储的，那么您需要创建一个新的数据集类。数据集类需要继承自 `BaseDataset` 类，并且需要按照以下步骤实现：\n\n1. 在 `mmpose/datasets/datasets` 目录下找到该数据集符合的 package，如果没有符合的，则创建一个新的 package。\n\n2. 在该 package 下创建一个新的数据集类，在对应的注册器中进行注册：\n\n   ```python\n   from mmengine.dataset import BaseDataset\n   from mmpose.registry import DATASETS\n\n   @DATASETS.register_module(name='MyCustomDataset')\n   class MyCustomDataset(BaseDataset):\n   ```\n\n   如果未注册，你会在运行时遇到 `KeyError: 'XXXXX is not in the dataset registry'`。\n   关于 `mmengine.BaseDataset` 的更多信息，请参考 [这个文档](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html)。\n\n3. 确保你在 package 的 `__init__.py` 中导入了该数据集类。\n\n4. 确保你在 `mmpose/datasets/__init__.py` 中导入了该 package。\n\n## 创建自定义配置文件\n\n在配置文件中，你需要修改跟数据集有关的部分，例如：\n\n```python\n...\n# 自定义数据集\ndataset_type = 'MyCustomDataset' # or 'CocoDataset'\n\ntrain_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # 标注文件路径为 {data_root}/{ann_file}\n        # 例如： aaa/annotations/xxx.json\n        ann_file='annotations/xxx.json',\n        # 图片路径为 {data_root}/{img}/\n        # 例如： aaa/train/c.jpg\n        data_prefix=dict(img='train'),\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n\nval_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # 标注文件路径为 {data_root}/{ann_file}\n        # 例如： aaa/annotations/yyy.json\n        ann_file='annotations/yyy.json',\n        # 图片路径为 {data_root}/{img}/\n        # 例如： aaa/val/c.jpg\n        data_prefix=dict(img='val'),\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n\ntest_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # 标注文件路径为 {data_root}/{ann_file}\n        # 例如： aaa/annotations/zzz.json\n        ann_file='annotations/zzz.json',\n        # 图片路径为 {data_root}/{img}/\n        # 例如： aaa/test/c.jpg\n        data_prefix=dict(img='test'),\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\n...\n```\n\n请确保所有的路径都是正确的。\n\n## 数据集封装\n\n在 MMPose 中，支持使用 MMPose 实现的数据集封装和 [MMEngine](https://github.com/open-mmlab/mmengine) 实现的数据集封装。目前 [MMEngine](https://github.com/open-mmlab/mmengine) 支持以下数据集封装：\n\n- [ConcatDataset](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/basedataset.html#concatdataset)\n- [RepeatDataset](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/basedataset.html#repeatdataset)\n\n### CombinedDataset\n\nMMPose 提供了一个 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) 类，它可以将多个数据集封装成一个数据集。它的使用方法如下：\n\n```python\ndataset_1 = dict(\n    type='dataset_type_1',\n    data_root='aaa',\n    # 图片路径为 {data_root}/{img_path}/\n    # 例如： aaa/train/c.jpg\n    data_prefix=dict(img_path='train'),\n    # 标注文件路径为 {data_root}/{ann_file}\n    # 例如： aaa/annotations/train.json\n    ann_file='annotations/train.json',\n    pipeline=[\n        # 使用转换器将标注信息统一为需要的格式\n        converter_transform_1\n    ])\n\ndataset_2 = dict(\n    type='dataset_type_2',\n    data_root='bbb',\n    # 图片路径为 {data_root}/{img_path}/\n    # 例如： bbb/train/c.jpg\n    data_prefix=dict(img_path='train'),\n    # 标注文件路径为 {data_root}/{ann_file}\n    # 例如： bbb/annotations/train.json\n    ann_file='annotations/train.json',\n    pipeline=[\n        converter_transform_2\n    ])\n\nshared_pipeline = [\n    LoadImage(),\n    ParseImage(),\n]\n\ncombined_dataset = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='path/to/your/metainfo'),\n    datasets=[dataset_1, dataset_2],\n    pipeline=shared_pipeline,\n)\n```\n\n- **合并数据集的元信息** 决定了标注格式，可以是子数据集的元信息，也可以是自定义的元信息。如果要自定义元信息，可以参考 [创建自定义数据集的元信息文件](#创建自定义数据集的元信息文件)。\n- **KeypointConverter** 用于将不同的标注格式转换成统一的格式。比如将关键点个数不同、关键点排列顺序不同的数据集进行合并。\n- 更详细的说明请前往[混合数据集训练](../user_guides/mixed_datasets.md)。\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/customize_evaluation.md",
    "content": "# Customize Evaluation\n\nComing soon.\n\nCurrently, you can refer to [Evaluation Tutorial of MMEngine](https://mmengine.readthedocs.io/en/latest/tutorials/evaluation.html) to customize your own evaluation.\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/customize_logging.md",
    "content": "# Customize Logging\n\nComing soon.\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/customize_optimizer.md",
    "content": "# Customize Optimizer and Scheduler\n\nComing soon.\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/customize_transforms.md",
    "content": "# 自定义数据变换和数据增强\n\n### 数据变换\n\n在**OpenMMLab**算法库中，数据集的构建和数据的准备是相互解耦的，通常，数据集的构建只对数据集进行解析，记录每个样本的基本信息，而数据的准备则是通过一系列的数据变换，根据样本的基本信息进行数据加载、预处理、格式化等操作。\n\n### 数据变换的使用\n\n**MMPose**中的`数据变换`和`数据增强`类定义在[$MMPose/datasets/transforms](https://github.com/open-mmlab/mmpose/tree/dev-1.x/mmpose/datasets/transforms)目录中，对应的文件结构如下:\n\n```txt\nmmpose\n|----datasets\n    |----transforms\n        |----bottomup_transforms    # 自底向上\n        |----common_transforms      # 常用变换\n        |----converting             # 关键点转换\n        |----formatting             # 输入数据格式化\n        |----loading                # 原始数据加载\n        |----pose3d_transforms      # 三维变换\n        |----topdown_transforms     # 自顶向下\n```\n\n在**MMPose**中，**数据增强**和**数据变换**是使用者经常需要考虑的一个阶段，可参考如下流程进行相关阶段的设计：\n\n[![](https://mermaid.ink/img/pako:eNp9UT1LA0EQ_SvH1knhXXeFhYpfWIQklVwz3s7mFvd2jr09JIaAjQQRRLAU0Ua0t5X8m4v-DHcThPOIqfbNe2_fMDMTlhJHFjOh6CLNwNjgpJ_oICirs5GBIguGBnQpyOTlluf3lSz8ewhK7BAfe9wnC1aS9niQSWGXJJbyEj3aJUXmWFpLxpeo-T8NQs8foEYDFodgRmg3f4g834P0vEclHumiavrru-f67bZ-nH_dzIJud7s9yUpfvMwWH-_r9Ea5lL_nD_X16ypvg_507yLrq09vaVGtLuHflLAlR42EdUNErMNyNDlI7u438e6E2QxzTFjsIEcBlbIJS_TUWaGyNBjrlMXWVNhhVcHdlvckuKXmLBagSscWoE-JfuvpD2uI1Wk?type=png)](https://mermaid-js.github.io/mermaid-live-editor/edit#pako:eNp9UT1LA0EQ_SvH1knhXXeFhYpfWIQklVwz3s7mFvd2jr09JIaAjQQRRLAU0Ua0t5X8m4v-DHcThPOIqfbNe2_fMDMTlhJHFjOh6CLNwNjgpJ_oICirs5GBIguGBnQpyOTlluf3lSz8ewhK7BAfe9wnC1aS9niQSWGXJJbyEj3aJUXmWFpLxpeo-T8NQs8foEYDFodgRmg3f4g834P0vEclHumiavrru-f67bZ-nH_dzIJud7s9yUpfvMwWH-_r9Ea5lL_nD_X16ypvg_507yLrq09vaVGtLuHflLAlR42EdUNErMNyNDlI7u438e6E2QxzTFjsIEcBlbIJS_TUWaGyNBjrlMXWVNhhVcHdlvckuKXmLBagSscWoE-JfuvpD2uI1Wk)\n\n[common_transforms](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py)组件提供了常用的`RandomFlip`,`RandomHalfBody`数据增强算法。\n\n- `Top-Down`方法中`Shift`,`Rotate`,`Resize`等操作体现为[RandomBBoxTransform](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L435)方法。\n- `Buttom-Up`算法中体现为[BottomupResize](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L327)方法。\n- `pose-3d`则为[RandomFlipAroundRoot](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/pose3d_transforms.py#L13)方法。\n\n**MMPose**对于`Top-Down`、`Buttom-Up`，`pose-3d`都提供了对应的数据变换接口。通过采用仿射变换，将图像和坐标标注从`原始图片空间`变换到`输入图片空间`。\n\n- `Top-Down`方法中体现为[TopdownAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/topdown_transforms.py#L14)。\n- `Buttom-Up`方法体现为[BottomupRandomAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L134)。\n\n以[RandomFlip](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py)为例，该方法随机的对`原始图片`进行变换，并转换为`输入图像`或`中间图像`。要定义一个数据变换的过程，需要继承[BaseTransform](https://github.com/open-mmlab/mmcv/blob/main/mmcv/transforms/base.py)类，并进行`TRANSFORM`注册：\n\n```python\nfrom mmcv.transforms import BaseTransform\nfrom mmpose.registry import TRANSFORMS\n\n@TRANSFORMS.register_module()\nclass RandomFlip(BaseTransform):\n      \"\"\"Randomly flip the image, bbox and keypoints.\n\n    Required Keys:\n\n        - img\n        - img_shape\n        - flip_indices\n        - input_size (optional)\n        - bbox (optional)\n        - bbox_center (optional)\n        - keypoints (optional)\n        - keypoints_visible (optional)\n        - img_mask (optional)\n\n    Modified Keys:\n\n        - img\n        - bbox (optional)\n        - bbox_center (optional)\n        - keypoints (optional)\n        - keypoints_visible (optional)\n        - img_mask (optional)\n\n    Added Keys:\n\n        - flip\n        - flip_direction\n\n    Args:\n        prob (float | list[float]): The flipping probability. If a list is\n            given, the argument `direction` should be a list with the same\n            length. And each element in `prob` indicates the flipping\n            probability of the corresponding one in ``direction``. Defaults\n            to 0.5\n        direction (str | list[str]): The flipping direction. Options are\n            ``'horizontal'``, ``'vertical'`` and ``'diagonal'``. If a list is\n            is given, each data sample's flipping direction will be sampled\n            from a distribution determined by the argument ``prob``. Defaults\n            to ``'horizontal'``.\n    \"\"\"\n    def __init__(self,\n                prob: Union[float, List[float]] = 0.5,\n                direction: Union[str, List[str]] = 'horizontal') -> None:\n      if isinstance(prob, list):\n          assert is_list_of(prob, float)\n          assert 0 <= sum(prob) <= 1\n      elif isinstance(prob, float):\n          assert 0 <= prob <= 1\n      else:\n          raise ValueError(f'probs must be float or list of float, but \\\n                            got `{type(prob)}`.')\n      self.prob = prob\n\n      valid_directions = ['horizontal', 'vertical', 'diagonal']\n      if isinstance(direction, str):\n          assert direction in valid_directions\n      elif isinstance(direction, list):\n          assert is_list_of(direction, str)\n          assert set(direction).issubset(set(valid_directions))\n      else:\n          raise ValueError(f'direction must be either str or list of str, \\\n                              but got `{type(direction)}`.')\n      self.direction = direction\n\n      if isinstance(prob, list):\n          assert len(prob) == len(self.direction)\n```\n\n**输入**：\n\n- `prob`指定了在水平，垂直，斜向等变换的概率，是一个范围在\\[0,1\\]之间的浮点数`list`。\n- `direction`指定了数据变换的方向：\n  - `horizontal`水平变换\n  - `vertical`垂直变换\n  - `diagonal`对角变换\n\n**输出**：\n\n- 输出一个经过**数据变换**后的`dict`数据\n\n`RandomFlip`的[transform](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py#L187)实现了对输入图像的以给定的`prob`概率进行水平、垂直或是对角方向的数据翻转，并返回输出图像。\n\n以下是使用`对角翻转变换`的一个简单示例：\n\n```python\nfrom mmpose.datasets.transforms import LoadImage, RandomFlip\nimport mmcv\n\n# 从路径中加载原始图片\nresults = dict(\n  img_path='data/test/multi-person.jpeg'\n  )\ntransform = LoadImage()\nresults = transform(results)\n# 此时，加载的原始图片是一个包含以下属性的`dict`:\n# - `img_path`: 图片的绝对路径\n# - `img`: 图片的像素点\n# - `img_shape`: 图片的形状\n# - `ori_shape`: 图片的原始形状\n\n# 对原始图像进行对角翻转变换\ntransform = RandomFlip(prob=1., direction='diagonal')\nresults = transform(results)\n# 此时，加载的原始图片是一个包含以下属性的`dict`:\n# - `img_path`: 图片的绝对路径\n# - `img`: 图片的像素点\n# - `img_shape`: 图片的形状\n# - `ori_shape`: 图片的原始形状\n# - `flip`: 图片是否进行翻转变换\n# - `flip_direction`: 图片进行翻转变换的方向\n\n# 取出经过翻转变换后的图片\nmmcv.imshow(results['img'])\n```\n\n更多有关自定义数据变换和增强的使用方法，可以参考[$MMPose/test/test_datasets/test_transforms/test_common_transforms](https://github.com/open-mmlab/mmpose/blob/main/tests/test_datasets/test_transforms/test_common_transforms.py#L59)等。\n\n#### RandomHalfBody\n\n[RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L263)**数据增强**算法概率的进行上半身或下半身的**数据变换**。\n**输入**：\n\n- `min_total_keypoints`最小总关键点数\n- `min_half_keypoints`最小半身关键点数\n- `padding`bbox的填充比例\n- `prob`在关键点数目符合要求下，接受半身变换的概率\n\n**输出**：\n\n- 输出一个经过**数据变换**后的`dict`数据\n\n#### TopdownAffine\n\n[TopdownAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/topdown_transforms.py#L14)**数据变换**算法通过仿射变换将`原始图片`变换为`输入图片`。\n\n**输入**：\n\n- `input_size`bbox区域将会被裁剪和修正到的\\[w,h\\]大小\n- `use_udp`是否使用公正的数据过程[UDP](https://arxiv.org/abs/1911.07524)\n\n**输出**：\n\n- 输出一个经过**数据变换**后的`dict`数据\n\n### 在流水线中使用数据增强和变换\n\n配置文件中的**数据增强**和**数据变换**过程可以是如下示例：\n\n```python\ntrain_pipeline_stage2 = [\n    ...\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(\n         type='TopdownAffine',\n         input_size=codec['input_size']),\n    ...\n]\n```\n\n示例中的流水线对输入数据进行**数据增强**，进行随机的水平增强和半身增强，\n并进行`Top-Down`的`Shift`、`Rotate`、`Resize`操作，通过`TopdownAffine`操作实现仿射变换，变换至`输入图片空间`。\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/dataflow.md",
    "content": "# Dataflow in MMPose\n\nComing soon.\n"
  },
  {
    "path": "docs/zh_cn/advanced_guides/implement_new_models.md",
    "content": "# 实现新模型\n\n本教程将介绍如何在 MMPose 中实现你自己的模型。我们经过总结，将实现新模型这一需求拆分为两类：\n\n1. 基于 MMPose 中已支持的算法范式，对模型中的模块（骨干网络、颈部、预测头、编解码器等）进行自定义\n2. 实现新的算法范式\n\n## 基础知识\n\n不论你想实现的模型是以上哪一种，这一节的内容都对你很重要，因为它是 OpenMMLab 系列算法库构建模型的基本原则。\n在 MMPose 中，所有与模型结构实现相关的代码都存放在 [models 目录](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models)下：\n\n```shell\nmmpose\n|----models\n     |----backbones             # 骨干网络\n     |----data_preprocessors    # 数据预处理，如：图片归一化\n     |----heads                 # 预测头\n     |----losses                # 损失函数\n     |----necks                 # 颈部\n     |----pose_estimators       # 姿态估计算法范式\n     |----utils                 # 工具方法\n```\n\n你可以参考以下流程图来定位你所需要实现的模块：\n\n![image](https://github.com/open-mmlab/mmpose/assets/13503330/f4eeb99c-e2a1-4907-9d46-f110c51f0814)\n\n## 姿态估计算法范式\n\n在姿态估计范式中，我们会定义一个模型的推理流程，并在 `predict()` 中对模型输出结果进行解码，先将其从 `输出尺度空间` 用 [编解码器](./codecs.md) 变换到 `输入图片空间`，然后再结合元信息变换到 `原始图片空间`。\n\n![pose_estimator_cn](https://github.com/open-mmlab/mmpose/assets/13503330/0c048f66-b889-4268-937f-71b8753b505f)\n\n当前 MMPose 已支持以下几类算法范式：\n\n1. [Top-down](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/topdown.py)：Pose 模型的输入为经过裁剪的单个目标（动物、人体、人脸、人手、植物、衣服等）图片，输出为这个目标的关键点预测结果\n2. [Bottom-up](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/bottomup.py)：Pose 模型的输入为包含任意个目标的图片，输出为图片中所有目标的关键点预测结果\n3. [Pose Lifting](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/pose_lifter.py)：Pose 模型的输入为 2D 关键点坐标数组，输出为 3D 关键点坐标数组\n\n如果你要实现的模型不属于以上算法范式，那么你需要继承 [BasePoseEstimator](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/base.py) 类来定义你自己的算法范式。\n\n## 骨干网络\n\n如果希望实现一个新的骨干网络，你需要在 [backbones 目录](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/backbones) 下新建一个文件进行定义。\n\n新建的骨干网络需要继承 [BaseBackbone](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/backbones/base_backbone.py) 类，其他方面与你继承 nn.Module 来创建没有任何不同。\n\n在完成骨干网络的实现后，你需要使用 `MODELS` 来对其进行注册：\n\n```Python3\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\n@MODELS.register_module()\nclass YourNewBackbone(BaseBackbone):\n```\n\n最后，请记得在 [backbones/\\_\\_init\\_\\_.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/backbones/__init__.py) 中导入你的新骨干网络。\n\n## 预测头部\n\n新的预测头部的加入与骨干网络流程类似，你需要在 [heads 目录](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/heads) 下新建一个文件进行定义，然后继承 [BaseHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py)。\n\n需要特别注意的一点是，在 MMPose 中会在 Head 里进行损失函数的计算。根据训练与评测阶段的不同，分别执行 `loss()` 和 `predict()`。\n\n在 `predict()` 中，模型会调用对应编解码器的 `decode()` 方法，将模型输出的结果从 `输出尺度空间` 转换到 `输入图片空间` 。\n\n在完成预测头部的实现后，你需要使用 `MODELS` 来对其进行注册：\n\n```Python3\nfrom mmpose.registry import MODELS\nfrom ..base_head import BaseHead\n\n@MODELS.register_module()\nclass YourNewHead(BaseHead):\n```\n\n最后，请记得在 [heads/\\_\\_init\\_\\_.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/__init__.py) 中导入你的新预测头部。\n\n### 关键点可见性预测头部\n\n许多模型都是通过对关键点坐标预测的置信度来判断关键点的可见性的。然而，这种解决方案并非最优。我们提供了一个叫做 [VisPredictHead](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/heads/hybrid_heads/vis_head.py) 的头部模块包装器，使得头部模块能够直接预测关键点的可见性。这个包装器是用训练数据中关键点可见性真值来训练的。因此，其预测会更加可靠。用户可以通过修改配置文件来对自己的头部模块加上这个包装器。下面是一个例子:\n\n```python\nmodel=dict(\n     ...\n     head=dict(\n          type='VisPredictHead',\n          loss=dict(\n               type='BCELoss',\n               use_target_weight=True,\n               use_sigmoid=True,\n               loss_weight=1e-3),\n          pose_cfg=dict(\n               type='HeatmapHead',\n               in_channels=2048,\n               out_channels=17,\n               loss=dict(type='KeypointMSELoss', use_target_weight=True),\n               decoder=codec)),\n     ...\n)\n```\n\n要实现这样一个预测头部模块包装器，我们只需要像定义正常的预测头部一样，继承 [BaseHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py)，然后在 `__init__()` 中传入关键点定位的头部配置，并通过 `MODELS.build()` 进行实例化。如下所示：\n\n```python\n@MODELS.register_module()\nclass VisPredictHead(BaseHead):\n    \"\"\"VisPredictHead must be used together with other heads. It can predict\n    keypoints coordinates of and their visibility simultaneously. In the\n    current version, it only supports top-down approaches.\n\n    Args:\n        pose_cfg (Config): Config to construct keypoints prediction head\n        loss (Config): Config for visibility loss. Defaults to use\n            :class:`BCELoss`\n        use_sigmoid (bool): Whether to use sigmoid activation function\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(self,\n                 pose_cfg: ConfigType,\n                 loss: ConfigType = dict(\n                     type='BCELoss', use_target_weight=False,\n                     use_sigmoid=True),\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = pose_cfg['in_channels']\n        if pose_cfg.get('num_joints', None) is not None:\n            self.out_channels = pose_cfg['num_joints']\n        elif pose_cfg.get('out_channels', None) is not None:\n            self.out_channels = pose_cfg['out_channels']\n        else:\n            raise ValueError('VisPredictHead requires \\'num_joints\\' or'\n                             ' \\'out_channels\\' in the pose_cfg.')\n\n        self.loss_module = MODELS.build(loss)\n\n        self.pose_head = MODELS.build(pose_cfg)\n        self.pose_cfg = pose_cfg\n\n        self.use_sigmoid = loss.get('use_sigmoid', False)\n\n        modules = [\n            nn.AdaptiveAvgPool2d(1),\n            nn.Flatten(),\n            nn.Linear(self.in_channels, self.out_channels)\n        ]\n        if self.use_sigmoid:\n            modules.append(nn.Sigmoid())\n\n        self.vis_head = nn.Sequential(*modules)\n```\n\n然后你只需要像一个普通的预测头一样继续实现其余部分即可。\n"
  },
  {
    "path": "docs/zh_cn/api.rst",
    "content": "mmpose.apis\n-------------\n.. automodule:: mmpose.apis\n    :members:\n\nmmpose.codecs\n-------------\n.. automodule:: mmpose.codecs\n    :members:\n\nmmpose.models\n---------------\nbackbones\n^^^^^^^^^^^\n.. automodule:: mmpose.models.backbones\n    :members:\n\nnecks\n^^^^^^^^^^^\n.. automodule:: mmpose.models.necks\n    :members:\n\ndetectors\n^^^^^^^^^^^\n.. automodule:: mmpose.models.pose_estimators\n    :members:\n\nheads\n^^^^^^^^^^^^^^^\n.. automodule:: mmpose.models.heads\n    :members:\n\nlosses\n^^^^^^^^^^^\n.. automodule:: mmpose.models.losses\n    :members:\n\nmisc\n^^^^^^^^^^^\n.. automodule:: mmpose.models.utils\n    :members:\n\nmmpose.datasets\n-----------------\n.. automodule:: mmpose.datasets\n    :members:\n\ndatasets\n^^^^^^^^^^^\n.. automodule:: mmpose.datasets.datasets.base\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.body\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.face\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.hand\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.animal\n    :members:\n    :noindex:\n\n.. automodule:: mmpose.datasets.datasets.fashion\n    :members:\n    :noindex:\n\ntransforms\n^^^^^^^^^^^\n.. automodule:: mmpose.datasets.transforms.loading\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.common_transforms\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.topdown_transforms\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.bottomup_transforms\n    :members:\n\n.. automodule:: mmpose.datasets.transforms.formatting\n    :members:\n\nmmpose.structures\n---------------\n.. automodule:: mmpose.structures\n    :members:\n\nbbox\n^^^^^^^^^^^\n.. automodule:: mmpose.structures.bbox\n    :members:\n\nkeypoint\n^^^^^^^^^^^\n.. automodule:: mmpose.structures.keypoint\n    :members:\n\n\nmmpose.registry\n---------------\n.. automodule:: mmpose.registry\n    :members:\n\nmmpose.evaluation\n-----------------\nmetrics\n^^^^^^^^^^^\n.. automodule:: mmpose.evaluation.metrics\n    :members:\n\nfunctional\n^^^^^^^^^^^\n.. automodule:: mmpose.evaluation.functional\n    :members:\n\nmmpose.visualization\n--------------------\n.. automodule:: mmpose.visualization\n    :members:\n\nmmpose.engine\n---------------\nhooks\n^^^^^^^^^^^\n.. automodule:: mmpose.engine.hooks\n    :members:\n"
  },
  {
    "path": "docs/zh_cn/collect_modelzoo.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport re\nfrom collections import defaultdict\nfrom glob import glob\n\nfrom addict import Addict\nfrom titlecase import titlecase\n\n\ndef _get_model_docs():\n    \"\"\"Get all model document files.\n\n    Returns:\n        list[str]: file paths\n    \"\"\"\n    config_root = osp.join('..', '..', 'configs')\n    pattern = osp.sep.join(['*'] * 4) + '.md'\n    docs = glob(osp.join(config_root, pattern))\n    docs = [doc for doc in docs if '_base_' not in doc]\n    return docs\n\n\ndef _parse_model_doc_path(path):\n    \"\"\"Parse doc file path.\n\n    Typical path would be like:\n\n        configs/<task>/<algorithm>/<dataset>/<setting>.md\n\n    An example is:\n\n        \"configs/animal_2d_keypoint/topdown_heatmap/\n        animalpose/resnet_animalpose.md\"\n\n    Returns:\n        tuple:\n        - task (str): e.g. ``'Animal 2D Keypoint'``\n        - dataset (str): e.g. ``'animalpose'``\n        - keywords (tuple): e.g. ``('topdown heatmap', 'resnet')``\n    \"\"\"\n    _path = path.split(osp.sep)\n    _rel_path = _path[_path.index('configs'):]\n\n    # get task\n    def _titlecase_callback(word, **kwargs):\n        if word == '2d':\n            return '2D'\n        if word == '3d':\n            return '3D'\n\n    task = titlecase(\n        _rel_path[1].replace('_', ' '), callback=_titlecase_callback)\n\n    # get dataset\n    dataset = _rel_path[3]\n\n    # get keywords\n    keywords_algo = (_rel_path[2], )\n    keywords_setting = tuple(_rel_path[4][:-3].split('_'))\n    keywords = keywords_algo + keywords_setting\n\n    return task, dataset, keywords\n\n\ndef _get_paper_refs():\n    \"\"\"Get all paper references.\n\n    Returns:\n        Dict[str, List[str]]: keys are paper categories and values are lists\n        of paper paths.\n    \"\"\"\n    papers = glob('../src/papers/*/*.md')\n    paper_refs = defaultdict(list)\n    for fn in papers:\n        category = fn.split(osp.sep)[3]\n        paper_refs[category].append(fn)\n\n    return paper_refs\n\n\ndef _parse_paper_ref(fn):\n    \"\"\"Get paper name and indicator pattern from a paper reference file.\n\n    Returns:\n        tuple:\n        - paper_name (str)\n        - paper_indicator (str)\n    \"\"\"\n    indicator = None\n    with open(fn, 'r', encoding='utf-8') as f:\n        for line in f.readlines():\n            if line.startswith('<summary'):\n                indicator = line\n                break\n    if indicator is None:\n        raise ValueError(f'Invalid paper reference file {fn}')\n\n    paper_name = re.sub(r'\\<.*?\\>', '', indicator).strip()\n    return paper_name, indicator\n\n\ndef main():\n\n    # Build output folders\n    os.makedirs('model_zoo', exist_ok=True)\n    os.makedirs('model_zoo_papers', exist_ok=True)\n\n    # Collect all document contents\n    model_doc_list = _get_model_docs()\n    model_docs = Addict()\n\n    for path in model_doc_list:\n        task, dataset, keywords = _parse_model_doc_path(path)\n        with open(path, 'r', encoding='utf-8') as f:\n            doc = {\n                'task': task,\n                'dataset': dataset,\n                'keywords': keywords,\n                'path': path,\n                'content': f.read()\n            }\n        model_docs[task][dataset][keywords] = doc\n\n    # Write files by task\n    for task, dataset_dict in model_docs.items():\n        lines = [f'# {task}', '']\n        for dataset, keywords_dict in dataset_dict.items():\n            lines += [\n                '<hr/>', '<br/><br/>', '', f'## {titlecase(dataset)} Dataset',\n                ''\n            ]\n\n            for keywords, doc in keywords_dict.items():\n                keyword_strs = [\n                    titlecase(x.replace('_', ' ')) for x in keywords\n                ]\n                dataset_str = titlecase(dataset)\n                if dataset_str in keyword_strs:\n                    keyword_strs.remove(dataset_str)\n\n                lines += [\n                    '<br/>', '',\n                    (f'### {\" + \".join(keyword_strs)}'\n                     f' on {dataset_str}'), '', doc['content'], ''\n                ]\n\n        fn = osp.join('model_zoo', f'{task.replace(\" \", \"_\").lower()}.md')\n        with open(fn, 'w', encoding='utf-8') as f:\n            f.write('\\n'.join(lines))\n\n    # Write files by paper\n    paper_refs = _get_paper_refs()\n\n    for paper_cat, paper_list in paper_refs.items():\n        lines = []\n        for paper_fn in paper_list:\n            paper_name, indicator = _parse_paper_ref(paper_fn)\n            paperlines = []\n            for task, dataset_dict in model_docs.items():\n                for dataset, keywords_dict in dataset_dict.items():\n                    for keywords, doc_info in keywords_dict.items():\n\n                        if indicator not in doc_info['content']:\n                            continue\n\n                        keyword_strs = [\n                            titlecase(x.replace('_', ' ')) for x in keywords\n                        ]\n\n                        dataset_str = titlecase(dataset)\n                        if dataset_str in keyword_strs:\n                            keyword_strs.remove(dataset_str)\n                        paperlines += [\n                            '<br/>', '',\n                            (f'### {\" + \".join(keyword_strs)}'\n                             f' on {dataset_str}'), '', doc_info['content'], ''\n                        ]\n            if paperlines:\n                lines += ['<hr/>', '<br/><br/>', '', f'## {paper_name}', '']\n                lines += paperlines\n\n        if lines:\n            lines = [f'# {titlecase(paper_cat)}', ''] + lines\n            with open(\n                    osp.join('model_zoo_papers', f'{paper_cat.lower()}.md'),\n                    'w',\n                    encoding='utf-8') as f:\n                f.write('\\n'.join(lines))\n\n\nif __name__ == '__main__':\n    print('collect model zoo documents')\n    main()\n"
  },
  {
    "path": "docs/zh_cn/collect_projects.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport re\nfrom glob import glob\n\n\ndef _get_project_docs():\n    \"\"\"Get all project document files.\n\n    Returns:\n        list[str]: file paths\n    \"\"\"\n    project_root = osp.join('..', '..', 'projects')\n    pattern = osp.sep.join(['*'] * 2) + '.md'\n    docs = glob(osp.join(project_root, pattern))\n    docs = [\n        doc for doc in docs\n        if 'example_project' not in doc and '_CN' not in doc\n    ]\n    return docs\n\n\ndef _parse_project_doc_path(fn):\n    \"\"\"Get project name and banner from a project reference file.\n\n    Returns:\n        tuple:\n        - project_name (str)\n        - project_banner (str)\n    \"\"\"\n    project_banner, project_name = None, None\n    with open(fn, 'r', encoding='utf-8') as f:\n        for line in f.readlines():\n            if re.match('^( )*<img', line) and not project_banner:\n                project_banner = line\n            if line.startswith('# ') and not project_name:\n                project_name = line\n            if project_name and project_banner:\n                break\n    if project_name is None or project_banner is None:\n        raise ValueError(f'Invalid paper reference file {fn}')\n\n    project_name = re.sub(r'^\\# ', '', project_name).strip()\n    project_banner = project_banner.strip()\n    return project_name, project_banner\n\n\ndef _get_project_intro_doc():\n    project_intro_doc = []\n    with open(\n            osp.join('..', '..', 'projects', 'README.md'), 'r',\n            encoding='utf-8') as f:\n        for line in f.readlines():\n            if line.startswith('# Welcome'):\n                continue\n            if './faq.md' in line:\n                line = line.replace('./faq.md', '#faq')\n            if 'example_project' in line:\n                line = line.replace(\n                    './', 'https://github.com/open-mmlab/mmpose/'\n                    'tree/dev-1.x/projects/')\n            project_intro_doc.append(line)\n            if line.startswith('## Project List'):\n                break\n    return project_intro_doc\n\n\ndef _get_faq_doc():\n    faq_doc = []\n    with open(\n            osp.join('..', '..', 'projects', 'faq.md'), 'r',\n            encoding='utf-8') as f:\n        for line in f.readlines():\n            if '#' in line:\n                line = re.sub(r'^(\\#+)', r'\\g<1>#', line)\n            faq_doc.append(line)\n    return faq_doc\n\n\ndef main():\n\n    # Build output folders\n    os.makedirs('projects', exist_ok=True)\n\n    # Collect all document contents\n    project_doc_list = _get_project_docs()\n\n    project_lines = []\n    for path in project_doc_list:\n        name, banner = _parse_project_doc_path(path)\n        _path = path.split(osp.sep)\n        _rel_path = _path[_path.index('projects'):-1]\n        url = 'https://github.com/open-mmlab/mmpose/blob/dev-1.x/' + '/'.join(\n            _rel_path)\n        _name = name.split(':', 1)\n        name, description = _name[0], '' if len(\n            _name) < 2 else f': {_name[-1]}'\n        project_lines += [\n            f'- **{name}**{description} [\\\\[github\\\\]]({url})', '',\n            '<div align=\"center\">', ' ' + banner, '</div>', '<br/>', ''\n        ]\n\n    project_intro_doc = _get_project_intro_doc()\n    faq_doc = _get_faq_doc()\n\n    with open(\n            osp.join('projects', 'community_projects.md'), 'w',\n            encoding='utf-8') as f:\n        f.write('# Projects of MMPose from Community Contributors\\n')\n        f.write(''.join(project_intro_doc))\n        f.write('\\n'.join(project_lines))\n        f.write(''.join(faq_doc))\n\n\nif __name__ == '__main__':\n    print('collect project documents')\n    main()\n"
  },
  {
    "path": "docs/zh_cn/conf.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n# Configuration file for the Sphinx documentation builder.\n#\n# This file only contains a selection of the most common options. For a full\n# list see the documentation:\n# https://www.sphinx-doc.org/en/master/usage/configuration.html\n\n# -- Path setup --------------------------------------------------------------\n\n# If extensions (or modules to document with autodoc) are in another directory,\n# add these directories to sys.path here. If the directory is relative to the\n# documentation root, use os.path.abspath to make it absolute, like shown here.\n\nimport os\nimport subprocess\nimport sys\n\nimport pytorch_sphinx_theme\n\nsys.path.insert(0, os.path.abspath('../..'))\n\n# -- Project information -----------------------------------------------------\n\nproject = 'MMPose'\ncopyright = '2020-2021, OpenMMLab'\nauthor = 'MMPose Authors'\n\n# The full version, including alpha/beta/rc tags\nversion_file = '../../mmpose/version.py'\n\n\ndef get_version():\n    with open(version_file, 'r') as f:\n        exec(compile(f.read(), version_file, 'exec'))\n    return locals()['__version__']\n\n\nrelease = get_version()\n\n# -- General configuration ---------------------------------------------------\n\n# Add any Sphinx extension module names here, as strings. They can be\n# extensions coming with Sphinx (named 'sphinx.ext.*') or your custom\n# ones.\nextensions = [\n    'sphinx.ext.autodoc', 'sphinx.ext.napoleon', 'sphinx.ext.viewcode',\n    'sphinx_markdown_tables', 'sphinx_copybutton', 'myst_parser',\n    'sphinx.ext.autosummary'\n]\n\nautodoc_mock_imports = ['json_tricks', 'mmpose.version']\n\n# Ignore >>> when copying code\ncopybutton_prompt_text = r'>>> |\\.\\.\\. '\ncopybutton_prompt_is_regexp = True\n\n# Add any paths that contain templates here, relative to this directory.\ntemplates_path = ['_templates']\n\n# List of patterns, relative to source directory, that match files and\n# directories to ignore when looking for source files.\n# This pattern also affects html_static_path and html_extra_path.\nexclude_patterns = ['_build', 'Thumbs.db', '.DS_Store']\n\n# -- Options for HTML output -------------------------------------------------\nsource_suffix = {\n    '.rst': 'restructuredtext',\n    '.md': 'markdown',\n}\n\n# The theme to use for HTML and HTML Help pages.  See the documentation for\n# a list of builtin themes.\n#\nhtml_theme = 'pytorch_sphinx_theme'\nhtml_theme_path = [pytorch_sphinx_theme.get_html_theme_path()]\nhtml_theme_options = {\n    'menu': [{\n        'name': 'GitHub',\n        'url': 'https://github.com/open-mmlab/mmpose'\n    }],\n    # Specify the language of the shared menu\n    'menu_lang': 'cn'\n}\n\n# Add any paths that contain custom static files (such as style sheets) here,\n# relative to this directory. They are copied after the builtin static files,\n# so a file named \"default.css\" will overwrite the builtin \"default.css\".\n\nlanguage = 'zh_CN'\n\nhtml_static_path = ['_static']\nhtml_css_files = ['css/readthedocs.css']\n\n# Enable ::: for my_st\nmyst_enable_extensions = ['colon_fence']\n\nmaster_doc = 'index'\n\n\ndef builder_inited_handler(app):\n    subprocess.run(['python', './collect_modelzoo.py'])\n    subprocess.run(['python', './collect_projects.py'])\n    subprocess.run(['sh', './merge_docs.sh'])\n    subprocess.run(['python', './stats.py'])\n\n\ndef setup(app):\n    app.connect('builder-inited', builder_inited_handler)\n"
  },
  {
    "path": "docs/zh_cn/contribution_guide.md",
    "content": "# 如何给 MMPose 贡献代码\n\n欢迎加入 MMPose 社区，我们致力于打造最前沿的计算机视觉基础库，我们欢迎任何形式的贡献，包括但不限于：\n\n- **修复错误**\n  1. 如果提交的代码改动较大，我们鼓励你先开一个 issue 并正确描述现象、原因和复现方式，讨论后确认修复方案。\n  2. 修复错误并补充相应的单元测试，提交 PR 。\n- **新增功能或组件**\n  1. 如果新功能或模块涉及较大的代码改动，我们建议先提交 issue，与我们确认功能的必要性。\n  2. 实现新增功能并添加单元测试，提交 PR 。\n- **文档补充或翻译**\n  - 如果发现文档有错误或不完善的地方，欢迎直接提交 PR 。\n\n```{note}\n- 如果你希望向 MMPose 1.0 贡献代码，请从 dev-1.x 上创建新分支，并提交 PR 到 dev-1.x 分支上。\n- 如果你是论文作者，并希望将你的方法加入到 MMPose 中，欢迎联系我们，我们将非常感谢你的贡献。\n- 如果你希望尽快将你的项目分享到 MMPose 开源社区，欢迎将 PR 提到 Projects 目录下，该目录下的项目将简化 Review 流程并尽快合入。\n- 如果你希望加入 MMPose 的维护者，欢迎联系我们，我们将邀请你加入 MMPose 的维护者群。\n```\n\n## 准备工作\n\nPR 操作所使用的命令都是用 Git 去实现的，该章节将介绍如何进行 Git 配置与 GitHub 绑定。\n\n### Git 配置\n\n首先，你需要在本地安装 Git，然后配置你的 Git 用户名和邮箱：\n\n```Shell\n# 在命令提示符（cmd）或终端（terminal）中输入以下命令，查看 Git 版本\ngit --version\n```\n\n然后，你需要检查自己的 Git Config 是否正确配置，如果 `user.name` 和 `user.email` 为空，你需要配置你的 Git 用户名和邮箱：\n\n```Shell\n# 在命令提示符（cmd）或终端（terminal）中输入以下命令，查看 Git 配置\ngit config --global --list\n# 设置 Git 用户名和邮箱\ngit config --global user.name \"这里填入你的用户名\"\ngit config --global user.email \"这里填入你的邮箱\"\n```\n\n## PR 流程\n\n如果你对 PR 流程不熟悉，接下来将会从零开始，一步一步地教你如何提交 PR。如果你想深入了解 PR 开发模式，可以参考 [GitHub 官方文档](https://docs.github.com/cn/github/collaborating-with-issues-and-pull-requests/about-pull-requests)。\n\n### 1. Fork 项目\n\n当你第一次提交 PR 时，需要先 Fork 项目到自己的 GitHub 账号下。点击项目右上角的 Fork 按钮，将项目 Fork 到自己的 GitHub 账号下。\n\n![](https://user-images.githubusercontent.com/13503330/223318144-a49c6cef-b1fb-45b8-aa2b-0833d0e3fd5c.png)\n\n接着，你需要将你的 Fork 仓库 Clone 到本地，然后添加官方仓库作为远程仓库：\n\n```Shell\n\n# Clone 你的 Fork 仓库到本地\ngit clone https://github.com/username/mmpose.git\n\n# 添加官方仓库作为远程仓库\ncd mmpose\ngit remote add upstream https://github.com/open-mmlab/mmpose.git\n```\n\n在终端中输入以下命令，查看远程仓库是否成功添加：\n\n```Shell\ngit remote -v\n```\n\n如果出现以下信息，说明你已经成功添加了远程仓库：\n\n```Shell\norigin\thttps://github.com/{username}/mmpose.git (fetch)\norigin\thttps://github.com/{username}/mmpose.git (push)\nupstream\thttps://github.com/open-mmlab/mmpose.git (fetch)\nupstream\thttps://github.com/open-mmlab/mmpose.git (push)\n```\n\n```{note}\n这里对 origin 和 upstream 进行一个简单的介绍，当我们使用 git clone 来克隆代码时，会默认创建一个 origin 的 remote，它指向我们克隆的代码库地址，而 upstream 则是我们自己添加的，用来指向原始代码库地址。当然如果你不喜欢他叫 upstream，也可以自己修改，比如叫 open-mmlab。我们通常向 origin 提交代码（即 fork 下来的远程仓库），然后向 upstream 提交一个 pull request。如果提交的代码和最新的代码发生冲突，再从 upstream 拉取最新的代码，和本地分支解决冲突，再提交到 origin。\n```\n\n### 2. 配置 pre-commit\n\n在本地开发环境中，我们使用 pre-commit 来检查代码风格，以确保代码风格的统一。在提交代码前，你需要先安装 pre-commit：\n\n```Shell\npip install -U pre-commit\n\n# 在 mmpose 根目录下安装 pre-commit\npre-commit install\n```\n\n检查 pre-commit 是否配置成功，并安装 `.pre-commit-config.yaml` 中的钩子：\n\n```Shell\npre-commit run --all-files\n```\n\n![](https://user-images.githubusercontent.com/57566630/202368856-0465a90d-8fce-4345-918e-67b8b9c82614.png)\n\n```{note}\n如果你是中国大陆用户，由于网络原因，可能会出现 pre-commit 安装失败的情况。\n\n这时你可以使用清华源来安装 pre-commit：\npip install -U pre-commit -i https://pypi.tuna.tsinghua.edu.cn/simple\n\n或者使用国内镜像来安装 pre-commit：\npip install -U pre-commit -i https://pypi.mirrors.ustc.edu.cn/simple\n```\n\n如果安装过程被中断，可以重复执行上述命令，直到安装成功。\n\n如果你提交的代码中有不符合规范的地方，pre-commit 会发出警告，并自动修复部分错误。\n\n![](https://user-images.githubusercontent.com/57566630/202369176-67642454-0025-4023-a095-263529107aa3.png)\n\n### 3. 创建开发分支\n\n安装完 pre-commit 之后，我们需要基于 dev 分支创建一个新的开发分支，建议以 `username/pr_name` 的形式命名，例如：\n\n```Shell\ngit checkout -b username/refactor_contributing_doc\n```\n\n在后续的开发中，如果本地仓库的 dev 分支落后于官方仓库的 dev 分支，需要先拉取 upstream 的 dev 分支，然后 rebase 到本地的开发分支上：\n\n```Shell\ngit checkout username/refactor_contributing_doc\ngit fetch upstream\ngit rebase upstream/dev-1.x\n```\n\n在 rebase 时，如果出现冲突，需要手动解决冲突，然后执行 `git add` 命令，再执行 `git rebase --continue` 命令，直到 rebase 完成。\n\n### 4. 提交代码并在本地通过单元测试\n\n在本地开发完成后，我们需要在本地通过单元测试，然后提交代码。\n\n```shell\n# 运行单元测试\npytest tests/\n\n# 提交代码\ngit add .\ngit commit -m \"commit message\"\n```\n\n### 5. 推送代码到远程仓库\n\n在本地开发完成后，我们需要将代码推送到远程仓库。\n\n```Shell\ngit push origin username/refactor_contributing_doc\n```\n\n### 6. 提交 Pull Request (PR)\n\n#### (1) 在 GitHub 上创建 PR\n\n![](https://user-images.githubusercontent.com/13503330/223321382-e6068e18-1d91-4458-8328-b1c7c907b3b2.png)\n\n#### (2) 在 PR 中根据指引修改描述，添加必要的信息\n\n![](https://user-images.githubusercontent.com/13503330/223322447-94ad4b8c-21bf-4ca7-b3d6-0568cace6eee.png)\n\n```{note}\n- 在 PR branch 左侧选择 `dev` 分支，否则 PR 会被拒绝。\n- 如果你是第一次向 OpenMMLab 提交 PR，需要签署 CLA。\n```\n\n![](https://user-images.githubusercontent.com/57566630/167307569-a794b967-6e28-4eac-a942-00deb657815f.png)\n\n## 代码风格\n\n### Python\n\n我们采用[PEP8](https://www.python.org/dev/peps/pep-0008/)作为代码风格。\n\n使用下面的工具来对代码进行整理和格式化：\n\n- [flake8](http://flake8.pycqa.org/en/latest/)：代码提示\n- [isort](https://github.com/timothycrosley/isort)：import 排序\n- [yapf](https://github.com/google/yapf)：格式化工具\n- [codespell](https://github.com/codespell-project/codespell)： 单词拼写检查\n- [mdformat](https://github.com/executablebooks/mdformat): markdown 文件格式化工具\n- [docformatter](https://github.com/myint/docformatter): docstring 格式化工具\n\n`yapf`和`isort`的样式配置可以在[setup.cfg](/setup.cfg)中找到。\n\n我们使用[pre-commit hook](https://pre-commit.com/)来：\n\n- 检查和格式化 `flake8`、`yapf`、`isort`、`trailing whitespaces`\n- 修复 `end-of-files`\n- 在每次提交时自动排序 `requirments.txt`\n\n`pre-commit`的配置存储在[.pre-commit-config](/.pre-commit-config.yaml)中。\n\n```{note}\n在你创建PR之前，请确保你的代码格式符合规范，且经过了 yapf 格式化。\n```\n\n### C++与CUDA\n\n遵循[Google C++风格指南](https://google.github.io/styleguide/cppguide.html)\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/2d_animal_keypoint.md",
    "content": "# 2D Animal Keypoint Dataset\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [Animal-Pose](#animal-pose) \\[ [Homepage](https://sites.google.com/view/animal-pose/) \\]\n- [AP-10K](#ap-10k) \\[ [Homepage](https://github.com/AlexTheBad/AP-10K/) \\]\n- [Horse-10](#horse-10) \\[ [Homepage](http://www.mackenziemathislab.org/horse10) \\]\n- [MacaquePose](#macaquepose) \\[ [Homepage](http://www.pri.kyoto-u.ac.jp/datasets/macaquepose/index.html) \\]\n- [Vinegar Fly](#vinegar-fly) \\[ [Homepage](https://github.com/jgraving/DeepPoseKit-Data) \\]\n- [Desert Locust](#desert-locust) \\[ [Homepage](https://github.com/jgraving/DeepPoseKit-Data) \\]\n- [Grévy’s Zebra](#grvys-zebra) \\[ [Homepage](https://github.com/jgraving/DeepPoseKit-Data) \\]\n- [ATRW](#atrw) \\[ [Homepage](https://cvwc2019.github.io/challenge.html) \\]\n- [Animal Kingdom](#Animal-Kindom) \\[ [Homepage](https://openaccess.thecvf.com/content/CVPR2022/html/Ng_Animal_Kingdom_A_Large_and_Diverse_Dataset_for_Animal_Behavior_CVPR_2022_paper.html) \\]\n\n## Animal-Pose\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227796953-95ae1e30-5323-43f8-9a19-c4c2326e9835.png\" height=\"200px\">\n</div>\n\nFor [Animal-Pose](https://sites.google.com/view/animal-pose/) dataset, we prepare the dataset as follows:\n\n1. Download the images of [PASCAL VOC2012](http://host.robots.ox.ac.uk/pascal/VOC/voc2012/#data), especially the five categories (dog, cat, sheep, cow, horse), which we use as trainval dataset.\n2. Download the [test-set](https://drive.google.com/drive/folders/1DwhQobZlGntOXxdm7vQsE4bqbFmN3b9y?usp=sharing) images with raw annotations (1000 images, 5 categories).\n3. We have pre-processed the annotations to make it compatible with MMPose. Please download the annotation files from [annotations](https://download.openmmlab.com/mmpose/datasets/animalpose_annotations.tar). If you would like to generate the annotations by yourself, please check our dataset parsing [codes](/tools/dataset_converters/parse_animalpose_dataset.py).\n\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── animalpose\n        │\n        │-- VOC2012\n        │   │-- Annotations\n        │   │-- ImageSets\n        │   │-- JPEGImages\n        │   │-- SegmentationClass\n        │   │-- SegmentationObject\n        │\n        │-- animalpose_image_part2\n        │   │-- cat\n        │   │-- cow\n        │   │-- dog\n        │   │-- horse\n        │   │-- sheep\n        │\n        │-- annotations\n        │   │-- animalpose_train.json\n        │   |-- animalpose_val.json\n        │   |-- animalpose_trainval.json\n        │   │-- animalpose_test.json\n        │\n        │-- PASCAL2011_animal_annotation\n        │   │-- cat\n        │   │   |-- 2007_000528_1.xml\n        │   │   |-- 2007_000549_1.xml\n        │   │   │-- ...\n        │   │-- cow\n        │   │-- dog\n        │   │-- horse\n        │   │-- sheep\n        │\n        │-- annimalpose_anno2\n        │   │-- cat\n        │   │   |-- ca1.xml\n        │   │   |-- ca2.xml\n        │   │   │-- ...\n        │   │-- cow\n        │   │-- dog\n        │   │-- horse\n        │   │-- sheep\n\n```\n\nThe official dataset does not provide the official train/val/test set split.\nWe choose the images from PascalVOC for train & val. In total, we have 3608 images and 5117 annotations for train+val, where\n2798 images with 4000 annotations are used for training, and 810 images with 1117 annotations are used for validation.\nThose images from other sources (1000 images with 1000 annotations) are used for testing.\n\n## AP-10K\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2108.12617\">AP-10K (NeurIPS'2021)</a></summary>\n\n```bibtex\n@misc{yu2021ap10k,\n      title={AP-10K: A Benchmark for Animal Pose Estimation in the Wild},\n      author={Hang Yu and Yufei Xu and Jing Zhang and Wei Zhao and Ziyu Guan and Dacheng Tao},\n      year={2021},\n      eprint={2108.12617},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227797151-091dc21a-d944-49c9-8b62-cc47fa89e69f.png\" height=\"200px\">\n</div>\n\nFor [AP-10K](https://github.com/AlexTheBad/AP-10K/) dataset, images and annotations can be downloaded from [download](https://drive.google.com/file/d/1-FNNGcdtAQRehYYkGY1y4wzFNg4iWNad/view?usp=sharing).\nNote, this data and annotation data is for non-commercial use only.\n\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ap10k\n        │-- annotations\n        │   │-- ap10k-train-split1.json\n        │   |-- ap10k-train-split2.json\n        │   |-- ap10k-train-split3.json\n        │   │-- ap10k-val-split1.json\n        │   |-- ap10k-val-split2.json\n        │   |-- ap10k-val-split3.json\n        │   |-- ap10k-test-split1.json\n        │   |-- ap10k-test-split2.json\n        │   |-- ap10k-test-split3.json\n        │-- data\n        │   │-- 000000000001.jpg\n        │   │-- 000000000002.jpg\n        │   │-- ...\n\n```\n\nThe annotation files in 'annotation' folder contains 50 labeled animal species. There are total 10,015 labeled images with 13,028 instances in the AP-10K dataset. We randonly split them into train, val, and test set following the ratio of 7:1:2.\n\n## Horse-10\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content/WACV2021/html/Mathis_Pretraining_Boosts_Out-of-Domain_Robustness_for_Pose_Estimation_WACV_2021_paper.html\">Horse-10 (WACV'2021)</a></summary>\n\n```bibtex\n@inproceedings{mathis2021pretraining,\n  title={Pretraining boosts out-of-domain robustness for pose estimation},\n  author={Mathis, Alexander and Biasi, Thomas and Schneider, Steffen and Yuksekgonul, Mert and Rogers, Byron and Bethge, Matthias and Mathis, Mackenzie W},\n  booktitle={Proceedings of the IEEE/CVF Winter Conference on Applications of Computer Vision},\n  pages={1859--1868},\n  year={2021}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227797934-32bc1b2c-7957-4a29-94df-8e431842ab3b.png\" height=\"200px\">\n</div>\n\nFor [Horse-10](http://www.mackenziemathislab.org/horse10) dataset, images can be downloaded from [download](http://www.mackenziemathislab.org/horse10).\nPlease download the annotation files from [horse10_annotations](https://download.openmmlab.com/mmpose/datasets/horse10_annotations.tar). Note, this data and annotation data is for non-commercial use only, per the authors (see http://horse10.deeplabcut.org for more information).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── horse10\n        │-- annotations\n        │   │-- horse10-train-split1.json\n        │   |-- horse10-train-split2.json\n        │   |-- horse10-train-split3.json\n        │   │-- horse10-test-split1.json\n        │   |-- horse10-test-split2.json\n        │   |-- horse10-test-split3.json\n        │-- labeled-data\n        │   │-- BrownHorseinShadow\n        │   │-- BrownHorseintoshadow\n        │   │-- ...\n\n```\n\n## MacaquePose\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/pmc7874091/\">MacaquePose (bioRxiv'2020)</a></summary>\n\n```bibtex\n@article{labuguen2020macaquepose,\n  title={MacaquePose: A novel ‘in the wild’macaque monkey pose dataset for markerless motion capture},\n  author={Labuguen, Rollyn and Matsumoto, Jumpei and Negrete, Salvador and Nishimaru, Hiroshi and Nishijo, Hisao and Takada, Masahiko and Go, Yasuhiro and Inoue, Ken-ichi and Shibata, Tomohiro},\n  journal={bioRxiv},\n  year={2020},\n  publisher={Cold Spring Harbor Laboratory}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227799576-f10f8469-9432-4139-beb4-195037dee72c.png\" height=\"200px\">\n</div>\n\nFor [MacaquePose](http://www.pri.kyoto-u.ac.jp/datasets/macaquepose/index.html) dataset, images can be downloaded from [download](http://www.pri.kyoto-u.ac.jp/datasets/macaquepose/index.html).\nPlease download the annotation files from [macaque_annotations](https://download.openmmlab.com/mmpose/datasets/macaque_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── macaque\n        │-- annotations\n        │   │-- macaque_train.json\n        │   |-- macaque_test.json\n        │-- images\n        │   │-- 01418849d54b3005.jpg\n        │   │-- 0142d1d1a6904a70.jpg\n        │   │-- 01ef2c4c260321b7.jpg\n        │   │-- 020a1c75c8c85238.jpg\n        │   │-- 020b1506eef2557d.jpg\n        │   │-- ...\n\n```\n\nSince the official dataset does not provide the test set, we randomly select 12500 images for training, and the rest for evaluation (see [code](/tools/dataset/parse_macaquepose_dataset.py)).\n\n## Vinegar Fly\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.nature.com/articles/s41592-018-0234-5\">Vinegar Fly (Nature Methods'2019)</a></summary>\n\n```bibtex\n@article{pereira2019fast,\n  title={Fast animal pose estimation using deep neural networks},\n  author={Pereira, Talmo D and Aldarondo, Diego E and Willmore, Lindsay and Kislin, Mikhail and Wang, Samuel S-H and Murthy, Mala and Shaevitz, Joshua W},\n  journal={Nature methods},\n  volume={16},\n  number={1},\n  pages={117--125},\n  year={2019},\n  publisher={Nature Publishing Group}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227802774-bb4e4ef2-2ade-42ad-80f1-97f2a7faa9e2.png\" height=\"200px\">\n</div>\n\nFor [Vinegar Fly](https://github.com/jgraving/DeepPoseKit-Data) dataset, images can be downloaded from [vinegar_fly_images](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_images.tar).\nPlease download the annotation files from [vinegar_fly_annotations](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── fly\n        │-- annotations\n        │   │-- fly_train.json\n        │   |-- fly_test.json\n        │-- images\n        │   │-- 0.jpg\n        │   │-- 1.jpg\n        │   │-- 2.jpg\n        │   │-- 3.jpg\n        │   │-- ...\n\n```\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation (see [code](/tools/dataset_converters/parse_deepposekit_dataset.py)).\n\n## Desert Locust\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Desert Locust (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227802779-09d0ec8c-8971-4c67-a315-e2d1355f7f72.png\" height=\"200px\">\n</div>\n\nFor [Desert Locust](https://github.com/jgraving/DeepPoseKit-Data) dataset, images can be downloaded from [locust_images](https://download.openmmlab.com/mmpose/datasets/locust_images.tar).\nPlease download the annotation files from [locust_annotations](https://download.openmmlab.com/mmpose/datasets/locust_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── locust\n        │-- annotations\n        │   │-- locust_train.json\n        │   |-- locust_test.json\n        │-- images\n        │   │-- 0.jpg\n        │   │-- 1.jpg\n        │   │-- 2.jpg\n        │   │-- 3.jpg\n        │   │-- ...\n\n```\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation (see [code](/tools/dataset_converters/parse_deepposekit_dataset.py)).\n\n## Grévy’s Zebra\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Grévy’s Zebra (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227802783-ace952bb-1ff9-4720-80a8-c63cc9e714b6.png\" height=\"200px\">\n</div>\n\nFor [Grévy’s Zebra](https://github.com/jgraving/DeepPoseKit-Data) dataset, images can be downloaded from [zebra_images](https://download.openmmlab.com/mmpose/datasets/zebra_images.tar).\nPlease download the annotation files from [zebra_annotations](https://download.openmmlab.com/mmpose/datasets/zebra_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── zebra\n        │-- annotations\n        │   │-- zebra_train.json\n        │   |-- zebra_test.json\n        │-- images\n        │   │-- 0.jpg\n        │   │-- 1.jpg\n        │   │-- 2.jpg\n        │   │-- 3.jpg\n        │   │-- ...\n\n```\n\nSince the official dataset does not provide the test set, we randomly select 90% images for training, and the rest (10%) for evaluation (see [code](/tools/dataset_converters/parse_deepposekit_dataset.py)).\n\n## ATRW\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1906.05586\">ATRW (ACM MM'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020atrw,\n  title={ATRW: A Benchmark for Amur Tiger Re-identification in the Wild},\n  author={Li, Shuyuan and Li, Jianguo and Tang, Hanlin and Qian, Rui and Lin, Weiyao},\n  booktitle={Proceedings of the 28th ACM International Conference on Multimedia},\n  pages={2590--2598},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227797386-fce99241-8a0e-4a40-a179-dad013e6c5a4.png\" height=\"200px\">\n</div>\n\nATRW captures images of the Amur tiger (also known as Siberian tiger, Northeast-China tiger) in the wild.\nFor [ATRW](https://cvwc2019.github.io/challenge.html) dataset, please download images from\n[Pose_train](https://lilablobssc.blob.core.windows.net/cvwc2019/train/atrw_pose_train.tar.gz),\n[Pose_val](https://lilablobssc.blob.core.windows.net/cvwc2019/train/atrw_pose_val.tar.gz), and\n[Pose_test](https://lilablobssc.blob.core.windows.net/cvwc2019/test/atrw_pose_test.tar.gz).\nNote that in the ATRW official annotation files, the key \"file_name\" is written as \"filename\". To make it compatible with\nother coco-type json files, we have modified this key.\nPlease download the modified annotation files from [atrw_annotations](https://download.openmmlab.com/mmpose/datasets/atrw_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── atrw\n        │-- annotations\n        │   │-- keypoint_train.json\n        │   │-- keypoint_val.json\n        │   │-- keypoint_trainval.json\n        │-- images\n        │   │-- train\n        │   │   │-- 000002.jpg\n        │   │   │-- 000003.jpg\n        │   │   │-- ...\n        │   │-- val\n        │   │   │-- 000001.jpg\n        │   │   │-- 000013.jpg\n        │   │   │-- ...\n        │   │-- test\n        │   │   │-- 000000.jpg\n        │   │   │-- 000004.jpg\n        │   │   │-- ...\n\n```\n\n## Animal Kingdom\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2204.08129\">Animal Kingdom (CVPR'2022)</a></summary>\n</details>\n<div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/53283758/8591989e-91fa-4f6e-99c8-48b614de862e\" height=\"200px\">\n</div>\n\n```bibtex\n@inproceedings{Ng_2022_CVPR,\n    author    = {Ng, Xun Long and Ong, Kian Eng and Zheng, Qichen and Ni, Yun and Yeo, Si Yong and Liu, Jun},\n    title     = {Animal Kingdom: A Large and Diverse Dataset for Animal Behavior Understanding},\n    booktitle = {Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n    month     = {June},\n    year      = {2022},\n    pages     = {19023-19034}\n }\n```\n\nFor [Animal Kingdom](https://github.com/sutdcv/Animal-Kingdom) dataset, images can be downloaded from [here](https://forms.office.com/pages/responsepage.aspx?id=drd2NJDpck-5UGJImDFiPVRYpnTEMixKqPJ1FxwK6VZUQkNTSkRISTNORUI2TDBWMUpZTlQ5WUlaSyQlQCN0PWcu).\nPlease Extract dataset under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ak\n        |--annotations\n        │  │-- ak_P1\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P2\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_amphibian\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_bird\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_fish\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_mammal\n        │  │   │-- train.json\n        │  │   │-- test.json\n        │  │-- ak_P3_reptile\n        │      │-- train.json\n        │      │-- test.json\n        │-- images\n        │   │-- AAACXZTV\n        │   │   │--AAACXZTV_f000059.jpg\n        │   │   │--...\n        │   │-- AAAUILHH\n        │   │   │--AAAUILHH_f000098.jpg\n        │   │   │--...\n        │   │-- ...\n```\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/2d_body_keypoint.md",
    "content": "# 2D 人体关键点数据集\n\n建议将数据集的根目录链接到 `$MMPOSE/data`。\n如果你的文件夹结构不同，你可能需要在配置文件中更改相应的路径。\n\nMMPose 支持的数据集：\n\n- Images\n  - [COCO](#coco) \\[ [主页](http://cocodataset.org/) \\]\n  - [MPII](#mpii) \\[ [主页](http://human-pose.mpi-inf.mpg.de/) \\]\n  - [MPII-TRB](#mpii-trb) \\[ [主页](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) \\]\n  - [AI Challenger](#aic) \\[ [主页](https://github.com/AIChallenger/AI_Challenger_2017) \\]\n  - [CrowdPose](#crowdpose) \\[ [主页](https://github.com/Jeff-sjtu/CrowdPose) \\]\n  - [OCHuman](#ochuman) \\[ [主页](https://github.com/liruilong940607/OCHumanApi) \\]\n  - [MHP](#mhp) \\[ [主页](https://lv-mhp.github.io/dataset) \\]\n  - [Human-Art](#humanart) \\[ [主页](https://idea-research.github.io/HumanArt/) \\]\n  - [ExLPose](#exlpose-dataset) \\[ [Homepage](http://cg.postech.ac.kr/research/ExLPose/) \\]\n- Videos\n  - [PoseTrack18](#posetrack18) \\[ [主页](https://posetrack.net/users/download.php) \\]\n  - [sub-JHMDB](#sub-jhmdb-dataset) \\[ [主页](http://jhmdb.is.tue.mpg.de/dataset) \\]\n\n## COCO\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864552-489d03de-e1b8-4ca2-8ac1-80dd99826cb7.png\" height=\"300px\">\n</div>\n\n对于 [COCO](http://cocodataset.org/) 数据，请从 [COCO 下载](http://cocodataset.org/#download) 中下载，需要 2017 训练/验证集进行 COCO 关键点的训练和验证。\n[HRNet-Human-Pose-Estimation](https://github.com/HRNet/HRNet-Human-Pose-Estimation) 提供了 COCO val2017 的人体检测结果，以便重现我们的多人姿态估计结果。\n请从 [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) 或 [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing) 下载。\n如果要在 COCO'2017 test-dev 上进行评估，请下载 [image-info](https://download.openmmlab.com/mmpose/datasets/person_keypoints_test-dev-2017.json)。\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- person_keypoints_train2017.json\n        │   |-- person_keypoints_val2017.json\n        │   |-- person_keypoints_test-dev-2017.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        |   |-- COCO_test-dev2017_detections_AP_H_609_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\n## MPII\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864660-e5f51e7d-deca-41d8-9725-8b5432bcc0e6.png\" height=\"300px\">\n</div>\n\n对于 [MPII](http://human-pose.mpi-inf.mpg.de/) 数据，请从 [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/) 下载。\n我们已将原始的注释文件转换为 json 格式，请从 [mpii_annotations](https://download.openmmlab.com/mmpose/datasets/mpii_annotations.tar) 下载。\n请将它们解压到 {MMPose}/data 下，并确保目录结构如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mpii\n        |── annotations\n        |   |── mpii_gt_val.mat\n        |   |── mpii_test.json\n        |   |── mpii_train.json\n        |   |── mpii_trainval.json\n        |   `── mpii_val.json\n        `── images\n            |── 000001163.jpg\n            |── 000003072.jpg\n\n```\n\n在训练和推理期间，默认情况下，预测结果将以 '.mat' 格式保存。我们还提供了一个工具，以将这个 '.mat' 转换为更易读的 '.json' 格式。\n\n```shell\npython tools/dataset/mat2json ${PRED_MAT_FILE} ${GT_JSON_FILE} ${OUTPUT_PRED_JSON_FILE}\n```\n\n例如，\n\n```shell\npython tools/dataset/mat2json work_dirs/res50_mpii_256x256/pred.mat data/mpii/annotations/mpii_val.json pred.json\n```\n\n## MPII-TRB\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Duan_TRB_A_Novel_Triplet_Representation_for_Understanding_2D_Human_Body_ICCV_2019_paper.html\">MPII-TRB (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{duan2019trb,\n  title={TRB: A Novel Triplet Representation for Understanding 2D Human Body},\n  author={Duan, Haodong and Lin, Kwan-Yee and Jin, Sheng and Liu, Wentao and Qian, Chen and Ouyang, Wanli},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={9479--9488},\n  year={2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864382-ab722299-6806-4ae4-babb-7bcc5fb09662.png\" height=\"300px\">\n</div>\n\n对于 [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) 数据，请从 [MPII Human Pose Dataset](http://human-pose.mpi-inf.mpg.de/) 下载。\n请从 [mpii_trb_annotations](https://download.openmmlab.com/mmpose/datasets/mpii_trb_annotations.tar) 下载注释文件。\n将它们解压到 {MMPose}/data 下，并确保它们的结构如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mpii\n        |── annotations\n        |   |── mpii_trb_train.json\n        |   |── mpii_trb_val.json\n        `── images\n            |── 000001163.jpg\n            |── 000003072.jpg\n\n```\n\n## AIC\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/1711.06475\">AI Challenger (ArXiv'2017)</a></summary>\n\n```bibtex\n@article{wu2017ai,\n  title={Ai challenger: A large-scale dataset for going deeper in image understanding},\n  author={Wu, Jiahong and Zheng, He and Zhao, Bo and Li, Yixin and Yan, Baoming and Liang, Rui and Wang, Wenjia and Zhou, Shipei and Lin, Guosen and Fu, Yanwei and others},\n  journal={arXiv preprint arXiv:1711.06475},\n  year={2017}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864755-dd19644e-fccb-458b-a8c0-de55920261f5.png\" height=\"300px\">\n</div>\n\n对于 [AIC](https://github.com/AIChallenger/AI_Challenger_2017) 数据，请从 [AI Challenger 2017](https://github.com/AIChallenger/AI_Challenger_2017) 下载。其中 2017 Train/Val 数据适用于关键点的训练和验证。\n请从 [aic_annotations](https://download.openmmlab.com/mmpose/datasets/aic_annotations.tar) 下载注释文件。\n下载并解压到 $MMPOSE/data 下，并确保它们的结构如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── aic\n        │-- annotations\n        │   │-- aic_train.json\n        │   |-- aic_val.json\n        │-- ai_challenger_keypoint_train_20170902\n        │   │-- keypoint_train_images_20170902\n        │   │   │-- 0000252aea98840a550dac9a78c476ecb9f47ffa.jpg\n        │   │   │-- 000050f770985ac9653198495ef9b5c82435d49c.jpg\n        │   │   │-- ...\n        `-- ai_challenger_keypoint_validation_20170911\n            │-- keypoint_validation_images_20170911\n                │-- 0002605c53fb92109a3f2de4fc3ce06425c3b61f.jpg\n                │-- 0003b55a2c991223e6d8b4b820045bd49507bf6d.jpg\n                │-- ...\n```\n\n## CrowdPose\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Li_CrowdPose_Efficient_Crowded_Scenes_Pose_Estimation_and_a_New_Benchmark_CVPR_2019_paper.html\">CrowdPose (CVPR'2019)</a></summary>\n\n```bibtex\n@article{li2018crowdpose,\n  title={CrowdPose: Efficient Crowded Scenes Pose Estimation and A New Benchmark},\n  author={Li, Jiefeng and Wang, Can and Zhu, Hao and Mao, Yihuan and Fang, Hao-Shu and Lu, Cewu},\n  journal={arXiv preprint arXiv:1812.00324},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864868-54a98493-df3a-44d8-acbc-6ec22043dfb9.png\" height=\"300px\">\n</div>\n\n对于 [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose)数据，请从 [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose) 下载。\n请下载标注文件和人体检测结果从 [crowdpose_annotations](https://download.openmmlab.com/mmpose/datasets/crowdpose_annotations.tar)。\n对于自上而下的方法，我们按照 [CrowdPose](https://arxiv.org/abs/1812.00324)使用[YOLOv3](https://github.com/eriklindernoren/PyTorch-YOLOv3) 的 [预训练权重](https://pjreddie.com/media/files/yolov3.weights) 来生成检测到的人体边界框。\n对于模型训练，我们按照 [HigherHRNet](https://github.com/HRNet/HigherHRNet-Human-Pose-Estimation) 在 CrowdPose 的训练/验证数据集上进行训练，并在 CrowdPose 测试数据集上评估模型。\n下载并解压缩它们到 $MMPOSE/data 目录下，结构应如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── crowdpose\n        │-- annotations\n        │   │-- mmpose_crowdpose_train.json\n        │   │-- mmpose_crowdpose_val.json\n        │   │-- mmpose_crowdpose_trainval.json\n        │   │-- mmpose_crowdpose_test.json\n        │   │-- det_for_crowd_test_0.1_0.5.json\n        │-- images\n            │-- 100000.jpg\n            │-- 100001.jpg\n            │-- 100002.jpg\n            │-- ...\n```\n\n## OCHuman\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_CVPR_2019/html/Zhang_Pose2Seg_Detection_Free_Human_Instance_Segmentation_CVPR_2019_paper.html\">OCHuman (CVPR'2019)</a></summary>\n\n```bibtex\n@inproceedings{zhang2019pose2seg,\n  title={Pose2seg: Detection free human instance segmentation},\n  author={Zhang, Song-Hai and Li, Ruilong and Dong, Xin and Rosin, Paul and Cai, Zixi and Han, Xi and Yang, Dingcheng and Huang, Haozhi and Hu, Shi-Min},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={889--898},\n  year={2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864552-489d03de-e1b8-4ca2-8ac1-80dd99826cb7.png\" height=\"300px\">\n</div>\n\n对于 [OCHuman](https://github.com/liruilong940607/OCHumanApi) 数据，请从 [OCHuman](https://github.com/liruilong940607/OCHumanApi) 下载图像和标注。\n将它们移动到 $MMPOSE/data 目录下，结构应如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ochuman\n        │-- annotations\n        │   │-- ochuman_coco_format_val_range_0.00_1.00.json\n        │   |-- ochuman_coco_format_test_range_0.00_1.00.json\n        |-- images\n            │-- 000001.jpg\n            │-- 000002.jpg\n            │-- 000003.jpg\n            │-- ...\n\n```\n\n## MHP\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://dl.acm.org/doi/abs/10.1145/3240508.3240509\">MHP (ACM MM'2018)</a></summary>\n\n```bibtex\n@inproceedings{zhao2018understanding,\n  title={Understanding humans in crowded scenes: Deep nested adversarial learning and a new benchmark for multi-human parsing},\n  author={Zhao, Jian and Li, Jianshu and Cheng, Yu and Sim, Terence and Yan, Shuicheng and Feng, Jiashi},\n  booktitle={Proceedings of the 26th ACM international conference on Multimedia},\n  pages={792--800},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227865030-2fd33ade-2cc2-4b67-aca0-6dea2124b63c.png\" height=\"300px\">\n</div>\n\n对于 [MHP](https://lv-mhp.github.io/dataset) 数据，请从 [MHP](https://lv-mhp.github.io/dataset) 下载。\n请从 [mhp_annotations](https://download.openmmlab.com/mmpose/datasets/mhp_annotations.tar.gz) 下载标注文件。\n请下载并解压到 $MMPOSE/data 目录下，并确保目录结构如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mhp\n        │-- annotations\n        │   │-- mhp_train.json\n        │   │-- mhp_val.json\n        │\n        `-- train\n        │   │-- images\n        │   │   │-- 1004.jpg\n        │   │   │-- 10050.jpg\n        │   │   │-- ...\n        │\n        `-- val\n        │   │-- images\n        │   │   │-- 10059.jpg\n        │   │   │-- 10068.jpg\n        │   │   │-- ...\n        │\n        `-- test\n        │   │-- images\n        │   │   │-- 1005.jpg\n        │   │   │-- 10052.jpg\n        │   │   │-- ...~~~~\n```\n\n## Human-Art dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://idea-research.github.io/HumanArt/\">Human-Art (CVPR'2023)</a></summary>\n\n```bibtex\n@inproceedings{ju2023humanart,\n    title={Human-Art: A Versatile Human-Centric Dataset Bridging Natural and Artificial Scenes},\n    author={Ju, Xuan and Zeng, Ailing and Jianan, Wang and Qiang, Xu and Lei, Zhang},\n    booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR),\n    year={2023}}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227864552-489d03de-e1b8-4ca2-8ac1-80dd99826cb7.png\" height=\"300px\">\n</div>\n\n对于 [Human-Art](https://idea-research.github.io/HumanArt/) 数据，请从 [其网站](https://idea-research.github.io/HumanArt/) 下载图像和标注文件。\n您需要填写 [申请表](https://docs.google.com/forms/d/e/1FAIpQLScroT_jvw6B9U2Qca1_cl5Kmmu1ceKtlh6DJNmWLte8xNEhEw/viewform) 以获取数据访问权限。\n请将它们移动到 $MMPOSE/data 目录下，目录结构应如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n|── data\n    │── HumanArt\n        │-- images\n        │   │-- 2D_virtual_human\n        │   │   |-- cartoon\n        │   │   |   |-- 000000000000.jpg\n        │   │   |   |-- ...\n        │   │   |-- digital_art\n        │   │   |-- ...\n        │   |-- 3D_virtual_human\n        │   |-- real_human\n        |-- annotations\n        │   │-- validation_humanart.json\n        │   │-- training_humanart_coco.json\n        |-- person_detection_results\n        │   │-- HumanArt_validation_detections_AP_H_56_person.json\n```\n\n您可以选择是否下载 Human-Art 的其他标注文件。如果你想使用其他标注文件（例如，卡通的验证集），你需要在配置文件中编辑相应的代码。\n\n## ExLPose dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://cg.postech.ac.kr/research/ExLPose/\">ExLPose (2023)</a></summary>\n\n```bibtex\n@inproceedings{ExLPose_2023_CVPR,\n title={Human Pose Estimation in Extremely Low-Light Conditions},\n author={Sohyun Lee, Jaesung Rim, Boseung Jeong, Geonu Kim, ByungJu Woo, Haechan Lee, Sunghyun Cho, Suha Kwak},\n booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition (CVPR)},\n year={2023}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/71805205/d2c7d552-249a-4ac0-8ac3-1467ace59f2f\" height=\"300px\">\n</div>\n\n请从 [ExLPose](https://drive.google.com/drive/folders/1E0Is4_cShxvsbJlep_aNEYLJpmHzq9FL) 下载数据，将其移动到 $MMPOSE/data 目录下，并使其结构如下：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── ExLPose\n        │-- annotations\n        |\t|-- ExLPose\n        │   |-- ExLPose_train_LL.json\n        │   |-- ExLPose_test_LL-A.json\n        │   |-- ExLPose_test_LL-E.json\n        │   |-- ExLPose_test_LL-H.json\n        │   |-- ExLPose_test_LL-N.json\n        |-- dark\n            |--00001.png\n            |--00002.png\n            |--...\n\n```\n\n## PoseTrack18\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Andriluka_PoseTrack_A_Benchmark_CVPR_2018_paper.html\">PoseTrack18 (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{andriluka2018posetrack,\n  title={Posetrack: A benchmark for human pose estimation and tracking},\n  author={Andriluka, Mykhaylo and Iqbal, Umar and Insafutdinov, Eldar and Pishchulin, Leonid and Milan, Anton and Gall, Juergen and Schiele, Bernt},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={5167--5176},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227865114-3f98c673-f6d0-4518-ae99-653f475f9fc8.png\" height=\"300px\">\n</div>\n\n关于 [PoseTrack18](https://posetrack.net/users/download.php) 的数据，请从 [PoseTrack18](https://posetrack.net/users/download.php) 下载。\n请从 [posetrack18_annotations](https://download.openmmlab.com/mmpose/datasets/posetrack18_annotations.tar) 下载标注文件。\n我们已经将分散在各个视频中的官方标注文件合并为两个 json 文件（posetrack18_train & posetrack18_val.json）。我们还生成了 [mask 文件](https://download.openmmlab.com/mmpose/datasets/posetrack18_mask.tar) 以加速训练。\n对于自上而下的方法，我们使用 [MMDetection](https://github.com/open-mmlab/mmdetection) 预训练的 [Cascade R-CNN](https://download.openmmlab.com/mmdetection/v2.0/cascade_rcnn/cascade_rcnn_x101_64x4d_fpn_20e_coco/cascade_rcnn_x101_64x4d_fpn_20e_coco_20200509_224357-051557b1.pth)（X-101-64x4d-FPN）来生成检测到的人体边界框。\n请下载并将它们解压到 $MMPOSE/data 下，目录结构应如下所示：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── posetrack18\n        │-- annotations\n        │   │-- posetrack18_train.json\n        │   │-- posetrack18_val.json\n        │   │-- posetrack18_val_human_detections.json\n        │   │-- train\n        │   │   │-- 000001_bonn_train.json\n        │   │   │-- 000002_bonn_train.json\n        │   │   │-- ...\n        │   │-- val\n        │   │   │-- 000342_mpii_test.json\n        │   │   │-- 000522_mpii_test.json\n        │   │   │-- ...\n        │   `-- test\n        │       │-- 000001_mpiinew_test.json\n        │       │-- 000002_mpiinew_test.json\n        │       │-- ...\n        │\n        `-- images\n        │   │-- train\n        │   │   │-- 000001_bonn_train\n        │   │   │   │-- 000000.jpg\n        │   │   │   │-- 000001.jpg\n        │   │   │   │-- ...\n        │   │   │-- ...\n        │   │-- val\n        │   │   │-- 000342_mpii_test\n        │   │   │   │-- 000000.jpg\n        │   │   │   │-- 000001.jpg\n        │   │   │   │-- ...\n        │   │   │-- ...\n        │   `-- test\n        │       │-- 000001_mpiinew_test\n        │       │   │-- 000000.jpg\n        │       │   │-- 000001.jpg\n        │       │   │-- ...\n        │       │-- ...\n        `-- mask\n            │-- train\n            │   │-- 000002_bonn_train\n            │   │   │-- 000000.jpg\n            │   │   │-- 000001.jpg\n            │   │   │-- ...\n            │   │-- ...\n            `-- val\n                │-- 000522_mpii_test\n                │   │-- 000000.jpg\n                │   │-- 000001.jpg\n                │   │-- ...\n                │-- ...\n```\n\n官方的 PoseTrack 评估工具可以使用以下命令安装。\n\n```shell\npip install git+https://github.com/svenkreiss/poseval.git\n```\n\n## sub-JHMDB dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58580-8_27\">RSN (ECCV'2020)</a></summary>\n\n```bibtex\n@misc{cai2020learning,\n    title={Learning Delicate Local Representations for Multi-Person Pose Estimation},\n    author={Yuanhao Cai and Zhicheng Wang and Zhengxiong Luo and Binyi Yin and Angang Du and Haoqian Wang and Xinyu Zhou and Erjin Zhou and Xiangyu Zhang and Jian Sun},\n    year={2020},\n    eprint={2003.04030},\n    archivePrefix={arXiv},\n    primaryClass={cs.CV}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227865619-d65f64ae-991d-4693-99c2-caecd1beb1fc.png\" height=\"300px\">\n</div>\n\n对于 [sub-JHMDB](http://jhmdb.is.tue.mpg.de/dataset) 的数据，请从 [JHMDB](http://jhmdb.is.tue.mpg.de/dataset) 下载 [图像](<(http://files.is.tue.mpg.de/jhmdb/Rename_Images.tar.gz)>)，\n请从 [jhmdb_annotations](https://download.openmmlab.com/mmpose/datasets/jhmdb_annotations.tar) 下载标注文件。\n将它们移至 $MMPOSE/data 下，并使目录结构如下所示：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── jhmdb\n        │-- annotations\n        │   │-- Sub1_train.json\n        │   |-- Sub1_test.json\n        │   │-- Sub2_train.json\n        │   |-- Sub2_test.json\n        │   │-- Sub3_train.json\n        │   |-- Sub3_test.json\n        |-- Rename_Images\n            │-- brush_hair\n            │   │--April_09_brush_hair_u_nm_np1_ba_goo_0\n            |   │   │--00001.png\n            |   │   │--00002.png\n            │-- catch\n            │-- ...\n\n```\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/2d_face_keypoint.md",
    "content": "# 2D Face Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [300W](#300w-dataset) \\[ [Homepage](https://ibug.doc.ic.ac.uk/resources/300-W/) \\]\n- [300VW](#300vw-dataset) \\[ [Homepage](https://ibug.doc.ic.ac.uk/resources/300-VW/) \\]\n- [WFLW](#wflw-dataset) \\[ [Homepage](https://wywu.github.io/projects/LAB/WFLW.html) \\]\n- [AFLW](#aflw-dataset) \\[ [Homepage](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/) \\]\n- [COFW](#cofw-dataset) \\[ [Homepage](http://www.vision.caltech.edu/xpburgos/ICCV13/) \\]\n- [COCO-WholeBody-Face](#coco-wholebody-face) \\[ [Homepage](https://github.com/jin-s13/COCO-WholeBody/) \\]\n- [LaPa](#lapa-dataset) \\[ [Homepage](https://github.com/JDAI-CV/lapa-dataset) \\]\n\n## 300W Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.sciencedirect.com/science/article/pii/S0262885616000147\">300W (IMAVIS'2016)</a></summary>\n\n```bibtex\n@article{sagonas2016300,\n  title={300 faces in-the-wild challenge: Database and results},\n  author={Sagonas, Christos and Antonakos, Epameinondas and Tzimiropoulos, Georgios and Zafeiriou, Stefanos and Pantic, Maja},\n  journal={Image and vision computing},\n  volume={47},\n  pages={3--18},\n  year={2016},\n  publisher={Elsevier}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227780043-e557acc3-5966-48ba-ac9e-b6c5916f1e55.jpg\" height=\"200px\">\n</div>\n\nFor 300W data, please download images from [300W Dataset](https://ibug.doc.ic.ac.uk/resources/300-W/).\nPlease download the annotation files from [300w_annotations](https://download.openmmlab.com/mmpose/datasets/300w_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── 300w\n        |── annotations\n        |   |── face_landmarks_300w_train.json\n        |   |── face_landmarks_300w_valid.json\n        |   |── face_landmarks_300w_valid_common.json\n        |   |── face_landmarks_300w_valid_challenge.json\n        |   |── face_landmarks_300w_test.json\n        `── images\n            |── afw\n            |   |── 1051618982_1.jpg\n            |   |── 111076519_1.jpg\n            |    ...\n            |── helen\n            |   |── trainset\n            |   |   |── 100032540_1.jpg\n            |   |   |── 100040721_1.jpg\n            |   |    ...\n            |   |── testset\n            |   |   |── 296814969_3.jpg\n            |   |   |── 2968560214_1.jpg\n            |   |    ...\n            |── ibug\n            |   |── image_003_1.jpg\n            |   |── image_004_1.jpg\n            |    ...\n            |── lfpw\n            |   |── trainset\n            |   |   |── image_0001.png\n            |   |   |── image_0002.png\n            |   |    ...\n            |   |── testset\n            |   |   |── image_0001.png\n            |   |   |── image_0002.png\n            |   |    ...\n            `── Test\n                |── 01_Indoor\n                |   |── indoor_001.png\n                |   |── indoor_002.png\n                |    ...\n                `── 02_Outdoor\n                    |── outdoor_001.png\n                    |── outdoor_002.png\n                     ...\n```\n\n## 300VW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://www.cv-foundation.org/openaccess/content_iccv_2015_workshops/w25/papers/Shen_The_First_Facial_ICCV_2015_paper.pdf\">300VW (ICCVW'2015)</a></summary>\n\n```bibtex\n@inproceedings{shen2015first,\n  title={The first facial landmark tracking in-the-wild challenge: Benchmark and results},\n  author={Shen, Jie and Zafeiriou, Stefanos and Chrysos, Grigoris G and Kossaifi, Jean and Tzimiropoulos, Georgios and Pantic, Maja},\n  booktitle={Proceedings of the IEEE international conference on computer vision workshops},\n  pages={50--58},\n  year={2015}\n}\n```\n\n</details>\n\n300VW dataset follows the same mark-up (i.e. set of facial landmarks) used in the 300W.\nFor 300VW data, please register and download images from [300VW Dataset](https://ibug.doc.ic.ac.uk/download/300VW_Dataset_2015_12_14.zip) .\nUnzip and use the \"tools/dataset_converters/300vw2coco.py\" to process the data.\n\n<!-- Please download the annotation files from [300w_annotations](https://download.openmmlab.com/mmpose/datasets/300w_annotations.tar). -->\n\nPut the 300VW under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── 300vw\n        |── annotations\n        |   |── train.json\n        |   |── test_1.json\n        |   |── test_2.json\n        |   `── test_3.json\n        `── images\n            |── 001\n            |   `── imgs\n            |       |── 000001.png\n            |       |── 000002.png\n            |       ...\n            |── 002\n            |   `── imgs\n            |       |── 000001.png\n            |       |── 000002.png\n            |       ...\n            |   ...\n```\n\n## WFLW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2018/html/Wu_Look_at_Boundary_CVPR_2018_paper.html\">WFLW (CVPR'2018)</a></summary>\n\n```bibtex\n@inproceedings{wu2018look,\n  title={Look at boundary: A boundary-aware face alignment algorithm},\n  author={Wu, Wayne and Qian, Chen and Yang, Shuo and Wang, Quan and Cai, Yici and Zhou, Qiang},\n  booktitle={Proceedings of the IEEE conference on computer vision and pattern recognition},\n  pages={2129--2138},\n  year={2018}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227785100-4b3d1e39-0d64-47c0-9e55-c947ce70866e.png\" height=\"200px\">\n</div>\n\nFor WFLW data, please download images from [WFLW Dataset](https://wywu.github.io/projects/LAB/WFLW.html).\nPlease download the annotation files from [wflw_annotations](https://download.openmmlab.com/mmpose/datasets/wflw_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── wflw\n        |── annotations\n        |   |── face_landmarks_wflw_train.json\n        |   |── face_landmarks_wflw_test.json\n        |   |── face_landmarks_wflw_test_blur.json\n        |   |── face_landmarks_wflw_test_occlusion.json\n        |   |── face_landmarks_wflw_test_expression.json\n        |   |── face_landmarks_wflw_test_largepose.json\n        |   |── face_landmarks_wflw_test_illumination.json\n        |   |── face_landmarks_wflw_test_makeup.json\n        |\n        `── images\n            |── 0--Parade\n            |   |── 0_Parade_marchingband_1_1015.jpg\n            |   |── 0_Parade_marchingband_1_1031.jpg\n            |    ...\n            |── 1--Handshaking\n            |   |── 1_Handshaking_Handshaking_1_105.jpg\n            |   |── 1_Handshaking_Handshaking_1_107.jpg\n            |    ...\n            ...\n```\n\nWe also supply a script which can convert the raw WFLW annotations to COCO style. The script's output is not completely consistent with the annotations downloaded from the URL, but it does not affect training and testing.\n\n## AFLW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6130513/\">AFLW (ICCVW'2011)</a></summary>\n\n```bibtex\n@inproceedings{koestinger2011annotated,\n  title={Annotated facial landmarks in the wild: A large-scale, real-world database for facial landmark localization},\n  author={Koestinger, Martin and Wohlhart, Paul and Roth, Peter M and Bischof, Horst},\n  booktitle={2011 IEEE international conference on computer vision workshops (ICCV workshops)},\n  pages={2144--2151},\n  year={2011},\n  organization={IEEE}\n}\n```\n\n</details>\n\nFor AFLW data, please download images from [AFLW Dataset](https://www.tugraz.at/institute/icg/research/team-bischof/lrs/downloads/aflw/).\nPlease download the annotation files from [aflw_annotations](https://download.openmmlab.com/mmpose/datasets/aflw_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── aflw\n        |── annotations\n        |   |── face_landmarks_aflw_train.json\n        |   |── face_landmarks_aflw_test_frontal.json\n        |   |── face_landmarks_aflw_test.json\n        `── images\n            |── flickr\n                |── 0\n                |   |── image00002.jpg\n                |   |── image00013.jpg\n                |    ...\n                |── 2\n                |   |── image00004.jpg\n                |   |── image00006.jpg\n                |    ...\n                `── 3\n                    |── image00032.jpg\n                    |── image00035.jpg\n                     ...\n```\n\n## COFW Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2013/html/Burgos-Artizzu_Robust_Face_Landmark_2013_ICCV_paper.html\">COFW (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{burgos2013robust,\n  title={Robust face landmark estimation under occlusion},\n  author={Burgos-Artizzu, Xavier P and Perona, Pietro and Doll{\\'a}r, Piotr},\n  booktitle={Proceedings of the IEEE international conference on computer vision},\n  pages={1513--1520},\n  year={2013}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227786792-06604943-c062-4bcd-bb2d-a2f78d80115b.png\" height=\"200px\">\n</div>\n\nFor COFW data, please download from [COFW Dataset (Color Images)](http://www.vision.caltech.edu/xpburgos/ICCV13/Data/COFW_color.zip).\nMove `COFW_train_color.mat` and `COFW_test_color.mat` to `data/cofw/` and make them look like:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n```\n\nRun the following script under `{MMPose}/data`\n\n`python tools/dataset_converters/parse_cofw_dataset.py`\n\nAnd you will get\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n        |── annotations\n        |   |── cofw_train.json\n        |   |── cofw_test.json\n        |── images\n            |── 000001.jpg\n            |── 000002.jpg\n```\n\n## COCO-WholeBody (Face)\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Face (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227787217-2f226dc0-e5d7-4d0b-9ab8-68b53a5467c2.png\" height=\"200px\">\n</div>\n\nFor [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/) dataset, images can be downloaded from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\nDownload COCO-WholeBody annotations for COCO-WholeBody annotations for [Train](https://drive.google.com/file/d/1thErEToRbmM9uLNi1JXXfOsaS5VK2FXf/view?usp=sharing) / [Validation](https://drive.google.com/file/d/1N6VgwKnj8DeyGXCvp1eYgNbRmw6jdfrb/view?usp=sharing) (Google Drive).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- coco_wholebody_train_v1.0.json\n        │   |-- coco_wholebody_val_v1.0.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n\n## LaPa\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://aaai.org/ojs/index.php/AAAI/article/view/6832/6686\">LaPa (AAAI'2020)</a></summary>\n\n```bibtex\n@inproceedings{liu2020new,\n  title={A New Dataset and Boundary-Attention Semantic Segmentation for Face Parsing.},\n  author={Liu, Yinglu and Shi, Hailin and Shen, Hao and Si, Yue and Wang, Xiaobo and Mei, Tao},\n  booktitle={AAAI},\n  pages={11637--11644},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://github.com/lucia123/lapa-dataset/raw/master/sample.png\" height=\"200px\">\n</div>\n\nFor [LaPa](https://github.com/JDAI-CV/lapa-dataset) dataset, images can be downloaded from [their github page](https://github.com/JDAI-CV/lapa-dataset).\n\nDownload and extract them under $MMPOSE/data, and use our `tools/dataset_converters/lapa2coco.py` to make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── LaPa\n        │-- annotations\n        │   │-- lapa_train.json\n        │   |-- lapa_val.json\n        │   |-- lapa_test.json\n        |   |-- lapa_trainval.json\n        │-- train\n        │   │-- images\n        │   │-- labels\n        │   │-- landmarks\n        │-- val\n        │   │-- images\n        │   │-- labels\n        │   │-- landmarks\n        `-- test\n        │   │-- images\n        │   │-- labels\n        │   │-- landmarks\n\n```\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/2d_fashion_landmark.md",
    "content": "# 2D Fashion Landmark Dataset\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [DeepFashion](#deepfashion) \\[ [Homepage](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html) \\]\n- [DeepFashion2](#deepfashion2) \\[ [Homepage](https://github.com/switchablenorms/DeepFashion2) \\]\n\n## DeepFashion (Fashion Landmark Detection, FLD)\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2016/html/Liu_DeepFashion_Powering_Robust_CVPR_2016_paper.html\">DeepFashion (CVPR'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuLQWTcvpr16DeepFashion,\n author = {Liu, Ziwei and Luo, Ping and Qiu, Shi and Wang, Xiaogang and Tang, Xiaoou},\n title = {DeepFashion: Powering Robust Clothes Recognition and Retrieval with Rich Annotations},\n booktitle = {Proceedings of IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n month = {June},\n year = {2016}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-46475-6_15\">DeepFashion (ECCV'2016)</a></summary>\n\n```bibtex\n@inproceedings{liuYLWTeccv16FashionLandmark,\n author = {Liu, Ziwei and Yan, Sijie and Luo, Ping and Wang, Xiaogang and Tang, Xiaoou},\n title = {Fashion Landmark Detection in the Wild},\n booktitle = {European Conference on Computer Vision (ECCV)},\n month = {October},\n year = {2016}\n }\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227774588-443fc5cc-7842-472a-abd5-827f0e3fd27f.png\" height=\"150px\">\n</div>\n\nFor [DeepFashion](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html) dataset, images can be downloaded from [download](http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html).\nPlease download the annotation files from [fld_annotations](https://download.openmmlab.com/mmpose/datasets/fld_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── fld\n        │-- annotations\n        │   │-- fld_upper_train.json\n        │   |-- fld_upper_val.json\n        │   |-- fld_upper_test.json\n        │   │-- fld_lower_train.json\n        │   |-- fld_lower_val.json\n        │   |-- fld_lower_test.json\n        │   │-- fld_full_train.json\n        │   |-- fld_full_val.json\n        │   |-- fld_full_test.json\n        │-- img\n        │   │-- img_00000001.jpg\n        │   │-- img_00000002.jpg\n        │   │-- img_00000003.jpg\n        │   │-- img_00000004.jpg\n        │   │-- img_00000005.jpg\n        │   │-- ...\n```\n\n## DeepFashion2\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/pdf/1901.07973.pdf\">DeepFashion2 (CVPR'2019)</a></summary>\n\n```bibtex\n@article{DeepFashion2,\n  author = {Yuying Ge and Ruimao Zhang and Lingyun Wu and Xiaogang Wang and Xiaoou Tang and Ping Luo},\n  title={A Versatile Benchmark for Detection, Pose Estimation, Segmentation and Re-Identification of Clothing Images},\n  journal={CVPR},\n  year={2019}\n}\n```\n\n</details>\n\n<!-- [DATASET] -->\n\nFor [DeepFashion2](https://github.com/switchablenorms/DeepFashion2) dataset, images can be downloaded from [download](https://drive.google.com/drive/folders/125F48fsMBz2EF0Cpqk6aaHet5VH399Ok?usp=sharing).\nPlease download the [annotation files](https://drive.google.com/file/d/1RM9l9EaB9ULRXhoCS72PkCXtJ4Cn4i6O/view?usp=share_link). These annotation files are converted by [deepfashion2_to_coco.py](https://github.com/switchablenorms/DeepFashion2/blob/master/evaluation/deepfashion2_to_coco.py).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── deepfashion2\n        │── train\n            │-- deepfashion2_short_sleeved_outwear_train.json\n            │-- deepfashion2_short_sleeved_dress_train.json\n            │-- deepfashion2_skirt_train.json\n            │-- deepfashion2_sling_dress_train.json\n            │-- ...\n            │-- image\n            │   │-- 000001.jpg\n            │   │-- 000002.jpg\n            │   │-- 000003.jpg\n            │   │-- 000004.jpg\n            │   │-- 000005.jpg\n            │   │-- ...\n        │── validation\n            │-- deepfashion2_short_sleeved_dress_validation.json\n            │-- deepfashion2_long_sleeved_shirt_validation.json\n            │-- deepfashion2_trousers_validation.json\n            │-- deepfashion2_skirt_validation.json\n            │-- ...\n            │-- image\n            │   │-- 000001.jpg\n            │   │-- 000002.jpg\n            │   │-- 000003.jpg\n            │   │-- 000004.jpg\n            │   │-- 000005.jpg\n            │   │-- ...\n```\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/2d_hand_keypoint.md",
    "content": "# 2D Hand Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [OneHand10K](#onehand10k) \\[ [Homepage](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) \\]\n- [FreiHand](#freihand-dataset) \\[ [Homepage](https://lmb.informatik.uni-freiburg.de/projects/freihand/) \\]\n- [CMU Panoptic HandDB](#cmu-panoptic-handdb) \\[ [Homepage](http://domedb.perception.cs.cmu.edu/handdb.html) \\]\n- [InterHand2.6M](#interhand26m) \\[ [Homepage](https://mks0601.github.io/InterHand2.6M/) \\]\n- [RHD](#rhd-dataset) \\[ [Homepage](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html) \\]\n- [COCO-WholeBody-Hand](#coco-wholebody-hand) \\[ [Homepage](https://github.com/jin-s13/COCO-WholeBody/) \\]\n\n## OneHand10K\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/8529221/\">OneHand10K (TCSVT'2019)</a></summary>\n\n```bibtex\n@article{wang2018mask,\n  title={Mask-pose cascaded cnn for 2d hand pose estimation from single color image},\n  author={Wang, Yangang and Peng, Cong and Liu, Yebin},\n  journal={IEEE Transactions on Circuits and Systems for Video Technology},\n  volume={29},\n  number={11},\n  pages={3258--3268},\n  year={2018},\n  publisher={IEEE}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) data, please download from [OneHand10K Dataset](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html).\nPlease download the annotation files from [onehand10k_annotations](https://download.openmmlab.com/mmpose/datasets/onehand10k_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── onehand10k\n        |── annotations\n        |   |── onehand10k_train.json\n        |   |── onehand10k_test.json\n        `── Train\n        |   |── source\n        |       |── 0.jpg\n        |       |── 1.jpg\n        |        ...\n        `── Test\n            |── source\n                |── 0.jpg\n                |── 1.jpg\n\n```\n\n## FreiHAND Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Zimmermann_FreiHAND_A_Dataset_for_Markerless_Capture_of_Hand_Pose_and_ICCV_2019_paper.html\">FreiHand (ICCV'2019)</a></summary>\n\n```bibtex\n@inproceedings{zimmermann2019freihand,\n  title={Freihand: A dataset for markerless capture of hand pose and shape from single rgb images},\n  author={Zimmermann, Christian and Ceylan, Duygu and Yang, Jimei and Russell, Bryan and Argus, Max and Brox, Thomas},\n  booktitle={Proceedings of the IEEE International Conference on Computer Vision},\n  pages={813--822},\n  year={2019}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [FreiHAND](https://lmb.informatik.uni-freiburg.de/projects/freihand/) data, please download from [FreiHand Dataset](https://lmb.informatik.uni-freiburg.de/resources/datasets/FreihandDataset.en.html).\nSince the official dataset does not provide validation set, we randomly split the training data into 8:1:1 for train/val/test.\nPlease download the annotation files from [freihand_annotations](https://download.openmmlab.com/mmpose/datasets/frei_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── freihand\n        |── annotations\n        |   |── freihand_train.json\n        |   |── freihand_val.json\n        |   |── freihand_test.json\n        `── training\n            |── rgb\n            |   |── 00000000.jpg\n            |   |── 00000001.jpg\n            |    ...\n            |── mask\n                |── 00000000.jpg\n                |── 00000001.jpg\n                 ...\n```\n\n## CMU Panoptic HandDB\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2017/html/Simon_Hand_Keypoint_Detection_CVPR_2017_paper.html\">CMU Panoptic HandDB (CVPR'2017)</a></summary>\n\n```bibtex\n@inproceedings{simon2017hand,\n  title={Hand keypoint detection in single images using multiview bootstrapping},\n  author={Simon, Tomas and Joo, Hanbyul and Matthews, Iain and Sheikh, Yaser},\n  booktitle={Proceedings of the IEEE conference on Computer Vision and Pattern Recognition},\n  pages={1145--1153},\n  year={2017}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html), please download from [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html).\nFollowing [Simon et al](https://arxiv.org/abs/1704.07809), panoptic images (hand143_panopticdb) and MPII & NZSL training sets (manual_train) are used for training, while MPII & NZSL test set (manual_test) for testing.\nPlease download the annotation files from [panoptic_annotations](https://download.openmmlab.com/mmpose/datasets/panoptic_annotations.tar).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── panoptic\n        |── annotations\n        |   |── panoptic_train.json\n        |   |── panoptic_test.json\n        |\n        `── hand143_panopticdb\n        |   |── imgs\n        |   |   |── 00000000.jpg\n        |   |   |── 00000001.jpg\n        |   |    ...\n        |\n        `── hand_labels\n            |── manual_train\n            |   |── 000015774_01_l.jpg\n            |   |── 000015774_01_r.jpg\n            |    ...\n            |\n            `── manual_test\n                |── 000648952_02_l.jpg\n                |── 000835470_01_l.jpg\n                 ...\n```\n\n## InterHand2.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterHand2.6M (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771753-5df1d722-59bd-4815-b85f-64a5ef79bbf5.png\" height=\"200px\">\n</div>\n\nFor [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/), please download from [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/).\nPlease download the annotation files from [annotations](https://download.openmmlab.com/mmpose/datasets/interhand2.6m_annotations.zip).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── interhand2.6m\n        |── annotations\n        |   |── all\n        |   |── human_annot\n        |   |── machine_annot\n        |   |── skeleton.txt\n        |   |── subject.txt\n        |\n        `── images\n        |   |── train\n        |   |   |-- Capture0 ~ Capture26\n        |   |── val\n        |   |   |-- Capture0\n        |   |── test\n        |   |   |-- Capture0 ~ Capture7\n```\n\n## RHD Dataset\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\">RHD (ICCV'2017)</a></summary>\n\n```bibtex\n@TechReport{zb2017hand,\n  author={Christian Zimmermann and Thomas Brox},\n  title={Learning to Estimate 3D Hand Pose from Single RGB Images},\n  institution={arXiv:1705.01389},\n  year={2017},\n  note=\"https://arxiv.org/abs/1705.01389\",\n  url=\"https://lmb.informatik.uni-freiburg.de/projects/hand3d/\"\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227772014-f7406a2b-2e64-42fb-8081-200d40104553.png\" height=\"200px\">\n</div>\n\nFor [RHD Dataset](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html), please download from [RHD Dataset](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html).\nPlease download the annotation files from [rhd_annotations](https://download.openmmlab.com/mmpose/datasets/rhd_annotations.zip).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── rhd\n        |── annotations\n        |   |── rhd_train.json\n        |   |── rhd_test.json\n        `── training\n        |   |── color\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── depth\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── mask\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        `── evaluation\n        |   |── color\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── depth\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n        |   |── mask\n        |   |   |── 00000.jpg\n        |   |   |── 00001.jpg\n```\n\n## COCO-WholeBody (Hand)\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody-Hand (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"200px\">\n</div>\n\nFor [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/) dataset, images can be downloaded from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\nDownload COCO-WholeBody annotations for COCO-WholeBody annotations for [Train](https://drive.google.com/file/d/1thErEToRbmM9uLNi1JXXfOsaS5VK2FXf/view?usp=sharing) / [Validation](https://drive.google.com/file/d/1N6VgwKnj8DeyGXCvp1eYgNbRmw6jdfrb/view?usp=sharing) (Google Drive).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- coco_wholebody_train_v1.0.json\n        │   |-- coco_wholebody_val_v1.0.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/2d_wholebody_keypoint.md",
    "content": "# 2D Wholebody Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [COCO-WholeBody](#coco-wholebody) \\[ [Homepage](https://github.com/jin-s13/COCO-WholeBody/) \\]\n- [Halpe](#halpe) \\[ [Homepage](https://github.com/Fang-Haoshu/Halpe-FullBody/) \\]\n\n## COCO-WholeBody\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-030-58545-7_12\">COCO-WholeBody (ECCV'2020)</a></summary>\n\n```bibtex\n@inproceedings{jin2020whole,\n  title={Whole-Body Human Pose Estimation in the Wild},\n  author={Jin, Sheng and Xu, Lumin and Xu, Jin and Wang, Can and Liu, Wentao and Qian, Chen and Ouyang, Wanli and Luo, Ping},\n  booktitle={Proceedings of the European Conference on Computer Vision (ECCV)},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227770977-c8f00355-c43a-467e-8444-d307789cf4b2.png\" height=\"300px\">\n</div>\n\nFor [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/) dataset, images can be downloaded from [COCO download](http://cocodataset.org/#download), 2017 Train/Val is needed for COCO keypoints training and validation.\nDownload COCO-WholeBody annotations for COCO-WholeBody annotations for [Train](https://drive.google.com/file/d/1thErEToRbmM9uLNi1JXXfOsaS5VK2FXf/view?usp=sharing) / [Validation](https://drive.google.com/file/d/1N6VgwKnj8DeyGXCvp1eYgNbRmw6jdfrb/view?usp=sharing) (Google Drive).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- annotations\n        │   │-- coco_wholebody_train_v1.0.json\n        │   |-- coco_wholebody_val_v1.0.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- train2017\n        │   │-- 000000000009.jpg\n        │   │-- 000000000025.jpg\n        │   │-- 000000000030.jpg\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) (version>=1.5) to support COCO-WholeBody evaluation:\n\n`pip install xtcocotools`\n\n## Halpe\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://arxiv.org/abs/2004.00945\">Halpe (CVPR'2020)</a></summary>\n\n```bibtex\n@inproceedings{li2020pastanet,\n  title={PaStaNet: Toward Human Activity Knowledge Engine},\n  author={Li, Yong-Lu and Xu, Liang and Liu, Xinpeng and Huang, Xijie and Xu, Yue and Wang, Shiyi and Fang, Hao-Shu and Ma, Ze and Chen, Mingyang and Lu, Cewu},\n  booktitle={CVPR},\n  year={2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227771087-b839ea5b-4461-4ba7-8a9a-823b78e2ca44.png\" height=\"300px\">\n</div>\n\nFor [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/) dataset, please download images and annotations from [Halpe download](https://github.com/Fang-Haoshu/Halpe-FullBody).\nThe images of the training set are from [HICO-Det](https://drive.google.com/open?id=1QZcJmGVlF9f4h-XLWe9Gkmnmj2z1gSnk) and those of the validation set are from [COCO](http://images.cocodataset.org/zips/val2017.zip).\nDownload person detection result of COCO val2017 from [OneDrive](https://1drv.ms/f/s!AhIXJn_J-blWzzDXoz5BeFl8sWM-) or [GoogleDrive](https://drive.google.com/drive/folders/1fRUDNUDxe9fjqcRZ2bnF_TKMlO0nB_dk?usp=sharing).\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── halpe\n        │-- annotations\n        │   │-- halpe_train_v1.json\n        │   |-- halpe_val_v1.json\n        |-- person_detection_results\n        |   |-- COCO_val2017_detections_AP_H_56_person.json\n        │-- hico_20160224_det\n        │   │-- anno_bbox.mat\n        │   │-- anno.mat\n        │   │-- README\n        │   │-- images\n        │   │   │-- train2015\n        │   │   │   │-- HICO_train2015_00000001.jpg\n        │   │   │   │-- HICO_train2015_00000002.jpg\n        │   │   │   │-- HICO_train2015_00000003.jpg\n        │   │   │   │-- ...\n        │   │   │-- test2015\n        │   │-- tools\n        │   │-- ...\n        `-- val2017\n            │-- 000000000139.jpg\n            │-- 000000000285.jpg\n            │-- 000000000632.jpg\n            │-- ...\n\n```\n\nPlease also install the latest version of [Extended COCO API](https://github.com/jin-s13/xtcocoapi) (version>=1.5) to support Halpe evaluation:\n\n`pip install xtcocotools`\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/3d_body_keypoint.md",
    "content": "# 3D Body Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [Human3.6M](#human36m) \\[ [Homepage](http://vision.imar.ro/human3.6m/description.php) \\]\n- [CMU Panoptic](#cmu-panoptic) \\[ [Homepage](http://domedb.perception.cs.cmu.edu/) \\]\n- [Campus/Shelf](#campus-and-shelf) \\[ [Homepage](http://campar.in.tum.de/Chair/MultiHumanPose) \\]\n\n## Human3.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227866174-0355e7dd-6965-4d1a-8bb6-32e8dce4cefc.png\" height=\"300px\">\n</div>\n\nFor [Human3.6M](http://vision.imar.ro/human3.6m/description.php), please download from the official website and run the [preprocessing script](/tools/dataset_converters/preprocess_h36m.py), which will extract camera parameters and pose annotations at full framerate (50 FPS) and downsampled framerate (10 FPS). The processed data should have the following structure:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── h36m\n        ├── annotation_body3d\n        |   ├── cameras.pkl\n        |   ├── fps50\n        |   |   ├── h36m_test.npz\n        |   |   ├── h36m_train.npz\n        |   |   ├── joint2d_rel_stats.pkl\n        |   |   ├── joint2d_stats.pkl\n        |   |   ├── joint3d_rel_stats.pkl\n        |   |   `── joint3d_stats.pkl\n        |   `── fps10\n        |       ├── h36m_test.npz\n        |       ├── h36m_train.npz\n        |       ├── joint2d_rel_stats.pkl\n        |       ├── joint2d_stats.pkl\n        |       ├── joint3d_rel_stats.pkl\n        |       `── joint3d_stats.pkl\n        `── images\n            ├── S1\n            |   ├── S1_Directions_1.54138969\n            |   |   ├── S1_Directions_1.54138969_00001.jpg\n            |   |   ├── S1_Directions_1.54138969_00002.jpg\n            |   |   ├── ...\n            |   ├── ...\n            ├── S5\n            ├── S6\n            ├── S7\n            ├── S8\n            ├── S9\n            `── S11\n```\n\n## CMU Panoptic\n\n<details>\n<summary align=\"right\"><a href=\"https://openaccess.thecvf.com/content_iccv_2015/html/Joo_Panoptic_Studio_A_ICCV_2015_paper.html\">CMU Panoptic (ICCV'2015)</a></summary>\n\n```bibtex\n@Article = {joo_iccv_2015,\nauthor = {Hanbyul Joo, Hao Liu, Lei Tan, Lin Gui, Bart Nabbe, Iain Matthews, Takeo Kanade, Shohei Nobuhara, and Yaser Sheikh},\ntitle = {Panoptic Studio: A Massively Multiview System for Social Motion Capture},\nbooktitle = {ICCV},\nyear = {2015}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227866246-1af9441b-4f6c-4340-ae98-e40d6b4e8e55.png\" height=\"300px\">\n</div>\n\nPlease follow [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch) to prepare this dataset.\n\n1. Download the dataset by following the instructions in [panoptic-toolbox](https://github.com/CMU-Perceptual-Computing-Lab/panoptic-toolbox) and extract them under `$MMPOSE/data/panoptic`.\n\n2. Only download those sequences that are needed. You can also just download a subset of camera views by specifying the number of views (HD_Video_Number) and changing the camera order in `./scripts/getData.sh`. The used sequences and camera views can be found in [VoxelPose](https://arxiv.org/abs/2004.06239). Note that the sequence \"160906_band3\" might not be available due to errors on the server of CMU Panoptic.\n\n3. Note that we only use HD videos,  calibration data, and 3D Body Keypoint in the codes. You can comment out other irrelevant codes such as downloading 3D Face data in `./scripts/getData.sh`.\n\nThe directory tree should be like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── panoptic\n        ├── 16060224_haggling1\n        |   |   ├── hdImgs\n        |   |   ├── hdvideos\n        |   |   ├── hdPose3d_stage1_coco19\n        |   |   ├── calibration_160224_haggling1.json\n        ├── 160226_haggling1\n            ├── ...\n```\n\n## Campus and Shelf\n\n<details>\n<summary align=\"right\"><a href=\"http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf\">Campus and Shelf (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings {belagian14multi,\n    title = {{3D} Pictorial Structures for Multiple Human Pose Estimation},\n    author = {Belagiannis, Vasileios and Amin, Sikandar and Andriluka, Mykhaylo and Schiele, Bernt and Navab\n    Nassir and Ilic, Slobo\n    booktitle = {IEEE Computer Society Conference on Computer Vision and Pattern Recognition (CVPR)},\n    year = {2014},\n    month = {June},\n    organization={IEEE}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227866373-ed8e6d1a-581b-4b88-93f5-2bc2caddbf6c.png\" height=\"300px\">\n</div>\n\nPlease follow [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch) to prepare these two datasets.\n\n1. Please download the datasets from the [official website](http://campar.in.tum.de/Chair/MultiHumanPose) and extract them under `$MMPOSE/data/campus` and `$MMPOSE/data/shelf`, respectively. The original data include images as well as the ground truth pose file `actorsGT.mat`.\n\n2. We directly use the processed camera parameters from [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch). You can download them from this repository and place in under `$MMPOSE/data/campus/calibration_campus.json` and `$MMPOSE/data/shelf/calibration_shelf.json`, respectively.\n\n3. Like [Voxelpose](https://github.com/microsoft/voxelpose-pytorch), due to the limited and incomplete annotations of the two datasets, we don't train the model using this dataset. Instead, we directly use the 2D pose estimator trained on COCO, and use independent 3D human poses from the CMU Panoptic dataset to train our 3D model. It lies in `${MMPOSE}/data/panoptic_training_pose.pkl`.\n\n4. Like [Voxelpose](https://github.com/microsoft/voxelpose-pytorch), for testing, we first estimate 2D poses and generate 2D heatmaps for these two datasets. You can download the predicted poses from [voxelpose-pytorch](https://github.com/microsoft/voxelpose-pytorch) and place them in  `$MMPOSE/data/campus/pred_campus_maskrcnn_hrnet_coco.pkl` and `$MMPOSE/data/shelf/pred_shelf_maskrcnn_hrnet_coco.pkl`, respectively. You can also use the models trained on COCO dataset (like HigherHRNet) to generate 2D heatmaps directly.\n\nThe directory tree should be like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── panoptic_training_pose.pkl\n    ├── campus\n    |   ├── Camera0\n    |   |   |   ├── campus4-c0-00000.png\n    |   |   |   ├── ...\n    |   |   |   ├── campus4-c0-01999.png\n    |   ...\n    |   ├── Camera2\n    |   |   |   ├── campus4-c2-00000.png\n    |   |   |   ├── ...\n    |   |   |   ├── campus4-c2-01999.png\n    |   ├── calibration_campus.json\n    |   ├── pred_campus_maskrcnn_hrnet_coco.pkl\n    |   ├── actorsGT.mat\n    ├── shelf\n    |   ├── Camera0\n    |   |   |   ├── img_000000.png\n    |   |   |   ├── ...\n    |   |   |   ├── img_003199.png\n    |   ...\n    |   ├── Camera4\n    |   |   |   ├── img_000000.png\n    |   |   |   ├── ...\n    |   |   |   ├── img_003199.png\n    |   ├── calibration_shelf.json\n    |   ├── pred_shelf_maskrcnn_hrnet_coco.pkl\n    |   ├── actorsGT.mat\n```\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/3d_body_mesh.md",
    "content": "# 3D Body Mesh Recovery Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nTo achieve high-quality human mesh estimation, we use multiple datasets for training.\nThe following items should be prepared for human mesh training:\n\n<!-- TOC -->\n\n- [3D Body Mesh Recovery Datasets](#3d-body-mesh-recovery-datasets)\n  - [Notes](#notes)\n    - [Annotation Files for Human Mesh Estimation](#annotation-files-for-human-mesh-estimation)\n    - [SMPL Model](#smpl-model)\n  - [COCO](#coco)\n  - [Human3.6M](#human36m)\n  - [MPI-INF-3DHP](#mpi-inf-3dhp)\n  - [LSP](#lsp)\n  - [LSPET](#lspet)\n  - [CMU MoShed Data](#cmu-moshed-data)\n\n<!-- TOC -->\n\n## Notes\n\n### Annotation Files for Human Mesh Estimation\n\nFor human mesh estimation, we use multiple datasets for training.\nThe annotation of different datasets are preprocessed to the same format. Please\nfollow the [preprocess procedure](https://github.com/nkolot/SPIN/tree/master/datasets/preprocess)\nof SPIN to generate the annotation files or download the processed files from\n[here](https://download.openmmlab.com/mmpose/datasets/mesh_annotation_files.zip),\nand make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mesh_annotation_files\n        ├── coco_2014_train.npz\n        ├── h36m_valid_protocol1.npz\n        ├── h36m_valid_protocol2.npz\n        ├── hr-lspet_train.npz\n        ├── lsp_dataset_original_train.npz\n        ├── mpi_inf_3dhp_train.npz\n        └── mpii_train.npz\n```\n\n### SMPL Model\n\n```bibtex\n@article{loper2015smpl,\n  title={SMPL: A skinned multi-person linear model},\n  author={Loper, Matthew and Mahmood, Naureen and Romero, Javier and Pons-Moll, Gerard and Black, Michael J},\n  journal={ACM transactions on graphics (TOG)},\n  volume={34},\n  number={6},\n  pages={1--16},\n  year={2015},\n  publisher={ACM New York, NY, USA}\n}\n```\n\nFor human mesh estimation, SMPL model is used to generate the human mesh.\nPlease download the [gender neutral SMPL model](http://smplify.is.tue.mpg.de/),\n[joints regressor](https://download.openmmlab.com/mmpose/datasets/joints_regressor_cmr.npy)\nand [mean parameters](https://download.openmmlab.com/mmpose/datasets/smpl_mean_params.npz)\nunder `$MMPOSE/models/smpl`, and make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── ...\n├── models\n    │── smpl\n        ├── joints_regressor_cmr.npy\n        ├── smpl_mean_params.npz\n        └── SMPL_NEUTRAL.pkl\n```\n\n## COCO\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/chapter/10.1007/978-3-319-10602-1_48\">COCO (ECCV'2014)</a></summary>\n\n```bibtex\n@inproceedings{lin2014microsoft,\n  title={Microsoft coco: Common objects in context},\n  author={Lin, Tsung-Yi and Maire, Michael and Belongie, Serge and Hays, James and Perona, Pietro and Ramanan, Deva and Doll{\\'a}r, Piotr and Zitnick, C Lawrence},\n  booktitle={European conference on computer vision},\n  pages={740--755},\n  year={2014},\n  organization={Springer}\n}\n```\n\n</details>\n\nFor [COCO](http://cocodataset.org/) data, please download from [COCO download](http://cocodataset.org/#download). COCO'2014 Train is needed for human mesh estimation training.\nDownload and extract them under $MMPOSE/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── coco\n        │-- train2014\n        │   ├── COCO_train2014_000000000009.jpg\n        │   ├── COCO_train2014_000000000025.jpg\n        │   ├── COCO_train2014_000000000030.jpg\n        |   │-- ...\n\n```\n\n## Human3.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\nFor [Human3.6M](http://vision.imar.ro/human3.6m/description.php), we use the MoShed data provided in [HMR](https://github.com/akanazawa/hmr) for training.\nHowever, due to license limitations, we are not allowed to redistribute the MoShed data.\n\nFor the evaluation on Human3.6M dataset, please follow the\n[preprocess procedure](https://github.com/nkolot/SPIN/tree/master/datasets/preprocess)\nof SPIN to extract test images from\n[Human3.6M](http://vision.imar.ro/human3.6m/description.php) original videos,\nand make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── Human3.6M\n        ├── images\n            ├── S11_Directions_1.54138969_000001.jpg\n            ├── S11_Directions_1.54138969_000006.jpg\n            ├── S11_Directions_1.54138969_000011.jpg\n            ├── ...\n```\n\nThe download of Human3.6M dataset is quite difficult, you can also download the\n[zip file](https://drive.google.com/file/d/1WnRJD9FS3NUf7MllwgLRJJC-JgYFr8oi/view?usp=sharing)\nof the test images. However, due to the license limitations, we are not allowed to\nredistribute the images either. So the users need to download the original video and\nextract the images by themselves.\n\n## MPI-INF-3DHP\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{mono-3dhp2017,\n author = {Mehta, Dushyant and Rhodin, Helge and Casas, Dan and Fua, Pascal and Sotnychenko, Oleksandr and Xu, Weipeng and Theobalt, Christian},\n title = {Monocular 3D Human Pose Estimation In The Wild Using Improved CNN Supervision},\n booktitle = {3D Vision (3DV), 2017 Fifth International Conference on},\n url = {http://gvv.mpi-inf.mpg.de/3dhp_dataset},\n year = {2017},\n organization={IEEE},\n doi={10.1109/3dv.2017.00064},\n}\n```\n\nFor [MPI-INF-3DHP](http://gvv.mpi-inf.mpg.de/3dhp-dataset/), please follow the\n[preprocess procedure](https://github.com/nkolot/SPIN/tree/master/datasets/preprocess)\nof SPIN to sample images, and make them like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── mpi_inf_3dhp_test_set\n    │   ├── TS1\n    │   ├── TS2\n    │   ├── TS3\n    │   ├── TS4\n    │   ├── TS5\n    │   └── TS6\n    ├── S1\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S2\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S3\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S4\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S5\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S6\n    │   ├── Seq1\n    │   └── Seq2\n    ├── S7\n    │   ├── Seq1\n    │   └── Seq2\n    └── S8\n        ├── Seq1\n        └── Seq2\n```\n\n## LSP\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{johnson2010clustered,\n  title={Clustered Pose and Nonlinear Appearance Models for Human Pose Estimation.},\n  author={Johnson, Sam and Everingham, Mark},\n  booktitle={bmvc},\n  volume={2},\n  number={4},\n  pages={5},\n  year={2010},\n  organization={Citeseer}\n}\n```\n\nFor [LSP](https://sam.johnson.io/research/lsp.html), please download the high resolution version\n[LSP dataset original](http://sam.johnson.io/research/lsp_dataset_original.zip).\nExtract them under `$MMPOSE/data`, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── lsp_dataset_original\n        ├── images\n            ├── im0001.jpg\n            ├── im0002.jpg\n            └── ...\n```\n\n## LSPET\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{johnson2011learning,\n  title={Learning effective human pose estimation from inaccurate annotation},\n  author={Johnson, Sam and Everingham, Mark},\n  booktitle={CVPR 2011},\n  pages={1465--1472},\n  year={2011},\n  organization={IEEE}\n}\n```\n\nFor [LSPET](https://sam.johnson.io/research/lspet.html), please download its high resolution form\n[HR-LSPET](http://datasets.d2.mpi-inf.mpg.de/hr-lspet/hr-lspet.zip).\nExtract them under `$MMPOSE/data`, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── lspet_dataset\n        ├── images\n        │   ├── im00001.jpg\n        │   ├── im00002.jpg\n        │   ├── im00003.jpg\n        │   └── ...\n        └── joints.mat\n```\n\n## CMU MoShed Data\n\n<!-- [DATASET] -->\n\n```bibtex\n@inproceedings{kanazawa2018end,\n  title={End-to-end recovery of human shape and pose},\n  author={Kanazawa, Angjoo and Black, Michael J and Jacobs, David W and Malik, Jitendra},\n  booktitle={Proceedings of the IEEE Conference on Computer Vision and Pattern Recognition},\n  pages={7122--7131},\n  year={2018}\n}\n```\n\nReal-world SMPL parameters are used for the adversarial training in human mesh estimation.\nThe MoShed data provided in [HMR](https://github.com/akanazawa/hmr) is included in this\n[zip file](https://download.openmmlab.com/mmpose/datasets/mesh_annotation_files.zip).\nPlease download and extract it under `$MMPOSE/data`, and make it look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── mesh_annotation_files\n        ├── CMU_mosh.npz\n        └── ...\n```\n"
  },
  {
    "path": "docs/zh_cn/dataset_zoo/3d_hand_keypoint.md",
    "content": "# 3D Hand Keypoint Datasets\n\nIt is recommended to symlink the dataset root to `$MMPOSE/data`.\nIf your folder structure is different, you may need to change the corresponding paths in config files.\n\nMMPose supported datasets:\n\n- [InterHand2.6M](#interhand26m) \\[ [Homepage](https://mks0601.github.io/InterHand2.6M/) \\]\n\n## InterHand2.6M\n\n<!-- [DATASET] -->\n\n<details>\n<summary align=\"right\"><a href=\"https://link.springer.com/content/pdf/10.1007/978-3-030-58565-5_33.pdf\">InterHand2.6M (ECCV'2020)</a></summary>\n\n```bibtex\n@InProceedings{Moon_2020_ECCV_InterHand2.6M,\nauthor = {Moon, Gyeongsik and Yu, Shoou-I and Wen, He and Shiratori, Takaaki and Lee, Kyoung Mu},\ntitle = {InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image},\nbooktitle = {European Conference on Computer Vision (ECCV)},\nyear = {2020}\n}\n```\n\n</details>\n\n<div align=\"center\">\n  <img src=\"https://user-images.githubusercontent.com/100993824/227867693-e36c2cbd-4089-4734-a310-37cb5db6cafa.png\" height=\"200px\">\n</div>\n\nFor [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/), please download from [InterHand2.6M](https://mks0601.github.io/InterHand2.6M/).\nPlease download the annotation files from [annotations](https://drive.google.com/drive/folders/1pWXhdfaka-J0fSAze0MsajN0VpZ8e8tO).\nExtract them under {MMPose}/data, and make them look like this:\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── interhand2.6m\n        |── annotations\n        |   |── all\n        |   |── human_annot\n        |   |── machine_annot\n        |   |── skeleton.txt\n        |   |── subject.txt\n        |\n        `── images\n        |   |── train\n        |   |   |-- Capture0 ~ Capture26\n        |   |── val\n        |   |   |-- Capture0\n        |   |── test\n        |   |   |-- Capture0 ~ Capture7\n```\n"
  },
  {
    "path": "docs/zh_cn/faq.md",
    "content": "# FAQ\n\nWe list some common issues faced by many users and their corresponding solutions here.\nFeel free to enrich the list if you find any frequent issues and have ways to help others to solve them.\nIf the contents here do not cover your issue, please create an issue using the [provided templates](/.github/ISSUE_TEMPLATE/error-report.md) and make sure you fill in all required information in the template.\n\n## Installation\n\nCompatibility issue between MMCV and MMPose; \"AssertionError: MMCV==xxx is used but incompatible. Please install mmcv>=xxx, \\<=xxx.\"\n\nHere are the version correspondences between `mmdet`, `mmcv` and `mmpose`:\n\n- mmdet 2.x \\<=> mmpose 0.x \\<=> mmcv 1.x\n- mmdet 3.x \\<=> mmpose 1.x \\<=> mmcv 2.x\n\nDetailed compatible MMPose and MMCV versions are shown as below. Please choose the correct version of MMCV to avoid installation issues.\n\n### MMPose 1.x\n\n| MMPose version |      MMCV/MMEngine version      |\n| :------------: | :-----------------------------: |\n|     1.3.2      |  mmcv>=2.0.1, mmengine>=0.9.0   |\n|     1.3.1      |  mmcv>=2.0.1, mmengine>=0.9.0   |\n|     1.3.0      |  mmcv>=2.0.1, mmengine>=0.9.0   |\n|     1.2.0      |  mmcv>=2.0.1, mmengine>=0.8.0   |\n|     1.1.0      |  mmcv>=2.0.1, mmengine>=0.8.0   |\n|     1.0.0      |  mmcv>=2.0.0, mmengine>=0.7.0   |\n|    1.0.0rc1    | mmcv>=2.0.0rc4, mmengine>=0.6.0 |\n|    1.0.0rc0    | mmcv>=2.0.0rc0, mmengine>=0.0.1 |\n|    1.0.0b0     | mmcv>=2.0.0rc0, mmengine>=0.0.1 |\n\n### MMPose 0.x\n\n| MMPose version |       MMCV version        |\n| :------------: | :-----------------------: |\n|      0.x       | mmcv-full>=1.3.8, \\<1.8.0 |\n|     0.29.0     | mmcv-full>=1.3.8, \\<1.7.0 |\n|     0.28.1     | mmcv-full>=1.3.8, \\<1.7.0 |\n|     0.28.0     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.27.0     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.26.0     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.25.1     | mmcv-full>=1.3.8, \\<1.6.0 |\n|     0.25.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.24.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.23.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.22.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.21.0     | mmcv-full>=1.3.8, \\<1.5.0 |\n|     0.20.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.19.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.18.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.17.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.16.0     | mmcv-full>=1.3.8, \\<1.4.0 |\n|     0.14.0     | mmcv-full>=1.1.3, \\<1.4.0 |\n|     0.13.0     | mmcv-full>=1.1.3, \\<1.4.0 |\n|     0.12.0     |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.11.0     |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.10.0     |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.9.0      |  mmcv-full>=1.1.3, \\<1.3  |\n|     0.8.0      |  mmcv-full>=1.1.1, \\<1.2  |\n|     0.7.0      |  mmcv-full>=1.1.1, \\<1.2  |\n\n- **Unable to install xtcocotools**\n\n  1. Try to install it using pypi manually `pip install xtcocotools`.\n  2. If step1 does not work. Try to install it from [source](https://github.com/jin-s13/xtcocoapi).\n\n  ```\n  git clone https://github.com/jin-s13/xtcocoapi\n  cd xtcocoapi\n  python setup.py install\n  ```\n\n- **No matching distribution found for xtcocotools>=1.6**\n\n  1. Install cython by `pip install cython`.\n  2. Install xtcocotools from [source](https://github.com/jin-s13/xtcocoapi).\n\n  ```\n  git clone https://github.com/jin-s13/xtcocoapi\n  cd xtcocoapi\n  python setup.py install\n  ```\n\n- **\"No module named 'mmcv.ops'\"; \"No module named 'mmcv.\\_ext'\"**\n\n  1. Uninstall existing mmcv in the environment using `pip uninstall mmcv`.\n  2. Install mmcv-full following the [installation instruction](https://mmcv.readthedocs.io/en/latest/#installation).\n\n## Data\n\n- **What if my custom dataset does not have bounding box label?**\n\n  We can estimate the bounding box of a person as the minimal box that tightly bounds all the keypoints.\n\n- **What is `COCO_val2017_detections_AP_H_56_person.json`? Can I train pose models without it?**\n\n  \"COCO_val2017_detections_AP_H_56_person.json\" contains the \"detected\" human bounding boxes for COCO validation set, which are generated by FasterRCNN.\n  One can choose to use gt bounding boxes to evaluate models, by setting `bbox_file=None''` in `val_dataloader.dataset` in config. Or one can use detected boxes to evaluate\n  the generalizability of models, by setting `bbox_file='COCO_val2017_detections_AP_H_56_person.json'`.\n\n## Training\n\n- **RuntimeError: Address already in use**\n\n  Set the environment variables `MASTER_PORT=XXX`. For example,\n  `MASTER_PORT=29517 GPUS=16 GPUS_PER_NODE=8 CPUS_PER_TASK=2 ./tools/slurm_train.sh Test res50 configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_8xb64-210e_coco-256x192.py work_dirs/res50_coco_256x192`\n\n- **\"Unexpected keys in source state dict\" when loading pre-trained weights**\n\n  It's normal that some layers in the pretrained model are not used in the pose model. ImageNet-pretrained classification network and the pose network may have different architectures (e.g. no classification head). So some unexpected keys in source state dict is actually expected.\n\n- **How to use trained models for backbone pre-training ?**\n\n  Refer to [Migration - Step3: Model - Backbone](../migration.md).\n\n  When training, the unexpected keys will be ignored.\n\n- **How to visualize the training accuracy/loss curves in real-time ?**\n\n  Use `TensorboardLoggerHook` in `log_config` like\n\n  ```python\n  log_config=dict(interval=20, hooks=[dict(type='TensorboardLoggerHook')])\n  ```\n\n  You can refer to [user_guides/visualization.md](../user_guides/visualization.md).\n\n- **Log info is NOT printed**\n\n  Use smaller log interval. For example, change `interval=50` to `interval=1` in the config.\n\n## Evaluation\n\n- **How to evaluate on MPII test dataset?**\n  Since we do not have the ground-truth for test dataset, we cannot evaluate it 'locally'.\n  If you would like to evaluate the performance on test set, you have to upload the pred.mat (which is generated during testing) to the official server via email, according to [the MPII guideline](http://human-pose.mpi-inf.mpg.de/#evaluation).\n\n- **For top-down 2d pose estimation, why predicted joint coordinates can be out of the bounding box (bbox)?**\n  We do not directly use the bbox to crop the image. bbox will be first transformed to center & scale, and the scale will be multiplied by a factor (1.25) to include some context. If the ratio of width/height is different from that of model input (possibly 192/256), we will adjust the bbox.\n\n## Inference\n\n- **How to run mmpose on CPU?**\n\n  Run demos with `--device=cpu`.\n\n- **How to speed up inference?**\n\n  For top-down models, try to edit the config file. For example,\n\n  1. set `flip_test=False` in `init_cfg` in the config file.\n  2. use faster human bounding box detector, see [MMDetection](https://mmdetection.readthedocs.io/zh_CN/3.x/model_zoo.html).\n\n- **What is the definition of each keypoint index?**\n\n  Check the [meta information file](https://github.com/open-mmlab/mmpose/tree/main/configs/_base_/datasets) for the dataset used to train the model you are using. They key `keypoint_info` includes the definition of each keypoint.\n"
  },
  {
    "path": "docs/zh_cn/guide_to_framework.md",
    "content": "# 20 分钟上手 MMPose\n\nMMPose 1.0 与之前的版本有较大改动，对部分模块进行了重新设计和组织，降低代码冗余度，提升运行效率，降低学习难度。\n\nMMPose 1.0 采用了全新的模块结构设计以精简代码，提升运行效率，降低学习难度。对于有一定深度学习基础的用户，本章节提供了对 MMPose 架构设计的总体介绍。不论你是**旧版 MMPose 的用户**，还是**希望直接从 MMPose 1.0 上手的新用户**，都可以通过本教程了解如何构建一个基于 MMPose 1.0 的项目。\n\n```{note}\n本教程包含了使用 MMPose 1.0 时开发者会关心的内容：\n\n- 整体代码架构与设计逻辑\n\n- 如何用config文件管理模块\n\n- 如何使用自定义数据集\n\n- 如何添加新的模块（骨干网络、模型头部、损失函数等）\n```\n\n以下是这篇教程的目录：\n\n- [20 分钟上手 MMPose](#20-分钟上手-mmpose)\n  - [文件结构](#文件结构)\n  - [总览](#总览)\n  - [Step1：配置文件](#step1配置文件)\n  - [Step2：数据](#step2数据)\n    - [数据集元信息](#数据集元信息)\n    - [数据集](#数据集)\n    - [数据流水线](#数据流水线)\n      - [i. 数据增强](#i-数据增强)\n      - [ii. 数据变换](#ii-数据变换)\n      - [iii. 数据编码](#iii-数据编码)\n      - [iv. 数据打包](#iv-数据打包)\n  - [Step3: 模型](#step3-模型)\n    - [前处理器（DataPreprocessor）](#前处理器datapreprocessor)\n    - [主干网络（Backbone）](#主干网络backbone)\n    - [颈部模块（Neck）](#颈部模块neck)\n    - [预测头（Head）](#预测头head)\n\n## 文件结构\n\nMMPose 1.0 的文件结构如下所示：\n\n```shell\nmmpose\n|----apis\n|----structures\n|----datasets\n     |----transforms\n|----codecs\n|----models\n     |----pose_estimators\n     |----data_preprocessors\n     |----backbones\n     |----necks\n     |----heads\n     |----losses\n|----engine\n     |----hooks\n|----evaluation\n|----visualization\n```\n\n- **apis** 提供用于模型推理的高级 API\n- **structures** 提供 bbox、keypoint 和 PoseDataSample 等数据结构\n- **datasets** 支持用于姿态估计的各种数据集\n  - **transforms** 包含各种数据增强变换\n- **codecs** 提供姿态编解码器：编码器用于将姿态信息（通常为关键点坐标）编码为模型学习目标（如热力图），解码器则用于将模型输出解码为姿态估计结果\n- **models** 以模块化结构提供了姿态估计模型的各类组件\n  - **pose_estimators** 定义了所有姿态估计模型类\n  - **data_preprocessors** 用于预处理模型的输入数据\n  - **backbones** 包含各种骨干网络\n  - **necks** 包含各种模型颈部组件\n  - **heads** 包含各种模型头部\n  - **losses** 包含各种损失函数\n- **engine** 包含与姿态估计任务相关的运行时组件\n  - **hooks** 提供运行时的各种钩子\n- **evaluation** 提供各种评估模型性能的指标\n- **visualization** 用于可视化关键点骨架和热力图等信息\n\n## 总览\n\n![overall-cn](https://user-images.githubusercontent.com/13503330/187830967-f2d7bf40-6261-42f3-91a5-ae045fa0dc0c.png)\n\n一般来说，开发者在项目开发过程中经常接触内容的主要有**五个**方面：\n\n- **通用**：环境、钩子（Hook）、模型权重存取（Checkpoint）、日志（Logger）等\n\n- **数据**：数据集、数据读取（Dataloader）、数据增强等\n\n- **训练**：优化器、学习率调整等\n\n- **模型**：主干网络、颈部模块（Neck）、预测头模块（Head）、损失函数等\n\n- **评测**：评测指标（Metric）、评测器（Evaluator）等\n\n其中**通用**、**训练**和**评测**相关的模块往往由训练框架提供，开发者只需要调用和调整参数，不需要自行实现，开发者主要实现的是**数据**和**模型**部分。\n\n## Step1：配置文件\n\n在MMPose中，我们通常 python 格式的配置文件，用于整个项目的定义、参数管理，因此我们强烈建议第一次接触 MMPose 的开发者，查阅 [【用户教程 - 如何看懂配置文件】](./user_guides/configs.md) 学习配置文件的定义。\n\n需要注意的是，所有新增的模块都需要使用注册器进行注册，并在对应目录的 `__init__.py` 中进行 `import`，以便能够使用配置文件构建其实例。\n\n## Step2：数据\n\nMMPose 数据的组织主要包含三个方面：\n\n- 数据集元信息（meta info）\n\n- 数据集（dataset）\n\n- 数据流水线（pipeline）\n\n### 数据集元信息\n\n元信息指具体标注之外的数据集信息。姿态估计数据集的元信息通常包括：关键点和骨骼连接的定义、对称性、关键点性质（如关键点权重、标注标准差、所属上下半身）等。这些信息在数据在数据处理、模型训练和测试中有重要作用。在 MMPose 中，数据集的元信息使用 python 格式的配置文件保存，位于 [$MMPOSE/configs/\\_base\\_/datasets](https://github.com/open-mmlab/mmpose/tree/main/configs/_base_/datasets) 目录下。\n\n在 MMPose 中使用自定义数据集时，你需要增加对应的元信息配置文件。以 MPII 数据集（[$MMPOSE/configs/\\_base\\_/datasets/mpii.py](https://github.com/open-mmlab/mmpose/blob/main/configs/_base_/datasets/mpii.py)）为例：\n\n```Python\ndataset_info = dict(\n    dataset_name='mpii',\n    paper_info=dict(\n        author='Mykhaylo Andriluka and Leonid Pishchulin and '\n        'Peter Gehler and Schiele, Bernt',\n        title='2D Human Pose Estimation: New Benchmark and '\n        'State of the Art Analysis',\n        container='IEEE Conference on Computer Vision and '\n        'Pattern Recognition (CVPR)',\n        year='2014',\n        homepage='http://human-pose.mpi-inf.mpg.de/',\n    ),\n    keypoint_info={\n        0:\n        dict(\n            name='right_ankle',\n            id=0,\n            color=[255, 128, 0],\n            type='lower',\n            swap='left_ankle'),\n        ## 内容省略\n    },\n    skeleton_info={\n        0:\n        dict(link=('right_ankle', 'right_knee'), id=0, color=[255, 128, 0]),\n        ## 内容省略\n    },\n    joint_weights=[\n        1.5, 1.2, 1., 1., 1.2, 1.5, 1., 1., 1., 1., 1.5, 1.2, 1., 1., 1.2, 1.5\n    ],\n    # 使用 COCO 数据集中提供的 sigmas 值\n    sigmas=[\n        0.089, 0.083, 0.107, 0.107, 0.083, 0.089, 0.026, 0.026, 0.026, 0.026,\n        0.062, 0.072, 0.179, 0.179, 0.072, 0.062\n    ])\n```\n\n在这份元信息配置文件中：\n\n- `keypoint_info`：每个关键点的信息：\n  1. `name`: 关键点名称，必须是唯一的，例如 `nose`、`left_eye` 等。\n  2. `id`: 关键点 ID，必须是唯一的，从 0 开始。\n  3. `color`: 关键点可视化时的颜色，以 (\\[B, G, R\\]) 格式组织起来，用于可视化。\n  4. `type`: 关键点类型，可以是 `upper`、`lower` 或 `''`，用于数据增强 [RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/b225a773d168fc2afd48cde5f76c0202d1ba2f52/mmpose/datasets/transforms/common_transforms.py#L263)。\n  5. `swap`: 关键点交换关系，用于水平翻转数据增强 [RandomFlip](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L94)。\n- `skeleton_info`：骨架连接关系，用于可视化。\n- `joint_weights`：每个关键点的权重，用于损失函数计算。\n- `sigma`：标准差，用于计算 OKS 分数，详细信息请参考 [keypoints-eval](https://cocodataset.org/#keypoints-eval)。\n\n在模型配置文件中，你需要为自定义数据集指定对应的元信息配置文件。假如该元信息配置文件路径为 `$MMPOSE/configs/_base_/datasets/{your_dataset}.py`，指定方式如下：\n\n```python\n# dataset and dataloader settings\ndataset_type = 'MyCustomDataset' # or 'CocoDataset'\ntrain_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # 标注文件路径为 {data_root}/{ann_file}\n        # 例如： aaa/annotations/train.json\n        ann_file='annotations/train.json',\n        # 图片路径为 {data_root}/{img_path}/\n        # 例如： aaa/train/c.jpg\n        data_prefix=dict(img='train'),\n        # 指定对应的元信息配置文件\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\nval_dataloader = dict(\n    batch_size=2,\n    dataset=dict(\n        type=dataset_type,\n        data_root='aaa',\n        # 标注文件路径为 {data_root}/{ann_file}\n        # 例如： aaa/annotations/val.json\n        ann_file='annotations/val.json',\n        # 图片路径为 {data_root}/{img_path}/\n        # 例如： aaa/val/c.jpg\n        data_prefix=dict(img='val'),\n        # 指定对应的元信息配置文件\n        metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n        ...),\n    )\ntest_dataloader = val_dataloader\n```\n\n下面是一个更加具体的例子，假设你的数据集按照以下结构进行组织：\n\n```shell\ndata\n├── annotations\n│   ├── train.json\n│   ├── val.json\n├── train\n│   ├── images\n│   │   ├── 000001.jpg\n├── val\n│   ├── images\n│   │   ├── 000002.jpg\n```\n\n你的数据集路径应该如下所示：\n\n```\ndataset=dict(\n    ...\n    data_root='data/',\n    ann_file='annotations/train.json',\n    data_prefix=dict(img='train/images/'),\n    ...),\n```\n\n### 数据集\n\n在 MMPose 中使用自定义数据集时，我们推荐将数据转化为已支持的格式（如 COCO 或 MPII），并直接使用我们提供的对应数据集实现。如果这种方式不可行，则用户需要实现自己的数据集类。\n\n更多自定义数据集的使用方式，请前往 [【进阶教程 - 自定义数据集】](./advanced_guides/customize_datasets.md)。\n\n````{note}\n如果你需要直接继承 [MMEngine](https://github.com/open-mmlab/mmengine) 中提供的 `BaseDataset` 基类。具体方法请参考相关[文档](https://mmengine.readthedocs.io/en/latest/advanced_tutorials/basedataset.html)\n\n\n#### 2D 数据集\nMMPose 中的大部分 2D 关键点数据集**以 COCO 形式组织**，为此我们提供了基类 [BaseCocoStyleDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_coco_style_dataset.py)。我们推荐用户继承该基类，并按需重写它的方法（通常是 `__init__()` 和 `_load_annotations()` 方法），以扩展到新的 2D 关键点数据集。\n\n```{note}\n关于COCO数据格式的详细说明请参考 [COCO](./dataset_zoo/2d_body_keypoint.md) 。\n````\n\n在 MMPose 中 bbox 的数据格式采用 `xyxy`，而不是 `xywh`，这与 [MMDetection](https://github.com/open-mmlab/mmdetection) 等其他 OpenMMLab 成员保持一致。为了实现不同 bbox 格式之间的转换，我们提供了丰富的函数：`bbox_xyxy2xywh`、`bbox_xywh2xyxy`、`bbox_xyxy2cs`等。这些函数定义在 [$MMPOSE/mmpose/structures/bbox/transforms.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/structures/bbox/transforms.py)。\n\n下面我们以 COCO 格式标注的 CrowdPose 数据集的实现（[$MMPOSE/mmpose/datasets/datasets/body/crowdpose_dataset.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/body/crowdpose_dataset.py)）为例：\n\n```Python\n@DATASETS.register_module()\nclass CrowdPoseDataset(BaseCocoStyleDataset):\n    \"\"\"CrowdPose dataset for pose estimation.\n\n    \"CrowdPose: Efficient Crowded Scenes Pose Estimation and\n    A New Benchmark\", CVPR'2019.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1812.00324>`__.\n\n    CrowdPose keypoints::\n\n        0: 'left_shoulder',\n        1: 'right_shoulder',\n        2: 'left_elbow',\n        3: 'right_elbow',\n        4: 'left_wrist',\n        5: 'right_wrist',\n        6: 'left_hip',\n        7: 'right_hip',\n        8: 'left_knee',\n        9: 'right_knee',\n        10: 'left_ankle',\n        11: 'right_ankle',\n        12: 'top_head',\n        13: 'neck'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/crowdpose.py')\n```\n\n对于使用 COCO 格式标注的数据集，只需要继承 [BaseCocoStyleDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_coco_style_dataset.py) 并指定 `METAINFO`，就可以十分轻松地集成到 MMPose 中参与训练。\n\n````\n\n\n#### 3D 数据集\n我们提供了基类 [BaseMocapStyleDataset](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/datasets/base/base_mocap_dataset.py)。我们推荐用户继承该基类，并按需重写它的方法（通常是 `__init__()` 和 `_load_annotations()` 方法），以扩展到新的 2D 关键点数据集。\n\n### 数据流水线\n\n一个典型的数据流水线配置如下：\n\n```Python\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n````\n\n在关键点检测任务中，数据一般会在三个尺度空间中变换：\n\n- **原始图片空间**：图片存储时的原始空间，不同图片的尺寸不一定相同\n\n- **输入图片空间**：模型输入的图片尺度空间，所有**图片**和**标注**被缩放到输入尺度，如 `256x256`，`256x192` 等\n\n- **输出尺度空间**：模型输出和训练监督信息所在的尺度空间，如`64x64(热力图)`，`1x1(回归坐标值)`等\n\n数据在三个空间中变换的流程如图所示：\n\n![tour_cn](https://github.com/open-mmlab/mmpose/assets/13503330/4c989d86-e824-49ea-9ba8-b3978548db37)\n\n在MMPose中，数据变换所需要的模块在 [$MMPOSE/mmpose/datasets/transforms](https://github.com/open-mmlab/mmpose/tree/main/mmpose/datasets/transforms) 目录下，它们的工作流程如图所示：\n\n![transforms-cn](https://user-images.githubusercontent.com/13503330/187831611-8db89e20-95c7-42bc-8b0d-700fadf60328.png)\n\n#### i. 数据增强\n\n数据增强中常用的变换存放在 [$MMPOSE/mmpose/datasets/transforms/common_transforms.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/common_transforms.py) 中，如 [RandomFlip](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L94)、[RandomHalfBody](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L263) 等。对于 top-down 方法，`Shift`、`Rotate`、`Resize` 操作由 [RandomBBoxTransform](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L433) 来实现；对于 bottom-up 方法，这些则是由 [BottomupRandomAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L134) 实现。\n\n3D 姿态数据的变换存放在 [$MMPOSE/mmpose/datasets/transforms/pose3d_transforms.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/pose3d_transforms.py) 中。\n\n```{note}\n值得注意的是，大部分数据变换都依赖于 `bbox_center` 和 `bbox_scale`，它们可以通过 [GetBBoxCenterScale](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L31) 来得到。\n```\n\n#### ii. 数据变换\n\n对于二维图片输入，我们使用仿射变换，将图像和坐标标注从原始图片空间变换到输入图片空间。这一操作在 top-down 方法中由 [TopdownAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/topdown_transforms.py#L14) 完成，在 bottom-up 方法中则由 [BottomupRandomAffine](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/bottomup_transforms.py#L134) 完成。\n\n对于 3D 姿态提升任务，变换被合并进[数据编码](./guide_to_framework.md#iii-数据编码)。\n\n#### iii. 数据编码\n\n在模型训练时，数据从原始空间变换到输入图片空间后，需要使用 [GenerateTarget](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/common_transforms.py#L873) 来生成训练所需的监督目标（比如用坐标值生成高斯热图），我们将这一过程称为编码（Encode），反之，通过高斯热图得到对应坐标值的过程称为解码（Decode）。\n\n在 MMPose 中，我们将编码和解码过程集合成一个编解码器（Codec），在其中实现 `encode()` 和 `decode()`。\n\n目前 MMPose 支持生成以下类型的监督目标：\n\n- `heatmap`: 高斯热图\n- `keypoint_label`: 关键点标签（如归一化的坐标值）\n- `keypoint_xy_label`: 单个坐标轴关键点标签\n- `heatmap+keypoint_label`: 同时生成高斯热图和关键点标签\n- `multiscale_heatmap`: 多尺度高斯热图\n- `lifting_target_label`: 3D 提升目标的关键点标签\n\n生成的监督目标会按以下关键字进行封装：\n\n- `heatmaps`：高斯热图\n- `keypoint_labels`：关键点标签（如归一化的坐标值）\n- `keypoint_x_labels`：x 轴关键点标签\n- `keypoint_y_labels`：y 轴关键点标签\n- `keypoint_weights`：关键点权重\n- `lifting_target_label`: 3D 提升目标的关键点标签\n- `lifting_target_weight`: 3D 提升目标的关键点权重\n\n```Python\n@TRANSFORMS.register_module()\nclass GenerateTarget(BaseTransform):\n    \"\"\"Encode keypoints into Target.\n\n    Added Keys (depends on the args):\n        - heatmaps\n        - keypoint_labels\n        - keypoint_x_labels\n        - keypoint_y_labels\n        - keypoint_weights\n    \"\"\"\n```\n\n值得注意的是，我们对 top-down，pose-lifting 和 bottom-up 的数据格式进行了统一，这意味着标注信息中会新增一个维度来代表同一张图里的不同目标（如人），格式为：\n\n```Python\n[batch_size, num_instances, num_keypoints, dim_coordinates]\n```\n\n- top-down 和 pose-lifting：`[B, 1, K, D]`\n\n- bottom-up: `[B, N, K, D]`\n\n当前已经支持的编解码器定义在 [$MMPOSE/mmpose/codecs](https://github.com/open-mmlab/mmpose/tree/main/mmpose/codecs) 目录下，如果你需要自定新的编解码器，可以前往[编解码器](./user_guides/codecs.md)了解更多详情。\n\n#### iv. 数据打包\n\n数据经过前处理变换后，最终需要通过 [PackPoseInputs](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/formatting.py) 打包成数据样本。\n\n打包过程会将数据流水线中用字典 `results` 存储的数据转换成用 MMPose 所需的标准数据结构， 如 `InstanceData`，`PixelData`，[PoseDataSample](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/structures/pose_data_sample.py) 等。\n\n具体而言，我们将数据样本内容分为 `gt`（标注真值） 和 `pred`（模型预测）两部分，它们都包含以下数据项：\n\n- **instances**(numpy.array)：实例级别的原始标注或预测结果，属于原始尺度空间\n\n- **instance_labels**(torch.tensor)：实例级别的训练标签（如归一化的坐标值、关键点可见性），属于输出尺度空间\n\n- **fields**(torch.tensor)：像素级别的训练标签（如高斯热图）或预测结果，属于输出尺度空间\n\n下面是 [PoseDataSample](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/structures/pose_data_sample.py) 底层实现的例子：\n\n```Python\ndef get_pose_data_sample(self):\n    # meta\n    pose_meta = dict(\n        img_shape=(600, 900),  # [h, w, c]\n        crop_size=(256, 192),  # [h, w]\n        heatmap_size=(64, 48),  # [h, w]\n    )\n\n    # gt_instances\n    gt_instances = InstanceData()\n    gt_instances.bboxes = np.random.rand(1, 4)\n    gt_instances.keypoints = np.random.rand(1, 17, 2)\n\n    # gt_instance_labels\n    gt_instance_labels = InstanceData()\n    gt_instance_labels.keypoint_labels = torch.rand(1, 17, 2)\n    gt_instance_labels.keypoint_weights = torch.rand(1, 17)\n\n    # pred_instances\n    pred_instances = InstanceData()\n    pred_instances.keypoints = np.random.rand(1, 17, 2)\n    pred_instances.keypoint_scores = np.random.rand(1, 17)\n\n    # gt_fields\n    gt_fields = PixelData()\n    gt_fields.heatmaps = torch.rand(17, 64, 48)\n\n    # pred_fields\n    pred_fields = PixelData()\n    pred_fields.heatmaps = torch.rand(17, 64, 48)\n    data_sample = PoseDataSample(\n        gt_instances=gt_instances,\n        pred_instances=pred_instances,\n        gt_fields=gt_fields,\n        pred_fields=pred_fields,\n        metainfo=pose_meta)\n\n    return data_sample\n```\n\n## Step3: 模型\n\n在 MMPose 1.0中，模型由以下几部分构成：\n\n- **预处理器（DataPreprocessor）**：完成图像归一化和通道转换等前处理\n\n- **主干网络 （Backbone）**：用于特征提取\n\n- **颈部模块（Neck）**：GAP，FPN 等可选项\n\n- **预测头（Head）**：用于实现核心算法功能和损失函数定义\n\n我们在 [$MMPOSE/mmpose/models/pose_estimators/base.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/pose_estimators/base.py) 下为姿态估计模型定义了一个基类 [BasePoseEstimator](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/pose_estimators/base.py)，所有的模型（如 [TopdownPoseEstimator](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/pose_estimators/topdown.py)）都需要继承这个基类，并重载对应的方法。\n\n在模型的 `forward()` 方法中提供了三种不同的模式：\n\n- `mode == 'loss'`：返回损失函数计算的结果，用于模型训练\n\n- `mode == 'predict'`：返回输入尺度下的预测结果，用于模型推理\n\n- `mode == 'tensor'`：返回输出尺度下的模型输出，即只进行模型前向传播，用于模型导出\n\n开发者需要在 `PoseEstimator` 中按照模型结构调用对应的 `Registry` ，对模块进行实例化。以 top-down 模型为例：\n\n```Python\n@MODELS.register_module()\nclass TopdownPoseEstimator(BasePoseEstimator):\n    def __init__(self,\n                 backbone: ConfigType,\n                 neck: OptConfigType = None,\n                 head: OptConfigType = None,\n                 train_cfg: OptConfigType = None,\n                 test_cfg: OptConfigType = None,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None):\n        super().__init__(data_preprocessor, init_cfg)\n\n        self.backbone = MODELS.build(backbone)\n\n        if neck is not None:\n            self.neck = MODELS.build(neck)\n\n        if head is not None:\n            self.head = MODELS.build(head)\n```\n\n### 前处理器（DataPreprocessor）\n\n从 MMPose 1.0 开始，我们在模型中添加了新的前处理器模块，用以完成图像归一化、通道顺序变换等操作。这样做的好处是可以利用 GPU 等设备的计算能力加快计算，并使模型在导出和部署时更具完整性。\n\n在配置文件中，一个常见的 `data_preprocessor` 如下：\n\n```Python\ndata_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n```\n\n它会将输入图片的通道顺序从 `bgr` 转换为 `rgb`，并根据 `mean` 和 `std` 进行数据归一化。\n\n### 主干网络（Backbone）\n\nMMPose 实现的主干网络存放在 [$MMPOSE/mmpose/models/backbones](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/backbones) 目录下。\n\n在实际开发中，开发者经常会使用预训练的网络权重进行迁移学习，这能有效提升模型在小数据集上的性能。 在 MMPose 中，只需要在配置文件 `backbone` 的 `init_cfg` 中设置：\n\n```Python\ninit_cfg=dict(\n    type='Pretrained',\n    checkpoint='PATH/TO/YOUR_MODEL_WEIGHTS.pth'),\n```\n\n如果你想只加载一个训练好的 checkpoint 的 backbone 部分，你需要指明一下前缀 `prefix`:\n\n```Python\ninit_cfg=dict(\n    type='Pretrained',\n    prefix='backbone.',\n    checkpoint='PATH/TO/YOUR_CHECKPOINT.pth'),\n```\n\n其中 `checkpoint` 既可以是本地路径，也可以是下载链接。因此，如果你想使用 Torchvision 提供的预训练模型（比如ResNet50），可以使用：\n\n```Python\ninit_cfg=dict(\n    type='Pretrained',\n    checkpoint='torchvision://resnet50')\n```\n\n除了这些常用的主干网络以外，你还可以从 MMClassification 等其他 OpenMMLab 项目中方便地迁移主干网络，它们都遵循同一套配置文件格式，并提供了预训练权重可供使用。\n\n需要强调的是，如果你加入了新的主干网络，需要在模型定义时进行注册：\n\n```Python\n@MODELS.register_module()\nclass YourBackbone(BaseBackbone):\n```\n\n同时在 [$MMPOSE/mmpose/models/backbones/\\_\\_init\\_\\_.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/backbones/__init__.py) 下进行 `import`，并加入到 `__all__` 中，才能被配置文件正确地调用。\n\n### 颈部模块（Neck）\n\nMMPose 中 Neck 相关的模块定义在 [$MMPOSE/mmpose/models/necks](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/necks) 目录下.\n\n颈部模块通常是介于主干网络和预测头之间的模块，在部分模型算法中会用到，常见的颈部模块有：\n\n- Global Average Pooling (GAP)\n\n- Feature Pyramid Networks (FPN)\n\n- Feature Map Processor (FMP)\n\n  [FeatureMapProcessor](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/models/necks/fmap_proc_neck.py) 是一个通用的 PyTorch 模块，旨在通过选择、拼接和缩放等非参数变换将主干网络输出的特征图转换成适合预测头的格式。以下是一些操作的配置方式及效果示意图:\n\n  - 选择操作\n\n    ```python\n    neck=dict(type='FeatureMapProcessor', select_index=0)\n    ```\n\n    <img src=\"https://user-images.githubusercontent.com/26127467/227108468-b44c9c13-9e51-403c-a035-b17b5268acc3.png\" height=\"100px\" alt><br>\n\n  - 拼接操作\n\n    ```python\n    neck=dict(type='FeatureMapProcessor', concat=True)\n    ```\n\n    <img src=\"https://user-images.githubusercontent.com/26127467/227108705-4d197c71-4019-42cb-abdb-ba159111abb4.png\" height=\"85px\" alt><br>\n\n    拼接之前，其它特征图会被缩放到和序号为 0 的特征图相同的尺寸。\n\n  - 缩放操作\n\n    ```python\n    neck=dict(type='FeatureMapProcessor', scale_factor=2.0)\n    ```\n\n    <img src=\"https://user-images.githubusercontent.com/26127467/227109402-94106e4b-b941-4ce9-8201-c64920d82ed1.png\" height=\"120px\" alt><br>\n\n### 预测头（Head）\n\n通常来说，预测头是模型算法实现的核心，用于控制模型的输出，并进行损失函数计算。\n\nMMPose 中 Head 相关的模块定义在 [$MMPOSE/mmpose/models/heads](https://github.com/open-mmlab/mmpose/tree/main/mmpose/models/heads) 目录下，开发者在自定义预测头时需要继承我们提供的基类 [BaseHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py)，并重载以下三个方法对应模型推理的三种模式：\n\n- forward()\n\n- predict()\n\n- loss()\n\n具体而言，`predict()` 返回的应是输入图片尺度下的结果，因此需要调用 `self.decode()` 对网络输出进行解码，这一过程实现在 [BaseHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/base_head.py) 中已经实现，它会调用编解码器提供的 `decode()` 方法来完成解码。\n\n另一方面，我们会在 `predict()` 中进行测试时增强。在进行预测时，一个常见的测试时增强技巧是进行翻转集成。即，将一张图片先进行一次推理，再将图片水平翻转进行一次推理，推理的结果再次水平翻转回去，对两次推理的结果进行平均。这个技巧能有效提升模型的预测稳定性。\n\n下面是在 [RegressionHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/regression_heads/regression_head.py) 中定义 `predict()` 的例子：\n\n```Python\ndef predict(self,\n            feats: Tuple[Tensor],\n            batch_data_samples: OptSampleList,\n            test_cfg: ConfigType = {}) -> Predictions:\n    \"\"\"Predict results from outputs.\"\"\"\n\n    if test_cfg.get('flip_test', False):\n        # TTA: flip test -> feats = [orig, flipped]\n        assert isinstance(feats, list) and len(feats) == 2\n        flip_indices = batch_data_samples[0].metainfo['flip_indices']\n        input_size = batch_data_samples[0].metainfo['input_size']\n        _feats, _feats_flip = feats\n        _batch_coords = self.forward(_feats)\n        _batch_coords_flip = flip_coordinates(\n            self.forward(_feats_flip),\n            flip_indices=flip_indices,\n            shift_coords=test_cfg.get('shift_coords', True),\n            input_size=input_size)\n        batch_coords = (_batch_coords + _batch_coords_flip) * 0.5\n    else:\n        batch_coords = self.forward(feats)  # (B, K, D)\n\n    batch_coords.unsqueeze_(dim=1)  # (B, N, K, D)\n    preds = self.decode(batch_coords)\n```\n\n`loss()`除了进行损失函数的计算，还会进行 accuracy 等训练时指标的计算，并通过一个字典 `losses` 来传递:\n\n```Python\n # calculate accuracy\n_, avg_acc, _ = keypoint_pck_accuracy(\n    pred=to_numpy(pred_coords),\n    gt=to_numpy(keypoint_labels),\n    mask=to_numpy(keypoint_weights) > 0,\n    thr=0.05,\n    norm_factor=np.ones((pred_coords.size(0), 2), dtype=np.float32))\n\nacc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\nlosses.update(acc_pose=acc_pose)\n```\n\n每个 batch 的数据都打包成了 `batch_data_samples`。以 Regression-based 方法为例，训练所需的归一化的坐标值和关键点权重可以用如下方式获取：\n\n```Python\nkeypoint_labels = torch.cat(\n    [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\nkeypoint_weights = torch.cat([\n    d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n])\n```\n\n以下为 [RegressionHead](https://github.com/open-mmlab/mmpose/blob/main/mmpose/models/heads/regression_heads/regression_head.py) 中完整的 `loss()` 实现：\n\n```Python\ndef loss(self,\n         inputs: Tuple[Tensor],\n         batch_data_samples: OptSampleList,\n         train_cfg: ConfigType = {}) -> dict:\n    \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n    pred_outputs = self.forward(inputs)\n\n    keypoint_labels = torch.cat(\n        [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n    keypoint_weights = torch.cat([\n        d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n    ])\n\n    # calculate losses\n    losses = dict()\n    loss = self.loss_module(pred_outputs, keypoint_labels,\n                            keypoint_weights.unsqueeze(-1))\n\n    if isinstance(loss, dict):\n        losses.update(loss)\n    else:\n        losses.update(loss_kpt=loss)\n\n    # calculate accuracy\n    _, avg_acc, _ = keypoint_pck_accuracy(\n        pred=to_numpy(pred_outputs),\n        gt=to_numpy(keypoint_labels),\n        mask=to_numpy(keypoint_weights) > 0,\n        thr=0.05,\n        norm_factor=np.ones((pred_outputs.size(0), 2), dtype=np.float32))\n    acc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\n    losses.update(acc_pose=acc_pose)\n\n    return losses\n```\n\n```{note}\n如果你想了解更多模型实现的内容，如：\n- 支持关键点可见性预测的头部\n- 2D-to-3D 模型实现\n\n请前往 [【进阶教程 - 实现新模型】](./advanced_guides/implement_new_models.md)\n```\n"
  },
  {
    "path": "docs/zh_cn/index.rst",
    "content": "欢迎来到 MMPose 中文文档!\n==================================\n\n您可以在页面左下角切换文档语言。\n\nYou can change the documentation language at the lower-left corner of the page.\n\n.. toctree::\n   :maxdepth: 1\n   :caption: 开启 MMPose 之旅\n\n   overview.md\n   installation.md\n   guide_to_framework.md\n   demos.md\n   contribution_guide.md\n   faq.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: 用户教程\n\n   user_guides/inference.md\n   user_guides/configs.md\n   user_guides/prepare_datasets.md\n   user_guides/train_and_test.md\n   user_guides/how_to_deploy.md\n   user_guides/model_analysis.md\n   user_guides/dataset_tools.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: 进阶教程\n\n   advanced_guides/codecs.md\n   advanced_guides/dataflow.md\n   advanced_guides/implement_new_models.md\n   advanced_guides/customize_datasets.md\n   advanced_guides/customize_transforms.md\n   advanced_guides/customize_evaluation.md\n   advanced_guides/customize_optimizer.md\n   advanced_guides/customize_logging.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: 1.x 版本迁移指南\n\n   migration.md\n\n.. toctree::\n   :maxdepth: 2\n   :caption: 模型库\n\n   model_zoo.txt\n   model_zoo/body_2d_keypoint.md\n   model_zoo/body_3d_keypoint.md\n   model_zoo/face_2d_keypoint.md\n   model_zoo/hand_2d_keypoint.md\n   model_zoo/wholebody_2d_keypoint.md\n   model_zoo/animal_2d_keypoint.md\n\n.. toctree::\n   :maxdepth: 2\n   :caption: 模型库（按论文整理）\n\n   model_zoo_papers/algorithms.md\n   model_zoo_papers/backbones.md\n   model_zoo_papers/techniques.md\n   model_zoo_papers/datasets.md\n\n.. toctree::\n   :maxdepth: 2\n   :caption: 数据集\n\n   dataset_zoo.md\n   dataset_zoo/2d_body_keypoint.md\n   dataset_zoo/2d_wholebody_keypoint.md\n   dataset_zoo/2d_face_keypoint.md\n   dataset_zoo/2d_hand_keypoint.md\n   dataset_zoo/2d_fashion_landmark.md\n   dataset_zoo/2d_animal_keypoint.md\n   dataset_zoo/3d_body_keypoint.md\n   dataset_zoo/3d_hand_keypoint.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: 相关项目\n\n   projects/community_projects.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: 其他说明\n\n   notes/ecosystem.md\n   notes/changelog.md\n   notes/benchmark.md\n   notes/pytorch_2.md\n\n.. toctree::\n   :maxdepth: 1\n   :caption: API 参考文档\n\n   api.rst\n\n.. toctree::\n   :caption: 切换语言\n\n   switch_language.md\n\n\n\n索引与表格\n==================\n\n* :ref:`genindex`\n* :ref:`search`\n"
  },
  {
    "path": "docs/zh_cn/installation.md",
    "content": "# 安装\n\n我们推荐用户按照我们的最佳实践来安装 MMPose。但除此之外，如果您想根据\n您的习惯完成安装流程，也可以参见 [自定义安装](#自定义安装) 一节来获取更多信息。\n\n- [安装](#安装)\n  - [依赖环境](#依赖环境)\n  - [最佳实践](#最佳实践)\n    - [从源码安装 MMPose](#从源码安装-mmpose)\n    - [作为 Python 包安装](#作为-python-包安装)\n  - [验证安装](#验证安装)\n  - [自定义安装](#自定义安装)\n    - [CUDA 版本](#cuda-版本)\n    - [不使用 MIM 安装 MMEngine](#不使用-mim-安装-mmengine)\n    - [在 CPU 环境中安装](#在-cpu-环境中安装)\n    - [在 Google Colab 中安装](#在-google-colab-中安装)\n    - [通过 Docker 使用 MMPose](#通过-docker-使用-mmpose)\n  - [故障解决](#故障解决)\n\n## 依赖环境\n\n在本节中，我们将演示如何准备 PyTorch 相关的依赖环境。\n\nMMPose 适用于 Linux、Windows 和 macOS。它需要 Python 3.7+、CUDA 9.2+ 和 PyTorch 1.8+。\n\n如果您对配置 PyTorch 环境已经很熟悉，并且已经完成了配置，可以直接进入下一节：[安装](#安装-mmpose)。否则，请依照以下步骤完成配置。\n\n**第 1 步** 从[官网](https://docs.conda.io/en/latest/miniconda.html) 下载并安装 Miniconda。\n\n**第 2 步** 创建一个 conda 虚拟环境并激活它。\n\n```shell\nconda create --name openmmlab python=3.8 -y\nconda activate openmmlab\n```\n\n**第 3 步** 按照[官方指南](https://pytorch.org/get-started/locally/) 安装 PyTorch。例如：\n\n在 GPU 平台：\n\n```shell\nconda install pytorch torchvision -c pytorch\n```\n\n```{warning}\n以上命令会自动安装最新版的 PyTorch 与对应的 cudatoolkit，请检查它们是否与您的环境匹配。\n```\n\n在 CPU 平台：\n\n```shell\nconda install pytorch torchvision cpuonly -c pytorch\n```\n\n**第 4 步** 使用 [MIM](https://github.com/open-mmlab/mim) 安装 [MMEngine](https://github.com/open-mmlab/mmengine) 和 [MMCV](https://github.com/open-mmlab/mmcv/tree/2.x)\n\n```shell\npip install -U openmim\nmim install mmengine\nmim install \"mmcv>=2.0.1\"\n```\n\n请注意，MMPose 中的一些推理示例脚本需要使用 [MMDetection](https://github.com/open-mmlab/mmdetection) (mmdet) 检测人体。如果您想运行这些示例脚本，可以通过运行以下命令安装 mmdet:\n\n```shell\nmim install \"mmdet>=3.1.0\"\n```\n\n```{note}\n新旧版本 mmpose、mmdet、mmcv 的对应关系为：\n\n- mmdet 2.x <=> mmpose 0.x <=> mmcv 1.x\n- mmdet 3.x <=> mmpose 1.x <=> mmcv 2.x\n\n如果遇到版本不兼容的问题，请使用 `pip list | grep mm` 检查对应关系后，升级或降级相关依赖。注意，`mmcv-full` 只对应旧版本 `mmcv 1.x`，所以请先卸载它后，再通过 `mim install mmcv` 来安装 `mmcv 2.x`。\n```\n\n## 最佳实践\n\n根据具体需求，我们支持两种安装模式: 从源码安装（推荐）和作为 Python 包安装\n\n### 从源码安装（推荐）\n\n如果基于 MMPose 框架开发自己的任务，需要添加新的功能，比如新的模型或是数据集，或者使用我们提供的各种工具。从源码按如下方式安装 mmpose：\n\n```shell\ngit clone https://github.com/open-mmlab/mmpose.git\ncd mmpose\npip install -r requirements.txt\npip install -v -e .\n# \"-v\" 表示输出更多安装相关的信息\n# \"-e\" 表示以可编辑形式安装，这样可以在不重新安装的情况下，让本地修改直接生效\n```\n\n### 作为 Python 包安装\n\n如果只是希望调用 MMPose 的接口，或者在自己的项目中导入 MMPose 中的模块。直接使用 mim 安装即可。\n\n```shell\nmim install \"mmpose>=1.1.0\"\n```\n\n## 验证安装\n\n为了验证 MMPose 是否安装正确，您可以通过以下步骤运行模型推理。\n\n**第 1 步** 我们需要下载配置文件和模型权重文件\n\n```shell\nmim download mmpose --config td-hm_hrnet-w48_8xb32-210e_coco-256x192  --dest .\n```\n\n下载过程往往需要几秒或更多的时间，这取决于您的网络环境。完成之后，您会在当前目录下找到这两个文件：`td-hm_hrnet-w48_8xb32-210e_coco-256x192.py` 和 `td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth`, 分别是配置文件和对应的模型权重文件。\n\n**第 2 步** 验证推理示例\n\n如果您是**从源码安装**的 mmpose，可以直接运行以下命令进行验证：\n\n```shell\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    td-hm_hrnet-w48_8xb32-210e_coco-256x192.py \\\n    td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth \\\n    --out-file vis_results.jpg \\\n    --draw-heatmap\n```\n\n如果一切顺利，您将会得到这样的可视化结果：\n\n![image](https://user-images.githubusercontent.com/87690686/187824033-2cce0f55-034a-4127-82e2-52744178bc32.jpg)\n\n代码会将预测的关键点和热图绘制在图像中的人体上，并保存到当前文件夹下的 `vis_results.jpg`。\n\n如果您是**作为 Python 包安装**，可以打开您的 Python 解释器，复制并粘贴如下代码：\n\n```python\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.utils import register_all_modules\n\nregister_all_modules()\n\nconfig_file = 'td-hm_hrnet-w48_8xb32-210e_coco-256x192.py'\ncheckpoint_file = 'td-hm_hrnet-w48_8xb32-210e_coco-256x192-0e67c616_20220913.pth'\nmodel = init_model(config_file, checkpoint_file, device='cpu')  # or device='cuda:0'\n\n# 请准备好一张带有人体的图片\nresults = inference_topdown(model, 'demo.jpg')\n```\n\n示例图片 `demo.jpg` 可以从 [Github](https://raw.githubusercontent.com/open-mmlab/mmpose/main/tests/data/coco/000000000785.jpg) 下载。\n推理结果是一个 `PoseDataSample` 列表，预测结果将会保存在 `pred_instances` 中，包括检测到的关键点位置和置信度。\n\n```{note}\nMMCV 版本与 PyTorch 版本需要严格对应，如果遇到如下问题：\n\n- No module named 'mmcv.ops'\n- No module named 'mmcv._ext'\n\n说明当前环境中的 PyTorch 版本与 CUDA 版本不匹配。你可以通过 `nvidia-smi` 查看 CUDA 版本，需要与 `pip list | grep torch` 中 PyTorch 的 `+cu1xx` 对应，否则，你需要先卸载 PyTorch 并重新安装，然后重新安装 MMCV（这里的安装顺序**不可以**交换）。\n```\n\n## 自定义安装\n\n### CUDA 版本\n\n安装 PyTorch 时，需要指定 CUDA 版本。如果您不清楚选择哪个，请遵循我们的建议：\n\n- 对于 Ampere 架构的 NVIDIA GPU，例如 GeForce 30 系列 以及 NVIDIA A100，CUDA 11 是必需的。\n- 对于更早的 NVIDIA GPU，CUDA 11 是向后兼容 (backward compatible) 的，但 CUDA 10.2 能够提供更好的兼容性，也更加轻量。\n\n请确保您的 GPU 驱动版本满足最低的版本需求，参阅[这张表](https://docs.nvidia.com/cuda/cuda-toolkit-release-notes/index.html#cuda-major-component-versions__table-cuda-toolkit-driver-versions)。\n\n```{note}\n如果按照我们的最佳实践进行安装，CUDA 运行时库就足够了，因为我们提供相关 CUDA 代码的预编译，您不需要进行本地编译。\n但如果您希望从源码进行 MMCV 的编译，或是进行其他 CUDA 算子的开发，那么就必须安装完整的 CUDA 工具链，参见\n[NVIDIA 官网](https://developer.nvidia.com/cuda-downloads)，另外还需要确保该 CUDA 工具链的版本与 PyTorch 安装时\n的配置相匹配（如用 `conda install` 安装 PyTorch 时指定的 cudatoolkit 版本）。\n```\n\n### 不使用 MIM 安装 MMEngine\n\n若不使用 mim 安装 MMEngine，请遵循 [ MMEngine 安装指南](https://mmengine.readthedocs.io/zh_CN/latest/get_started/installation.html).\n\n例如，您可以通过以下命令安装 MMEngine:\n\n```shell\npip install mmengine\n```\n\n### 不使用 MIM 安装 MMCV\n\nMMCV 包含 C++ 和 CUDA 扩展，因此其对 PyTorch 的依赖比较复杂。MIM 会自动解析这些\n依赖，选择合适的 MMCV 预编译包，使安装更简单，但它并不是必需的。\n\n若不使用 mim 来安装 MMCV，请遵照 [MMCV 安装指南](https://mmcv.readthedocs.io/zh_CN/2.x/get_started/installation.html)。\n它需要您用指定 url 的形式手动指定对应的 PyTorch 和 CUDA 版本。\n\n举个例子，如下命令将会安装基于 PyTorch 1.10.x 和 CUDA 11.3 编译的 mmcv。\n\n```shell\npip install 'mmcv>=2.0.1' -f https://download.openmmlab.com/mmcv/dist/cu113/torch1.10/index.html\n```\n\n### 在 CPU 环境中安装\n\nMMPose 可以仅在 CPU 环境中安装，在 CPU 模式下，您可以完成训练、测试和模型推理等所有操作。\n\n在 CPU 模式下，MMCV 的部分功能将不可用，通常是一些 GPU 编译的算子，如 `Deformable Convolution`。MMPose 中大部分的模型都不会依赖这些算子，但是如果您尝试使用包含这些算子的模型来运行训练、测试或推理，将会报错。\n\n### 在 Google Colab 中安装\n\n[Google Colab](https://colab.research.google.com/) 通常已经包含了 PyTorch 环境，因此我们只需要安装 MMEngine, MMCV 和 MMPose 即可，命令如下：\n\n**第 1 步** 使用 [MIM](https://github.com/open-mmlab/mim) 安装 [MMEngine](https://github.com/open-mmlab/mmengine) 和 [MMCV](https://github.com/open-mmlab/mmcv/tree/2.x)\n\n```shell\n!pip3 install openmim\n!mim install mmengine\n!mim install \"mmcv>=2.0.1\"\n```\n\n**第 2 步** 从源码安装 mmpose\n\n```shell\n!git clone https://github.com/open-mmlab/mmpose.git\n%cd mmpose\n!pip install -e .\n```\n\n**第 3 步** 验证\n\n```python\nimport mmpose\nprint(mmpose.__version__)\n# 预期输出： 1.1.0\n```\n\n```{note}\n在 Jupyter 中，感叹号 `!` 用于执行外部命令，而 `%cd` 是一个[魔术命令](https://ipython.readthedocs.io/en/stable/interactive/magics.html#magic-cd)，用于切换 Python 的工作路径。\n```\n\n### 通过 Docker 使用 MMPose\n\nMMPose 提供 [Dockerfile](https://github.com/open-mmlab/mmpose/blob/master/docker/Dockerfile)\n用于构建镜像。请确保您的 [Docker 版本](https://docs.docker.com/engine/install/) >=19.03。\n\n```shell\n# 构建默认的 PyTorch 1.8.0，CUDA 10.1 版本镜像\n# 如果您希望使用其他版本，请修改 Dockerfile\ndocker build -t mmpose docker/\n```\n\n**注意**：请确保您已经安装了 [nvidia-container-toolkit](https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/install-guide.html#docker)。\n\n用以下命令运行 Docker 镜像：\n\n```shell\ndocker run --gpus all --shm-size=8g -it -v {DATA_DIR}:/mmpose/data mmpose\n```\n\n`{DATA_DIR}` 是您本地存放用于 MMPose 训练、测试、推理等流程的数据目录。\n\n## 故障解决\n\n如果您在安装过程中遇到了什么问题，请先查阅[常见问题](faq.md)。如果没有找到解决方法，可以在 GitHub\n上[提出 issue](https://github.com/open-mmlab/mmpose/issues/new/choose)。\n"
  },
  {
    "path": "docs/zh_cn/make.bat",
    "content": "@ECHO OFF\n\npushd %~dp0\n\nREM Command file for Sphinx documentation\n\nif \"%SPHINXBUILD%\" == \"\" (\n\tset SPHINXBUILD=sphinx-build\n)\nset SOURCEDIR=.\nset BUILDDIR=_build\n\nif \"%1\" == \"\" goto help\n\n%SPHINXBUILD% >NUL 2>NUL\nif errorlevel 9009 (\n\techo.\n\techo.The 'sphinx-build' command was not found. Make sure you have Sphinx\n\techo.installed, then set the SPHINXBUILD environment variable to point\n\techo.to the full path of the 'sphinx-build' executable. Alternatively you\n\techo.may add the Sphinx directory to PATH.\n\techo.\n\techo.If you don't have Sphinx installed, grab it from\n\techo.http://sphinx-doc.org/\n\texit /b 1\n)\n\n%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\ngoto end\n\n:help\n%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% %O%\n\n:end\npopd\n"
  },
  {
    "path": "docs/zh_cn/merge_docs.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nsed -i '$a\\\\n' ../../demo/docs/zh_cn/*_demo.md\ncat ../../demo/docs/zh_cn/*_demo.md | sed \"s/^## 2D\\(.*\\)Demo/##\\1Estimation/\" | sed \"s/md###t/html#t/g\" | sed '1i\\# Demos\\n' | sed 's=](/docs/en/=](/=g' | sed 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' >demos.md\n\n # remove /docs/ for link used in doc site\nsed -i 's=](/docs/zh_cn/=](=g' overview.md\nsed -i 's=](/docs/zh_cn/=](=g' installation.md\nsed -i 's=](/docs/zh_cn/=](=g' quick_run.md\nsed -i 's=](/docs/zh_cn/=](=g' migration.md\nsed -i 's=](/docs/zh_cn/=](=g' ./model_zoo/*.md\nsed -i 's=](/docs/zh_cn/=](=g' ./model_zoo_papers/*.md\nsed -i 's=](/docs/zh_cn/=](=g' ./user_guides/*.md\nsed -i 's=](/docs/zh_cn/=](=g' ./advanced_guides/*.md\nsed -i 's=](/docs/zh_cn/=](=g' ./dataset_zoo/*.md\nsed -i 's=](/docs/zh_cn/=](=g' ./notes/*.md\nsed -i 's=](/docs/zh_cn/=](=g' ./projects/*.md\n\n\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' overview.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' installation.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' quick_run.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' migration.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./advanced_guides/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./model_zoo/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./model_zoo_papers/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./user_guides/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./dataset_zoo/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./notes/*.md\nsed -i 's=](/=](https://github.com/open-mmlab/mmpose/tree/dev-1.x/=g' ./projects/*.md\n"
  },
  {
    "path": "docs/zh_cn/migration.md",
    "content": "# MMPose 0.X 兼容性说明\n\nMMPose 1.0 经过了大规模重构并解决了许多遗留问题，对于 0.x 版本的大部分代码 MMPose 1.0 将不兼容。\n\n## 数据变换\n\n### 平移、旋转和缩放\n\n旧版的数据变换方法 `TopDownRandomShiftBboxCenter` 和 `TopDownGetRandomScaleRotation`，将被合并为 `RandomBBoxTransform`：\n\n```Python\n@TRANSFORMS.register_module()\nclass RandomBBoxTransform(BaseTransform):\n    r\"\"\"Rnadomly shift, resize and rotate the bounding boxes.\n\n    Required Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Modified Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Added Keys:\n        - bbox_rotation\n\n    Args:\n        shift_factor (float): Randomly shift the bbox in range\n            :math:`[-dx, dx]` and :math:`[-dy, dy]` in X and Y directions,\n            where :math:`dx(y) = x(y)_scale \\cdot shift_factor` in pixels.\n            Defaults to 0.16\n        shift_prob (float): Probability of applying random shift. Defaults to\n            0.3\n        scale_factor (Tuple[float, float]): Randomly resize the bbox in range\n            :math:`[scale_factor[0], scale_factor[1]]`. Defaults to (0.5, 1.5)\n        scale_prob (float): Probability of applying random resizing. Defaults\n            to 1.0\n        rotate_factor (float): Randomly rotate the bbox in\n            :math:`[-rotate_factor, rotate_factor]` in degrees. Defaults\n            to 80.0\n        rotate_prob (float): Probability of applying random rotation. Defaults\n            to 0.6\n    \"\"\"\n\n    def __init__(self,\n                 shift_factor: float = 0.16,\n                 shift_prob: float = 0.3,\n                 scale_factor: Tuple[float, float] = (0.5, 1.5),\n                 scale_prob: float = 1.0,\n                 rotate_factor: float = 80.0,\n                 rotate_prob: float = 0.6) -> None:\n```\n\n### 标签生成\n\n旧版用于训练标签生成的方法 `TopDownGenerateTarget` 、`TopDownGenerateTargetRegression`、`BottomUpGenerateHeatmapTarget`、`BottomUpGenerateTarget` 等将被合并为 `GenerateTarget`，而实际的生成方法由[编解码器](./user_guides/codecs.md) 提供：\n\n```Python\n@TRANSFORMS.register_module()\nclass GenerateTarget(BaseTransform):\n    \"\"\"Encode keypoints into Target.\n\n    The generated target is usually the supervision signal of the model\n    learning, e.g. heatmaps or regression labels.\n\n    Required Keys:\n\n        - keypoints\n        - keypoints_visible\n        - dataset_keypoint_weights\n\n    Added Keys:\n\n        - The keys of the encoded items from the codec will be updated into\n            the results, e.g. ``'heatmaps'`` or ``'keypoint_weights'``. See\n            the specific codec for more details.\n\n    Args:\n        encoder (dict | list[dict]): The codec config for keypoint encoding.\n            Both single encoder and multiple encoders (given as a list) are\n            supported\n        multilevel (bool): Determine the method to handle multiple encoders.\n            If ``multilevel==True``, generate multilevel targets from a group\n            of encoders of the same type (e.g. multiple :class:`MSRAHeatmap`\n            encoders with different sigma values); If ``multilevel==False``,\n            generate combined targets from a group of different encoders. This\n            argument will have no effect in case of single encoder. Defaults\n            to ``False``\n        use_dataset_keypoint_weights (bool): Whether use the keypoint weights\n            from the dataset meta information. Defaults to ``False``\n    \"\"\"\n\n    def __init__(self,\n                 encoder: MultiConfig,\n                 multilevel: bool = False,\n                 use_dataset_keypoint_weights: bool = False) -> None:\n```\n\n### 数据归一化\n\n旧版的数据归一化操作 `NormalizeTensor` 和 `ToTensor` 方法将由 **DataPreprocessor** 模块替代，不再作为流水线的一部分，而是作为模块加入到模型前向传播中。\n\n旧版用于 3D 人类姿态数据变换的方法 `GetRootCenteredPose`, `ImageCoordinateNormalization` 和 `NormalizeJointCoordinate` 等，将被合并入编码器，比如 [`ImagePoseLifting`](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/image_pose_lifting.py#L11) 和 [`VideoPoseLifting`](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/codecs/video_pose_lifting.py#L13) 等。\n\n数据转换和重构操作 `PoseSequenceToTensor` 将在相应的编解码器和 [`PackPoseInputs`](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/transforms/formatting.py) 中实现。\n\n## 模型兼容\n\n我们对 model zoo 提供的模型权重进行了兼容性处理，确保相同的模型权重测试精度能够与 0.x 版本保持同等水平，但由于在这两个版本中存在大量处理细节的差异，推理结果可能会产生轻微的不同（精度误差小于 0.05%）。\n\n对于使用 0.x 版本训练保存的模型权重，我们在预测头中提供了 `_load_state_dict_pre_hook()` 方法来将旧版的权重字典替换为新版，如果你希望将在旧版上开发的模型兼容到新版，可以参考我们的实现。\n\n```Python\n@MODELS.register_module()\nclass YourHead(BaseHead):\ndef __init__(self):\n\n    ## omitted\n\n    # Register the hook to automatically convert old version state dicts\n    self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n```\n\n### Heatmap-based 方法\n\n对于基于SimpleBaseline方法的模型，主要需要注意最后一层卷积层的兼容：\n\n```Python\ndef _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                              **kwargs):\n    version = local_meta.get('version', None)\n\n    if version and version >= self._version:\n        return\n\n    # convert old-version state dict\n    keys = list(state_dict.keys())\n    for _k in keys:\n        if not _k.startswith(prefix):\n            continue\n        v = state_dict.pop(_k)\n        k = _k[len(prefix):]\n        # In old version, \"final_layer\" includes both intermediate\n        # conv layers (new \"conv_layers\") and final conv layers (new\n        # \"final_layer\").\n        #\n        # If there is no intermediate conv layer, old \"final_layer\" will\n        # have keys like \"final_layer.xxx\", which should be still\n        # named \"final_layer.xxx\";\n        #\n        # If there are intermediate conv layers, old \"final_layer\"  will\n        # have keys like \"final_layer.n.xxx\", where the weights of the last\n        # one should be renamed \"final_layer.xxx\", and others should be\n        # renamed \"conv_layers.n.xxx\"\n        k_parts = k.split('.')\n        if k_parts[0] == 'final_layer':\n            if len(k_parts) == 3:\n                assert isinstance(self.conv_layers, nn.Sequential)\n                idx = int(k_parts[1])\n                if idx < len(self.conv_layers):\n                    # final_layer.n.xxx -> conv_layers.n.xxx\n                    k_new = 'conv_layers.' + '.'.join(k_parts[1:])\n                else:\n                    # final_layer.n.xxx -> final_layer.xxx\n                    k_new = 'final_layer.' + k_parts[2]\n            else:\n                # final_layer.xxx remains final_layer.xxx\n                k_new = k\n        else:\n            k_new = k\n\n        state_dict[prefix + k_new] = v\n```\n\n### RLE-based 方法\n\n对于基于 RLE 的模型，由于新版的 `loss` 模块更名为 `loss_module`，且 flow 模型归属在 `loss` 模块下，因此需要对权重字典中 `loss` 字段进行更改：\n\n```Python\ndef _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                              **kwargs):\n\n    version = local_meta.get('version', None)\n\n    if version and version >= self._version:\n        return\n\n    # convert old-version state dict\n    keys = list(state_dict.keys())\n    for _k in keys:\n        v = state_dict.pop(_k)\n        k = _k.lstrip(prefix)\n        # In old version, \"loss\" includes the instances of loss,\n        # now it should be renamed \"loss_module\"\n        k_parts = k.split('.')\n        if k_parts[0] == 'loss':\n            # loss.xxx -> loss_module.xxx\n            k_new = prefix + 'loss_module.' + '.'.join(k_parts[1:])\n        else:\n            k_new = _k\n\n        state_dict[k_new] = v\n```\n"
  },
  {
    "path": "docs/zh_cn/notes/changelog.md",
    "content": "# Changelog\n\n## **v1.3.1 (11/01/2024)**\n\n修复了用 `mim` 下载配置文件和模型权重时的 bug （详见 [Issue #2918](https://github.com/open-mmlab/mmpose/issues/2918)）。\n\n## **v1.3.0 (04/01/2024)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.3.0\n\n## **v1.2.0 (12/10/2023)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.2.0\n\n## **v1.1.0 (04/07/2023)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.1.0\n\n## **v1.0.0 (06/04/2023)**\n\nRelease note: https://github.com/open-mmlab/mmpose/releases/tag/v1.0.0\n\n## **v1.0.0rc1 (14/10/2022)**\n\n**Highlights**\n\n- Release RTMPose, a high-performance real-time pose estimation algorithm with cross-platform deployment and inference support. See details at the [project page](/projects/rtmpose/)\n- Support several new algorithms: ViTPose (arXiv'2022), CID (CVPR'2022), DEKR (CVPR'2021)\n- Add Inferencer, a convenient inference interface that perform pose estimation and visualization on images, videos and webcam streams with only one line of code\n- Introduce *Project*, a new form for rapid and easy implementation of new algorithms and features in MMPose, which is more handy for community contributors\n\n**New Features**\n\n- Support RTMPose ([#1971](https://github.com/open-mmlab/mmpose/pull/1971), [#2024](https://github.com/open-mmlab/mmpose/pull/2024), [#2028](https://github.com/open-mmlab/mmpose/pull/2028), [#2030](https://github.com/open-mmlab/mmpose/pull/2030), [#2040](https://github.com/open-mmlab/mmpose/pull/2040), [#2057](https://github.com/open-mmlab/mmpose/pull/2057))\n- Support Inferencer ([#1969](https://github.com/open-mmlab/mmpose/pull/1969))\n- Support ViTPose ([#1876](https://github.com/open-mmlab/mmpose/pull/1876), [#2056](https://github.com/open-mmlab/mmpose/pull/2056), [#2058](https://github.com/open-mmlab/mmpose/pull/2058)， [#2065](https://github.com/open-mmlab/mmpose/pull/2065))\n- Support CID ([#1907](https://github.com/open-mmlab/mmpose/pull/1907))\n- Support DEKR ([#1834](https://github.com/open-mmlab/mmpose/pull/1834), [#1901](https://github.com/open-mmlab/mmpose/pull/1901))\n- Support training with multiple datasets ([#1767](https://github.com/open-mmlab/mmpose/pull/1767), [#1930](https://github.com/open-mmlab/mmpose/pull/1930), [#1938](https://github.com/open-mmlab/mmpose/pull/1938), [#2025](https://github.com/open-mmlab/mmpose/pull/2025))\n- Add *project* to allow rapid and easy implementation of new models and features ([#1914](https://github.com/open-mmlab/mmpose/pull/1914))\n\n**Improvements**\n\n- Improve documentation quality ([#1846](https://github.com/open-mmlab/mmpose/pull/1846), [#1858](https://github.com/open-mmlab/mmpose/pull/1858), [#1872](https://github.com/open-mmlab/mmpose/pull/1872), [#1899](https://github.com/open-mmlab/mmpose/pull/1899), [#1925](https://github.com/open-mmlab/mmpose/pull/1925), [#1945](https://github.com/open-mmlab/mmpose/pull/1945), [#1952](https://github.com/open-mmlab/mmpose/pull/1952), [#1990](https://github.com/open-mmlab/mmpose/pull/1990), [#2023](https://github.com/open-mmlab/mmpose/pull/2023), [#2042](https://github.com/open-mmlab/mmpose/pull/2042))\n- Support visualizing keypoint indices ([#2051](https://github.com/open-mmlab/mmpose/pull/2051))\n- Support OpenPose style visualization ([#2055](https://github.com/open-mmlab/mmpose/pull/2055))\n- Accelerate image transpose in data pipelines with tensor operation ([#1976](https://github.com/open-mmlab/mmpose/pull/1976))\n- Support auto-import modules from registry ([#1961](https://github.com/open-mmlab/mmpose/pull/1961))\n- Support keypoint partition metric ([#1944](https://github.com/open-mmlab/mmpose/pull/1944))\n- Support SimCC 1D-heatmap visualization ([#1912](https://github.com/open-mmlab/mmpose/pull/1912))\n- Support saving predictions and data metainfo in demos ([#1814](https://github.com/open-mmlab/mmpose/pull/1814), [#1879](https://github.com/open-mmlab/mmpose/pull/1879))\n- Support SimCC with DARK ([#1870](https://github.com/open-mmlab/mmpose/pull/1870))\n- Remove Gaussian blur for offset maps in UDP-regress ([#1815](https://github.com/open-mmlab/mmpose/pull/1815))\n- Refactor encoding interface of Codec for better extendibility and easier configuration ([#1781](https://github.com/open-mmlab/mmpose/pull/1781))\n- Support evaluating CocoMetric without annotation file ([#1722](https://github.com/open-mmlab/mmpose/pull/1722))\n- Improve unit tests ([#1765](https://github.com/open-mmlab/mmpose/pull/1765))\n\n**Bug Fixes**\n\n- Fix repeated warnings from different ranks ([#2053](https://github.com/open-mmlab/mmpose/pull/2053))\n- Avoid frequent scope switching when using mmdet inference api ([#2039](https://github.com/open-mmlab/mmpose/pull/2039))\n- Remove EMA parameters and message hub data when publishing model checkpoints ([#2036](https://github.com/open-mmlab/mmpose/pull/2036))\n- Fix metainfo copying in dataset class ([#2017](https://github.com/open-mmlab/mmpose/pull/2017))\n- Fix top-down demo bug when there is no object detected ([#2007](https://github.com/open-mmlab/mmpose/pull/2007))\n- Fix config errors ([#1882](https://github.com/open-mmlab/mmpose/pull/1882), [#1906](https://github.com/open-mmlab/mmpose/pull/1906), [#1995](https://github.com/open-mmlab/mmpose/pull/1995))\n- Fix image demo failure when GUI is unavailable ([#1968](https://github.com/open-mmlab/mmpose/pull/1968))\n- Fix bug in AdaptiveWingLoss ([#1953](https://github.com/open-mmlab/mmpose/pull/1953))\n- Fix incorrect importing of RepeatDataset which is deprecated ([#1943](https://github.com/open-mmlab/mmpose/pull/1943))\n- Fix bug in bottom-up datasets that ignores images without instances ([#1752](https://github.com/open-mmlab/mmpose/pull/1752), [#1936](https://github.com/open-mmlab/mmpose/pull/1936))\n- Fix upstream dependency issues ([#1867](https://github.com/open-mmlab/mmpose/pull/1867), [#1921](https://github.com/open-mmlab/mmpose/pull/1921))\n- Fix evaluation issues and update results ([#1763](https://github.com/open-mmlab/mmpose/pull/1763), [#1773](https://github.com/open-mmlab/mmpose/pull/1773), [#1780](https://github.com/open-mmlab/mmpose/pull/1780), [#1850](https://github.com/open-mmlab/mmpose/pull/1850), [#1868](https://github.com/open-mmlab/mmpose/pull/1868))\n- Fix local registry missing warnings ([#1849](https://github.com/open-mmlab/mmpose/pull/1849))\n- Remove deprecated scripts for model deployment ([#1845](https://github.com/open-mmlab/mmpose/pull/1845))\n- Fix a bug in input transformation in BaseHead ([#1843](https://github.com/open-mmlab/mmpose/pull/1843))\n- Fix an interface mismatch with MMDetection in webcam demo ([#1813](https://github.com/open-mmlab/mmpose/pull/1813))\n- Fix a bug in heatmap visualization that causes incorrect scale ([#1800](https://github.com/open-mmlab/mmpose/pull/1800))\n- Add model metafiles ([#1768](https://github.com/open-mmlab/mmpose/pull/1768))\n\n## **v1.0.0rc0 (14/10/2022)**\n\n**New Features**\n\n- Support 4 light-weight pose estimation algorithms: [SimCC](https://doi.org/10.48550/arxiv.2107.03332) (ECCV'2022), [Debias-IPR](https://openaccess.thecvf.com/content/ICCV2021/papers/Gu_Removing_the_Bias_of_Integral_Pose_Regression_ICCV_2021_paper.pdf) (ICCV'2021), [IPR](https://arxiv.org/abs/1711.08229) (ECCV'2018), and [DSNT](https://arxiv.org/abs/1801.07372v2) (ArXiv'2018) ([#1628](https://github.com/open-mmlab/mmpose/pull/1628))\n\n**Migrations**\n\n- Add Webcam API in MMPose 1.0 ([#1638](https://github.com/open-mmlab/mmpose/pull/1638), [#1662](https://github.com/open-mmlab/mmpose/pull/1662)) @Ben-Louis\n- Add codec for Associative Embedding (beta) ([#1603](https://github.com/open-mmlab/mmpose/pull/1603)) @ly015\n\n**Improvements**\n\n- Add a colab tutorial for MMPose 1.0 ([#1660](https://github.com/open-mmlab/mmpose/pull/1660)) @Tau-J\n- Add model index in config folder ([#1710](https://github.com/open-mmlab/mmpose/pull/1710), [#1709](https://github.com/open-mmlab/mmpose/pull/1709), [#1627](https://github.com/open-mmlab/mmpose/pull/1627)) @ly015, @Tau-J, @Ben-Louis\n- Update and improve documentation ([#1692](https://github.com/open-mmlab/mmpose/pull/1692), [#1656](https://github.com/open-mmlab/mmpose/pull/1656), [#1681](https://github.com/open-mmlab/mmpose/pull/1681), [#1677](https://github.com/open-mmlab/mmpose/pull/1677), [#1664](https://github.com/open-mmlab/mmpose/pull/1664), [#1659](https://github.com/open-mmlab/mmpose/pull/1659)) @Tau-J, @Ben-Louis, @liqikai9\n- Improve config structures and formats ([#1651](https://github.com/open-mmlab/mmpose/pull/1651)) @liqikai9\n\n**Bug Fixes**\n\n- Update mmengine version requirements ([#1715](https://github.com/open-mmlab/mmpose/pull/1715)) @Ben-Louis\n- Update dependencies of pre-commit hooks ([#1705](https://github.com/open-mmlab/mmpose/pull/1705)) @Ben-Louis\n- Fix mmcv version in DockerFile ([#1704](https://github.com/open-mmlab/mmpose/pull/1704))\n- Fix a bug in setting dataset metainfo in configs ([#1684](https://github.com/open-mmlab/mmpose/pull/1684)) @ly015\n- Fix a bug in UDP training ([#1682](https://github.com/open-mmlab/mmpose/pull/1682)) @liqikai9\n- Fix a bug in Dark decoding ([#1676](https://github.com/open-mmlab/mmpose/pull/1676)) @liqikai9\n- Fix bugs in visualization ([#1671](https://github.com/open-mmlab/mmpose/pull/1671), [#1668](https://github.com/open-mmlab/mmpose/pull/1668), [#1657](https://github.com/open-mmlab/mmpose/pull/1657)) @liqikai9, @Ben-Louis\n- Fix incorrect flops calculation ([#1669](https://github.com/open-mmlab/mmpose/pull/1669)) @liqikai9\n- Fix `tensor.tile` compatibility issue for pytorch 1.6 ([#1658](https://github.com/open-mmlab/mmpose/pull/1658)) @ly015\n- Fix compatibility with `MultilevelPixelData` ([#1647](https://github.com/open-mmlab/mmpose/pull/1647)) @liqikai9\n\n## **v1.0.0beta (1/09/2022)**\n\nWe are excited to announce the release of MMPose 1.0.0beta.\nMMPose 1.0.0beta is the first version of MMPose 1.x, a part of the OpenMMLab 2.0 projects.\nBuilt upon the new [training engine](https://github.com/open-mmlab/mmengine),\nMMPose 1.x unifies the interfaces of dataset, models, evaluation, and visualization with faster training and testing speed.\nIt also provide a general semi-supervised object detection framework, and more strong baselines.\n\n**Highlights**\n\n- **New engines**. MMPose 1.x is based on [MMEngine](https://github.com/open-mmlab/mmengine), which provides a general and powerful runner that allows more flexible customizations and significantly simplifies the entrypoints of high-level interfaces.\n\n- **Unified interfaces**. As a part of the OpenMMLab 2.0 projects, MMPose 1.x unifies and refactors the interfaces and internal logics of train, testing, datasets, models, evaluation, and visualization. All the OpenMMLab 2.0 projects share the same design in those interfaces and logics to allow the emergence of multi-task/modality algorithms.\n\n- **More documentation and tutorials**. We add a bunch of documentation and tutorials to help users get started more smoothly. Read it [here](https://mmpose.readthedocs.io/en/latest/).\n\n**Breaking Changes**\n\nIn this release, we made lots of major refactoring and modifications. Please refer to the [migration guide](../migration.md) for details and migration instructions.\n\n## **v0.28.1 (28/07/2022)**\n\nThis release is meant to fix the compatibility with the latest mmcv v1.6.1\n\n## **v0.28.0 (06/07/2022)**\n\n**Highlights**\n\n- Support [TCFormer](https://openaccess.thecvf.com/content/CVPR2022/html/Zeng_Not_All_Tokens_Are_Equal_Human-Centric_Visual_Analysis_via_Token_CVPR_2022_paper.html) backbone, CVPR'2022 ([#1447](https://github.com/open-mmlab/mmpose/pull/1447), [#1452](https://github.com/open-mmlab/mmpose/pull/1452)) @zengwang430521\n\n- Add [RLE](https://arxiv.org/abs/2107.11291) models on COCO dataset ([#1424](https://github.com/open-mmlab/mmpose/pull/1424)) @Indigo6, @Ben-Louis, @ly015\n\n- Update swin models with better performance ([#1467](https://github.com/open-mmlab/mmpose/pull/1434)) @jin-s13\n\n**New Features**\n\n- Support [TCFormer](https://openaccess.thecvf.com/content/CVPR2022/html/Zeng_Not_All_Tokens_Are_Equal_Human-Centric_Visual_Analysis_via_Token_CVPR_2022_paper.html) backbone, CVPR'2022 ([#1447](https://github.com/open-mmlab/mmpose/pull/1447), [#1452](https://github.com/open-mmlab/mmpose/pull/1452)) @zengwang430521\n\n- Add [RLE](https://arxiv.org/abs/2107.11291) models on COCO dataset ([#1424](https://github.com/open-mmlab/mmpose/pull/1424)) @Indigo6, @Ben-Louis, @ly015\n\n- Support layer decay optimizer constructor and learning rate decay optimizer constructor ([#1423](https://github.com/open-mmlab/mmpose/pull/1423)) @jin-s13\n\n**Improvements**\n\n- Improve documentation quality ([#1416](https://github.com/open-mmlab/mmpose/pull/1416), [#1421](https://github.com/open-mmlab/mmpose/pull/1421), [#1423](https://github.com/open-mmlab/mmpose/pull/1423), [#1426](https://github.com/open-mmlab/mmpose/pull/1426), [#1458](https://github.com/open-mmlab/mmpose/pull/1458), [#1463](https://github.com/open-mmlab/mmpose/pull/1463)) @ly015, @liqikai9\n\n- Support installation by [mim](https://github.com/open-mmlab/mim) ([#1425](https://github.com/open-mmlab/mmpose/pull/1425)) @liqikai9\n\n- Support PAVI logger ([#1434](https://github.com/open-mmlab/mmpose/pull/1434)) @EvelynWang-0423\n\n- Add progress bar for some demos ([#1454](https://github.com/open-mmlab/mmpose/pull/1454)) @liqikai9\n\n- Webcam API supports quick device setting in terminal commands ([#1466](https://github.com/open-mmlab/mmpose/pull/1466)) @ly015\n\n- Update swin models with better performance ([#1467](https://github.com/open-mmlab/mmpose/pull/1434)) @jin-s13\n\n**Bug Fixes**\n\n- Rename `custom_hooks_config` to `custom_hooks` in configs to align with the documentation ([#1427](https://github.com/open-mmlab/mmpose/pull/1427)) @ly015\n\n- Fix deadlock issue in Webcam API ([#1430](https://github.com/open-mmlab/mmpose/pull/1430)) @ly015\n\n- Fix smoother configs in video 3D demo ([#1457](https://github.com/open-mmlab/mmpose/pull/1457)) @ly015\n\n## **v0.27.0 (07/06/2022)**\n\n**Highlights**\n\n- Support hand gesture recognition\n\n  - Try the demo for gesture recognition\n  - Learn more about the algorithm, dataset and experiment results\n\n- Major upgrade to the Webcam API\n\n  - Tutorials (EN|zh_CN)\n  - [API Reference](https://mmpose.readthedocs.io/en/latest/api.html#mmpose-apis-webcam)\n  - Demo\n\n**New Features**\n\n- Support gesture recognition algorithm [MTUT](https://openaccess.thecvf.com/content_CVPR_2019/html/Abavisani_Improving_the_Performance_of_Unimodal_Dynamic_Hand-Gesture_Recognition_With_Multimodal_CVPR_2019_paper.html) CVPR'2019 and dataset [NVGesture](https://openaccess.thecvf.com/content_cvpr_2016/html/Molchanov_Online_Detection_and_CVPR_2016_paper.html) CVPR'2016 ([#1380](https://github.com/open-mmlab/mmpose/pull/1380)) @Ben-Louis\n\n**Improvements**\n\n- Upgrade Webcam API and related documents ([#1393](https://github.com/open-mmlab/mmpose/pull/1393), [#1404](https://github.com/open-mmlab/mmpose/pull/1404), [#1413](https://github.com/open-mmlab/mmpose/pull/1413)) @ly015\n\n- Support exporting COCO inference result without the annotation file ([#1368](https://github.com/open-mmlab/mmpose/pull/1368)) @liqikai9\n\n- Replace markdownlint with mdformat in CI to avoid the dependence on ruby [#1382](https://github.com/open-mmlab/mmpose/pull/1382) @ly015\n\n- Improve documentation quality ([#1385](https://github.com/open-mmlab/mmpose/pull/1385), [#1394](https://github.com/open-mmlab/mmpose/pull/1394), [#1395](https://github.com/open-mmlab/mmpose/pull/1395), [#1408](https://github.com/open-mmlab/mmpose/pull/1408)) @chubei-oppen, @ly015, @liqikai9\n\n**Bug Fixes**\n\n- Fix xywh->xyxy bbox conversion in dataset sanity check ([#1367](https://github.com/open-mmlab/mmpose/pull/1367)) @jin-s13\n\n- Fix a bug in two-stage 3D keypoint demo ([#1373](https://github.com/open-mmlab/mmpose/pull/1373)) @ly015\n\n- Fix out-dated settings in PVT configs ([#1376](https://github.com/open-mmlab/mmpose/pull/1376)) @ly015\n\n- Fix myst settings for document compiling ([#1381](https://github.com/open-mmlab/mmpose/pull/1381)) @ly015\n\n- Fix a bug in bbox transform ([#1384](https://github.com/open-mmlab/mmpose/pull/1384)) @ly015\n\n- Fix inaccurate description of `min_keypoints` in tracking apis ([#1398](https://github.com/open-mmlab/mmpose/pull/1398)) @pallgeuer\n\n- Fix warning with `torch.meshgrid` ([#1402](https://github.com/open-mmlab/mmpose/pull/1402)) @pallgeuer\n\n- Remove redundant transformer modules from `mmpose.datasets.backbones.utils` ([#1405](https://github.com/open-mmlab/mmpose/pull/1405)) @ly015\n\n## **v0.26.0 (05/05/2022)**\n\n**Highlights**\n\n- Support [RLE (Residual Log-likelihood Estimation)](https://arxiv.org/abs/2107.11291), ICCV'2021 ([#1259](https://github.com/open-mmlab/mmpose/pull/1259)) @Indigo6, @ly015\n\n- Support [Swin Transformer](https://arxiv.org/abs/2103.14030), ICCV'2021 ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @yumendecc, @ly015\n\n- Support [PVT](https://arxiv.org/abs/2102.12122), ICCV'2021 and [PVTv2](https://arxiv.org/abs/2106.13797), CVMJ'2022 ([#1343](https://github.com/open-mmlab/mmpose/pull/1343)) @zengwang430521\n\n- Speed up inference and reduce CPU usage by optimizing the pre-processing pipeline ([#1320](https://github.com/open-mmlab/mmpose/pull/1320)) @chenxinfeng4, @liqikai9\n\n**New Features**\n\n- Support [RLE (Residual Log-likelihood Estimation)](https://arxiv.org/abs/2107.11291), ICCV'2021 ([#1259](https://github.com/open-mmlab/mmpose/pull/1259)) @Indigo6, @ly015\n\n- Support [Swin Transformer](https://arxiv.org/abs/2103.14030), ICCV'2021 ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @yumendecc, @ly015\n\n- Support [PVT](https://arxiv.org/abs/2102.12122), ICCV'2021 and [PVTv2](https://arxiv.org/abs/2106.13797), CVMJ'2022 ([#1343](https://github.com/open-mmlab/mmpose/pull/1343)) @zengwang430521\n\n- Support [FPN](https://openaccess.thecvf.com/content_cvpr_2017/html/Lin_Feature_Pyramid_Networks_CVPR_2017_paper.html), CVPR'2017 ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @yumendecc, @ly015\n\n**Improvements**\n\n- Speed up inference and reduce CPU usage by optimizing the pre-processing pipeline ([#1320](https://github.com/open-mmlab/mmpose/pull/1320)) @chenxinfeng4, @liqikai9\n\n- Video demo supports models that requires multi-frame inputs ([#1300](https://github.com/open-mmlab/mmpose/pull/1300)) @liqikai9, @jin-s13\n\n- Update benchmark regression list ([#1328](https://github.com/open-mmlab/mmpose/pull/1328)) @ly015, @liqikai9\n\n- Remove unnecessary warnings in `TopDownPoseTrack18VideoDataset` ([#1335](https://github.com/open-mmlab/mmpose/pull/1335)) @liqikai9\n\n- Improve documentation quality ([#1313](https://github.com/open-mmlab/mmpose/pull/1313), [#1305](https://github.com/open-mmlab/mmpose/pull/1305)) @Ben-Louis, @ly015\n\n- Update deprecating settings in configs ([#1317](https://github.com/open-mmlab/mmpose/pull/1317)) @ly015\n\n**Bug Fixes**\n\n- Fix a bug in human skeleton grouping that may skip the matching process unexpectedly when `ignore_to_much` is True ([#1341](https://github.com/open-mmlab/mmpose/pull/1341)) @daixinghome\n\n- Fix a GPG key error that leads to CI failure ([#1354](https://github.com/open-mmlab/mmpose/pull/1354)) @ly015\n\n- Fix bugs in distributed training script ([#1338](https://github.com/open-mmlab/mmpose/pull/1338), [#1298](https://github.com/open-mmlab/mmpose/pull/1298)) @ly015\n\n- Fix an upstream bug in xtoccotools that causes incorrect AP(M) results ([#1308](https://github.com/open-mmlab/mmpose/pull/1308)) @jin-s13, @ly015\n\n- Fix indentiation errors in the colab tutorial ([#1298](https://github.com/open-mmlab/mmpose/pull/1298)) @YuanZi1501040205\n\n- Fix incompatible model weight initialization with other OpenMMLab codebases ([#1329](https://github.com/open-mmlab/mmpose/pull/1329)) @274869388\n\n- Fix HRNet FP16 checkpoints download URL ([#1309](https://github.com/open-mmlab/mmpose/pull/1309)) @YinAoXiong\n\n- Fix typos in `body3d_two_stage_video_demo.py` ([#1295](https://github.com/open-mmlab/mmpose/pull/1295)) @mucozcan\n\n**Breaking Changes**\n\n- Refactor bbox processing in datasets and pipelines ([#1311](https://github.com/open-mmlab/mmpose/pull/1311)) @ly015, @Ben-Louis\n\n- The bbox format conversion (xywh to center-scale) and random translation are moved from the dataset to the pipeline. The comparison between new and old version is as below:\n\nv0.26.0v0.25.0Dataset\n(e.g. [TopDownCOCODataset](https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/top_down/topdown_coco_dataset.py))\n\n... # Data sample only contains bbox rec.append({    'bbox': obj\\['clean_bbox\\]\\[:4\\],    ... })\n\n</td>\n\n<td  valign='top'>\n\n... # Convert bbox from xywh to center-scale center, scale = self.\\_xywh2cs(\\*obj\\['clean_bbox'\\]\\[:4\\]) # Data sample contains center and scale rec.append({    'bbox': obj\\['clean_bbox\\]\\[:4\\],    'center': center,    'scale': scale,    ... })\n\n</td>\n\n</tr>\n\n<tr>\n\n<th>Pipeline Config\n\n(e.g. [HRNet+COCO](https://github.com/open-mmlab/mmpose/blob/master/configs/body/2d_kpt_sview_rgb_img/topdown_heatmap/coco/hrnet_w32_coco_256x192.py))</th>\n\n<td valign='top'>\n\n... train_pipeline = \\[    dict(type='LoadImageFromFile'),    # Convert bbox from xywh to center-scale    dict(type='TopDownGetBboxCenterScale', padding=1.25),    # Randomly shift bbox center    dict(type='TopDownRandomShiftBboxCenter', shift_factor=0.16, prob=0.3),    ... \\]\n\n</td>\n\n<td valign='top'>\n\n... train_pipeline = \\[    dict(type='LoadImageFromFile'),    ... \\]\n\n</td>\n\n</tr>\n\n<tr>\n\n<th>Advantage</th>\n\n<td valign='top'>\n\n<li>Simpler data sample content</li>\n\n<li>Flexible bbox format conversion and augmentation</li>\n\n<li>Apply bbox random translation every epoch (instead of only applying once at the annotation loading)\n\n</td>\n\n<td valign='top'>-</td>\n\n</tr>\n\n<tr>\n\n<th>BC Breaking</th>\n\n<td valign='top'>The method `_xywh2cs` of dataset base classes (e.g. [Kpt2dSviewRgbImgTopDownDataset](https://github.com/open-mmlab/mmpose/blob/master/mmpose/datasets/datasets/base/kpt_2d_sview_rgb_img_top_down_dataset.py)) will be deprecated in the future. Custom datasets will need modifications to move the bbox format conversion to pipelines.</td>\n\n<td valign='top'>-</td>\n\n</tr>\n\n</tbody>\n\n</table>\n\n## **v0.25.0 (02/04/2022)**\n\n**Highlights**\n\n- Support Shelf and Campus datasets with pre-trained VoxelPose models, [\"3D Pictorial Structures for Multiple Human Pose Estimation\"](http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf), CVPR'2014 ([#1225](https://github.com/open-mmlab/mmpose/pull/1225)) @liqikai9, @wusize\n\n- Add `Smoother` module for temporal smoothing of the pose estimation with configurable filters ([#1127](https://github.com/open-mmlab/mmpose/pull/1127)) @ailingzengzzz, @ly015\n\n- Support SmoothNet for pose smoothing, [\"SmoothNet: A Plug-and-Play Network for Refining Human Poses in Videos\"](https://arxiv.org/abs/2112.13715), arXiv'2021 ([#1279](https://github.com/open-mmlab/mmpose/pull/1279)) @ailingzengzzz, @ly015\n\n- Add multiview 3D pose estimation demo ([#1270](https://github.com/open-mmlab/mmpose/pull/1270)) @wusize\n\n**New Features**\n\n- Support Shelf and Campus datasets with pre-trained VoxelPose models, [\"3D Pictorial Structures for Multiple Human Pose Estimation\"](http://campar.in.tum.de/pub/belagiannis2014cvpr/belagiannis2014cvpr.pdf), CVPR'2014 ([#1225](https://github.com/open-mmlab/mmpose/pull/1225)) @liqikai9, @wusize\n\n- Add `Smoother` module for temporal smoothing of the pose estimation with configurable filters ([#1127](https://github.com/open-mmlab/mmpose/pull/1127)) @ailingzengzzz, @ly015\n\n- Support SmoothNet for pose smoothing, [\"SmoothNet: A Plug-and-Play Network for Refining Human Poses in Videos\"](https://arxiv.org/abs/2112.13715), arXiv'2021 ([#1279](https://github.com/open-mmlab/mmpose/pull/1279)) @ailingzengzzz, @ly015\n\n- Add multiview 3D pose estimation demo ([#1270](https://github.com/open-mmlab/mmpose/pull/1270)) @wusize\n\n- Support multi-machine distributed training ([#1248](https://github.com/open-mmlab/mmpose/pull/1248)) @ly015\n\n**Improvements**\n\n- Update HRFormer configs and checkpoints with relative position bias ([#1245](https://github.com/open-mmlab/mmpose/pull/1245)) @zengwang430521\n\n- Support using different random seed for each distributed node ([#1257](https://github.com/open-mmlab/mmpose/pull/1257), [#1229](https://github.com/open-mmlab/mmpose/pull/1229)) @ly015\n\n- Improve documentation quality ([#1275](https://github.com/open-mmlab/mmpose/pull/1275), [#1255](https://github.com/open-mmlab/mmpose/pull/1255), [#1258](https://github.com/open-mmlab/mmpose/pull/1258), [#1249](https://github.com/open-mmlab/mmpose/pull/1249), [#1247](https://github.com/open-mmlab/mmpose/pull/1247), [#1240](https://github.com/open-mmlab/mmpose/pull/1240), [#1235](https://github.com/open-mmlab/mmpose/pull/1235)) @ly015, @jin-s13, @YoniChechik\n\n**Bug Fixes**\n\n- Fix keypoint index in RHD dataset meta information ([#1265](https://github.com/open-mmlab/mmpose/pull/1265)) @liqikai9\n\n- Fix pre-commit hook unexpected behavior on Windows ([#1282](https://github.com/open-mmlab/mmpose/pull/1282)) @liqikai9\n\n- Remove python-dev installation in CI ([#1276](https://github.com/open-mmlab/mmpose/pull/1276)) @ly015\n\n- Unify hyphens in argument names in tools and demos ([#1271](https://github.com/open-mmlab/mmpose/pull/1271)) @ly015\n\n- Fix ambiguous channel size in `channel_shuffle` that may cause exporting failure (#1242) @PINTO0309\n\n- Fix a bug in Webcam API that causes single-class detectors fail ([#1239](https://github.com/open-mmlab/mmpose/pull/1239)) @674106399\n\n- Fix the issue that `custom_hook` can not be set in configs ([#1236](https://github.com/open-mmlab/mmpose/pull/1236)) @bladrome\n\n- Fix incompatible MMCV version in DockerFile ([#raykindle](https://github.com/open-mmlab/mmpose/pull/raykindle))\n\n- Skip invisible joints in visualization ([#1228](https://github.com/open-mmlab/mmpose/pull/1228)) @womeier\n\n## **v0.24.0 (07/03/2022)**\n\n**Highlights**\n\n- Support HRFormer [\"HRFormer: High-Resolution Vision Transformer for Dense Predict\"](https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html), NeurIPS'2021 ([#1203](https://github.com/open-mmlab/mmpose/pull/1203)) @zengwang430521\n\n- Support Windows installation with pip ([#1213](https://github.com/open-mmlab/mmpose/pull/1213)) @jin-s13, @ly015\n\n- Add WebcamAPI documents ([#1187](https://github.com/open-mmlab/mmpose/pull/1187)) @ly015\n\n**New Features**\n\n- Support HRFormer [\"HRFormer: High-Resolution Vision Transformer for Dense Predict\"](https://proceedings.neurips.cc/paper/2021/hash/3bbfdde8842a5c44a0323518eec97cbe-Abstract.html), NeurIPS'2021 ([#1203](https://github.com/open-mmlab/mmpose/pull/1203)) @zengwang430521\n\n- Support Windows installation with pip ([#1213](https://github.com/open-mmlab/mmpose/pull/1213)) @jin-s13, @ly015\n\n- Support CPU training with mmcv \\< v1.4.4 ([#1161](https://github.com/open-mmlab/mmpose/pull/1161)) @EasonQYS, @ly015\n\n- Add \"Valentine Magic\" demo with WebcamAPI ([#1189](https://github.com/open-mmlab/mmpose/pull/1189), [#1191](https://github.com/open-mmlab/mmpose/pull/1191)) @liqikai9\n\n**Improvements**\n\n- Refactor multi-view 3D pose estimation framework towards better modularization and expansibility ([#1196](https://github.com/open-mmlab/mmpose/pull/1196)) @wusize\n\n- Add WebcamAPI documents and tutorials ([#1187](https://github.com/open-mmlab/mmpose/pull/1187)) @ly015\n\n- Refactor dataset evaluation interface to align with other OpenMMLab codebases ([#1209](https://github.com/open-mmlab/mmpose/pull/1209)) @ly015\n\n- Add deprecation message for deploy tools since [MMDeploy](https://github.com/open-mmlab/mmdeploy) has supported MMPose ([#1207](https://github.com/open-mmlab/mmpose/pull/1207)) @QwQ2000\n\n- Improve documentation quality ([#1206](https://github.com/open-mmlab/mmpose/pull/1206), [#1161](https://github.com/open-mmlab/mmpose/pull/1161)) @ly015\n\n- Switch to OpenMMLab official pre-commit-hook for copyright check ([#1214](https://github.com/open-mmlab/mmpose/pull/1214)) @ly015\n\n**Bug Fixes**\n\n- Fix hard-coded data collating and scattering in inference ([#1175](https://github.com/open-mmlab/mmpose/pull/1175)) @ly015\n\n- Fix model configs on JHMDB dataset ([#1188](https://github.com/open-mmlab/mmpose/pull/1188)) @jin-s13\n\n- Fix area calculation in pose tracking inference ([#1197](https://github.com/open-mmlab/mmpose/pull/1197)) @pallgeuer\n\n- Fix registry scope conflict of module wrapper ([#1204](https://github.com/open-mmlab/mmpose/pull/1204)) @ly015\n\n- Update MMCV installation in CI and documents ([#1205](https://github.com/open-mmlab/mmpose/pull/1205))\n\n- Fix incorrect color channel order in visualization functions ([#1212](https://github.com/open-mmlab/mmpose/pull/1212)) @ly015\n\n## **v0.23.0 (11/02/2022)**\n\n**Highlights**\n\n- Add [MMPose Webcam API](https://github.com/open-mmlab/mmpose/tree/master/tools/webcam): A simple yet powerful tools to develop interactive webcam applications with MMPose functions. ([#1178](https://github.com/open-mmlab/mmpose/pull/1178), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1143](https://github.com/open-mmlab/mmpose/pull/1143), [#1094](https://github.com/open-mmlab/mmpose/pull/1094), [#1133](https://github.com/open-mmlab/mmpose/pull/1133), [#1098](https://github.com/open-mmlab/mmpose/pull/1098), [#1160](https://github.com/open-mmlab/mmpose/pull/1160)) @ly015, @jin-s13, @liqikai9, @wusize, @luminxu, @zengwang430521 @mzr1996\n\n**New Features**\n\n- Add [MMPose Webcam API](https://github.com/open-mmlab/mmpose/tree/master/tools/webcam): A simple yet powerful tools to develop interactive webcam applications with MMPose functions. ([#1178](https://github.com/open-mmlab/mmpose/pull/1178), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1173](https://github.com/open-mmlab/mmpose/pull/1173), [#1143](https://github.com/open-mmlab/mmpose/pull/1143), [#1094](https://github.com/open-mmlab/mmpose/pull/1094), [#1133](https://github.com/open-mmlab/mmpose/pull/1133), [#1098](https://github.com/open-mmlab/mmpose/pull/1098), [#1160](https://github.com/open-mmlab/mmpose/pull/1160)) @ly015, @jin-s13, @liqikai9, @wusize, @luminxu, @zengwang430521 @mzr1996\n\n- Support ConcatDataset ([#1139](https://github.com/open-mmlab/mmpose/pull/1139)) @Canwang-sjtu\n\n- Support CPU training and testing ([#1157](https://github.com/open-mmlab/mmpose/pull/1157)) @ly015\n\n**Improvements**\n\n- Add multi-processing configurations to speed up distributed training and testing ([#1146](https://github.com/open-mmlab/mmpose/pull/1146)) @ly015\n\n- Add default runtime config ([#1145](https://github.com/open-mmlab/mmpose/pull/1145))\n\n- Upgrade isort in pre-commit hook ([#1179](https://github.com/open-mmlab/mmpose/pull/1179)) @liqikai9\n\n- Update README and documents ([#1171](https://github.com/open-mmlab/mmpose/pull/1171), [#1167](https://github.com/open-mmlab/mmpose/pull/1167), [#1153](https://github.com/open-mmlab/mmpose/pull/1153), [#1149](https://github.com/open-mmlab/mmpose/pull/1149), [#1148](https://github.com/open-mmlab/mmpose/pull/1148), [#1147](https://github.com/open-mmlab/mmpose/pull/1147), [#1140](https://github.com/open-mmlab/mmpose/pull/1140)) @jin-s13, @wusize, @TommyZihao, @ly015\n\n**Bug Fixes**\n\n- Fix undeterministic behavior in pre-commit hooks ([#1136](https://github.com/open-mmlab/mmpose/pull/1136)) @jin-s13\n\n- Deprecate the support for \"python setup.py test\" ([#1179](https://github.com/open-mmlab/mmpose/pull/1179)) @ly015\n\n- Fix incompatible settings with MMCV on HSigmoid default parameters ([#1132](https://github.com/open-mmlab/mmpose/pull/1132)) @ly015\n\n- Fix albumentation installation ([#1184](https://github.com/open-mmlab/mmpose/pull/1184)) @BIGWangYuDong\n\n## **v0.22.0 (04/01/2022)**\n\n**Highlights**\n\n- Support VoxelPose [\"VoxelPose: Towards Multi-Camera 3D Human Pose Estimation in Wild Environment\"](https://arxiv.org/abs/2004.06239), ECCV'2020 ([#1050](https://github.com/open-mmlab/mmpose/pull/1050)) @wusize\n\n- Support Soft Wing loss [\"Structure-Coherent Deep Feature Learning for Robust Face Alignment\"](https://linchunze.github.io/papers/TIP21_Structure_coherent_FA.pdf), TIP'2021 ([#1077](https://github.com/open-mmlab/mmpose/pull/1077)) @jin-s13\n\n- Support Adaptive Wing loss [\"Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression\"](https://arxiv.org/abs/1904.07399), ICCV'2019 ([#1072](https://github.com/open-mmlab/mmpose/pull/1072)) @jin-s13\n\n**New Features**\n\n- Support VoxelPose [\"VoxelPose: Towards Multi-Camera 3D Human Pose Estimation in Wild Environment\"](https://arxiv.org/abs/2004.06239), ECCV'2020 ([#1050](https://github.com/open-mmlab/mmpose/pull/1050)) @wusize\n\n- Support Soft Wing loss [\"Structure-Coherent Deep Feature Learning for Robust Face Alignment\"](https://linchunze.github.io/papers/TIP21_Structure_coherent_FA.pdf), TIP'2021 ([#1077](https://github.com/open-mmlab/mmpose/pull/1077)) @jin-s13\n\n- Support Adaptive Wing loss [\"Adaptive Wing Loss for Robust Face Alignment via Heatmap Regression\"](https://arxiv.org/abs/1904.07399), ICCV'2019 ([#1072](https://github.com/open-mmlab/mmpose/pull/1072)) @jin-s13\n\n- Add LiteHRNet-18 Checkpoints trained on COCO. ([#1120](https://github.com/open-mmlab/mmpose/pull/1120)) @jin-s13\n\n**Improvements**\n\n- Improve documentation quality ([#1115](https://github.com/open-mmlab/mmpose/pull/1115), [#1111](https://github.com/open-mmlab/mmpose/pull/1111), [#1105](https://github.com/open-mmlab/mmpose/pull/1105), [#1087](https://github.com/open-mmlab/mmpose/pull/1087), [#1086](https://github.com/open-mmlab/mmpose/pull/1086), [#1085](https://github.com/open-mmlab/mmpose/pull/1085), [#1084](https://github.com/open-mmlab/mmpose/pull/1084), [#1083](https://github.com/open-mmlab/mmpose/pull/1083), [#1124](https://github.com/open-mmlab/mmpose/pull/1124), [#1070](https://github.com/open-mmlab/mmpose/pull/1070), [#1068](https://github.com/open-mmlab/mmpose/pull/1068)) @jin-s13, @liqikai9, @ly015\n\n- Support CircleCI ([#1074](https://github.com/open-mmlab/mmpose/pull/1074)) @ly015\n\n- Skip unit tests in CI when only document files were changed ([#1074](https://github.com/open-mmlab/mmpose/pull/1074), [#1041](https://github.com/open-mmlab/mmpose/pull/1041)) @QwQ2000, @ly015\n\n- Support file_client_args in LoadImageFromFile ([#1076](https://github.com/open-mmlab/mmpose/pull/1076)) @jin-s13\n\n**Bug Fixes**\n\n- Fix a bug in Dark UDP postprocessing that causes error when the channel number is large. ([#1079](https://github.com/open-mmlab/mmpose/pull/1079), [#1116](https://github.com/open-mmlab/mmpose/pull/1116)) @X00123, @jin-s13\n\n- Fix hard-coded `sigmas` in bottom-up image demo ([#1107](https://github.com/open-mmlab/mmpose/pull/1107), [#1101](https://github.com/open-mmlab/mmpose/pull/1101)) @chenxinfeng4, @liqikai9\n\n- Fix unstable checks in unit tests ([#1112](https://github.com/open-mmlab/mmpose/pull/1112)) @ly015\n\n- Do not destroy NULL windows if `args.show==False` in demo scripts ([#1104](https://github.com/open-mmlab/mmpose/pull/1104)) @bladrome\n\n## **v0.21.0 (06/12/2021)**\n\n**Highlights**\n\n- Support [\"Learning Temporal Pose Estimation from Sparsely-Labeled Videos\"](https://arxiv.org/abs/1906.04016), NeurIPS'2019 ([#932](https://github.com/open-mmlab/mmpose/pull/932), [#1006](https://github.com/open-mmlab/mmpose/pull/1006), [#1036](https://github.com/open-mmlab/mmpose/pull/1036), [#1060](https://github.com/open-mmlab/mmpose/pull/1060)) @liqikai9\n\n- Add ViPNAS-MobileNetV3 models ([#1025](https://github.com/open-mmlab/mmpose/pull/1025)) @luminxu, @jin-s13\n\n- Add inference speed benchmark ([#1028](https://github.com/open-mmlab/mmpose/pull/1028), [#1034](https://github.com/open-mmlab/mmpose/pull/1034), [#1044](https://github.com/open-mmlab/mmpose/pull/1044)) @liqikai9\n\n**New Features**\n\n- Support [\"Learning Temporal Pose Estimation from Sparsely-Labeled Videos\"](https://arxiv.org/abs/1906.04016), NeurIPS'2019 ([#932](https://github.com/open-mmlab/mmpose/pull/932), [#1006](https://github.com/open-mmlab/mmpose/pull/1006), [#1036](https://github.com/open-mmlab/mmpose/pull/1036)) @liqikai9\n\n- Add ViPNAS-MobileNetV3 models ([#1025](https://github.com/open-mmlab/mmpose/pull/1025)) @luminxu, @jin-s13\n\n- Add light-weight top-down models for whole-body keypoint detection ([#1009](https://github.com/open-mmlab/mmpose/pull/1009), [#1020](https://github.com/open-mmlab/mmpose/pull/1020), [#1055](https://github.com/open-mmlab/mmpose/pull/1055)) @luminxu, @ly015\n\n- Add HRNet checkpoints with various settings on PoseTrack18 ([#1035](https://github.com/open-mmlab/mmpose/pull/1035)) @liqikai9\n\n**Improvements**\n\n- Add inference speed benchmark ([#1028](https://github.com/open-mmlab/mmpose/pull/1028), [#1034](https://github.com/open-mmlab/mmpose/pull/1034), [#1044](https://github.com/open-mmlab/mmpose/pull/1044)) @liqikai9\n\n- Update model metafile format ([#1001](https://github.com/open-mmlab/mmpose/pull/1001)) @ly015\n\n- Support minus output feature index in mobilenet_v3 ([#1005](https://github.com/open-mmlab/mmpose/pull/1005)) @luminxu\n\n- Improve documentation quality ([#1018](https://github.com/open-mmlab/mmpose/pull/1018), [#1026](https://github.com/open-mmlab/mmpose/pull/1026), [#1027](https://github.com/open-mmlab/mmpose/pull/1027), [#1031](https://github.com/open-mmlab/mmpose/pull/1031), [#1038](https://github.com/open-mmlab/mmpose/pull/1038), [#1046](https://github.com/open-mmlab/mmpose/pull/1046), [#1056](https://github.com/open-mmlab/mmpose/pull/1056), [#1057](https://github.com/open-mmlab/mmpose/pull/1057)) @edybk, @luminxu, @ly015, @jin-s13\n\n- Set default random seed in training initialization ([#1030](https://github.com/open-mmlab/mmpose/pull/1030)) @ly015\n\n- Skip CI when only specific files changed ([#1041](https://github.com/open-mmlab/mmpose/pull/1041), [#1059](https://github.com/open-mmlab/mmpose/pull/1059)) @QwQ2000, @ly015\n\n- Automatically cancel uncompleted action runs when new commit arrives ([#1053](https://github.com/open-mmlab/mmpose/pull/1053)) @ly015\n\n**Bug Fixes**\n\n- Update pose tracking demo to be compatible with latest mmtracking ([#1014](https://github.com/open-mmlab/mmpose/pull/1014)) @jin-s13\n\n- Fix symlink creation failure when installed in Windows environments ([#1039](https://github.com/open-mmlab/mmpose/pull/1039)) @QwQ2000\n\n- Fix AP-10K dataset sigmas ([#1040](https://github.com/open-mmlab/mmpose/pull/1040)) @jin-s13\n\n## **v0.20.0 (01/11/2021)**\n\n**Highlights**\n\n- Add AP-10K dataset for animal pose estimation ([#987](https://github.com/open-mmlab/mmpose/pull/987)) @Annbless, @AlexTheBad, @jin-s13, @ly015\n\n- Support TorchServe ([#979](https://github.com/open-mmlab/mmpose/pull/979)) @ly015\n\n**New Features**\n\n- Add AP-10K dataset for animal pose estimation ([#987](https://github.com/open-mmlab/mmpose/pull/987)) @Annbless, @AlexTheBad, @jin-s13, @ly015\n\n- Add HRNetv2 checkpoints on 300W and COFW datasets ([#980](https://github.com/open-mmlab/mmpose/pull/980)) @jin-s13\n\n- Support TorchServe ([#979](https://github.com/open-mmlab/mmpose/pull/979)) @ly015\n\n**Bug Fixes**\n\n- Fix some deprecated or risky settings in configs ([#963](https://github.com/open-mmlab/mmpose/pull/963), [#976](https://github.com/open-mmlab/mmpose/pull/976), [#992](https://github.com/open-mmlab/mmpose/pull/992)) @jin-s13, @wusize\n\n- Fix issues of default arguments of training and testing scripts ([#970](https://github.com/open-mmlab/mmpose/pull/970), [#985](https://github.com/open-mmlab/mmpose/pull/985)) @liqikai9, @wusize\n\n- Fix heatmap and tag size mismatch in bottom-up with UDP ([#994](https://github.com/open-mmlab/mmpose/pull/994)) @wusize\n\n- Fix python3.9 installation in CI ([#983](https://github.com/open-mmlab/mmpose/pull/983)) @ly015\n\n- Fix model zoo document integrity issue ([#990](https://github.com/open-mmlab/mmpose/pull/990)) @jin-s13\n\n**Improvements**\n\n- Support non-square input shape for bottom-up ([#991](https://github.com/open-mmlab/mmpose/pull/991)) @wusize\n\n- Add image and video resources for demo ([#971](https://github.com/open-mmlab/mmpose/pull/971)) @liqikai9\n\n- Use CUDA docker images to accelerate CI ([#973](https://github.com/open-mmlab/mmpose/pull/973)) @ly015\n\n- Add codespell hook and fix detected typos ([#977](https://github.com/open-mmlab/mmpose/pull/977)) @ly015\n\n## **v0.19.0 (08/10/2021)**\n\n**Highlights**\n\n- Add models for Associative Embedding with Hourglass network backbone ([#906](https://github.com/open-mmlab/mmpose/pull/906), [#955](https://github.com/open-mmlab/mmpose/pull/955)) @jin-s13, @luminxu\n\n- Support COCO-Wholebody-Face and COCO-Wholebody-Hand datasets ([#813](https://github.com/open-mmlab/mmpose/pull/813)) @jin-s13, @innerlee, @luminxu\n\n- Upgrade dataset interface ([#901](https://github.com/open-mmlab/mmpose/pull/901), [#924](https://github.com/open-mmlab/mmpose/pull/924)) @jin-s13, @innerlee, @ly015, @liqikai9\n\n- New style of documentation ([#945](https://github.com/open-mmlab/mmpose/pull/945)) @ly015\n\n**New Features**\n\n- Add models for Associative Embedding with Hourglass network backbone ([#906](https://github.com/open-mmlab/mmpose/pull/906), [#955](https://github.com/open-mmlab/mmpose/pull/955)) @jin-s13, @luminxu\n\n- Support COCO-Wholebody-Face and COCO-Wholebody-Hand datasets ([#813](https://github.com/open-mmlab/mmpose/pull/813)) @jin-s13, @innerlee, @luminxu\n\n- Add pseudo-labeling tool to generate COCO style keypoint annotations with given bounding boxes ([#928](https://github.com/open-mmlab/mmpose/pull/928)) @soltkreig\n\n- New style of documentation ([#945](https://github.com/open-mmlab/mmpose/pull/945)) @ly015\n\n**Bug Fixes**\n\n- Fix segmentation parsing in Macaque dataset preprocessing ([#948](https://github.com/open-mmlab/mmpose/pull/948)) @jin-s13\n\n- Fix dependencies that may lead to CI failure in downstream projects ([#936](https://github.com/open-mmlab/mmpose/pull/936), [#953](https://github.com/open-mmlab/mmpose/pull/953)) @RangiLyu, @ly015\n\n- Fix keypoint order in Human3.6M dataset ([#940](https://github.com/open-mmlab/mmpose/pull/940)) @ttxskk\n\n- Fix unstable image loading for Interhand2.6M ([#913](https://github.com/open-mmlab/mmpose/pull/913)) @zengwang430521\n\n**Improvements**\n\n- Upgrade dataset interface ([#901](https://github.com/open-mmlab/mmpose/pull/901), [#924](https://github.com/open-mmlab/mmpose/pull/924)) @jin-s13, @innerlee, @ly015, @liqikai9\n\n- Improve demo usability and stability ([#908](https://github.com/open-mmlab/mmpose/pull/908), [#934](https://github.com/open-mmlab/mmpose/pull/934)) @ly015\n\n- Standardize model metafile format ([#941](https://github.com/open-mmlab/mmpose/pull/941)) @ly015\n\n- Support `persistent_worker` and several other arguments in configs ([#946](https://github.com/open-mmlab/mmpose/pull/946)) @jin-s13\n\n- Use MMCV root model registry to enable cross-project module building ([#935](https://github.com/open-mmlab/mmpose/pull/935)) @RangiLyu\n\n- Improve the document quality ([#916](https://github.com/open-mmlab/mmpose/pull/916), [#909](https://github.com/open-mmlab/mmpose/pull/909), [#942](https://github.com/open-mmlab/mmpose/pull/942), [#913](https://github.com/open-mmlab/mmpose/pull/913), [#956](https://github.com/open-mmlab/mmpose/pull/956)) @jin-s13, @ly015, @bit-scientist, @zengwang430521\n\n- Improve pull request template ([#952](https://github.com/open-mmlab/mmpose/pull/952), [#954](https://github.com/open-mmlab/mmpose/pull/954)) @ly015\n\n**Breaking Changes**\n\n- Upgrade dataset interface ([#901](https://github.com/open-mmlab/mmpose/pull/901)) @jin-s13, @innerlee, @ly015\n\n## **v0.18.0 (01/09/2021)**\n\n**Bug Fixes**\n\n- Fix redundant model weight loading in pytorch-to-onnx conversion ([#850](https://github.com/open-mmlab/mmpose/pull/850)) @ly015\n\n- Fix a bug in update_model_index.py that may cause pre-commit hook failure([#866](https://github.com/open-mmlab/mmpose/pull/866)) @ly015\n\n- Fix a bug in interhand_3d_head ([#890](https://github.com/open-mmlab/mmpose/pull/890)) @zengwang430521\n\n- Fix pose tracking demo failure caused by out-of-date configs ([#891](https://github.com/open-mmlab/mmpose/pull/891))\n\n**Improvements**\n\n- Add automatic benchmark regression tools ([#849](https://github.com/open-mmlab/mmpose/pull/849), [#880](https://github.com/open-mmlab/mmpose/pull/880), [#885](https://github.com/open-mmlab/mmpose/pull/885)) @liqikai9, @ly015\n\n- Add copyright information and checking hook ([#872](https://github.com/open-mmlab/mmpose/pull/872))\n\n- Add PR template ([#875](https://github.com/open-mmlab/mmpose/pull/875)) @ly015\n\n- Add citation information ([#876](https://github.com/open-mmlab/mmpose/pull/876)) @ly015\n\n- Add python3.9 in CI ([#877](https://github.com/open-mmlab/mmpose/pull/877), [#883](https://github.com/open-mmlab/mmpose/pull/883)) @ly015\n\n- Improve the quality of the documents ([#845](https://github.com/open-mmlab/mmpose/pull/845), [#845](https://github.com/open-mmlab/mmpose/pull/845), [#848](https://github.com/open-mmlab/mmpose/pull/848), [#867](https://github.com/open-mmlab/mmpose/pull/867), [#870](https://github.com/open-mmlab/mmpose/pull/870), [#873](https://github.com/open-mmlab/mmpose/pull/873), [#896](https://github.com/open-mmlab/mmpose/pull/896)) @jin-s13, @ly015, @zhiqwang\n\n## **v0.17.0 (06/08/2021)**\n\n**Highlights**\n\n1. Support [\"Lite-HRNet: A Lightweight High-Resolution Network\"](https://arxiv.org/abs/2104.06403) CVPR'2021 ([#733](https://github.com/open-mmlab/mmpose/pull/733),[#800](https://github.com/open-mmlab/mmpose/pull/800)) @jin-s13\n\n2. Add 3d body mesh demo ([#771](https://github.com/open-mmlab/mmpose/pull/771)) @zengwang430521\n\n3. Add Chinese documentation ([#787](https://github.com/open-mmlab/mmpose/pull/787), [#798](https://github.com/open-mmlab/mmpose/pull/798), [#799](https://github.com/open-mmlab/mmpose/pull/799), [#802](https://github.com/open-mmlab/mmpose/pull/802), [#804](https://github.com/open-mmlab/mmpose/pull/804), [#805](https://github.com/open-mmlab/mmpose/pull/805), [#815](https://github.com/open-mmlab/mmpose/pull/815), [#816](https://github.com/open-mmlab/mmpose/pull/816), [#817](https://github.com/open-mmlab/mmpose/pull/817), [#819](https://github.com/open-mmlab/mmpose/pull/819), [#839](https://github.com/open-mmlab/mmpose/pull/839)) @ly015, @luminxu, @jin-s13, @liqikai9, @zengwang430521\n\n4. Add Colab Tutorial ([#834](https://github.com/open-mmlab/mmpose/pull/834)) @ly015\n\n**New Features**\n\n- Support [\"Lite-HRNet: A Lightweight High-Resolution Network\"](https://arxiv.org/abs/2104.06403) CVPR'2021 ([#733](https://github.com/open-mmlab/mmpose/pull/733),[#800](https://github.com/open-mmlab/mmpose/pull/800)) @jin-s13\n\n- Add 3d body mesh demo ([#771](https://github.com/open-mmlab/mmpose/pull/771)) @zengwang430521\n\n- Add Chinese documentation ([#787](https://github.com/open-mmlab/mmpose/pull/787), [#798](https://github.com/open-mmlab/mmpose/pull/798), [#799](https://github.com/open-mmlab/mmpose/pull/799), [#802](https://github.com/open-mmlab/mmpose/pull/802), [#804](https://github.com/open-mmlab/mmpose/pull/804), [#805](https://github.com/open-mmlab/mmpose/pull/805), [#815](https://github.com/open-mmlab/mmpose/pull/815), [#816](https://github.com/open-mmlab/mmpose/pull/816), [#817](https://github.com/open-mmlab/mmpose/pull/817), [#819](https://github.com/open-mmlab/mmpose/pull/819), [#839](https://github.com/open-mmlab/mmpose/pull/839)) @ly015, @luminxu, @jin-s13, @liqikai9, @zengwang430521\n\n- Add Colab Tutorial ([#834](https://github.com/open-mmlab/mmpose/pull/834)) @ly015\n\n- Support training for InterHand v1.0 dataset ([#761](https://github.com/open-mmlab/mmpose/pull/761)) @zengwang430521\n\n**Bug Fixes**\n\n- Fix mpii pckh@0.1 index ([#773](https://github.com/open-mmlab/mmpose/pull/773)) @jin-s13\n\n- Fix multi-node distributed test ([#818](https://github.com/open-mmlab/mmpose/pull/818)) @ly015\n\n- Fix docstring and init_weights error of ShuffleNetV1 ([#814](https://github.com/open-mmlab/mmpose/pull/814)) @Junjun2016\n\n- Fix imshow_bbox error when input bboxes is empty ([#796](https://github.com/open-mmlab/mmpose/pull/796)) @ly015\n\n- Fix model zoo doc generation ([#778](https://github.com/open-mmlab/mmpose/pull/778)) @ly015\n\n- Fix typo ([#767](https://github.com/open-mmlab/mmpose/pull/767)), ([#780](https://github.com/open-mmlab/mmpose/pull/780), [#782](https://github.com/open-mmlab/mmpose/pull/782)) @ly015, @jin-s13\n\n**Breaking Changes**\n\n- Use MMCV EvalHook ([#686](https://github.com/open-mmlab/mmpose/pull/686)) @ly015\n\n**Improvements**\n\n- Add pytest.ini and fix docstring ([#812](https://github.com/open-mmlab/mmpose/pull/812)) @jin-s13\n\n- Update MSELoss ([#829](https://github.com/open-mmlab/mmpose/pull/829)) @Ezra-Yu\n\n- Move process_mmdet_results into inference.py ([#831](https://github.com/open-mmlab/mmpose/pull/831)) @ly015\n\n- Update resource limit ([#783](https://github.com/open-mmlab/mmpose/pull/783)) @jin-s13\n\n- Use COCO 2D pose model in 3D demo examples ([#785](https://github.com/open-mmlab/mmpose/pull/785)) @ly015\n\n- Change model zoo titles in the doc from center-aligned to left-aligned ([#792](https://github.com/open-mmlab/mmpose/pull/792), [#797](https://github.com/open-mmlab/mmpose/pull/797)) @ly015\n\n- Support MIM ([#706](https://github.com/open-mmlab/mmpose/pull/706), [#794](https://github.com/open-mmlab/mmpose/pull/794)) @ly015\n\n- Update out-of-date configs ([#827](https://github.com/open-mmlab/mmpose/pull/827)) @jin-s13\n\n- Remove opencv-python-headless dependency by albumentations ([#833](https://github.com/open-mmlab/mmpose/pull/833)) @ly015\n\n- Update QQ QR code in README_CN.md ([#832](https://github.com/open-mmlab/mmpose/pull/832)) @ly015\n\n## **v0.16.0 (02/07/2021)**\n\n**Highlights**\n\n1. Support [\"ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\"](https://arxiv.org/abs/2105.10154) CVPR'2021 ([#742](https://github.com/open-mmlab/mmpose/pull/742),[#755](https://github.com/open-mmlab/mmpose/pull/755)).\n\n2. Support MPI-INF-3DHP dataset ([#683](https://github.com/open-mmlab/mmpose/pull/683),[#746](https://github.com/open-mmlab/mmpose/pull/746),[#751](https://github.com/open-mmlab/mmpose/pull/751)).\n\n3. Add webcam demo tool ([#729](https://github.com/open-mmlab/mmpose/pull/729))\n\n4. Add 3d body and hand pose estimation demo ([#704](https://github.com/open-mmlab/mmpose/pull/704), [#727](https://github.com/open-mmlab/mmpose/pull/727)).\n\n**New Features**\n\n- Support [\"ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\"](https://arxiv.org/abs/2105.10154) CVPR'2021 ([#742](https://github.com/open-mmlab/mmpose/pull/742),[#755](https://github.com/open-mmlab/mmpose/pull/755))\n\n- Support MPI-INF-3DHP dataset ([#683](https://github.com/open-mmlab/mmpose/pull/683),[#746](https://github.com/open-mmlab/mmpose/pull/746),[#751](https://github.com/open-mmlab/mmpose/pull/751))\n\n- Support Webcam demo ([#729](https://github.com/open-mmlab/mmpose/pull/729))\n\n- Support Interhand 3d demo ([#704](https://github.com/open-mmlab/mmpose/pull/704))\n\n- Support 3d pose video demo ([#727](https://github.com/open-mmlab/mmpose/pull/727))\n\n- Support H36m dataset for 2d pose estimation ([#709](https://github.com/open-mmlab/mmpose/pull/709), [#735](https://github.com/open-mmlab/mmpose/pull/735))\n\n- Add scripts to generate mim metafile ([#749](https://github.com/open-mmlab/mmpose/pull/749))\n\n**Bug Fixes**\n\n- Fix typos ([#692](https://github.com/open-mmlab/mmpose/pull/692),[#696](https://github.com/open-mmlab/mmpose/pull/696),[#697](https://github.com/open-mmlab/mmpose/pull/697),[#698](https://github.com/open-mmlab/mmpose/pull/698),[#712](https://github.com/open-mmlab/mmpose/pull/712),[#718](https://github.com/open-mmlab/mmpose/pull/718),[#728](https://github.com/open-mmlab/mmpose/pull/728))\n\n- Change model download links from `http` to `https` ([#716](https://github.com/open-mmlab/mmpose/pull/716))\n\n**Breaking Changes**\n\n- Switch to MMCV MODEL_REGISTRY ([#669](https://github.com/open-mmlab/mmpose/pull/669))\n\n**Improvements**\n\n- Refactor MeshMixDataset ([#752](https://github.com/open-mmlab/mmpose/pull/752))\n\n- Rename 'GaussianHeatMap' to 'GaussianHeatmap' ([#745](https://github.com/open-mmlab/mmpose/pull/745))\n\n- Update out-of-date configs ([#734](https://github.com/open-mmlab/mmpose/pull/734))\n\n- Improve compatibility for breaking changes ([#731](https://github.com/open-mmlab/mmpose/pull/731))\n\n- Enable to control radius and thickness in visualization ([#722](https://github.com/open-mmlab/mmpose/pull/722))\n\n- Add regex dependency ([#720](https://github.com/open-mmlab/mmpose/pull/720))\n\n## **v0.15.0 (02/06/2021)**\n\n**Highlights**\n\n1. Support 3d video pose estimation (VideoPose3D).\n\n2. Support 3d hand pose estimation (InterNet).\n\n3. Improve presentation of modelzoo.\n\n**New Features**\n\n- Support \"InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose Estimation from a Single RGB Image\" (ECCV‘20) ([#624](https://github.com/open-mmlab/mmpose/pull/624))\n\n- Support \"3D human pose estimation in video with temporal convolutions and semi-supervised training\" (CVPR'19)  ([#602](https://github.com/open-mmlab/mmpose/pull/602), [#681](https://github.com/open-mmlab/mmpose/pull/681))\n\n- Support 3d pose estimation demo ([#653](https://github.com/open-mmlab/mmpose/pull/653), [#670](https://github.com/open-mmlab/mmpose/pull/670))\n\n- Support bottom-up whole-body pose estimation ([#689](https://github.com/open-mmlab/mmpose/pull/689))\n\n- Support mmcli ([#634](https://github.com/open-mmlab/mmpose/pull/634))\n\n**Bug Fixes**\n\n- Fix opencv compatibility ([#635](https://github.com/open-mmlab/mmpose/pull/635))\n\n- Fix demo with UDP ([#637](https://github.com/open-mmlab/mmpose/pull/637))\n\n- Fix bottom-up model onnx conversion ([#680](https://github.com/open-mmlab/mmpose/pull/680))\n\n- Fix `GPU_IDS` in distributed training ([#668](https://github.com/open-mmlab/mmpose/pull/668))\n\n- Fix MANIFEST.in ([#641](https://github.com/open-mmlab/mmpose/pull/641), [#657](https://github.com/open-mmlab/mmpose/pull/657))\n\n- Fix docs ([#643](https://github.com/open-mmlab/mmpose/pull/643),[#684](https://github.com/open-mmlab/mmpose/pull/684),[#688](https://github.com/open-mmlab/mmpose/pull/688),[#690](https://github.com/open-mmlab/mmpose/pull/690),[#692](https://github.com/open-mmlab/mmpose/pull/692))\n\n**Breaking Changes**\n\n- Reorganize configs by tasks, algorithms, datasets, and techniques ([#647](https://github.com/open-mmlab/mmpose/pull/647))\n\n- Rename heads and detectors ([#667](https://github.com/open-mmlab/mmpose/pull/667))\n\n**Improvements**\n\n- Add `radius` and `thickness` parameters in visualization ([#638](https://github.com/open-mmlab/mmpose/pull/638))\n\n- Add `trans_prob` parameter in `TopDownRandomTranslation` ([#650](https://github.com/open-mmlab/mmpose/pull/650))\n\n- Switch to `MMCV MODEL_REGISTRY` ([#669](https://github.com/open-mmlab/mmpose/pull/669))\n\n- Update dependencies ([#674](https://github.com/open-mmlab/mmpose/pull/674), [#676](https://github.com/open-mmlab/mmpose/pull/676))\n\n## **v0.14.0 (06/05/2021)**\n\n**Highlights**\n\n1. Support animal pose estimation with 7 popular datasets.\n\n2. Support \"A simple yet effective baseline for 3d human pose estimation\" (ICCV'17).\n\n**New Features**\n\n- Support \"A simple yet effective baseline for 3d human pose estimation\" (ICCV'17)  ([#554](https://github.com/open-mmlab/mmpose/pull/554),[#558](https://github.com/open-mmlab/mmpose/pull/558),[#566](https://github.com/open-mmlab/mmpose/pull/566),[#570](https://github.com/open-mmlab/mmpose/pull/570),[#589](https://github.com/open-mmlab/mmpose/pull/589))\n\n- Support animal pose estimation ([#559](https://github.com/open-mmlab/mmpose/pull/559),[#561](https://github.com/open-mmlab/mmpose/pull/561),[#563](https://github.com/open-mmlab/mmpose/pull/563),[#571](https://github.com/open-mmlab/mmpose/pull/571),[#603](https://github.com/open-mmlab/mmpose/pull/603),[#605](https://github.com/open-mmlab/mmpose/pull/605))\n\n- Support Horse-10 dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), MacaquePose dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), Vinegar Fly dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), Desert Locust dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), Grevy's Zebra dataset ([#561](https://github.com/open-mmlab/mmpose/pull/561)), ATRW dataset ([#571](https://github.com/open-mmlab/mmpose/pull/571)), and Animal-Pose dataset ([#603](https://github.com/open-mmlab/mmpose/pull/603))\n\n- Support bottom-up pose tracking demo ([#574](https://github.com/open-mmlab/mmpose/pull/574))\n\n- Support FP16 training ([#584](https://github.com/open-mmlab/mmpose/pull/584),[#616](https://github.com/open-mmlab/mmpose/pull/616),[#626](https://github.com/open-mmlab/mmpose/pull/626))\n\n- Support NMS for bottom-up ([#609](https://github.com/open-mmlab/mmpose/pull/609))\n\n**Bug Fixes**\n\n- Fix bugs in the top-down demo, when there are no people in the images ([#569](https://github.com/open-mmlab/mmpose/pull/569)).\n\n- Fix the links in the doc ([#612](https://github.com/open-mmlab/mmpose/pull/612))\n\n**Improvements**\n\n- Speed up top-down inference ([#560](https://github.com/open-mmlab/mmpose/pull/560))\n\n- Update github CI ([#562](https://github.com/open-mmlab/mmpose/pull/562), [#564](https://github.com/open-mmlab/mmpose/pull/564))\n\n- Update Readme ([#578](https://github.com/open-mmlab/mmpose/pull/578),[#579](https://github.com/open-mmlab/mmpose/pull/579),[#580](https://github.com/open-mmlab/mmpose/pull/580),[#592](https://github.com/open-mmlab/mmpose/pull/592),[#599](https://github.com/open-mmlab/mmpose/pull/599),[#600](https://github.com/open-mmlab/mmpose/pull/600),[#607](https://github.com/open-mmlab/mmpose/pull/607))\n\n- Update Faq ([#587](https://github.com/open-mmlab/mmpose/pull/587), [#610](https://github.com/open-mmlab/mmpose/pull/610))\n\n## **v0.13.0 (31/03/2021)**\n\n**Highlights**\n\n1. Support Wingloss.\n\n2. Support RHD hand dataset.\n\n**New Features**\n\n- Support Wingloss ([#482](https://github.com/open-mmlab/mmpose/pull/482))\n\n- Support RHD hand dataset ([#523](https://github.com/open-mmlab/mmpose/pull/523), [#551](https://github.com/open-mmlab/mmpose/pull/551))\n\n- Support Human3.6m dataset for 3d keypoint detection ([#518](https://github.com/open-mmlab/mmpose/pull/518), [#527](https://github.com/open-mmlab/mmpose/pull/527))\n\n- Support TCN model for 3d keypoint detection ([#521](https://github.com/open-mmlab/mmpose/pull/521), [#522](https://github.com/open-mmlab/mmpose/pull/522))\n\n- Support Interhand3D model for 3d hand detection ([#536](https://github.com/open-mmlab/mmpose/pull/536))\n\n- Support Multi-task detector ([#480](https://github.com/open-mmlab/mmpose/pull/480))\n\n**Bug Fixes**\n\n- Fix PCKh@0.1 calculation ([#516](https://github.com/open-mmlab/mmpose/pull/516))\n\n- Fix unittest ([#529](https://github.com/open-mmlab/mmpose/pull/529))\n\n- Fix circular importing ([#542](https://github.com/open-mmlab/mmpose/pull/542))\n\n- Fix bugs in bottom-up keypoint score ([#548](https://github.com/open-mmlab/mmpose/pull/548))\n\n**Improvements**\n\n- Update config & checkpoints ([#525](https://github.com/open-mmlab/mmpose/pull/525), [#546](https://github.com/open-mmlab/mmpose/pull/546))\n\n- Fix typos ([#514](https://github.com/open-mmlab/mmpose/pull/514), [#519](https://github.com/open-mmlab/mmpose/pull/519), [#532](https://github.com/open-mmlab/mmpose/pull/532), [#537](https://github.com/open-mmlab/mmpose/pull/537), )\n\n- Speed up post processing ([#535](https://github.com/open-mmlab/mmpose/pull/535))\n\n- Update mmcv version dependency ([#544](https://github.com/open-mmlab/mmpose/pull/544))\n\n## **v0.12.0 (28/02/2021)**\n\n**Highlights**\n\n1. Support DeepPose algorithm.\n\n**New Features**\n\n- Support DeepPose algorithm ([#446](https://github.com/open-mmlab/mmpose/pull/446), [#461](https://github.com/open-mmlab/mmpose/pull/461))\n\n- Support interhand3d dataset ([#468](https://github.com/open-mmlab/mmpose/pull/468))\n\n- Support Albumentation pipeline ([#469](https://github.com/open-mmlab/mmpose/pull/469))\n\n- Support PhotometricDistortion pipeline ([#485](https://github.com/open-mmlab/mmpose/pull/485))\n\n- Set seed option for training ([#493](https://github.com/open-mmlab/mmpose/pull/493))\n\n- Add demos for face keypoint detection ([#502](https://github.com/open-mmlab/mmpose/pull/502))\n\n**Bug Fixes**\n\n- Change channel order according to configs ([#504](https://github.com/open-mmlab/mmpose/pull/504))\n\n- Fix `num_factors` in UDP encoding ([#495](https://github.com/open-mmlab/mmpose/pull/495))\n\n- Fix configs ([#456](https://github.com/open-mmlab/mmpose/pull/456))\n\n**Breaking Changes**\n\n- Refactor configs for wholebody pose estimation ([#487](https://github.com/open-mmlab/mmpose/pull/487), [#491](https://github.com/open-mmlab/mmpose/pull/491))\n\n- Rename `decode` function for heads ([#481](https://github.com/open-mmlab/mmpose/pull/481))\n\n**Improvements**\n\n- Update config & checkpoints ([#453](https://github.com/open-mmlab/mmpose/pull/453),[#484](https://github.com/open-mmlab/mmpose/pull/484),[#487](https://github.com/open-mmlab/mmpose/pull/487))\n\n- Add README in Chinese ([#462](https://github.com/open-mmlab/mmpose/pull/462))\n\n- Add tutorials about configs  ([#465](https://github.com/open-mmlab/mmpose/pull/465))\n\n- Add demo videos for various tasks ([#499](https://github.com/open-mmlab/mmpose/pull/499), [#503](https://github.com/open-mmlab/mmpose/pull/503))\n\n- Update docs about MMPose installation ([#467](https://github.com/open-mmlab/mmpose/pull/467), [#505](https://github.com/open-mmlab/mmpose/pull/505))\n\n- Rename `stat.py` to `stats.py` ([#483](https://github.com/open-mmlab/mmpose/pull/483))\n\n- Fix typos ([#463](https://github.com/open-mmlab/mmpose/pull/463), [#464](https://github.com/open-mmlab/mmpose/pull/464), [#477](https://github.com/open-mmlab/mmpose/pull/477), [#481](https://github.com/open-mmlab/mmpose/pull/481))\n\n- latex to bibtex ([#471](https://github.com/open-mmlab/mmpose/pull/471))\n\n- Update FAQ ([#466](https://github.com/open-mmlab/mmpose/pull/466))\n\n## **v0.11.0 (31/01/2021)**\n\n**Highlights**\n\n1. Support fashion landmark detection.\n\n2. Support face keypoint detection.\n\n3. Support pose tracking with MMTracking.\n\n**New Features**\n\n- Support fashion landmark detection (DeepFashion) ([#413](https://github.com/open-mmlab/mmpose/pull/413))\n\n- Support face keypoint detection (300W, AFLW, COFW, WFLW) ([#367](https://github.com/open-mmlab/mmpose/pull/367))\n\n- Support pose tracking demo with MMTracking ([#427](https://github.com/open-mmlab/mmpose/pull/427))\n\n- Support face demo ([#443](https://github.com/open-mmlab/mmpose/pull/443))\n\n- Support AIC dataset for bottom-up methods ([#438](https://github.com/open-mmlab/mmpose/pull/438), [#449](https://github.com/open-mmlab/mmpose/pull/449))\n\n**Bug Fixes**\n\n- Fix multi-batch training ([#434](https://github.com/open-mmlab/mmpose/pull/434))\n\n- Fix sigmas in AIC dataset ([#441](https://github.com/open-mmlab/mmpose/pull/441))\n\n- Fix config file ([#420](https://github.com/open-mmlab/mmpose/pull/420))\n\n**Breaking Changes**\n\n- Refactor Heads ([#382](https://github.com/open-mmlab/mmpose/pull/382))\n\n**Improvements**\n\n- Update readme ([#409](https://github.com/open-mmlab/mmpose/pull/409), [#412](https://github.com/open-mmlab/mmpose/pull/412), [#415](https://github.com/open-mmlab/mmpose/pull/415), [#416](https://github.com/open-mmlab/mmpose/pull/416), [#419](https://github.com/open-mmlab/mmpose/pull/419), [#421](https://github.com/open-mmlab/mmpose/pull/421), [#422](https://github.com/open-mmlab/mmpose/pull/422), [#424](https://github.com/open-mmlab/mmpose/pull/424), [#425](https://github.com/open-mmlab/mmpose/pull/425), [#435](https://github.com/open-mmlab/mmpose/pull/435), [#436](https://github.com/open-mmlab/mmpose/pull/436), [#437](https://github.com/open-mmlab/mmpose/pull/437), [#444](https://github.com/open-mmlab/mmpose/pull/444), [#445](https://github.com/open-mmlab/mmpose/pull/445))\n\n- Add GAP (global average pooling) neck ([#414](https://github.com/open-mmlab/mmpose/pull/414))\n\n- Speed up ([#411](https://github.com/open-mmlab/mmpose/pull/411), [#423](https://github.com/open-mmlab/mmpose/pull/423))\n\n- Support COCO test-dev test ([#433](https://github.com/open-mmlab/mmpose/pull/433))\n\n## **v0.10.0 (31/12/2020)**\n\n**Highlights**\n\n1. Support more human pose estimation methods.\n\n   1. [UDP](https://arxiv.org/abs/1911.07524)\n\n2. Support pose tracking.\n\n3. Support multi-batch inference.\n\n4. Add some useful tools, including `analyze_logs`, `get_flops`, `print_config`.\n\n5. Support more backbone networks.\n\n   1. [ResNest](https://arxiv.org/pdf/2004.08955.pdf)\n   2. [VGG](https://arxiv.org/abs/1409.1556)\n\n**New Features**\n\n- Support UDP ([#353](https://github.com/open-mmlab/mmpose/pull/353), [#371](https://github.com/open-mmlab/mmpose/pull/371), [#402](https://github.com/open-mmlab/mmpose/pull/402))\n\n- Support multi-batch inference ([#390](https://github.com/open-mmlab/mmpose/pull/390))\n\n- Support MHP dataset ([#386](https://github.com/open-mmlab/mmpose/pull/386))\n\n- Support pose tracking demo ([#380](https://github.com/open-mmlab/mmpose/pull/380))\n\n- Support mpii-trb demo ([#372](https://github.com/open-mmlab/mmpose/pull/372))\n\n- Support mobilenet for hand pose estimation ([#377](https://github.com/open-mmlab/mmpose/pull/377))\n\n- Support ResNest backbone ([#370](https://github.com/open-mmlab/mmpose/pull/370))\n\n- Support VGG backbone ([#370](https://github.com/open-mmlab/mmpose/pull/370))\n\n- Add some useful tools, including `analyze_logs`, `get_flops`, `print_config` ([#324](https://github.com/open-mmlab/mmpose/pull/324))\n\n**Bug Fixes**\n\n- Fix bugs in pck evaluation ([#328](https://github.com/open-mmlab/mmpose/pull/328))\n\n- Fix model download links in README ([#396](https://github.com/open-mmlab/mmpose/pull/396), [#397](https://github.com/open-mmlab/mmpose/pull/397))\n\n- Fix CrowdPose annotations and update benchmarks ([#384](https://github.com/open-mmlab/mmpose/pull/384))\n\n- Fix modelzoo stat ([#354](https://github.com/open-mmlab/mmpose/pull/354), [#360](https://github.com/open-mmlab/mmpose/pull/360), [#362](https://github.com/open-mmlab/mmpose/pull/362))\n\n- Fix config files for aic datasets ([#340](https://github.com/open-mmlab/mmpose/pull/340))\n\n**Breaking Changes**\n\n- Rename `image_thr` to `det_bbox_thr` for top-down methods.\n\n**Improvements**\n\n- Organize the readme files ([#398](https://github.com/open-mmlab/mmpose/pull/398), [#399](https://github.com/open-mmlab/mmpose/pull/399), [#400](https://github.com/open-mmlab/mmpose/pull/400))\n\n- Check linting for markdown ([#379](https://github.com/open-mmlab/mmpose/pull/379))\n\n- Add faq.md ([#350](https://github.com/open-mmlab/mmpose/pull/350))\n\n- Remove PyTorch 1.4 in CI ([#338](https://github.com/open-mmlab/mmpose/pull/338))\n\n- Add pypi badge in readme ([#329](https://github.com/open-mmlab/mmpose/pull/329))\n\n## **v0.9.0 (30/11/2020)**\n\n**Highlights**\n\n1. Support more human pose estimation methods.\n\n   1. [MSPN](https://arxiv.org/abs/1901.00148)\n   2. [RSN](https://arxiv.org/abs/2003.04030)\n\n2. Support video pose estimation datasets.\n\n   1. [sub-JHMDB](http://jhmdb.is.tue.mpg.de/dataset)\n\n3. Support Onnx model conversion.\n\n**New Features**\n\n- Support MSPN ([#278](https://github.com/open-mmlab/mmpose/pull/278))\n\n- Support RSN ([#221](https://github.com/open-mmlab/mmpose/pull/221), [#318](https://github.com/open-mmlab/mmpose/pull/318))\n\n- Support new post-processing method for MSPN & RSN ([#288](https://github.com/open-mmlab/mmpose/pull/288))\n\n- Support sub-JHMDB dataset ([#292](https://github.com/open-mmlab/mmpose/pull/292))\n\n- Support urls for pre-trained models in config files ([#232](https://github.com/open-mmlab/mmpose/pull/232))\n\n- Support Onnx ([#305](https://github.com/open-mmlab/mmpose/pull/305))\n\n**Bug Fixes**\n\n- Fix model download links in README ([#255](https://github.com/open-mmlab/mmpose/pull/255), [#315](https://github.com/open-mmlab/mmpose/pull/315))\n\n**Breaking Changes**\n\n- `post_process=True|False` and `unbiased_decoding=True|False` are deprecated, use `post_process=None|default|unbiased` etc. instead ([#288](https://github.com/open-mmlab/mmpose/pull/288))\n\n**Improvements**\n\n- Enrich the model zoo ([#256](https://github.com/open-mmlab/mmpose/pull/256), [#320](https://github.com/open-mmlab/mmpose/pull/320))\n\n- Set the default map_location as 'cpu' to reduce gpu memory cost ([#227](https://github.com/open-mmlab/mmpose/pull/227))\n\n- Support return heatmaps and backbone features for bottom-up models ([#229](https://github.com/open-mmlab/mmpose/pull/229))\n\n- Upgrade mmcv maximum & minimum version ([#269](https://github.com/open-mmlab/mmpose/pull/269), [#313](https://github.com/open-mmlab/mmpose/pull/313))\n\n- Automatically add modelzoo statistics to readthedocs ([#252](https://github.com/open-mmlab/mmpose/pull/252))\n\n- Fix Pylint issues ([#258](https://github.com/open-mmlab/mmpose/pull/258), [#259](https://github.com/open-mmlab/mmpose/pull/259), [#260](https://github.com/open-mmlab/mmpose/pull/260), [#262](https://github.com/open-mmlab/mmpose/pull/262), [#265](https://github.com/open-mmlab/mmpose/pull/265), [#267](https://github.com/open-mmlab/mmpose/pull/267), [#268](https://github.com/open-mmlab/mmpose/pull/268), [#270](https://github.com/open-mmlab/mmpose/pull/270), [#271](https://github.com/open-mmlab/mmpose/pull/271), [#272](https://github.com/open-mmlab/mmpose/pull/272), [#273](https://github.com/open-mmlab/mmpose/pull/273), [#275](https://github.com/open-mmlab/mmpose/pull/275), [#276](https://github.com/open-mmlab/mmpose/pull/276), [#283](https://github.com/open-mmlab/mmpose/pull/283), [#285](https://github.com/open-mmlab/mmpose/pull/285), [#293](https://github.com/open-mmlab/mmpose/pull/293), [#294](https://github.com/open-mmlab/mmpose/pull/294), [#295](https://github.com/open-mmlab/mmpose/pull/295))\n\n- Improve README ([#226](https://github.com/open-mmlab/mmpose/pull/226), [#257](https://github.com/open-mmlab/mmpose/pull/257), [#264](https://github.com/open-mmlab/mmpose/pull/264), [#280](https://github.com/open-mmlab/mmpose/pull/280), [#296](https://github.com/open-mmlab/mmpose/pull/296))\n\n- Support PyTorch 1.7 in CI ([#274](https://github.com/open-mmlab/mmpose/pull/274))\n\n- Add docs/tutorials for running demos ([#263](https://github.com/open-mmlab/mmpose/pull/263))\n\n## **v0.8.0 (31/10/2020)**\n\n**Highlights**\n\n1. Support more human pose estimation datasets.\n\n   1. [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose)\n   2. [PoseTrack18](https://posetrack.net/)\n\n2. Support more 2D hand keypoint estimation datasets.\n\n   1. [InterHand2.6](https://github.com/facebookresearch/InterHand2.6M)\n\n3. Support adversarial training for 3D human shape recovery.\n\n4. Support multi-stage losses.\n\n5. Support mpii demo.\n\n**New Features**\n\n- Support [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose) dataset ([#195](https://github.com/open-mmlab/mmpose/pull/195))\n\n- Support [PoseTrack18](https://posetrack.net/) dataset ([#220](https://github.com/open-mmlab/mmpose/pull/220))\n\n- Support [InterHand2.6](https://github.com/facebookresearch/InterHand2.6M) dataset ([#202](https://github.com/open-mmlab/mmpose/pull/202))\n\n- Support adversarial training for 3D human shape recovery ([#192](https://github.com/open-mmlab/mmpose/pull/192))\n\n- Support multi-stage losses ([#204](https://github.com/open-mmlab/mmpose/pull/204))\n\n**Bug Fixes**\n\n- Fix config files ([#190](https://github.com/open-mmlab/mmpose/pull/190))\n\n**Improvements**\n\n- Add mpii demo ([#216](https://github.com/open-mmlab/mmpose/pull/216))\n\n- Improve README ([#181](https://github.com/open-mmlab/mmpose/pull/181), [#183](https://github.com/open-mmlab/mmpose/pull/183), [#208](https://github.com/open-mmlab/mmpose/pull/208))\n\n- Support return heatmaps and backbone features ([#196](https://github.com/open-mmlab/mmpose/pull/196), [#212](https://github.com/open-mmlab/mmpose/pull/212))\n\n- Support different return formats of mmdetection models ([#217](https://github.com/open-mmlab/mmpose/pull/217))\n\n## **v0.7.0 (30/9/2020)**\n\n**Highlights**\n\n1. Support HMR for 3D human shape recovery.\n\n2. Support WholeBody human pose estimation.\n\n   1. [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody)\n\n3. Support more 2D hand keypoint estimation datasets.\n\n   1. [Frei-hand](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\n   2. [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html)\n\n4. Add more popular backbones & enrich the [modelzoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html)\n\n   1. ShuffleNetv2\n\n5. Support hand demo and whole-body demo.\n\n**New Features**\n\n- Support HMR for 3D human shape recovery ([#157](https://github.com/open-mmlab/mmpose/pull/157), [#160](https://github.com/open-mmlab/mmpose/pull/160), [#161](https://github.com/open-mmlab/mmpose/pull/161), [#162](https://github.com/open-mmlab/mmpose/pull/162))\n\n- Support [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody) dataset ([#133](https://github.com/open-mmlab/mmpose/pull/133))\n\n- Support [Frei-hand](https://lmb.informatik.uni-freiburg.de/projects/freihand/) dataset ([#125](https://github.com/open-mmlab/mmpose/pull/125))\n\n- Support [CMU Panoptic HandDB](http://domedb.perception.cs.cmu.edu/handdb.html) dataset ([#144](https://github.com/open-mmlab/mmpose/pull/144))\n\n- Support H36M dataset ([#159](https://github.com/open-mmlab/mmpose/pull/159))\n\n- Support ShuffleNetv2 ([#139](https://github.com/open-mmlab/mmpose/pull/139))\n\n- Support saving best models based on key indicator ([#127](https://github.com/open-mmlab/mmpose/pull/127))\n\n**Bug Fixes**\n\n- Fix typos in docs ([#121](https://github.com/open-mmlab/mmpose/pull/121))\n\n- Fix assertion ([#142](https://github.com/open-mmlab/mmpose/pull/142))\n\n**Improvements**\n\n- Add tools to transform .mat format to .json format ([#126](https://github.com/open-mmlab/mmpose/pull/126))\n\n- Add hand demo ([#115](https://github.com/open-mmlab/mmpose/pull/115))\n\n- Add whole-body demo ([#163](https://github.com/open-mmlab/mmpose/pull/163))\n\n- Reuse mmcv utility function and update version files ([#135](https://github.com/open-mmlab/mmpose/pull/135), [#137](https://github.com/open-mmlab/mmpose/pull/137))\n\n- Enrich the modelzoo ([#147](https://github.com/open-mmlab/mmpose/pull/147), [#169](https://github.com/open-mmlab/mmpose/pull/169))\n\n- Improve docs ([#174](https://github.com/open-mmlab/mmpose/pull/174), [#175](https://github.com/open-mmlab/mmpose/pull/175), [#178](https://github.com/open-mmlab/mmpose/pull/178))\n\n- Improve README ([#176](https://github.com/open-mmlab/mmpose/pull/176))\n\n- Improve version.py ([#173](https://github.com/open-mmlab/mmpose/pull/173))\n\n## **v0.6.0 (31/8/2020)**\n\n**Highlights**\n\n1. Add more popular backbones & enrich the [modelzoo](https://mmpose.readthedocs.io/en/latest/model_zoo.html)\n\n   1. ResNext\n   2. SEResNet\n   3. ResNetV1D\n   4. MobileNetv2\n   5. ShuffleNetv1\n   6. CPM (Convolutional Pose Machine)\n\n2. Add more popular datasets:\n\n   1. [AIChallenger](https://arxiv.org/abs/1711.06475?context=cs.CV)\n   2. [MPII](http://human-pose.mpi-inf.mpg.de/)\n   3. [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body)\n   4. [OCHuman](http://www.liruilong.cn/projects/pose2seg/index.html)\n\n3. Support 2d hand keypoint estimation.\n\n   1. [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\n\n4. Support bottom-up inference.\n\n**New Features**\n\n- Support [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html) dataset ([#52](https://github.com/open-mmlab/mmpose/pull/52))\n\n- Support [MPII](http://human-pose.mpi-inf.mpg.de/) dataset ([#55](https://github.com/open-mmlab/mmpose/pull/55))\n\n- Support [MPII-TRB](https://github.com/kennymckormick/Triplet-Representation-of-human-Body) dataset ([#19](https://github.com/open-mmlab/mmpose/pull/19), [#47](https://github.com/open-mmlab/mmpose/pull/47), [#48](https://github.com/open-mmlab/mmpose/pull/48))\n\n- Support [OCHuman](http://www.liruilong.cn/projects/pose2seg/index.html) dataset ([#70](https://github.com/open-mmlab/mmpose/pull/70))\n\n- Support [AIChallenger](https://arxiv.org/abs/1711.06475?context=cs.CV) dataset ([#87](https://github.com/open-mmlab/mmpose/pull/87))\n\n- Support multiple backbones ([#26](https://github.com/open-mmlab/mmpose/pull/26))\n\n- Support CPM model ([#56](https://github.com/open-mmlab/mmpose/pull/56))\n\n**Bug Fixes**\n\n- Fix configs for MPII & MPII-TRB datasets ([#93](https://github.com/open-mmlab/mmpose/pull/93))\n\n- Fix the bug of missing `test_pipeline` in configs ([#14](https://github.com/open-mmlab/mmpose/pull/14))\n\n- Fix typos ([#27](https://github.com/open-mmlab/mmpose/pull/27), [#28](https://github.com/open-mmlab/mmpose/pull/28), [#50](https://github.com/open-mmlab/mmpose/pull/50), [#53](https://github.com/open-mmlab/mmpose/pull/53), [#63](https://github.com/open-mmlab/mmpose/pull/63))\n\n**Improvements**\n\n- Update benchmark ([#93](https://github.com/open-mmlab/mmpose/pull/93))\n\n- Add Dockerfile ([#44](https://github.com/open-mmlab/mmpose/pull/44))\n\n- Improve unittest coverage and minor fix ([#18](https://github.com/open-mmlab/mmpose/pull/18))\n\n- Support CPUs for train/val/demo ([#34](https://github.com/open-mmlab/mmpose/pull/34))\n\n- Support bottom-up demo ([#69](https://github.com/open-mmlab/mmpose/pull/69))\n\n- Add tools to publish model ([#62](https://github.com/open-mmlab/mmpose/pull/62))\n\n- Enrich the modelzoo ([#64](https://github.com/open-mmlab/mmpose/pull/64), [#68](https://github.com/open-mmlab/mmpose/pull/68), [#82](https://github.com/open-mmlab/mmpose/pull/82))\n\n## **v0.5.0 (21/7/2020)**\n\n**Highlights**\n\n- MMPose is released.\n\n**Main Features**\n\n- Support both top-down and bottom-up pose estimation approaches.\n\n- Achieve higher training efficiency and higher accuracy than other popular codebases (e.g. AlphaPose, HRNet)\n\n- Support various backbone models: ResNet, HRNet, SCNet, Houglass and HigherHRNet.\n"
  },
  {
    "path": "docs/zh_cn/notes/ecosystem.md",
    "content": "# Ecosystem\n\nComing soon.\n"
  },
  {
    "path": "docs/zh_cn/notes/projects.md",
    "content": "# Projects based on MMPose\n\nThere are many projects built upon MMPose. We list some of them as examples of how to extend MMPose for your own projects. As the page might not be completed, please feel free to create a PR to update this page.\n\n## Projects as an extension\n\nSome projects extend the boundary of MMPose for deployment or other research fields. They reveal the potential of what MMPose can do. We list several of them as below.\n\n- [Anime Face Detector](https://github.com/hysts/anime-face-detector): An anime face landmark detection toolbox.\n- [PosePipeline](https://github.com/peabody124/PosePipeline): Open-Source Human Pose Estimation Pipeline for Clinical Research\n\n## Projects of papers\n\nThere are also projects released with papers. Some of the papers are published in top-tier conferences (CVPR, ICCV, and ECCV), the others are also highly influential. We list some of these works as a reference for the community to develop and compare new pose estimation algorithms. Methods already supported and maintained by MMPose are not listed.\n\n- Pose for Everything: Towards Category-Agnostic Pose Estimation, ECCV 2022. [\\[paper\\]](https://arxiv.org/abs/2207.10387)[\\[github\\]](https://github.com/luminxu/Pose-for-Everything)\n- UniFormer: Unified Transformer for Efficient Spatiotemporal Representation Learning, ICLR 2022. [\\[paper\\]](https://arxiv.org/abs/2201.04676)[\\[github\\]](https://github.com/Sense-X/UniFormer)\n- Poseur:Direct Human Pose Regression with Transformers, ECCV 2022. [\\[paper\\]](https://arxiv.org/abs/2201.07412)[\\[github\\]](https://github.com/aim-uofa/Poseur)\n- ViTAEv2: Vision Transformer Advanced by Exploring Inductive Bias for Image Recognition and Beyond, NeurIPS 2022. [\\[paper\\]](https://arxiv.org/abs/2106.03348)[\\[github\\]](https://github.com/ViTAE-Transformer/ViTAE-Transformer)\n- Dite-HRNet:Dynamic Lightweight High-Resolution Network for Human Pose Estimation, IJCAI-ECAI 2021. [\\[paper\\]](https://arxiv.org/abs/2204.10762)[\\[github\\]](https://github.com/ZiyiZhang27/Dite-HRNet)\n"
  },
  {
    "path": "docs/zh_cn/notes/pytorch_2.md",
    "content": "# PyTorch 2.0 Compatibility and Benchmarks\n\nMMPose 1.0.0 is now compatible with PyTorch 2.0, ensuring that users can leverage the latest features and performance improvements offered by the PyTorch 2.0 framework when using MMPose. With the integration of inductor, users can expect faster model speeds. The table below shows several example models:\n\n| Model     |     Training Speed      |    Memory     |\n| :-------- | :---------------------: | :-----------: |\n| ViTPose-B | 29.6% ↑ (0.931 → 0.655) | 10586 → 10663 |\n| ViTPose-S | 33.7% ↑ (0.563 → 0.373) |  6091 → 6170  |\n| HRNet-w32 | 12.8% ↑ (0.553 → 0.482) | 9849 → 10145  |\n| HRNet-w48 | 37.1% ↑ (0.437 → 0.275) |  7319 → 7394  |\n| RTMPose-t | 6.3% ↑ (1.533 → 1.437)  |  6292 → 6489  |\n| RTMPose-s | 13.1% ↑ (1.645 → 1.430) |  9013 → 9208  |\n\n- Pytorch 2.0 test, add projects doc and refactor by @LareinaM in [PR#2136](https://github.com/open-mmlab/mmpose/pull/2136)\n"
  },
  {
    "path": "docs/zh_cn/overview.md",
    "content": "# 概述\n\n本章将向你介绍 MMPose 的整体框架，并提供详细的教程链接。\n\n## 什么是 MMPose\n\n![overview](https://user-images.githubusercontent.com/13503330/191004511-508d3ec6-9ead-4c52-a522-4d9aa1f26027.png)\n\nMMPose 是一款基于 Pytorch 的姿态估计开源工具箱，是 OpenMMLab 项目的成员之一，包含了丰富的 2D 多人姿态估计、2D 手部姿态估计、2D 人脸关键点检测、133关键点全身人体姿态估计、动物关键点检测、服饰关键点检测等算法以及相关的组件和模块，下面是它的整体框架：\n\nMMPose 由 **8** 个主要部分组成，apis、structures、datasets、codecs、models、engine、evaluation 和 visualization。\n\n- **apis** 提供用于模型推理的高级 API\n- **structures** 提供 bbox、keypoint 和 PoseDataSample 等数据结构\n- **datasets** 支持用于姿态估计的各种数据集\n  - **transforms** 包含各种数据增强变换\n- **codecs** 提供姿态编解码器：编码器用于将姿态信息（通常为关键点坐标）编码为模型学习目标（如热力图），解码器则用于将模型输出解码为姿态估计结果\n- **models** 以模块化结构提供了姿态估计模型的各类组件\n  - **pose_estimators** 定义了所有姿态估计模型类\n  - **data_preprocessors** 用于预处理模型的输入数据\n  - **backbones** 包含各种骨干网络\n  - **necks** 包含各种模型颈部组件\n  - **heads** 包含各种模型头部\n  - **losses** 包含各种损失函数\n- **engine** 包含与姿态估计任务相关的运行时组件\n  - **hooks** 提供运行时的各种钩子\n- **evaluation** 提供各种评估模型性能的指标\n- **visualization** 用于可视化关键点骨架和热力图等信息\n\n## 如何使用本指南\n\n针对不同类型的用户，我们准备了详细的指南：\n\n1. 安装说明：\n\n   - [安装](./installation.md)\n\n2. MMPose 的基本使用方法：\n\n   - [20 分钟上手教程](./guide_to_framework.md)\n   - [Demos](./demos.md)\n   - [模型推理](./user_guides/inference.md)\n   - [配置文件](./user_guides/configs.md)\n   - [准备数据集](./user_guides/prepare_datasets.md)\n   - [训练与测试](./user_guides/train_and_test.md)\n   - [模型部署](./user_guides/how_to_deploy.md)\n   - [模型分析工具](./user_guides/model_analysis.md)\n   - [数据集标注与预处理脚本](./user_guides/dataset_tools.md)\n\n3. 对于希望基于 MMPose 进行开发的研究者和开发者：\n\n   - [编解码器](./advanced_guides/codecs.md)\n   - [数据流](./advanced_guides/dataflow.md)\n   - [实现新模型](./advanced_guides/implement_new_models.md)\n   - [自定义数据集](./advanced_guides/customize_datasets.md)\n   - [自定义数据变换](./advanced_guides/customize_transforms.md)\n   - [自定义优化器](./advanced_guides/customize_optimizer.md)\n   - [自定义日志](./advanced_guides/customize_logging.md)\n   - [迁移指南](./migration.md)\n\n4. 对于希望加入开源社区，向 MMPose 贡献代码的研究者和开发者：\n\n   - [参与贡献代码](./contribution_guide.md)\n\n5. 对于使用过程中的常见问题：\n\n   - [FAQ](./faq.md)\n"
  },
  {
    "path": "docs/zh_cn/quick_run.md",
    "content": "# 快速上手\n\n在这一章里，我们将带领你走过MMPose工作流程中关键的七个步骤，帮助你快速上手：\n\n1. 使用预训练模型进行推理\n2. 准备数据集\n3. 准备配置文件\n4. 可视化训练图片\n5. 训练\n6. 测试\n7. 可视化\n\n## 安装\n\n请查看[安装指南](./installation.md)，以了解完整步骤。\n\n## 快速开始\n\n### 使用预训练模型进行推理\n\n你可以通过以下命令来使用预训练模型对单张图片进行识别：\n\n```Bash\npython demo/image_demo.py \\\n    tests/data/coco/000000000785.jpg \\\n    configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py\\\n    https://download.openmmlab.com/mmpose/top_down/deeppose/deeppose_res50_coco_256x192_rle-2ea9bb4a_20220616.pth\n```\n\n该命令中用到了测试图片、完整的配置文件、预训练模型，如果MMPose安装无误，将会弹出一个新窗口，对检测结果进行可视化显示：\n\n![inference_demo](https://user-images.githubusercontent.com/13503330/187112344-0c5062f2-689c-445c-a259-d5d4311e2497.png)\n\n更多演示脚本的详细参数说明可以在 [模型推理](./user_guides/inference.md) 中找到。\n\n### 准备数据集\n\nMMPose支持各种不同的任务，我们提供了对应的数据集准备教程。\n\n- [2D人体关键点](./dataset_zoo/2d_body_keypoint.md)\n\n- [3D人体关键点](./dataset_zoo/3d_body_keypoint.md)\n\n- [2D人手关键点](./dataset_zoo/2d_hand_keypoint.md)\n\n- [3D人手关键点](./dataset_zoo/3d_hand_keypoint.md)\n\n- [2D人脸关键点](./dataset_zoo/2d_face_keypoint.md)\n\n- [2D全身人体关键点](./dataset_zoo/2d_wholebody_keypoint.md)\n\n- [2D服饰关键点](./dataset_zoo/2d_fashion_landmark.md)\n\n- [2D动物关键点](./dataset_zoo/2d_animal_keypoint.md)\n\n你可以在【2D人体关键点数据集】>【COCO】下找到COCO数据集的准备教程，并按照教程完成数据集的下载和整理。\n\n```{note}\n在MMPose中，我们建议将COCO数据集存放到新建的 `$MMPOSE/data` 目录下。\n```\n\n### 准备配置文件\n\nMMPose拥有一套强大的配置系统，用于管理训练所需的一系列必要参数：\n\n- **通用**：环境、Hook、Checkpoint、Logger、Timer等\n\n- **数据**：Dataset、Dataloader、数据增强等\n\n- **训练**：优化器、学习率调整等\n\n- **模型**：Backbone、Neck、Head、损失函数等\n\n- **评测**：Metrics\n\n在`$MMPOSE/configs`目录下，我们提供了大量前沿论文方法的配置文件，可供直接使用和参考。\n\n要在COCO数据集上训练基于ResNet50的RLE模型时，所需的配置文件为：\n\n```Bash\n$MMPOSE/configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py\n```\n\n我们需要将配置文件中的 data_root 变量修改为COCO数据集存放路径：\n\n```Python\ndata_root = 'data/coco'\n```\n\n```{note}\n感兴趣的读者也可以查阅 [配置文件](./user_guides/configs.md) 来进一步学习MMPose所使用的配置系统。\n```\n\n### 可视化训练图片\n\n在开始训练之前，我们还可以对训练图片进行可视化，检查训练图片是否正确进行了数据增强。\n\n我们提供了相应的可视化脚本：\n\n```Bash\npython tools/misc/browse_dastaset.py \\\n    configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py \\\n    --mode transformed\n```\n\n![transformed_training_img](https://user-images.githubusercontent.com/13503330/187112376-e604edcb-46cc-4995-807b-e8f204f991b0.png)\n\n### 训练\n\n确定数据无误后，运行以下命令启动训练：\n\n```Bash\npython tools/train.py configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py\n```\n\n```{note}\nMMPose中集成了大量实用训练trick和功能：\n\n- 学习率warmup和scheduling\n\n- ImageNet预训练权重\n\n- 自动学习率缩放、自动batch size缩放\n\n- CPU训练、多机多卡训练、集群训练\n\n- HardDisk、LMDB、Petrel、HTTP等不同数据后端\n\n- 混合精度浮点训练\n\n- TensorBoard\n```\n\n### 测试\n\n在不指定额外参数时，训练的权重和日志信息会默认存储到`$MMPOSE/work_dirs`目录下，最优的模型权重存放在`$MMPOSE/work_dir/best_coco`目录下。\n\n我们可以通过如下指令测试模型在COCO验证集上的精度：\n\n```Bash\npython tools/test.py \\\n    configs/body_2d_keypoint/topdown_regression/coco/td-reg_res50_rle-8xb64-210e_coco-256x192.py \\\n    work_dir/best_coco/AP_epoch_20.pth\n```\n\n在COCO验证集上评测结果样例如下：\n\n```Bash\n Average Precision  (AP) @[ IoU=0.50:0.95 | area=   all | maxDets= 20 ] =  0.704\n Average Precision  (AP) @[ IoU=0.50      | area=   all | maxDets= 20 ] =  0.883\n Average Precision  (AP) @[ IoU=0.75      | area=   all | maxDets= 20 ] =  0.777\n Average Precision  (AP) @[ IoU=0.50:0.95 | area=medium | maxDets= 20 ] =  0.667\n Average Precision  (AP) @[ IoU=0.50:0.95 | area= large | maxDets= 20 ] =  0.769\n Average Recall     (AR) @[ IoU=0.50:0.95 | area=   all | maxDets= 20 ] =  0.751\n Average Recall     (AR) @[ IoU=0.50      | area=   all | maxDets= 20 ] =  0.920\n Average Recall     (AR) @[ IoU=0.75      | area=   all | maxDets= 20 ] =  0.815\n Average Recall     (AR) @[ IoU=0.50:0.95 | area=medium | maxDets= 20 ] =  0.709\n Average Recall     (AR) @[ IoU=0.50:0.95 | area= large | maxDets= 20 ] =  0.811\n08/23 12:04:42 - mmengine - INFO - Epoch(test) [3254/3254]  coco/AP: 0.704168  coco/AP .5: 0.883134  coco/AP .75: 0.777015  coco/AP (M): 0.667207  coco/AP (L): 0.768644  coco/AR: 0.750913  coco/AR .5: 0.919710  coco/AR .75: 0.815334  coco/AR (M): 0.709232  coco/AR (L): 0.811334\n```\n\n```{note}\n如果需要测试模型在其他数据集上的表现，可以前往 [训练与测试](./user_guides/train_and_test.md) 查看。\n```\n\n### 可视化\n\n除了对关键点骨架的可视化以外，我们还支持对热度图进行可视化，你只需要在配置文件中设置`output_heatmap=True`：\n\n```Python\nmodel = dict(\n    ## 内容省略\n    test_cfg = dict(\n        ## 内容省略\n        output_heatmaps=True\n    )\n)\n```\n\n或在命令行中添加`--cfg-options='model.test_cfg.output_heatmaps=True'`。\n\n可视化效果如下：\n\n![vis_pred](https://user-images.githubusercontent.com/26127467/187578902-30ef7bb0-9a93-4e03-bae0-02aeccf7f689.jpg)\n\n```{note}\n如果你希望深入地学习MMPose，将其应用到自己的项目当中，我们准备了一份详细的 [迁移指南](./migration.md) 。\n```\n"
  },
  {
    "path": "docs/zh_cn/stats.py",
    "content": "#!/usr/bin/env python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport functools as func\nimport glob\nimport re\nfrom os.path import basename, splitext\n\nimport numpy as np\nimport titlecase\n\n\ndef anchor(name):\n    return re.sub(r'-+', '-', re.sub(r'[^a-zA-Z0-9]', '-',\n                                     name.strip().lower())).strip('-')\n\n\n# Count algorithms\n\nfiles = sorted(glob.glob('model_zoo/*.md'))\n\nstats = []\n\nfor f in files:\n    with open(f, 'r') as content_file:\n        content = content_file.read()\n\n    # title\n    title = content.split('\\n')[0].replace('#', '')\n\n    # count papers\n    papers = set(\n        (papertype, titlecase.titlecase(paper.lower().strip()))\n        for (papertype, paper) in re.findall(\n            r'<!--\\s*\\[([A-Z]*?)\\]\\s*-->\\s*\\n.*?\\btitle\\s*=\\s*{(.*?)}',\n            content, re.DOTALL))\n    # paper links\n    revcontent = '\\n'.join(list(reversed(content.splitlines())))\n    paperlinks = {}\n    for _, p in papers:\n        # print(p)\n        paperlinks[p] = ', '.join(\n            ((f'[{paperlink} ⇨]'\n              f'(model_zoo/{splitext(basename(f))[0]}.html#'\n              f'{anchor(paperlink)})') for paperlink in re.findall(\n                  rf'\\btitle\\s*=\\s*{{\\s*{p}\\s*}}.*?\\n### (.*?)\\s*[,;]?\\s*\\n',\n                  revcontent, re.DOTALL | re.IGNORECASE)))\n        # print('   ', paperlinks[p])\n    paperlist = '\\n'.join(\n        sorted(f'    - [{t}] {x} ({paperlinks[x]})' for t, x in papers))\n    # count configs\n    configs = set(x.lower().strip()\n                  for x in re.findall(r'.*configs/.*\\.py', content))\n\n    # count ckpts\n    ckpts = set(x.lower().strip()\n                for x in re.findall(r'https://download.*\\.pth', content)\n                if 'mmpose' in x)\n\n    statsmsg = f\"\"\"\n## [{title}]({f})\n\n* 模型权重文件数量: {len(ckpts)}\n* 配置文件数量: {len(configs)}\n* 论文数量: {len(papers)}\n{paperlist}\n\n    \"\"\"\n\n    stats.append((papers, configs, ckpts, statsmsg))\n\nallpapers = func.reduce(lambda a, b: a.union(b), [p for p, _, _, _ in stats])\nallconfigs = func.reduce(lambda a, b: a.union(b), [c for _, c, _, _ in stats])\nallckpts = func.reduce(lambda a, b: a.union(b), [c for _, _, c, _ in stats])\n\n# Summarize\n\nmsglist = '\\n'.join(x for _, _, _, x in stats)\npapertypes, papercounts = np.unique([t for t, _ in allpapers],\n                                    return_counts=True)\ncountstr = '\\n'.join(\n    [f'   - {t}: {c}' for t, c in zip(papertypes, papercounts)])\n\nmodelzoo = f\"\"\"\n# 概览\n\n* 模型权重文件数量: {len(allckpts)}\n* 配置文件数量: {len(allconfigs)}\n* 论文数量: {len(allpapers)}\n{countstr}\n\n已支持的数据集详细信息请见 [数据集](dataset_zoo.md).\n\n{msglist}\n\n\"\"\"\n\nwith open('model_zoo.md', 'w') as f:\n    f.write(modelzoo)\n\n# Count datasets\n\nfiles = sorted(glob.glob('model_zoo/*.md'))\n# files = sorted(glob.glob('docs/tasks/*.md'))\n\ndatastats = []\n\nfor f in files:\n    with open(f, 'r') as content_file:\n        content = content_file.read()\n\n    # title\n    title = content.split('\\n')[0].replace('#', '')\n\n    # count papers\n    papers = set(\n        (papertype, titlecase.titlecase(paper.lower().strip()))\n        for (papertype, paper) in re.findall(\n            r'<!--\\s*\\[([A-Z]*?)\\]\\s*-->\\s*\\n.*?\\btitle\\s*=\\s*{(.*?)}',\n            content, re.DOTALL))\n    # paper links\n    revcontent = '\\n'.join(list(reversed(content.splitlines())))\n    paperlinks = {}\n    for _, p in papers:\n        # print(p)\n        paperlinks[p] = ', '.join(\n            (f'[{p} ⇨](model_zoo/{splitext(basename(f))[0]}.html#'\n             f'{anchor(p)})' for p in re.findall(\n                 rf'\\btitle\\s*=\\s*{{\\s*{p}\\s*}}.*?\\n## (.*?)\\s*[,;]?\\s*\\n',\n                 revcontent, re.DOTALL | re.IGNORECASE)))\n        # print('   ', paperlinks[p])\n    paperlist = '\\n'.join(\n        sorted(f'    - [{t}] {x} ({paperlinks[x]})' for t, x in papers))\n    # count configs\n    configs = set(x.lower().strip()\n                  for x in re.findall(r'https.*configs/.*\\.py', content))\n\n    # count ckpts\n    ckpts = set(x.lower().strip()\n                for x in re.findall(r'https://download.*\\.pth', content)\n                if 'mmpose' in x)\n\n    statsmsg = f\"\"\"\n## [{title}]({f})\n\n* 论文数量: {len(papers)}\n{paperlist}\n\n    \"\"\"\n\n    datastats.append((papers, configs, ckpts, statsmsg))\n\nalldatapapers = func.reduce(lambda a, b: a.union(b),\n                            [p for p, _, _, _ in datastats])\n\n# Summarize\n\nmsglist = '\\n'.join(x for _, _, _, x in stats)\ndatamsglist = '\\n'.join(x for _, _, _, x in datastats)\npapertypes, papercounts = np.unique([t for t, _ in alldatapapers],\n                                    return_counts=True)\ncountstr = '\\n'.join(\n    [f'   - {t}: {c}' for t, c in zip(papertypes, papercounts)])\n\ndataset_zoo = f\"\"\"\n# 概览\n\n* 论文数量: {len(alldatapapers)}\n{countstr}\n\n已支持的算法详细信息请见 [模型池](model_zoo.md).\n\n{datamsglist}\n\"\"\"\n\nwith open('dataset_zoo.md', 'w') as f:\n    f.write(dataset_zoo)\n"
  },
  {
    "path": "docs/zh_cn/switch_language.md",
    "content": "## <a href='https://mmpose.readthedocs.io/zh_CN/latest/'>简体中文</a>\n\n## <a href='https://mmpose.readthedocs.io/en/latest/'>English</a>\n"
  },
  {
    "path": "docs/zh_cn/user_guides/configs.md",
    "content": "# 如何看懂配置文件\n\nMMPose 使用 Python 文件作为配置文件，将模块化设计和继承设计结合到配置系统中，便于进行各种实验。\n\n## 目录结构\n\nMMPose 的配置文件目录结构如下：\n\n```shell\nconfigs\n|----_base_\n     |----datasets\n     |----default_runtime.py\n|----animal_2d_keypoint\n|----body_2d_keypoint\n|----body_3d_keypoint\n|----face_2d_keypoint\n|----fashion_2d_keypoint\n|----hand_2d_keypoint\n|----hand_3d_keypoint\n|----wholebody_2d_keypoint\n```\n\n## 简介\n\nMMPose 拥有一套强大的配置系统，在注册器的配合下，用户可以通过一个配置文件来定义整个项目需要用到的所有内容，以 Python 字典形式组织配置信息，传递给注册器完成对应模块的实例化。\n\n下面是一个常见的 Pytorch 模块定义的例子：\n\n```Python\n# 在loss_a.py中定义Loss_A类\nClass Loss_A(nn.Module):\n    def __init__(self, param1, param2):\n        self.param1 = param1\n        self.param2 = param2\n    def forward(self, x):\n        return x\n\n# 在需要的地方进行实例化\nloss = Loss_A(param1=1.0, param2=True)\n```\n\n只需要通过一行代码对这个类进行注册：\n\n```Python\n# 在loss_a.py中定义Loss_A类\nfrom mmpose.registry import MODELS\n\n@MODELS.register_module() # 注册该类到 MODELS 下\nClass Loss_A(nn.Module):\n    def __init__(self, param1, param2):\n        self.param1 = param1\n        self.param2 = param2\n    def forward(self, x):\n        return x\n```\n\n并在对应目录下的 `__init__.py` 中进行 `import`：\n\n```Python\n# __init__.py of mmpose/models/losses\nfrom .loss_a.py import Loss_A\n\n__all__ = ['Loss_A']\n```\n\n我们就可以通过如下方式来从配置文件定义并进行实例化：\n\n```Python\n# 在config_file.py中定义\nloss_cfg = dict(\n    type='Loss_A', # 通过type指定类名\n    param1=1.0,    # 传递__init__所需的参数\n    param2=True\n)\n\n# 在需要的地方进行实例化\nloss = MODELS.build(loss_cfg) # 等价于 loss = Loss_A(param1=1.0, param2=True)\n```\n\nMMPose 预定义的 Registry 在 `$MMPOSE/mmpose/registry.py` 中，目前支持的有：\n\n- `DATASETS`：数据集\n\n- `TRANSFORMS`：数据变换\n\n- `MODELS`：模型模块（Backbone、Neck、Head、Loss等）\n\n- `VISUALIZERS`：可视化工具\n\n- `VISBACKENDS`：可视化后端\n\n- `METRICS`：评测指标\n\n- `KEYPOINT_CODECS`：编解码器\n\n- `HOOKS`：钩子类\n\n```{note}\n需要注意的是，所有新增的模块都需要使用注册器（Registry）进行注册，并在对应目录的 `__init__.py` 中进行 `import`，以便能够使用配置文件构建其实例。\n```\n\n## 配置系统\n\n具体而言，一个配置文件主要包含如下五个部分：\n\n- 通用配置：与训练或测试无关的通用配置，如时间统计，模型存储与加载，可视化等相关 Hook，以及一些分布式相关的环境配置\n\n- 数据配置：数据增强策略，Dataset和Dataloader相关配置\n\n- 训练配置：断点恢复、模型权重加载、优化器、学习率调整、训练轮数和测试间隔等\n\n- 模型配置：模型模块、参数、损失函数等\n\n- 评测配置：模型性能评测指标\n\n你可以在 `$MMPOSE/configs` 下找到我们提供的配置文件，配置文件之间通过继承来避免冗余。为了保持配置文件简洁易读，我们将一些必要但不常改动的配置存放到了 `$MMPOSE/configs/_base_` 目录下，如果希望查阅完整的配置信息，你可以运行如下指令：\n\n```Bash\npython tools/analysis/print_config.py /PATH/TO/CONFIG\n```\n\n### 通用配置\n\n通用配置指与训练或测试无关的必要配置，主要包括：\n\n- **默认Hook**：迭代时间统计，训练日志，参数更新，checkpoint 等\n\n- **环境配置**：分布式后端，cudnn，多进程配置等\n\n- **可视化器**：可视化后端和策略设置\n\n- **日志配置**：日志等级，格式，打印和记录间隔等\n\n下面是通用配置的样例说明：\n\n```Python\n# 通用配置\ndefault_scope = 'mmpose'\ndefault_hooks = dict(\n    # 迭代时间统计，包括数据耗时和模型耗时\n    timer=dict(type='IterTimerHook'),\n\n    # 日志打印间隔，默认每 50 iters 打印一次\n    logger=dict(type='LoggerHook', interval=50),\n\n    # 用于调度学习率更新的 Hook\n    param_scheduler=dict(type='ParamSchedulerHook'),\n\n    checkpoint=dict(\n        # ckpt 保存间隔，最优 ckpt 参考指标。\n        # 例如：\n        # save_best='coco/AP' 代表以 coco/AP 作为最优指标，对应 CocoMetric 评测器的 AP 指标\n        # save_best='PCK' 代表以 PCK 作为最优指标，对应 PCKAccuracy 评测器的 PCK 指标\n        # 更多指标请前往 mmpose/evaluation/metrics/\n        type='CheckpointHook', interval=1, save_best='coco/AP',\n\n        # 最优 ckpt 保留规则，greater 代表越大越好，less 代表越小越好\n        rule='greater'),\n\n    # 分布式随机种子设置 Hook\n    sampler_seed=dict(type='DistSamplerSeedHook'))\nenv_cfg = dict(\n    # cudnn benchmark 开关，用于加速训练，但会增加显存占用\n    cudnn_benchmark=False,\n\n    # opencv 多线程配置，用于加速数据加载，但会增加显存占用\n    # 默认为 0，代表使用单线程\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n\n    # 分布式训练后端设置，支持 nccl 和 gloo\n    dist_cfg=dict(backend='nccl'))\n\n# 可视化器后端设置，默认为本地可视化\nvis_backends = [dict(type='LocalVisBackend')]\n\n# 可视化器设置\nvisualizer = dict(\n    type='PoseLocalVisualizer',\n    vis_backends=[dict(type='LocalVisBackend')],\n    name='visualizer')\nlog_processor = dict( # 训练日志格式、间隔\n    type='LogProcessor', window_size=50, by_epoch=True, num_digits=6)\n# 日志记录等级，INFO 代表记录训练日志，WARNING 代表只记录警告信息，ERROR 代表只记录错误信息\nlog_level = 'INFO'\n```\n\n```{note}\n可视化器后端设置支持 LocalVisBackend 和 TensorboardVisBackend，前者用于本地可视化，后者用于 Tensorboard 可视化，你可以根据需要进行选择。详情见 [训练与测试](./train_and_test.md) 的 【可视化训练进程】。\n```\n\n通用配置一般单独存放到 `$MMPOSE/configs/_base_` 目录下，通过如下方式进行继承：\n\n```Python\n_base_ = ['../../../_base_/default_runtime.py'] # 以运行时的config文件位置为相对路径起点\n```\n\n### 数据配置\n\n数据配置指数据处理相关的配置，主要包括：\n\n- **数据后端**：数据供给后端设置，默认为本地硬盘，我们也支持从 LMDB，S3 Bucket 等加载\n\n- **数据集**：图像与标注文件路径\n\n- **加载**：加载策略，批量大小等\n\n- **流水线**：数据增强策略\n\n- **编码器**：根据标注生成特定格式的监督信息\n\n下面是数据配置的样例说明：\n\n```Python\nbackend_args = dict(backend='local') # 数据加载后端设置，默认从本地硬盘加载\ndataset_type = 'CocoDataset' # 数据集类名\ndata_mode = 'topdown' # 算法结构类型，用于指定标注信息加载策略\ndata_root = 'data/coco/' # 数据存放路径\n # 定义数据编解码器，用于生成target和对pred进行解码，同时包含了输入图片和输出heatmap尺寸等信息\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\ntrain_pipeline = [ # 训练时数据增强\n    dict(type='LoadImage', backend_args=backend_args, # 加载图片\n    dict(type='GetBBoxCenterScale'), # 根据bbox获取center和scale\n    dict(type='RandomBBoxTransform'), # 生成随机位移、缩放、旋转变换矩阵\n    dict(type='RandomFlip', direction='horizontal'), # 生成随机翻转变换矩阵\n    dict(type='RandomHalfBody'), # 随机半身增强\n    dict(type='TopdownAffine', input_size=codec['input_size']), # 根据变换矩阵更新目标数据\n    dict(\n        type='GenerateTarget', # 根据目标数据生成监督信息\n        # 监督信息类型\n        encoder=codec, # 传入编解码器，用于数据编码，生成特定格式的监督信息\n    dict(type='PackPoseInputs') # 对target进行打包用于训练\n]\ntest_pipeline = [ # 测试时数据增强\n    dict(type='LoadImage', backend_args=backend_args), # 加载图片\n    dict(type='GetBBoxCenterScale'), # 根据bbox获取center和scale\n    dict(type='TopdownAffine', input_size=codec['input_size']), # 根据变换矩阵更新目标数据\n    dict(type='PackPoseInputs') # 对target进行打包用于训练\n]\ntrain_dataloader = dict( # 训练数据加载\n    batch_size=64, # 批次大小\n    num_workers=2, # 数据加载进程数\n    persistent_workers=True, # 在不活跃时维持进程不终止，避免反复启动进程的开销\n    sampler=dict(type='DefaultSampler', shuffle=True), # 采样策略，打乱数据\n    dataset=dict(\n        type=dataset_type , # 数据集类名\n        data_root=data_root, # 数据集路径\n        data_mode=data_mode, # 算法类型\n        ann_file='annotations/person_keypoints_train2017.json', # 标注文件路径\n        data_prefix=dict(img='train2017/'), # 图像路径\n        pipeline=train_pipeline # 数据流水线\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True, # 在不活跃时维持进程不终止，避免反复启动进程的开销\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False), # 采样策略，不进行打乱\n    dataset=dict(\n        type=dataset_type , # 数据集类名\n        data_root=data_root, # 数据集路径\n        data_mode=data_mode, # 算法类型\n        ann_file='annotations/person_keypoints_val2017.json', # 标注文件路径\n        bbox_file=\n        'data/coco/person_detection_results/COCO_val2017_detections_AP_H_56_person.json', # 检测框标注文件，topdown方法专用\n        data_prefix=dict(img='val2017/'), # 图像路径\n        test_mode=True, # 测试模式开关\n        pipeline=test_pipeline # 数据流水线\n    ))\ntest_dataloader = val_dataloader # 默认情况下不区分验证集和测试集，用户根据需要来自行定义\n```\n\n```{note}\n常用功能可以参考以下教程:\n- [恢复训练](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/train_and_test.html#id7)\n- [自动混合精度训练](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/train_and_test.html#amp)\n- [设置随机种子](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/train_and_test.html#id10)\n```\n\n### 训练配置\n\n训练配置指训练策略相关的配置，主要包括：\n\n- 从断点恢复训练\n\n- 模型权重加载\n\n- 训练轮数和测试间隔\n\n- 学习率调整策略，如 warmup，scheduler\n\n- 优化器和学习率\n\n- 高级训练策略设置，如自动学习率缩放\n\n下面是训练配置的样例说明：\n\n```Python\nresume = False # 断点恢复\nload_from = None # 模型权重加载\ntrain_cfg = dict(by_epoch=True, max_epochs=210, val_interval=10) # 训练轮数，测试间隔\nparam_scheduler = [\n    dict( # warmup策略\n        type='LinearLR', begin=0, end=500, start_factor=0.001, by_epoch=False),\n    dict( # scheduler\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\noptim_wrapper = dict(optimizer=dict(type='Adam', lr=0.0005)) # 优化器和学习率\nauto_scale_lr = dict(base_batch_size=512) # 根据batch_size自动缩放学习率\n```\n\n### 模型配置\n\n模型配置指模型训练和推理相关的配置，主要包括：\n\n- 模型结构\n\n- 损失函数\n\n- 数据解码策略\n\n- 测试时增强策略\n\n下面是模型配置的样例说明，定义了一个基于 HRNetw32 的 Top-down Heatmap-based 模型：\n\n```Python\n# 定义数据编解码器，如果在数据配置部分已经定义过则无需重复定义\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n# 模型配置\nmodel = dict(\n    type='TopdownPoseEstimator', # 模型结构决定了算法流程\n    data_preprocessor=dict( # 数据归一化和通道顺序调整，作为模型的一部分\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict( # 骨干网络定义\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256))),\n        init_cfg=dict(\n            type='Pretrained', # 预训练参数，只加载backbone权重用于迁移学习\n            checkpoint='https://download.openmmlab.com/mmpose'\n            '/pretrain_models/hrnet_w32-36af842e.pth'),\n    ),\n    head=dict( # 模型头部\n        type='HeatmapHead',\n        in_channels=32,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True), # 损失函数\n        decoder=codec), # 解码器，将heatmap解码成坐标值\n    test_cfg=dict(\n        flip_test=True, # 开启测试时水平翻转集成\n        flip_mode='heatmap', # 对heatmap进行翻转\n        shift_heatmap=True,  # 对翻转后的结果进行平移提高精度\n    ))\n```\n\n### 评测配置\n\n评测配置指公开数据集中关键点检测任务常用的评测指标，主要包括：\n\n- AR, AP and mAP\n\n- PCK, PCKh, tPCK\n\n- AUC\n\n- EPE\n\n- NME\n\n下面是评测配置的样例说明，定义了一个COCO指标评测器：\n\n```Python\nval_evaluator = dict(\n    type='CocoMetric', # coco 评测指标\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json') # 加载评测标注数据\ntest_evaluator = val_evaluator # 默认情况下不区分验证集和测试集，用户根据需要来自行定义\n```\n\n## 配置文件命名规则\n\nMMPose 配置文件命名风格如下：\n\n```Python\n{{算法信息}}_{{模块信息}}_{{训练信息}}_{{数据信息}}.py\n```\n\n文件名总体分为四部分：算法信息，模块信息，训练信息和数据信息。不同部分的单词之间用下划线 `'_'` 连接，同一部分有多个单词用短横线 `'-'` 连接。\n\n- **算法信息**：算法名称，如 `topdown-heatmap`，`topdown-rle` 等\n\n- **模块信息**：按照数据流的顺序列举一些中间的模块，其内容依赖于算法任务，如 `res101`，`hrnet-w48`等\n\n- **训练信息**：训练策略的一些设置，包括 `batch size`，`schedule` 等，如 `8xb64-210e`\n\n- **数据信息**：数据集名称、模态、输入尺寸等，如 `ap10k-256x256`，`zebra-160x160` 等\n\n有时为了避免文件名过长，会省略模型信息中一些强相关的模块，只保留关键信息，如RLE-based算法中的`GAP`，Heatmap-based算法中的 `deconv` 等。\n\n如果你希望向MMPose添加新的方法，你的配置文件同样需要遵守该命名规则。\n\n## 常见用法\n\n### 配置文件的继承\n\n该用法常用于隐藏一些必要但不需要修改的配置，以提高配置文件的可读性。假如有如下两个配置文件：\n\n`optimizer_cfg.py`:\n\n```Python\noptimizer = dict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\n```\n\n`resnet50.py`:\n\n```Python\n_base_ = ['optimizer_cfg.py']\nmodel = dict(type='ResNet', depth=50)\n```\n\n虽然我们在 `resnet50.py` 中没有定义 optimizer 字段，但由于我们写了 `_base_ = ['optimizer_cfg.py']`，会使这个配置文件获得 `optimizer_cfg.py` 中的所有字段：\n\n```Python\ncfg = Config.fromfile('resnet50.py')\ncfg.optimizer  # ConfigDict(type='SGD', lr=0.02, momentum=0.9, weight_decay=0.0001)\n```\n\n### 继承字段的修改\n\n对于继承过来的已经定义好的字典，可以直接指定对应字段进行修改，而不需要重新定义完整的字典：\n\n`resnet50_lr0.01.py`:\n\n```Python\n_base_ = ['optimizer_cfg.py']\nmodel = dict(type='ResNet', depth=50)\noptimizer = dict(lr=0.01) # 直接修改对应字段\n```\n\n这个配置文件只修改了对应字段`lr`的信息：\n\n```Python\ncfg = Config.fromfile('resnet50_lr0.01.py')\ncfg.optimizer  # ConfigDict(type='SGD', lr=0.01, momentum=0.9, weight_decay=0.0001)\n```\n\n### 删除字典中的字段\n\n如果不仅是需要修改某些字段，还需要删除已定义的一些字段，需要在重新定义这个字典时指定`_delete_=True`，表示将没有在新定义中出现的字段全部删除：\n\n`resnet50.py`:\n\n```Python\n_base_ = ['optimizer_cfg.py', 'runtime_cfg.py']\nmodel = dict(type='ResNet', depth=50)\noptimizer = dict(_delete_=True, type='SGD', lr=0.01) # 重新定义字典\n```\n\n此时字典中除了 `type` 和 `lr` 以外的内容（`momentum`和`weight_decay`）将被全部删除：\n\n```Python\ncfg = Config.fromfile('resnet50_lr0.01.py')\ncfg.optimizer  # ConfigDict(type='SGD', lr=0.01)\n```\n\n```{note}\n如果你希望更深入地了解配置系统的高级用法，可以查看 [MMEngine 教程](https://mmengine.readthedocs.io/zh_CN/latest/advanced_tutorials/config.html)。\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/dataset_tools.md",
    "content": "# 数据集标注与格式转换\n\n本章提供了一些有用的数据集处理脚本，来满足 MMPose 的数据格式要求。\n\n## 数据集标注\n\n对于 [Label Studio](https://github.com/heartexlabs/label-studio/) 用户，请依照 [Label Studio 转换工具文档](./label_studio.md) 中的方法进行标注，并将结果导出为 Label Studio 标准的 `.json` 文件，将 `Labeling Interface` 中的 `Code` 保存为 `.xml` 文件。\n\n```{note}\nMMPose **没有**对用户使用的标注工具做任何限制，只要最终的标注结果符合 MMPose 的数据格式要求即可。我们非常欢迎社区用户贡献更多的数据集标注工具使用教程和转换脚本。\n```\n\n## 浏览数据集\n\nMMPose 提供了一个有用的数据集浏览工具，通过它用户可以可视化地查看数据集的原始标注，和数据增强后的标注。这对于用户检查数据集加载和数据增强是否正确非常有用。\n\n详细的使用方法请参考 [【浏览数据集】](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/prepare_datasets.html#id5)。\n\n## 通过 MIM 下载开源数据集\n\n通过使用 [OpenXLab](https://openxlab.org.cn/datasets)，您可以直接下载开源数据集。通过平台的搜索功能，您可以快速轻松地找到他们正在寻找的数据集。使用平台上的格式化数据集，您可以高效地跨数据集执行任务。\n\n我们推荐用户跟随 [MIM 数据集下载教程](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/prepare_datasets.html#mim) 进行开源数据集的下载。\n\n## 格式转换脚本\n\nMMPose 提供了一些工具来帮助用户处理数据集。\n\n### Animal Pose 数据集\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_ICCV_2019/html/Cao_Cross-Domain_Adaptation_for_Animal_Pose_Estimation_ICCV_2019_paper.html\">Animal-Pose (ICCV'2019)</a></summary>\n\n```bibtex\n@InProceedings{Cao_2019_ICCV,\n    author = {Cao, Jinkun and Tang, Hongyang and Fang, Hao-Shu and Shen, Xiaoyong and Lu, Cewu and Tai, Yu-Wing},\n    title = {Cross-Domain Adaptation for Animal Pose Estimation},\n    booktitle = {The IEEE International Conference on Computer Vision (ICCV)},\n    month = {October},\n    year = {2019}\n}\n```\n\n</details>\n\n对于 [Animal-Pose](https://sites.google.com/view/animal-pose/)，可以从[官方网站](https://sites.google.com/view/animal-pose/)下载图像和标注。脚本 `tools/dataset_converters/parse_animalpose_dataset.py` 将原始标注转换为 MMPose 兼容的格式。预处理的[标注文件](https://download.openmmlab.com/mmpose/datasets/animalpose_annotations.tar)可用。如果您想自己生成标注，请按照以下步骤操作：\n\n1. 下载图片与标注信息并解压到 `$MMPOSE/data`，按照以下格式组织：\n\n   ```text\n   mmpose\n   ├── mmpose\n   ├── docs\n   ├── tests\n   ├── tools\n   ├── configs\n   `── data\n       │── animalpose\n           │\n           │-- VOC2012\n           │   │-- Annotations\n           │   │-- ImageSets\n           │   │-- JPEGImages\n           │   │-- SegmentationClass\n           │   │-- SegmentationObject\n           │\n           │-- animalpose_image_part2\n           │   │-- cat\n           │   │-- cow\n           │   │-- dog\n           │   │-- horse\n           │   │-- sheep\n           │\n           │-- PASCAL2011_animal_annotation\n           │   │-- cat\n           │   │   |-- 2007_000528_1.xml\n           │   │   |-- 2007_000549_1.xml\n           │   │   │-- ...\n           │   │-- cow\n           │   │-- dog\n           │   │-- horse\n           │   │-- sheep\n           │\n           │-- annimalpose_anno2\n           │   │-- cat\n           │   │   |-- ca1.xml\n           │   │   |-- ca2.xml\n           │   │   │-- ...\n           │   │-- cow\n           │   │-- dog\n           │   │-- horse\n           │   │-- sheep\n   ```\n\n2. 运行脚本\n\n   ```bash\n   python tools/dataset_converters/parse_animalpose_dataset.py\n   ```\n\n   生成的标注文件将保存在 `$MMPOSE/data/animalpose/annotations` 中。\n\n开源作者没有提供官方的 train/val/test 划分，我们选择来自 PascalVOC 的图片作为 train & val，train+val 一共 3600 张图片，5117 个标注。其中 2798 张图片，4000 个标注用于训练，810 张图片，1117 个标注用于验证。测试集包含 1000 张图片，1000 个标注用于评估。\n\n### COFW 数据集\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_iccv_2013/html/Burgos-Artizzu_Robust_Face_Landmark_2013_ICCV_paper.html\">COFW (ICCV'2013)</a></summary>\n\n```bibtex\n@inproceedings{burgos2013robust,\n  title={Robust face landmark estimation under occlusion},\n  author={Burgos-Artizzu, Xavier P and Perona, Pietro and Doll{\\'a}r, Piotr},\n  booktitle={Proceedings of the IEEE international conference on computer vision},\n  pages={1513--1520},\n  year={2013}\n}\n```\n\n</details>\n\n对于 COFW 数据集，请从 [COFW Dataset (Color Images)](https://data.caltech.edu/records/20099) 进行下载。\n\n将 `COFW_train_color.mat` 和 `COFW_test_color.mat` 移动到 `$MMPOSE/data/cofw/`，确保它们按照以下格式组织：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n```\n\n运行 `pip install h5py` 安装依赖，然后在 `$MMPOSE` 下运行脚本：\n\n```bash\npython tools/dataset_converters/parse_cofw_dataset.py\n```\n\n最终结果为：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    │── cofw\n        |── COFW_train_color.mat\n        |── COFW_test_color.mat\n        |── annotations\n        |   |── cofw_train.json\n        |   |── cofw_test.json\n        |── images\n            |── 000001.jpg\n            |── 000002.jpg\n```\n\n### DeepposeKit 数据集\n\n<details>\n<summary align=\"right\"><a href=\"https://elifesciences.org/articles/47994\">Desert Locust (Elife'2019)</a></summary>\n\n```bibtex\n@article{graving2019deepposekit,\n  title={DeepPoseKit, a software toolkit for fast and robust animal pose estimation using deep learning},\n  author={Graving, Jacob M and Chae, Daniel and Naik, Hemal and Li, Liang and Koger, Benjamin and Costelloe, Blair R and Couzin, Iain D},\n  journal={Elife},\n  volume={8},\n  pages={e47994},\n  year={2019},\n  publisher={eLife Sciences Publications Limited}\n}\n```\n\n</details>\n\n对于 [Vinegar Fly](https://github.com/jgraving/DeepPoseKit-Data)，[Desert Locust](https://github.com/jgraving/DeepPoseKit-Data), 和 [Grévy’s Zebra](https://github.com/jgraving/DeepPoseKit-Data) 数据集，请从 [DeepPoseKit-Data](https://github.com/jgraving/DeepPoseKit-Data) 下载数据。\n\n`tools/dataset_converters/parse_deepposekit_dataset.py` 脚本可以将原始标注转换为 MMPose 支持的格式。我们已经转换好的标注文件可以在这里下载：\n\n- [vinegar_fly_annotations](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_annotations.tar)\n- [locust_annotations](https://download.openmmlab.com/mmpose/datasets/locust_annotations.tar)\n- [zebra_annotations](https://download.openmmlab.com/mmpose/datasets/zebra_annotations.tar)\n\n如果你希望自己转换数据，请按照以下步骤操作：\n\n1. 下载原始图片和标注，并解压到 `$MMPOSE/data`，将它们按照以下格式组织：\n\n   ```text\n   mmpose\n   ├── mmpose\n   ├── docs\n   ├── tests\n   ├── tools\n   ├── configs\n   `── data\n       |\n       |── DeepPoseKit-Data\n       |   `── datasets\n       |       |── fly\n       |       |   |── annotation_data_release.h5\n       |       |   |── skeleton.csv\n       |       |   |── ...\n       |       |\n       |       |── locust\n       |       |   |── annotation_data_release.h5\n       |       |   |── skeleton.csv\n       |       |   |── ...\n       |       |\n       |       `── zebra\n       |           |── annotation_data_release.h5\n       |           |── skeleton.csv\n       |           |── ...\n       |\n       │── fly\n           `-- images\n               │-- 0.jpg\n               │-- 1.jpg\n               │-- ...\n   ```\n\n   图片也可以在 [vinegar_fly_images](https://download.openmmlab.com/mmpose/datasets/vinegar_fly_images.tar)，[locust_images](https://download.openmmlab.com/mmpose/datasets/locust_images.tar) 和[zebra_images](https://download.openmmlab.com/mmpose/datasets/zebra_images.tar) 下载。\n\n2. 运行脚本：\n\n   ```bash\n   python tools/dataset_converters/parse_deepposekit_dataset.py\n   ```\n\n   生成的标注文件将保存在 $MMPOSE/data/fly/annotations`，`$MMPOSE/data/locust/annotations`和`$MMPOSE/data/zebra/annotations\\` 中。\n\n由于官方数据集中没有提供测试集，我们随机选择了 90% 的图片用于训练，剩下的 10% 用于测试。\n\n### Macaque 数据集\n\n<details>\n<summary align=\"right\"><a href=\"https://www.ncbi.nlm.nih.gov/pmc/articles/pmc7874091/\">MacaquePose (bioRxiv'2020)</a></summary>\n\n```bibtex\n@article{labuguen2020macaquepose,\n  title={MacaquePose: A novel ‘in the wild’macaque monkey pose dataset for markerless motion capture},\n  author={Labuguen, Rollyn and Matsumoto, Jumpei and Negrete, Salvador and Nishimaru, Hiroshi and Nishijo, Hisao and Takada, Masahiko and Go, Yasuhiro and Inoue, Ken-ichi and Shibata, Tomohiro},\n  journal={bioRxiv},\n  year={2020},\n  publisher={Cold Spring Harbor Laboratory}\n}\n```\n\n</details>\n\n对于 [MacaquePose](http://www2.ehub.kyoto-u.ac.jp/datasets/macaquepose/index.html) 数据集，请从 [这里](http://www2.ehub.kyoto-u.ac.jp/datasets/macaquepose/index.html) 下载数据。\n\n`tools/dataset_converters/parse_macaquepose_dataset.py` 脚本可以将原始标注转换为 MMPose 支持的格式。我们已经转换好的标注文件可以在 [这里](https://download.openmmlab.com/mmpose/datasets/macaque_annotations.tar) 下载。\n\n如果你希望自己转换数据，请按照以下步骤操作：\n\n1. 下载原始图片和标注，并解压到 `$MMPOSE/data`，将它们按照以下格式组织：\n\n   ```text\n   mmpose\n   ├── mmpose\n   ├── docs\n   ├── tests\n   ├── tools\n   ├── configs\n   `── data\n       │── macaque\n           │-- annotations.csv\n           │-- images\n           │   │-- 01418849d54b3005.jpg\n           │   │-- 0142d1d1a6904a70.jpg\n           │   │-- 01ef2c4c260321b7.jpg\n           │   │-- 020a1c75c8c85238.jpg\n           │   │-- 020b1506eef2557d.jpg\n           │   │-- ...\n   ```\n\n2. 运行脚本：\n\n   ```bash\n   python tools/dataset_converters/parse_macaquepose_dataset.py\n   ```\n\n   生成的标注文件将保存在 `$MMPOSE/data/macaque/annotations` 中。\n\n由于官方数据集中没有提供测试集，我们随机选择了 90% 的图片用于训练，剩下的 10% 用于测试。\n\n### Human3.6M 数据集\n\n<details>\n<summary align=\"right\"><a href=\"https://ieeexplore.ieee.org/abstract/document/6682899/\">Human3.6M (TPAMI'2014)</a></summary>\n\n```bibtex\n@article{h36m_pami,\n  author = {Ionescu, Catalin and Papava, Dragos and Olaru, Vlad and Sminchisescu,  Cristian},\n  title = {Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human Sensing in Natural Environments},\n  journal = {IEEE Transactions on Pattern Analysis and Machine Intelligence},\n  publisher = {IEEE Computer Society},\n  volume = {36},\n  number = {7},\n  pages = {1325-1339},\n  month = {jul},\n  year = {2014}\n}\n```\n\n</details>\n\n对于 [Human3.6M](http://vision.imar.ro/human3.6m/description.php) 数据集，请从官网下载数据，放置到 `$MMPOSE/data/h36m` 下。\n\n然后执行 [预处理脚本](/tools/dataset_converters/preprocess_h36m.py)。\n\n```bash\npython tools/dataset_converters/preprocess_h36m.py --metadata {path to metadata.xml} --original data/h36m\n```\n\n这将在全帧率（50 FPS）和降频帧率（10 FPS）下提取相机参数和姿势注释。处理后的数据应具有以下结构：\n\n```text\nmmpose\n├── mmpose\n├── docs\n├── tests\n├── tools\n├── configs\n`── data\n    ├── h36m\n        ├── annotation_body3d\n        |   ├── cameras.pkl\n        |   ├── fps50\n        |   |   ├── h36m_test.npz\n        |   |   ├── h36m_train.npz\n        |   |   ├── joint2d_rel_stats.pkl\n        |   |   ├── joint2d_stats.pkl\n        |   |   ├── joint3d_rel_stats.pkl\n        |   |   `── joint3d_stats.pkl\n        |   `── fps10\n        |       ├── h36m_test.npz\n        |       ├── h36m_train.npz\n        |       ├── joint2d_rel_stats.pkl\n        |       ├── joint2d_stats.pkl\n        |       ├── joint3d_rel_stats.pkl\n        |       `── joint3d_stats.pkl\n        `── images\n            ├── S1\n            |   ├── S1_Directions_1.54138969\n            |   |   ├── S1_Directions_1.54138969_00001.jpg\n            |   |   ├── S1_Directions_1.54138969_00002.jpg\n            |   |   ├── ...\n            |   ├── ...\n            ├── S5\n            ├── S6\n            ├── S7\n            ├── S8\n            ├── S9\n            `── S11\n```\n\n然后，标注信息需要转换为 MMPose 支持的 COCO 格式。这可以通过运行以下命令完成：\n\n```bash\npython tools/dataset_converters/h36m_to_coco.py\n```\n\n### MPII 数据集\n\n<details>\n<summary align=\"right\"><a href=\"http://openaccess.thecvf.com/content_cvpr_2014/html/Andriluka_2D_Human_Pose_2014_CVPR_paper.html\">MPII (CVPR'2014)</a></summary>\n\n```bibtex\n@inproceedings{andriluka14cvpr,\n  author = {Mykhaylo Andriluka and Leonid Pishchulin and Peter Gehler and Schiele, Bernt},\n  title = {2D Human Pose Estimation: New Benchmark and State of the Art Analysis},\n  booktitle = {IEEE Conference on Computer Vision and Pattern Recognition (CVPR)},\n  year = {2014},\n  month = {June}\n}\n```\n\n</details>\n\n对于 [MPII](http://human-pose.mpi-inf.mpg.de/) 数据集，请从官网下载数据，放置到 `$MMPOSE/data/mpii` 下。\n\n我们提供了一个脚本来将 `.mat` 格式的标注文件转换为 `.json` 格式。这可以通过运行以下命令完成：\n\n```shell\npython tools/dataset_converters/mat2json ${PRED_MAT_FILE} ${GT_JSON_FILE} ${OUTPUT_PRED_JSON_FILE}\n```\n\n例如：\n\n```shell\npython tools/dataset/mat2json work_dirs/res50_mpii_256x256/pred.mat data/mpii/annotations/mpii_val.json pred.json\n```\n\n### Label Studio 数据集\n\n<details>\n<summary align=\"right\"><a href=\"https://github.com/heartexlabs/label-studio/\">Label Studio</a></summary>\n\n```bibtex\n@misc{Label Studio,\n  title={{Label Studio}: Data labeling software},\n  url={https://github.com/heartexlabs/label-studio},\n  note={Open source software available from https://github.com/heartexlabs/label-studio},\n  author={\n    Maxim Tkachenko and\n    Mikhail Malyuk and\n    Andrey Holmanyuk and\n    Nikolai Liubimov},\n  year={2020-2022},\n}\n```\n\n</details>\n\n对于 [Label Studio](https://github.com/heartexlabs/label-studio/) 用户，请依照 [Label Studio 转换工具文档](./label_studio.md) 中的方法进行标注，并将结果导出为 Label Studio 标准的 `.json` 文件，将 `Labeling Interface` 中的 `Code` 保存为 `.xml` 文件。\n\n我们提供了一个脚本来将 Label Studio 标准的 `.json` 格式标注文件转换为 COCO 标准的 `.json` 格式。这可以通过运行以下命令完成：\n\n```shell\npython tools/dataset_converters/labelstudio2coco.py ${LS_JSON_FILE} ${LS_XML_FILE} ${OUTPUT_COCO_JSON_FILE}\n```\n\n例如：\n\n```shell\npython tools/dataset_converters/labelstudio2coco.py config.xml project-1-at-2023-05-13-09-22-91b53efa.json output/result.json\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/how_to_deploy.md",
    "content": "# 模型精简与部署\n\n本章将介绍如何导出与部署 MMPose 训练得到的模型，包含以下内容：\n\n- [模型精简](#模型精简)\n- [使用 MMDeploy 部署](#使用-mmdeploy-部署)\n  - [MMDeploy 介绍](#mmdeploy-介绍)\n  - [模型支持列表](#模型支持列表)\n  - [安装](#安装)\n  - [模型转换](#模型转换)\n    - [如何查找 MMPose 模型对应的部署配置文件](#如何查找-mmpose-模型对应的部署配置文件)\n    - [RTMPose 模型导出示例](#rtmpose-模型导出示例)\n    - [ONNX](#onnx)\n    - [TensorRT](#tensorrt)\n    - [高级设置](#高级设置)\n  - [模型测速](#模型测速)\n  - [精度验证](#精度验证)\n\n## 模型精简\n\n在默认状态下，MMPose 训练过程中保存的 checkpoint 文件包含了模型的所有信息，包括模型结构、权重、优化器状态等。这些信息对于模型的部署来说是冗余的，因此我们需要对模型进行精简，精简后的 `.pth` 文件大小甚至能够缩小一半以上。\n\nMMPose 提供了 [tools/misc/publish_model.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tools/misc/publish_model.py) 来进行模型精简，使用方式如下：\n\n```shell\npython tools/misc/publish_model.py ${IN_FILE} ${OUT_FILE}\n```\n\n例如：\n\n```shell\npython tools/misc/publish_model.py ./epoch_10.pth ./epoch_10_publish.pth\n```\n\n脚本会自动对模型进行精简，并将精简后的模型保存到制定路径，并在文件名的最后加上时间戳，例如 `./epoch_10_publish-21815b2c_20230726.pth`。\n\n## 使用 MMDeploy 部署\n\n### MMDeploy 介绍\n\nMMDeploy 是 OpenMMLab 模型部署工具箱，为各算法库提供统一的部署体验。基于 MMDeploy，开发者可以轻松从 MMPose 生成指定硬件所需 SDK，省去大量适配时间。\n\n- 你可以从 [【硬件模型库】](https://platform.openmmlab.com/deploee) 直接下载 SDK 版模型（ONNX、TensorRT、ncnn 等）。\n- 同时我们也支持 [在线模型转换](https://platform.openmmlab.com/deploee/task-convert-list)，从而无需本地安装 MMDeploy。\n\n更多介绍和使用指南见 [MMDeploy 文档](https://mmdeploy.readthedocs.io/zh_CN/latest/get_started.html)。\n\n### 模型支持列表\n\n| Model                                                                                                     | Task          | ONNX Runtime | TensorRT | ncnn | PPLNN | OpenVINO | CoreML | TorchScript |\n| :-------------------------------------------------------------------------------------------------------- | :------------ | :----------: | :------: | :--: | :---: | :------: | :----: | :---------: |\n| [HRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#hrnet-cvpr-2019)          | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [MSPN](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#mspn-arxiv-2019)           | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [LiteHRNet](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/backbones.html#litehrnet-cvpr-2021)  | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [Hourglass](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#hourglass-eccv-2016) | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [SimCC](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html#simcc-eccv-2022)         | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [RTMPose](https://github.com/open-mmlab/mmpose/tree/main/projects/rtmpose)                                | PoseDetection |      Y       |    Y     |  Y   |   N   |    Y     |   Y    |      Y      |\n| [YoloX-Pose](https://github.com/open-mmlab/mmpose/tree/main/projects/yolox_pose)                          | PoseDetection |      Y       |    Y     |  N   |   N   |    Y     |   Y    |      Y      |\n\n### 安装\n\n在开始部署之前，首先你需要确保正确安装了 MMPose, MMDetection, MMDeploy，相关安装教程如下：\n\n- [安装 MMPose 与 MMDetection](../installation.md)\n- [安装 MMDeploy](https://mmdeploy.readthedocs.io/zh_CN/latest/04-supported-codebases/mmpose.html)\n\n根据部署后端的不同，有的后端需要对 MMDeploy 支持的**自定义算子进行编译**，请根据需求前往对应的文档确保环境搭建正确：\n\n- [ONNX](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/onnxruntime.html)\n- [TensorRT](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/tensorrt.html)\n- [OpenVINO](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/openvino.html)\n- [ncnn](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/ncnn.html)\n- [TorchScript](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/torchscript.html)\n- [更多](https://github.com/open-mmlab/mmdeploy/tree/main/docs/zh_cn/05-supported-backends)\n\n### 模型转换\n\n在完成安装之后，你就可以开始模型部署了。通过 MMDeploy 提供的 [tools/deploy.py](https://github.com/open-mmlab/mmdeploy/blob/main/tools/deploy.py) 可以方便地将 MMPose 模型转换到不同的部署后端。\n\n使用方法如下：\n\n```shell\npython ./tools/deploy.py \\\n    ${DEPLOY_CFG_PATH} \\\n    ${MODEL_CFG_PATH} \\\n    ${MODEL_CHECKPOINT_PATH} \\\n    ${INPUT_IMG} \\\n    --test-img ${TEST_IMG} \\\n    --work-dir ${WORK_DIR} \\\n    --calib-dataset-cfg ${CALIB_DATA_CFG} \\\n    --device ${DEVICE} \\\n    --log-level INFO \\\n    --show \\\n    --dump-info\n```\n\n参数描述：\n\n- `deploy_cfg` : mmdeploy 针对此模型的部署配置，包含推理框架类型、是否量化、输入 shape 是否动态等。配置文件之间可能有引用关系，`configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py` 是一个示例。\n\n- `model_cfg` : mm 算法库的模型配置，例如 `mmpose/configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_aic-coco-256x192.py`，与 mmdeploy 的路径无关。\n\n- `checkpoint` : torch 模型路径。可以 http/https 开头，详见 mmcv.FileClient 的实现。\n\n- `img` : 模型转换时，用做测试的图像或点云文件路径。\n\n- `--test-img` : 用于测试模型的图像文件路径。默认设置成None。\n\n- `--work-dir` : 工作目录，用来保存日志和模型文件。\n\n- `--calib-dataset-cfg` : 此参数只有int8模式下生效，用于校准数据集配置文件。若在int8模式下未传入参数，则会自动使用模型配置文件中的’val’数据集进行校准。\n\n- `--device` : 用于模型转换的设备。 默认是cpu，对于 trt 可使用 cuda:0 这种形式。\n\n- `--log-level` : 设置日记的等级，选项包括'CRITICAL'， 'FATAL'， 'ERROR'， 'WARN'， 'WARNING'， 'INFO'， 'DEBUG'， 'NOTSET'。 默认是INFO。\n\n- `--show` : 是否显示检测的结果。\n\n- `--dump-info` : 是否输出 SDK 信息。\n\n#### 如何查找 MMPose 模型对应的部署配置文件\n\n1. 所有与 MMPose 相关的部署配置文件都存放在 [configs/mmpose/](https://github.com/open-mmlab/mmdeploy/tree/main/configs/mmpose) 目录下。\n2. 部署配置文件命名遵循 `{任务}_{算法}_{部署后端}_{动态/静态}_{输入尺寸}` 。\n\n#### RTMPose 模型导出示例\n\n我们本节演示将 RTMPose 模型导出为 ONNX 和 TensorRT 格式，如果你希望了解更多内容请前往 [MMDeploy 文档](https://mmdeploy.readthedocs.io/zh_CN/latest/02-how-to-run/convert_model.html)。\n\n- ONNX 配置\n\n  - [pose-detection_simcc_onnxruntime_dynamic.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py)\n\n- TensorRT 配置\n\n  - [pose-detection_simcc_tensorrt_dynamic-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py)\n\n- 更多\n\n  |  Backend  |                                                                                Config                                                                                |\n  | :-------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n  | ncnn-fp16 | [pose-detection_simcc_ncnn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_ncnn-fp16_static-256x192.py) |\n  |  CoreML   |    [pose-detection_simcc_coreml_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_coreml_static-256x192.py)    |\n  | OpenVINO  |  [pose-detection_simcc_openvino_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_openvino_static-256x192.py)  |\n  |   RKNN    | [pose-detection_simcc_rknn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_rknn-fp16_static-256x192.py) |\n\n如果你需要对部署配置进行修改，请参考 [MMDeploy config tutorial](https://mmdeploy.readthedocs.io/zh_CN/latest/02-how-to-run/write_config.html).\n\n本教程中使用的文件结构如下：\n\n```shell\n|----mmdeploy\n|----mmpose\n```\n\n##### ONNX\n\n运行如下命令：\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}\n\n# 转换 RTMPose\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmpose-m \\\n    --device cpu \\\n    --show \\\n    --dump-info   # 导出 sdk info\n```\n\n默认导出模型文件为 `{work-dir}/end2end.onnx`\n\n##### TensorRT\n\n运行如下命令：\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}\n\n# 转换 RTMPose\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-trt/rtmpose-m \\\n    --device cuda:0 \\\n    --show \\\n    --dump-info   # 导出 sdk info\n```\n\n默认导出模型文件为 `{work-dir}/end2end.engine`\n\n如果模型顺利导出，你将会看到样例图片上的检测结果：\n\n![convert_models](https://user-images.githubusercontent.com/13503330/217726963-7815dd01-561a-4605-b0c6-07b6fe1956c3.png)\n\n###### 高级设置\n\n如果需要使用 TensorRT-FP16，你可以通过修改 MMDeploy config 中以下配置开启：\n\n```Python\n# in MMDeploy config\nbackend_config = dict(\n    type='tensorrt',\n    common_config=dict(\n        fp16_mode=True  # 打开 fp16\n    ))\n```\n\n### 模型测速\n\n如果需要测试模型在部署框架下的推理速度，MMDeploy 提供了方便的 [tools/profiler.py](https://github.com/open-mmlab/mmdeploy/blob/main/tools/profiler.py) 脚本。\n\n用户需要准备一个存放测试图片的文件夹`./test_images`，profiler 将随机从该目录下抽取图片用于模型测速。\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}\n\npython tools/profiler.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    ../test_images \\\n    --model {WORK_DIR}/end2end.onnx \\\n    --shape 256x192 \\\n    --device cpu \\\n    --warmup 50 \\\n    --num-iter 200\n```\n\n测试结果如下：\n\n```shell\n01/30 15:06:35 - mmengine - INFO - [onnxruntime]-70 times per count: 8.73 ms, 114.50 FPS\n01/30 15:06:36 - mmengine - INFO - [onnxruntime]-90 times per count: 9.05 ms, 110.48 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-110 times per count: 9.87 ms, 101.32 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-130 times per count: 9.99 ms, 100.10 FPS\n01/30 15:06:38 - mmengine - INFO - [onnxruntime]-150 times per count: 10.39 ms, 96.29 FPS\n01/30 15:06:39 - mmengine - INFO - [onnxruntime]-170 times per count: 10.77 ms, 92.86 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-190 times per count: 10.98 ms, 91.05 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-210 times per count: 11.19 ms, 89.33 FPS\n01/30 15:06:41 - mmengine - INFO - [onnxruntime]-230 times per count: 11.16 ms, 89.58 FPS\n01/30 15:06:42 - mmengine - INFO - [onnxruntime]-250 times per count: 11.06 ms, 90.41 FPS\n----- Settings:\n+------------+---------+\n| batch size |    1    |\n|   shape    | 256x192 |\n| iterations |   200   |\n|   warmup   |    50   |\n+------------+---------+\n----- Results:\n+--------+------------+---------+\n| Stats  | Latency/ms |   FPS   |\n+--------+------------+---------+\n|  Mean  |   11.060   |  90.412 |\n| Median |   11.852   |  84.375 |\n|  Min   |   7.812    | 128.007 |\n|  Max   |   13.690   |  73.044 |\n+--------+------------+---------+\n```\n\n```{note}\n如果你希望详细了解 profiler 的更多参数设置与功能，可以前往 [Profiler 文档](https://mmdeploy.readthedocs.io/en/main/02-how-to-run/useful_tools.html#profiler)。\n```\n\n### 精度验证\n\n如果需要测试模型在部署框架下的推理精度，MMDeploy 提供了方便的 `tools/test.py` 脚本。\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}\n\npython tools/test.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ./mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    --model {PATH_TO_MODEL}/rtmpose_m.pth \\\n    --device cpu\n```\n\n```{note}\n详细内容请参考 [MMDeploy 文档](https://github.com/open-mmlab/mmdeploy/blob/main/docs/zh_cn/02-how-to-run/profile_model.md)\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/inference.md",
    "content": "# 使用现有模型进行推理\n\nMMPose 为姿态估计提供了大量可以从 [模型库](https://mmpose.readthedocs.io/en/latest/model_zoo.html) 中找到的预测训练模型。\n\n本指南将演示**如何执行推理**，或使用训练过的模型对提供的图像或视频运行姿态估计。\n\nMMPose 提供了两种推理接口：\n\n1. 推理器：统一的推理接口\n2. 推理 API：用于更加灵活的自定义推理\n\n## 推理器：统一的推理接口\n\nMMPose 提供了一个被称为 [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 的、全面的推理 API。这个 API 使得用户得以使用所有 MMPose 支持的模型来对图像和视频进行模型推理。此外，该API可以完成推理结果自动化，并方便用户保存预测结果。\n\n### 基本用法\n\n[MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 可以在任何 Python 程序中被用来执行姿态估计任务。以下是在一个在 Python Shell 中使用预训练的人体姿态模型对给定图像进行推理的示例。\n\n```python\nfrom mmpose.apis import MMPoseInferencer\n\nimg_path = 'tests/data/coco/000000000785.jpg'   # 将img_path替换给你自己的路径\n\n# 使用模型别名创建推理器\ninferencer = MMPoseInferencer('human')\n\n# MMPoseInferencer采用了惰性推断方法，在给定输入时创建一个预测生成器\nresult_generator = inferencer(img_path, show=True)\nresult = next(result_generator)\n```\n\n如果一切正常，你将在一个新窗口中看到下图：\n\n![inferencer_result_coco](https://user-images.githubusercontent.com/26127467/220008302-4a57fd44-0978-408e-8351-600e5513316a.jpg)\n\n`result` 变量是一个包含两个键值 `'visualization'` 和 `'predictions'` 的字典。\n\n- `'visualization'` 键对应的值是一个列表，该列表：\n  - 包含可视化结果，例如输入图像、估计姿态的标记，以及可选的预测热图。\n  - 如果没有指定 `return_vis` 参数，该列表将保持为空。\n- `'predictions'` 键对应的值是：\n  - 一个包含每个检测实例的预估关键点的列表。\n\n`result` 字典的结构如下所示：\n\n```python\nresult = {\n    'visualization': [\n        # 元素数量：batch_size（默认为1）\n        vis_image_1,\n        ...\n    ],\n    'predictions': [\n        # 每张图像的姿态估计结果\n        # 元素数量：batch_size（默认为1）\n        [\n            # 每个检测到的实例的姿态信息\n            # 元素数量：检测到的实例数\n            {'keypoints': ...,  # 实例 1\n            'keypoint_scores': ...,\n            ...\n            },\n            {'keypoints': ...,  # 实例 2\n            'keypoint_scores': ...,\n            ...\n            },\n        ]\n    ...\n    ]\n}\n```\n\n还可以使用用于用于推断的**命令行界面工具**（CLI, command-line interface）: `demo/inferencer_demo.py`。这个工具允许用户使用以下命令使用相同的模型和输入执行推理：\n\n```python\npython demo/inferencer_demo.py 'tests/data/coco/000000000785.jpg' \\\n    --pose2d 'human' --show --pred-out-dir 'predictions'\n```\n\n预测结果将被保存在路径 `predictions/000000000785.json` 。作为一个API，`inferencer_demo.py` 的输入参数与 [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 的相同。前者能够处理一系列输入类型，包括以下内容：\n\n- 图像路径\n\n- 视频路径\n\n- 文件夹路径（这会导致该文件夹中的所有图像都被推断出来）\n\n- 表示图像的 numpy array (在命令行界面工具中未支持)\n\n- 表示图像的 numpy array 列表 (在命令行界面工具中未支持)\n\n- 摄像头（在这种情况下，输入参数应该设置为 `webcam` 或 `webcam:{CAMERA_ID}`）\n\n当输入对应于多个图像时，例如输入为**视频**或**文件夹**路径时，推理生成器必须被遍历，以便推理器对视频/文件夹中的所有帧/图像进行推理。以下是一个示例：\n\n```python\nfolder_path = 'tests/data/coco'\n\nresult_generator = inferencer(folder_path, show=True)\nresults = [result for result in result_generator]\n```\n\n在这个示例中，`inferencer` 接受 `folder_path` 作为输入，并返回一个生成器对象（`result_generator`），用于生成推理结果。通过遍历 `result_generator` 并将每个结果存储在 `results` 列表中，您可以获得视频/文件夹中所有帧/图像的推理结果。\n\n### 自定义姿态估计模型\n\n[MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 提供了几种可用于自定义所使用的模型的方法：\n\n```python\n# 使用模型别名构建推理器\ninferencer = MMPoseInferencer('human')\n\n# 使用模型配置名构建推理器\ninferencer = MMPoseInferencer('td-hm_hrnet-w32_8xb64-210e_coco-256x192')\n# 使用 3D 模型配置名构建推理器\ninferencer = MMPoseInferencer(pose3d=\"motionbert_dstformer-ft-243frm_8xb32-120e_h36m\")\n\n# 使用模型配置文件和权重文件的路径或 URL 构建推理器\ninferencer = MMPoseInferencer(\n    pose2d='configs/body_2d_keypoint/topdown_heatmap/coco/' \\\n           'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py',\n    pose2d_weights='https://download.openmmlab.com/mmpose/top_down/' \\\n                   'hrnet/hrnet_w32_coco_256x192-c78dce93_20200708.pth'\n)\n```\n\n模型别名的完整列表可以在模型别名部分中找到。\n\n上述代码为 2D 模型推理器的构建例子。3D 模型的推理器可以用类似的方式通过 `pose3d` 参数构建：\n\n```python\n# 使用 3D 模型别名构建推理器\ninferencer = MMPoseInferencer(pose3d=\"human3d\")\n\n# 使用 3D 模型配置名构建推理器\ninferencer = MMPoseInferencer(pose3d=\"motionbert_dstformer-ft-243frm_8xb32-120e_h36m\")\n\n# 使用 3D 模型配置文件和权重文件的路径或 URL 构建推理器\ninferencer = MMPoseInferencer(\n    pose3d='configs/body_3d_keypoint/motionbert/h36m/' \\\n           'motionbert_dstformer-ft-243frm_8xb32-120e_h36m.py',\n    pose3d_weights='https://download.openmmlab.com/mmpose/v1/body_3d_keypoint/' \\\n                   'pose_lift/h36m/motionbert_ft_h36m-d80af323_20230531.pth'\n)\n```\n\n此外，自顶向下的姿态估计器还需要一个对象检测模型。[MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 能够推断用 MMPose 支持的数据集训练的模型的实例类型，然后构建必要的对象检测模型。用户也可以通过以下方式手动指定检测模型:\n\n```python\n# 通过别名指定检测模型\n# 可用的别名包括“human”、“hand”、“face”、“animal”、\n# 以及mmdet中定义的任何其他别名\ninferencer = MMPoseInferencer(\n    # 假设姿态估计器是在自定义数据集上训练的\n    pose2d='custom_human_pose_estimator.py',\n    pose2d_weights='custom_human_pose_estimator.pth',\n    det_model='human'\n)\n\n# 使用模型配置名称指定检测模型\ninferencer = MMPoseInferencer(\n    pose2d='human',\n    det_model='yolox_l_8x8_300e_coco',\n    det_cat_ids=[0],  # 指定'human'类的类别id\n)\n\n# 使用模型配置文件和权重文件的路径或URL构建推理器\ninferencer = MMPoseInferencer(\n    pose2d='human',\n    det_model=f'{PATH_TO_MMDET}/configs/yolox/yolox_l_8x8_300e_coco.py',\n    det_weights='https://download.openmmlab.com/mmdetection/v2.0/' \\\n                'yolox/yolox_l_8x8_300e_coco/' \\\n                'yolox_l_8x8_300e_coco_20211126_140236-d3bd2b23.pth',\n    det_cat_ids=[0],  # 指定'human'类的类别id\n)\n```\n\n### 转储结果\n\n在执行姿态估计推理任务之后，您可能希望保存结果以供进一步分析或处理。本节将指导您将预测的关键点和可视化结果保存到本地。\n\n要将预测保存在<mark>JSON文件</mark>中，在运行 [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 的实例 `inferencer` 时使用 `pred_out_dir` 参数:\n\n```python\nresult_generator = inferencer(img_path, pred_out_dir='predictions')\nresult = next(result_generator)\n```\n\n预测结果将以 JSON 格式保存在 `predictions/` 文件夹中，每个文件以相应的输入图像或视频的名称命名。\n\n对于更高级的场景，还可以直接从 `inferencer` 返回的 `result` 字典中访问预测结果。其中，`predictions` 包含输入图像或视频中每个单独实例的预测关键点列表。然后，您可以使用您喜欢的方法操作或存储这些结果。\n\n请记住，如果你想将<mark>可视化图像</mark>和预测文件保存在一个文件夹中，你可以使用 `out_dir` 参数：\n\n```python\nresult_generator = inferencer(img_path, out_dir='output')\nresult = next(result_generator)\n```\n\n在这种情况下，可视化图像将保存在 `output/visualization/` 文件夹中，而预测将存储在 `output/forecasts/` 文件夹中。\n\n### 可视化\n\n推理器 `inferencer` 可以自动对输入的图像或视频进行预测。可视化结果可以显示在一个新的窗口中，并保存在本地。\n\n要在新窗口中查看可视化结果，请使用以下代码：\n\n请注意：\n\n- 如果输入视频来自网络摄像头，默认情况下将在新窗口中显示可视化结果，以此让用户看到输入\n\n- 如果平台上没有 GUI，这个步骤可能会卡住\n\n要将可视化结果保存在本地，可以像这样指定`vis_out_dir`参数:\n\n```python\nresult_generator = inferencer(img_path, vis_out_dir='vis_results')\nresult = next(result_generator)\n```\n\n输入图片或视频的可视化预测结果将保存在 `vis_results/` 文件夹中\n\n在开头展示的滑雪图中，姿态的可视化估计结果由关键点（用实心圆描绘）和骨架（用线条表示）组成。这些视觉元素的默认大小可能不会产生令人满意的结果。用户可以使用 `radius` 和 `thickness` 参数来调整圆的大小和线的粗细，如下所示：\n\n```python\nresult_generator = inferencer(img_path, show=True, radius=4, thickness=2)\nresult = next(result_generator)\n```\n\n### 推理器参数\n\n[MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 提供了各种自定义姿态估计、可视化和保存预测结果的参数。下面是<mark>初始化</mark>推理器时可用的参数列表及对这些参数的描述：\n\n| Argument         | Description                                                  |\n| ---------------- | ------------------------------------------------------------ |\n| `pose2d`         | 指定 2D 姿态估计模型的模型别名、配置文件名称或配置文件路径。 |\n| `pose2d_weights` | 指定 2D 姿态估计模型权重文件的URL或本地路径。                |\n| `pose3d`         | 指定 3D 姿态估计模型的模型别名、配置文件名称或配置文件路径。 |\n| `pose3d_weights` | 指定 3D 姿态估计模型权重文件的URL或本地路径。                |\n| `det_model`      | 指定对象检测模型的模型别名、配置文件名或配置文件路径。       |\n| `det_weights`    | 指定对象检测模型权重文件的 URL 或本地路径。                  |\n| `det_cat_ids`    | 指定与要检测的对象类对应的类别 id 列表。                     |\n| `device`         | 执行推理的设备。如果为 `None`，推理器将选择最合适的一个。    |\n| `scope`          | 定义模型模块的名称空间                                       |\n\n推理器被设计用于可视化和保存预测。以下表格列出了在使用 [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) <mark>进行推断</mark>时可用的参数列表，以及它们与 2D 和 3D 推理器的兼容性：\n\n| 参数                      | 描述                                                                                                                       | 2D  | 3D  |\n| ------------------------- | -------------------------------------------------------------------------------------------------------------------------- | --- | --- |\n| `show`                    | 控制是否在弹出窗口中显示图像或视频。                                                                                       | ✔️  | ✔️  |\n| `radius`                  | 设置可视化关键点的半径。                                                                                                   | ✔️  | ✔️  |\n| `thickness`               | 确定可视化链接的厚度。                                                                                                     | ✔️  | ✔️  |\n| `kpt_thr`                 | 设置关键点分数阈值。分数超过此阈值的关键点将被显示。                                                                       | ✔️  | ✔️  |\n| `draw_bbox`               | 决定是否显示实例的边界框。                                                                                                 | ✔️  | ✔️  |\n| `draw_heatmap`            | 决定是否绘制预测的热图。                                                                                                   | ✔️  | ❌  |\n| `black_background`        | 决定是否在黑色背景上显示预估的姿势。                                                                                       | ✔️  | ❌  |\n| `skeleton_style`          | 设置骨架样式。可选项包括 'mmpose'（默认）和 'openpose'。                                                                   | ✔️  | ❌  |\n| `use_oks_tracking`        | 决定是否在追踪中使用OKS作为相似度测量。                                                                                    | ❌  | ✔️  |\n| `tracking_thr`            | 设置追踪的相似度阈值。                                                                                                     | ❌  | ✔️  |\n| `disable_norm_pose_2d`    | 决定是否将边界框缩放至数据集的平均边界框尺寸，并将边界框移至数据集的平均边界框中心。                                       | ❌  | ✔️  |\n| `disable_rebase_keypoint` | 决定是否将最低关键点的高度置为 0。                                                                                         | ❌  | ✔️  |\n| `num_instances`           | 设置可视化结果中显示的实例数量。如果设置为负数，则所有实例的结果都会可视化。                                               | ❌  | ✔️  |\n| `return_vis`              | 决定是否在结果中包含可视化图像。                                                                                           | ✔️  | ✔️  |\n| `vis_out_dir`             | 定义保存可视化图像的文件夹路径。如果未设置，将不保存可视化图像。                                                           | ✔️  | ✔️  |\n| `return_datasamples`      | 决定是否以 `PoseDataSample` 格式返回预测。                                                                                 | ✔️  | ✔️  |\n| `pred_out_dir`            | 指定保存预测的文件夹路径。如果未设置，将不保存预测。                                                                       | ✔️  | ✔️  |\n| `out_dir`                 | 如果 `vis_out_dir` 或 `pred_out_dir` 未设置，它们将分别设置为 `f'{out_dir}/visualization'` 或 `f'{out_dir}/predictions'`。 | ✔️  | ✔️  |\n\n### 模型别名\n\nMMPose 为常用模型提供了一组预定义的别名。在初始化 [MMPoseInferencer](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/apis/inferencers/mmpose_inferencer.py#L24) 时，这些别名可以用作简略的表达方式，而不是指定完整的模型配置名称。下面是可用的模型别名及其对应的配置名称的列表：\n\n| 别名      | 配置文件名称                                       | 对应任务         | 姿态估计模型  | 检测模型            |\n| --------- | -------------------------------------------------- | ---------------- | ------------- | ------------------- |\n| animal    | rtmpose-m_8xb64-210e_ap10k-256x256                 | 动物姿态估计     | RTMPose-m     | RTMDet-m            |\n| human     | rtmpose-m_8xb256-420e_body8-256x192                | 人体姿态估计     | RTMPose-m     | RTMDet-m            |\n| body26    | rtmpose-m_8xb512-700e_body8-halpe26-256x192        | 人体姿态估计     | RTMPose-m     | RTMDet-m            |\n| face      | rtmpose-m_8xb256-120e_face6-256x256                | 人脸关键点检测   | RTMPose-m     | yolox-s             |\n| hand      | rtmpose-m_8xb256-210e_hand5-256x256                | 手部关键点检测   | RTMPose-m     | ssdlite_mobilenetv2 |\n| wholebody | rtmpose-m_8xb64-270e_coco-wholebody-256x192        | 人体全身姿态估计 | RTMPose-m     | RTMDet-m            |\n| vitpose   | td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192  | 人体姿态估计     | ViTPose-base  | RTMDet-m            |\n| vitpose-s | td-hm_ViTPose-small-simple_8xb64-210e_coco-256x192 | 人体姿态估计     | ViTPose-small | RTMDet-m            |\n| vitpose-b | td-hm_ViTPose-base-simple_8xb64-210e_coco-256x192  | 人体姿态估计     | ViTPose-base  | RTMDet-m            |\n| vitpose-l | td-hm_ViTPose-large-simple_8xb64-210e_coco-256x192 | 人体姿态估计     | ViTPose-large | RTMDet-m            |\n| vitpose-h | td-hm_ViTPose-huge-simple_8xb64-210e_coco-256x192  | 人体姿态估计     | ViTPose-huge  | RTMDet-m            |\n\n下表列出了可用的 3D 姿态估计模型别名及其对应的配置文件：\n\n| 别名    | 配置文件名称                                 | 对应任务          | 3D 姿态估计模型 | 2D 姿态估计模型 | 检测模型 |\n| ------- | -------------------------------------------- | ----------------- | --------------- | --------------- | -------- |\n| human3d | vid_pl_motionbert_8xb32-120e_h36m            | 3D 人体姿态估计   | MotionBert      | RTMPose-m       | RTMDet-m |\n| hand3d  | internet_res50_4xb16-20e_interhand3d-256x256 | 3D 手部关键点检测 | InterNet        | -               | 全图     |\n\n此外，用户可以使用命令行界面工具显示所有可用的别名，使用以下命令:\n\n```shell\npython demo/inferencer_demo.py --show-alias\n```\n\n## 推理 API：用于更加灵活的自定义推理\n\nMMPose 提供了单独的 Python API 用于不同模型的推理，这种推理方式更加灵活，但是需要用户自己处理输入和输出，因此适合于**熟悉 MMPose** 的用户。\n\nMMPose 提供的 Python 推理接口存放于 [$MMPOSE/mmpose/apis](https://github.com/open-mmlab/mmpose/tree/dev-1.x/mmpose/apis) 目录下，以下是一个构建 topdown 模型并进行推理的示例：\n\n### 构建模型\n\n```python\nfrom mmcv.image import imread\n\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import merge_data_samples\n\nmodel_cfg = 'configs/body_2d_keypoint/rtmpose/coco/rtmpose-m_8xb256-420e_coco-256x192.py'\n\nckpt = 'https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.pth'\n\ndevice = 'cuda'\n\n# 使用初始化接口构建模型\nmodel = init_model(model_cfg, ckpt, device=device)\n```\n\n### 推理\n\n```python\nimg_path = 'tests/data/coco/000000000785.jpg'\n\n# 单张图片推理\nbatch_results = inference_topdown(model, img_path)\n```\n\n推理接口返回的结果是一个 PoseDataSample 列表，每个 PoseDataSample 对应一张图片的推理结果。PoseDataSample 的结构如下所示：\n\n```python\n[\n    <PoseDataSample(\n\n        ori_shape: (425, 640)\n        img_path: 'tests/data/coco/000000000785.jpg'\n        input_size: (192, 256)\n        flip_indices: [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]\n        img_shape: (425, 640)\n\n        gt_instances: <InstanceData(\n                bboxes: array([[  0.,   0., 640., 425.]], dtype=float32)\n                bbox_centers: array([[320. , 212.5]], dtype=float32)\n                bbox_scales: array([[ 800.    , 1066.6666]], dtype=float32)\n                bbox_scores: array([1.], dtype=float32)\n            )>\n\n        gt_instance_labels: <InstanceData()>\n\n        pred_instances: <InstanceData(\n                keypoints: array([[[365.83333333,  87.50000477],\n                            [372.08333333,  79.16667175],\n                            [361.66666667,  81.25000501],\n                            [384.58333333,  85.41667151],\n                            [357.5       ,  85.41667151],\n                            [407.5       , 112.50000381],\n                            [363.75      , 125.00000334],\n                            [438.75      , 150.00000238],\n                            [347.08333333, 158.3333354 ],\n                            [451.25      , 170.83333492],\n                            [305.41666667, 177.08333468],\n                            [432.5       , 214.58333325],\n                            [401.25      , 218.74999976],\n                            [430.41666667, 285.41666389],\n                            [370.        , 274.99999762],\n                            [470.        , 356.24999452],\n                            [403.33333333, 343.74999499]]])\n                bbox_scores: array([1.], dtype=float32)\n                bboxes: array([[  0.,   0., 640., 425.]], dtype=float32)\n                keypoint_scores: array([[0.8720184 , 0.9068178 , 0.89255375, 0.94684595, 0.83111566,\n                            0.9929208 , 1.0862956 , 0.9265839 , 0.9781244 , 0.9008082 ,\n                            0.9043166 , 1.0150217 , 1.1122335 , 1.0207931 , 1.0099326 ,\n                            1.0480015 , 1.0897669 ]], dtype=float32)\n                keypoints_visible: array([[0.8720184 , 0.9068178 , 0.89255375, 0.94684595, 0.83111566,\n                            0.9929208 , 1.0862956 , 0.9265839 , 0.9781244 , 0.9008082 ,\n                            0.9043166 , 1.0150217 , 1.1122335 , 1.0207931 , 1.0099326 ,\n                            1.0480015 , 1.0897669 ]], dtype=float32)\n            )>\n    )>\n]\n```\n\n用户可以通过 `.` 来访问 PoseDataSample 中的数据，例如：\n\n```python\npred_instances = batch_results[0].pred_instances\n\npred_instances.keypoints\n# array([[[365.83333333,  87.50000477],\n#         [372.08333333,  79.16667175],\n#         [361.66666667,  81.25000501],\n#         [384.58333333,  85.41667151],\n#         [357.5       ,  85.41667151],\n#         [407.5       , 112.50000381],\n#         [363.75      , 125.00000334],\n#         [438.75      , 150.00000238],\n#         [347.08333333, 158.3333354 ],\n#         [451.25      , 170.83333492],\n#         [305.41666667, 177.08333468],\n#         [432.5       , 214.58333325],\n#         [401.25      , 218.74999976],\n#         [430.41666667, 285.41666389],\n#         [370.        , 274.99999762],\n#         [470.        , 356.24999452],\n#         [403.33333333, 343.74999499]]])\n```\n\n### 可视化\n\n在 MMPose 中，大部分可视化基于可视化器实现。可视化器是一个类，它接受数据样本并将其可视化。MMPose 提供了一个可视化器注册表，用户可以使用 `VISUALIZERS` 来实例化它。以下是一个使用可视化器可视化推理结果的示例：\n\n```python\n# 将推理结果打包\nresults = merge_data_samples(batch_results)\n\n# 初始化可视化器\nvisualizer = VISUALIZERS.build(model.cfg.visualizer)\n\n# 设置数据集元信息\nvisualizer.set_dataset_meta(model.dataset_meta)\n\nimg = imread(img_path, channel_order='rgb')\n\n# 可视化\nvisualizer.add_datasample(\n    'result',\n    img,\n    data_sample=results,\n    show=True)\n```\n\nMMPose 也提供了更简洁的可视化接口：\n\n```python\nfrom mmpose.apis import visualize\n\npred_instances = batch_results[0].pred_instances\n\nkeypoints = pred_instances.keypoints\nkeypoint_scores = pred_instances.keypoint_scores\n\nmetainfo = 'config/_base_/datasets/coco.py'\n\nvisualize(\n    img_path,\n    keypoints,\n    keypoint_scores,\n    metainfo=metainfo,\n    show=True)\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/label_studio.md",
    "content": "# Label Studio 标注工具转COCO脚本\n\n[Label Studio](https://labelstud.io/) 是一款广受欢迎的深度学习标注工具，可以对多种任务进行标注，然而对于关键点标注，Label Studio 无法直接导出成 MMPose 所需要的 COCO 格式。本文将介绍如何使用Label Studio 标注关键点数据，并利用 [labelstudio2coco.py](../../../tools/dataset_converters/labelstudio2coco.py) 工具将其转换为训练所需的格式。\n\n## Label Studio 标注要求\n\n根据 COCO 格式的要求，每个标注的实例中都需要包含关键点、分割和 bbox 的信息，然而 Label Studio 在标注时会将这些信息分散在不同的实例中，因此需要按一定规则进行标注，才能正常使用后续的脚本。\n\n1. 标签接口设置\n\n对于一个新建的 Label Studio 项目，首先要设置它的标签接口。这里需要有三种类型的标注：`KeyPointLabels`、`PolygonLabels`、`RectangleLabels`，分别对应 COCO 格式中的`keypoints`、`segmentation`、`bbox`。以下是一个标签接口的示例，可以在项目的`Settings`中找到`Labeling Interface`，点击`Code`，粘贴使用该示例。\n\n```xml\n<View>\n  <KeyPointLabels name=\"kp-1\" toName=\"img-1\">\n      <Label value=\"person\" background=\"#D4380D\"/>\n  </KeyPointLabels>\n  <PolygonLabels name=\"polygonlabel\" toName=\"img-1\">\n      <Label value=\"person\" background=\"#0DA39E\"/>\n  </PolygonLabels>\n  <RectangleLabels name=\"label\" toName=\"img-1\">\n      <Label value=\"person\" background=\"#DDA0EE\"/>\n  </RectangleLabels>\n  <Image name=\"img-1\" value=\"$img\"/>\n</View>\n```\n\n2. 标注顺序\n\n由于需要将多个标注实例中的不同类型标注组合到一个实例中，因此采取了按特定顺序标注的方式，以此来判断各标注是否位于同一个实例。标注时须按照 **KeyPointLabels -> PolygonLabels/RectangleLabels** 的顺序标注，其中 KeyPointLabels 的顺序和数量要与 MMPose 配置文件中的`dataset_info`的关键点顺序和数量一致， PolygonLabels 和 RectangleLabels 的标注顺序可以互换，且可以只标注其中一个，只要保证一个实例的标注中，以关键点开始，以非关键点结束即可。下图为标注的示例：\n\n*注：bbox 和 area 会根据靠后的 PolygonLabels/RectangleLabels 来计算，如若先标 PolygonLabels，那么bbox会是靠后的 RectangleLabels 的范围，面积为矩形的面积，反之则是多边形外接矩形和多边形的面积*\n\n![image](https://github.com/open-mmlab/mmpose/assets/15847281/b2d004d0-8361-42c5-9180-cfbac0373a94)\n\n3. 导出标注\n\n上述标注完成后，需要将标注进行导出。选择项目界面的`Export`按钮，选择`JSON`格式，再点击`Export`即可下载包含标签的 JSON 格式文件。\n\n*注：上述文件中仅仅包含标签，不包含原始图片，因此需要额外提供标注对应的图片。由于 Label Studio 会对过长的文件名进行截断，因此不建议直接使用上传的文件，而是使用`Export`功能中的导出 COCO 格式工具，使用压缩包内的图片文件夹。*\n\n![image](https://github.com/open-mmlab/mmpose/assets/15847281/9f54ca3d-8cdd-4d7f-8ed6-494badcfeaf2)\n\n## 转换工具脚本的使用\n\n转换工具脚本位于`tools/dataset_converters/labelstudio2coco.py`，使用方式如下：\n\n```bash\npython tools/dataset_converters/labelstudio2coco.py config.xml project-1-at-2023-05-13-09-22-91b53efa.json output/result.json\n```\n\n其中`config.xml`的内容为标签接口设置中提到的`Labeling Interface`中的`Code`，`project-1-at-2023-05-13-09-22-91b53efa.json`即为导出标注时导出的 Label Studio 格式的 JSON 文件，`output/result.json`为转换后得到的 COCO 格式的 JSON 文件路径，若路径不存在，该脚本会自动创建路径。\n\n随后，将图片的文件夹放置在输出目录下，即可完成 COCO 数据集的转换。目录结构示例如下：\n\n```bash\n.\n├── images\n│   ├── 38b480f2.jpg\n│   └── aeb26f04.jpg\n└── result.json\n\n```\n\n若想在 MMPose 中使用该数据集，可以进行类似如下的修改：\n\n```python\ndataset=dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='result.json',\n    data_prefix=dict(img='images/'),\n    pipeline=train_pipeline,\n)\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/mixed_datasets.md",
    "content": "# 混合数据集训练\n\nMMPose 提供了一个灵活、便捷的工具 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) 来进行混合数据集训练。它作为一个封装器，可以包含多个子数据集，并将来自不同子数据集的数据转换成一个统一的格式，以用于模型训练。使用 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) 的数据处理流程如下图所示。\n\n![combined_dataset_pipeline](https://user-images.githubusercontent.com/26127467/223333154-fb88e511-810a-423c-b755-c791d296bc43.jpg)\n\n本篇教程的后续部分将通过一个结合 COCO 和 AI Challenger (AIC) 数据集的例子详细介绍如何配置 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15)。\n\n## COCO & AIC 数据集混合案例\n\nCOCO 和 AIC 都是 2D 人体姿态数据集。但是，这两个数据集在关键点的数量和排列顺序上有所不同。下面是分别来自这两个数据集的图片及关键点：\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223335806-748498af-8da4-4666-a6d3-337e4a8996f0.png\" height=\"300px\" alt><br>\n\n有些关键点（例如“左手”）在两个数据集中都有定义，但它们具有不同的序号。具体来说，“左手”关键点在 COCO 数据集中的序号为 9，在AIC数据集中的序号为 5。此外，每个数据集都包含独特的关键点，另一个数据集中不存在。例如，面部关键点（序号为0〜4）仅在 COCO 数据集中定义，而“头顶”（序号为 12）和“颈部”（序号为 13）关键点仅在 AIC 数据集中存在。以下的维恩图显示了两个数据集中关键点之间的关系。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223338755-d838dd39-901b-4e7d-af8b-b94b5f5f9ef3.png\" height=\"200px\" alt><br>\n\n接下来，我们会介绍两种混合数据集的方式：\n\n- [将 AIC 合入 COCO 数据集](#将-aic-合入-coco-数据集)\n- [合并 AIC 和 COCO 数据集](#合并-aic-和-coco-数据集)\n\n### 将 AIC 合入 COCO 数据集\n\n如果用户想提高其模型在 COCO 或类似数据集上的性能，可以将 AIC 数据集作为辅助数据。此时应该仅选择 AIC 数据集中与 COCO 数据集共享的关键点，忽略其余关键点。此外，还需要将这些被选择的关键点在 AIC 数据集中的序号进行转换，以匹配在 COCO 数据集中对应关键点的序号。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223348541-d1f9e3b7-7e60-41b5-bf68-22e61b34bb2b.png\" height=\"200px\" alt><br>\n\n在这种情况下，来自 COCO 的数据不需要进行转换。此时 COCO 数据集可通过如下方式配置：\n\n```python\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root='data/coco/',\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[], # `pipeline` 应为空列表，因为 COCO 数据不需要转换\n)\n```\n\n对于 AIC 数据集，需要转换关键点的顺序。MMPose 提供了一个 [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11) 转换器来实现这一点。以下是配置 AIC 子数据集的示例：\n\n```python\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=17,  # 与 COCO 数据集关键点数一致\n            mapping=[  # 需要列出所有带转换关键点的序号\n                (0, 6),  # 0 (AIC 中的序号) -> 6 (COCO 中的序号)\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n```\n\n[KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11) 会将原序号在 0 到 11 之间的关键点的序号转换为在 5 到 16 之间的对应序号。同时，在 AIC 中序号为为 12 和 13 的关键点将被删除。另外，目标序号在 0 到 4 之间的关键点在 `mapping` 参数中没有定义，这些点将被设为不可见，并且不会在训练中使用。\n\n子数据集都完成配置后, 混合数据集 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) 可以通过如下方式配置:\n\n```python\ndataset = dict(\n    type='CombinedDataset',\n    # 混合数据集关键点顺序和 COCO 数据集相同，\n    # 所以使用 COCO 数据集的描述信息\n    metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n    datasets=[dataset_coco, dataset_aic],\n    # `train_pipeline` 包含了常用的数据预处理，\n    # 比如图片读取、数据增广等\n    pipeline=train_pipeline,\n    # sample_ratio_factor 参数是用来调节每个子数据集\n    # 在组合数据集中的样本数量比例的\n    sample_ratio_factor=[1.0, 0.5]\n)\n```\n\nMMPose 提供了一份完整的 [配置文件](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-merge.py) 来将 AIC 合入 COCO 数据集并用于训练网络。用户可以查阅这个文件以获取更多细节，或者参考这个文件来构建新的混合数据集。\n\n### 合并 AIC 和 COCO 数据集\n\n将 AIC 合入 COCO 数据集的过程中丢弃了部分 AIC 数据集中的标注信息。如果用户想要使用两个数据集中的所有信息，可以将两个数据集合并，即在两个数据集中取关键点的并集。\n\n<img src=\"https://user-images.githubusercontent.com/26127467/223356617-075e0ab1-0ed3-426d-bc88-4f16be93f0ba.png\" height=\"200px\" alt><br>\n\n在这种情况下，COCO 和 AIC 数据集都需要使用 [KeypointConverter](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/transforms/converting.py#L11) 来调整它们关键点的顺序：\n\n```python\ndataset_coco = dict(\n    type='CocoDataset',\n    data_root='data/coco/',\n    ann_file='annotations/person_keypoints_train2017.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,  # 并集中有 19 个关键点\n            mapping=[\n                (0, 0),\n                (1, 1),\n                # 省略\n                (16, 16),\n            ])\n    ])\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root='data/aic/',\n    ann_file='annotations/aic_train.json',\n    data_prefix=dict(img='ai_challenger_keypoint_train_20170902/'\n                     'keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=19,  # 并集中有 19 个关键点\n            mapping=[\n                (0, 6),\n                # 省略\n                (12, 17),\n                (13, 18),\n            ])\n    ],\n)\n```\n\n合并后的数据集有 19 个关键点，这与 COCO 或 AIC 数据集都不同，因此需要一个新的数据集描述信息文件。[coco_aic.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/_base_/datasets/coco_aic.py) 是一个描述信息文件的示例，它基于 [coco.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/_base_/datasets/coco.py) 并进行了以下几点修改:\n\n- 添加了 AIC 数据集的文章信息；\n- 在 `keypoint_info` 中添加了“头顶”和“颈部”这两个只在 AIC 中定义的关键点；\n- 在 `skeleton_info` 中添加了“头顶”和“颈部”间的连线；\n- 拓展 `joint_weights` 和 `sigmas` 以添加新增关键点的信息。\n\n完成以上步骤后，合并数据集 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15) 可以通过以下方式配置：\n\n```python\ndataset = dict(\n    type='CombinedDataset',\n    # 使用新的描述信息文件\n    metainfo=dict(from_file='configs/_base_/datasets/coco_aic.py'),\n    datasets=[dataset_coco, dataset_aic],\n    # `train_pipeline` 包含了常用的数据预处理，\n    # 比如图片读取、数据增广等\n    pipeline=train_pipeline,\n)\n```\n\n此外，在使用混合数据集时，由于关键点数量的变化，模型的输出通道数也要做相应调整。如果用户用混合数据集训练了模型，但是要在 COCO 数据集上评估模型，就需要从模型输出的关键点中取出一个子集来匹配 COCO 中的关键点格式。可以通过 `test_cfg` 中的 `output_keypoint_indices` 参数自定义此子集。这个 [配置文件](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-aic-256x192-combine.py) 展示了如何用 AIC 和 COCO 合并后的数据集训练模型并在 COCO 数据集上进行测试。用户可以查阅这个文件以获取更多细节，或者参考这个文件来构建新的混合数据集。\n\n## 调整混合数据集采样策略\n\n在混合数据集训练中，常常面临着不同数据集的数据分布不统一问题，对此我们提供了两种不同的采样策略：\n\n1. 调整每个子数据集的采样比例\n2. 调整每个 batch 中每个子数据集的比例\n\n### 调整每个子数据集的采样比例\n\n在 [CombinedDataset](https://github.com/open-mmlab/mmpose/blob/dev-1.x/mmpose/datasets/dataset_wrappers.py#L15)  中，我们提供了 `sample_ratio_factor` 参数来调整每个子数据集的采样比例。\n\n例如：\n\n- 如果 `sample_ratio_factor` 为 `[1.0, 0.5]`，则第一个子数据集全部数据加入训练，第二个子数据集抽样出 0.5 加入训练。\n- 如果 `sample_ratio_factor` 为 `[1.0, 2.0]`，则第一个子数据集全部数据加入训练，第二个子数据集抽样出其总数的 2 倍加入训练。\n\n### 调整每个 batch 中每个子数据集的比例\n\n在 [$MMPOSE/datasets/samplers.py](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/samplers.py) 中，我们提供了 [MultiSourceSampler](https://github.com/open-mmlab/mmpose/blob/main/mmpose/datasets/samplers.py#L15) 来调整每个 batch 中每个子数据集的比例。\n\n例如：\n\n- 如果 `sample_ratio_factor` 为 `[1.0, 0.5]`，则每个 batch 中第一个子数据集的数据量为 `1.0 / (1.0 + 0.5) = 66.7%`，第二个子数据集的数据量为 `0.5 / (1.0 + 0.5) = 33.3%`。即，第一个子数据集在 batch 中的占比为第二个子数据集的 2 倍。\n\n用户可以在配置文件中通过 `sampler` 参数来进行设置：\n\n```python\n# data loaders\ntrain_bs = 256\ntrain_dataloader = dict(\n    batch_size=train_bs,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(\n        type='MultiSourceSampler',\n        batch_size=train_bs,\n        # 设置子数据集比例\n        source_ratio=[1.0, 0.5],\n        shuffle=True,\n        round_up=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        # 子数据集\n        datasets=[sub_dataset1, sub_dataset2],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/model_analysis.md",
    "content": "# 模型统计与分析\n\n## 统计模型参数量与计算量\n\nMMPose 提供了 [tools/analysis_tools/get_flops.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tools/analysis_tools/get_flops.py) 来统计模型的参数量与计算量。\n\n```shell\npython tools/analysis_tools/get_flops.py ${CONFIG_FILE} [--shape ${INPUT_SHAPE}] [--cfg-options ${CFG_OPTIONS}]\n```\n\n参数说明：\n\n`CONFIG_FILE` : 模型配置文件的路径。\n\n`--shape`: 模型的输入张量形状。\n\n`--input-constructor`: 如果指定为 `batch`，将会生成一个 `batch tensor` 来计算 FLOPs。\n\n`--batch-size`：如果 `--input-constructor` 指定为 `batch`，将会生成一个随机 `tensor`，形状为 `(batch_size, 3, **input_shape)` 来计算 FLOPs。\n\n`--cfg-options`: 如果指定，可选的 `cfg` 的键值对将会被合并到配置文件中。\n\n示例：\n\n```shell\npython tools/analysis_tools/get_flops.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py\n```\n\n结果如下：\n\n```text\n==============================\nInput shape: (1, 3, 256, 192)\nFlops: 7.7 GFLOPs\nParams: 28.54 M\n==============================\n```\n\n```{note}\n目前该工具仍处于实验阶段，我们不能保证统计结果绝对正确，一些算子（比如 GN 或自定义算子）没有被统计到 FLOPs 中。\n```\n\n## 分析训练日志\n\nMMPose 提供了 [tools/analysis_tools/analyze_logs.py](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tools/analysis_tools/analyze_logs.py) 来对训练日志进行简单的分析，包括：\n\n- 将日志绘制成损失和精度曲线图\n- 统计训练速度\n\n### 绘制损失和精度曲线图\n\n该功能依赖于 `seaborn`，请先运行 `pip install seaborn` 安装依赖包。\n\n![log_curve](https://user-images.githubusercontent.com/87690686/188538215-5d985aaa-59f8-44cf-b6f9-10890d599e9c.png)\n\n```shell\npython tools/analysis_tools/analyze_logs.py plot_curve ${JSON_LOGS} [--keys ${KEYS}] [--title ${TITLE}] [--legend ${LEGEND}] [--backend ${BACKEND}] [--style ${STYLE}] [--out ${OUT_FILE}]\n```\n\n示例：\n\n- 绘制损失曲线\n\n  ```shell\n  python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys loss_kpt --legend loss_kpt\n  ```\n\n- 绘制精度曲线并导出为 PDF 文件\n\n  ```shell\n  python tools/analysis_tools/analyze_logs.py plot_curve log.json --keys acc_pose --out results.pdf\n  ```\n\n- 将多个日志文件绘制在同一张图上\n\n  ```shell\n  python tools/analysis_tools/analyze_logs.py plot_curve log1.json log2.json --keys loss_kpt --legend run1 run2 --title loss_kpt --out loss_kpt.png\n  ```\n\n### 统计训练速度\n\n```shell\npython tools/analysis_tools/analyze_logs.py cal_train_time ${JSON_LOGS} [--include-outliers]\n```\n\n示例：\n\n```shell\npython tools/analysis_tools/analyze_logs.py cal_train_time log.json\n```\n\n结果如下：\n\n```text\n-----Analyze train time of hrnet_w32_256x192.json-----\nslowest epoch 56, average time is 0.6924\nfastest epoch 1, average time is 0.6502\ntime std over epochs is 0.0085\naverage iter time: 0.6688 s/iter\n```\n"
  },
  {
    "path": "docs/zh_cn/user_guides/prepare_datasets.md",
    "content": "# 准备数据集\n\n在这份文档将指导如何为 MMPose 准备数据集，包括使用内置数据集、创建自定义数据集、结合数据集进行训练、浏览和下载数据集。\n\n## 使用内置数据集\n\n**步骤一**: 准备数据\n\nMMPose 支持多种任务和相应的数据集。你可以在 [数据集仓库](https://mmpose.readthedocs.io/en/latest/dataset_zoo.html) 中找到它们。为了正确准备你的数据，请按照你选择的数据集的指南进行操作。\n\n**步骤二**: 在配置文件中进行数据集设置\n\n在开始训练或评估模型之前，你必须配置数据集设置。以 [`td-hm_hrnet-w32_8xb64-210e_coco-256x192.py`](/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py) 为例，它可以用于在 COCO 数据集上训练或评估 HRNet 姿态估计器。下面我们浏览一下数据集配置：\n\n- 基础数据集参数\n\n  ```python\n  # base dataset settings\n  dataset_type = 'CocoDataset'\n  data_mode = 'topdown'\n  data_root = 'data/coco/'\n  ```\n\n  - `dataset_type` 指定数据集的类名。用户可以参考 [数据集 API](https://mmpose.readthedocs.io/en/latest/api.html#datasets) 来找到他们想要的数据集的类名。\n  - `data_mode` 决定了数据集的输出格式，有两个选项可用：`'topdown'` 和 `'bottomup'`。如果 `data_mode='topdown'`，数据元素表示一个实例及其姿态；否则，一个数据元素代表一张图像，包含多个实例和姿态。\n  - `data_root` 指定数据集的根目录。\n\n- 数据处理流程\n\n  ```python\n  # pipelines\n  train_pipeline = [\n      dict(type='LoadImage'),\n      dict(type='GetBBoxCenterScale'),\n      dict(type='RandomFlip', direction='horizontal'),\n      dict(type='RandomHalfBody'),\n      dict(type='RandomBBoxTransform'),\n      dict(type='TopdownAffine', input_size=codec['input_size']),\n      dict(type='GenerateTarget', encoder=codec),\n      dict(type='PackPoseInputs')\n  ]\n  val_pipeline = [\n      dict(type='LoadImage'),\n      dict(type='GetBBoxCenterScale'),\n      dict(type='TopdownAffine', input_size=codec['input_size']),\n      dict(type='PackPoseInputs')\n  ]\n  ```\n\n  `train_pipeline` 和 `val_pipeline` 分别定义了训练和评估阶段处理数据元素的步骤。除了加载图像和打包输入之外，`train_pipeline` 主要包含数据增强技术和目标生成器，而 `val_pipeline` 则专注于将数据元素转换为统一的格式。\n\n- 数据加载器\n\n  ```python\n  # data loaders\n  train_dataloader = dict(\n      batch_size=64,\n      num_workers=2,\n      persistent_workers=True,\n      sampler=dict(type='DefaultSampler', shuffle=True),\n      dataset=dict(\n          type=dataset_type,\n          data_root=data_root,\n          data_mode=data_mode,\n          ann_file='annotations/person_keypoints_train2017.json',\n          data_prefix=dict(img='train2017/'),\n          pipeline=train_pipeline,\n      ))\n  val_dataloader = dict(\n      batch_size=32,\n      num_workers=2,\n      persistent_workers=True,\n      drop_last=False,\n      sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n      dataset=dict(\n          type=dataset_type,\n          data_root=data_root,\n          data_mode=data_mode,\n          ann_file='annotations/person_keypoints_val2017.json',\n          bbox_file='data/coco/person_detection_results/'\n          'COCO_val2017_detections_AP_H_56_person.json',\n          data_prefix=dict(img='val2017/'),\n          test_mode=True,\n          pipeline=val_pipeline,\n      ))\n  test_dataloader = val_dataloader\n  ```\n\n  这个部分是配置数据集的关键。除了前面讨论过的基础数据集参数和数据处理流程之外，这里还定义了其他重要的参数。`batch_size` 决定了每个 GPU 的 batch size；`ann_file` 指定了数据集的注释文件；`data_prefix` 指定了图像文件夹。`bbox_file` 仅在 top-down 数据集的 val/test 数据加载器中使用，用于提供检测到的边界框信息。\n\n我们推荐从使用相同数据集的配置文件中复制数据集配置，而不是从头开始编写，以最小化潜在的错误。通过这样做，用户可以根据需要进行必要的修改，从而确保更可靠和高效的设置过程。\n\n## 使用自定义数据集\n\n[自定义数据集](../advanced_guides/customize_datasets.md) 指南提供了如何构建自定义数据集的详细信息。在本节中，我们将强调一些使用和配置自定义数据集的关键技巧。\n\n- 确定数据集类名。如果你将数据集重组为 COCO 格式，你可以简单地使用 `CocoDataset` 作为 `dataset_type` 的值。否则，你将需要使用你添加的自定义数据集类的名称。\n\n- 指定元信息配置文件。假设你的数据集标注文件存储路径为 `aaa/annotations/xxx.json`，图片存储路径为 `aaa/train/c.jpg`，你应该按照以下方式指定元信息配置文件：\n\n  ```python\n  train_dataloader = dict(\n      ...\n      dataset=dict(\n          type=dataset_type,\n          data_root='aaa',\n          # 标注文件路径为 {data_root}/{ann_file}\n          # 例如： aaa/annotations/xxx.json\n          ann_file='annotations/xxx.json',\n          # 图片路径为 {data_root}/{img}/\n          # 例如： aaa/train/c.jpg\n          data_prefix=dict(img='train'),\n          # 指定元信息配置文件\n          metainfo=dict(from_file='configs/_base_/datasets/custom.py'),\n          ...),\n  )\n  ```\n\n  注意，`metainfo` 参数必须在 val/test 数据加载器中指定。\n\n## 使用混合数据集进行训练\n\nMMPose 提供了一个方便且多功能的解决方案，用于训练混合数据集。请参考[混合数据集训练](./mixed_datasets.md)。\n\n## 浏览数据集\n\n`tools/analysis_tools/browse_dataset.py` 帮助用户可视化地浏览姿态数据集，或将图像保存到指定的目录。\n\n```shell\npython tools/misc/browse_dataset.py ${CONFIG} [-h] [--output-dir ${OUTPUT_DIR}] [--max-item-per-dataset ${MAX_ITEM_PER_DATASET}] [--not-show] [--phase ${PHASE}] [--mode ${MODE}] [--show-interval ${SHOW_INTERVAL}]\n```\n\n| ARGS                             | Description                                                                                                |\n| -------------------------------- | ---------------------------------------------------------------------------------------------------------- |\n| `CONFIG`                         | 配置文件的路径                                                                                             |\n| `--output-dir OUTPUT_DIR`        | 保存可视化结果的目标文件夹。如果不指定，可视化的结果将不会被保存                                           |\n| `--not-show`                     | 不适用外部窗口显示可视化的结果                                                                             |\n| `--phase {train, val, test}`     | 数据集选项                                                                                                 |\n| `--mode {original, transformed}` | 指定可视化图片类型。 `original` 为不使用数据增强的原始图片及标注可视化; `transformed` 为经过增强后的可视化 |\n| `--show-interval SHOW_INTERVAL`  | 显示图片的时间间隔                                                                                         |\n| `--max-item-per-dataset`         | 定义每个数据集可视化的最大样本数。默认为 50                                                                |\n\n例如，用户想要可视化 COCO 数据集中的图像和标注，可以使用：\n\n```shell\npython tools/misc/browse_dataset.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-e210_coco-256x192.py --mode original\n```\n\n检测框和关键点将被绘制在原始图像上。下面是一个例子：\n![original_coco](https://user-images.githubusercontent.com/26127467/187383698-7e518f21-b4cc-4712-9e97-99ddd8f0e437.jpg)\n\n原始图像在被输入模型之前需要被处理。为了可视化预处理后的图像和标注，用户需要将参数 `mode` 修改为 `transformed`。例如：\n\n```shell\npython tools/misc/browse_dataset.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-e210_coco-256x192.py --mode transformed\n```\n\n这是一个处理后的样本：\n\n![transformed_coco](https://user-images.githubusercontent.com/26127467/187386652-bd47335d-797c-4e8c-b823-2a4915f9812f.jpg)\n\n热图目标将与之一起可视化，如果它是在 pipeline 中生成的。\n\n## 用 MIM 下载数据集\n\n通过使用 [OpenXLab](https://openxlab.org.cn/datasets)，您可以直接下载开源数据集。通过平台的搜索功能，您可以快速轻松地找到他们正在寻找的数据集。使用平台上的格式化数据集，您可以高效地跨数据集执行任务。\n\n如果您使用 MIM 下载，请确保版本大于 v0.3.8。您可以使用以下命令进行更新、安装、登录和数据集下载：\n\n```shell\n# upgrade your MIM\npip install -U openmim\n\n# install OpenXLab CLI tools\npip install -U openxlab\n# log in OpenXLab\nopenxlab login\n\n# download coco2017 and preprocess by MIM\nmim download mmpose --dataset coco2017\n```\n\n### 已支持的数据集\n\n下面是支持的数据集列表，更多数据集将在之后持续更新：\n\n#### 人体数据集\n\n| Dataset name  | Download command                          |\n| ------------- | ----------------------------------------- |\n| COCO 2017     | `mim download mmpose --dataset coco2017`  |\n| MPII          | `mim download mmpose --dataset mpii`      |\n| AI Challenger | `mim download mmpose --dataset aic`       |\n| CrowdPose     | `mim download mmpose --dataset crowdpose` |\n\n#### 人脸数据集\n\n| Dataset name | Download command                     |\n| ------------ | ------------------------------------ |\n| LaPa         | `mim download mmpose --dataset lapa` |\n| 300W         | `mim download mmpose --dataset 300w` |\n| WFLW         | `mim download mmpose --dataset wflw` |\n\n#### 手部数据集\n\n| Dataset name | Download command                           |\n| ------------ | ------------------------------------------ |\n| OneHand10K   | `mim download mmpose --dataset onehand10k` |\n| FreiHand     | `mim download mmpose --dataset freihand`   |\n| HaGRID       | `mim download mmpose --dataset hagrid`     |\n\n#### 全身数据集\n\n| Dataset name | Download command                      |\n| ------------ | ------------------------------------- |\n| Halpe        | `mim download mmpose --dataset halpe` |\n\n#### 动物数据集\n\n| Dataset name | Download command                      |\n| ------------ | ------------------------------------- |\n| AP-10K       | `mim download mmpose --dataset ap10k` |\n\n#### 服装数据集\n\nComing Soon\n"
  },
  {
    "path": "docs/zh_cn/user_guides/train_and_test.md",
    "content": "# 训练与测试\n\n## 启动训练\n\n### 本地训练\n\n你可以使用 `tools/train.py` 在单机上使用 CPU 或单个 GPU 训练模型。\n\n```shell\npython tools/train.py ${CONFIG_FILE} [ARGS]\n```\n\n```{note}\n默认情况下，MMPose 会优先使用 GPU 而不是 CPU。如果你想在 CPU 上训练模型，请清空 `CUDA_VISIBLE_DEVICES` 或将其设置为 -1，使 GPU 对程序不可见。\n```\n\n```shell\nCUDA_VISIBLE_DEVICES=-1 python tools/train.py ${CONFIG_FILE} [ARGS]\n```\n\n| ARGS                                  | Description                                                                                                                                                         |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG_FILE`                         | 配置文件路径                                                                                                                                                        |\n| `--work-dir WORK_DIR`                 | 训练日志与 checkpoint 存放目录，默认使用配置文件名作为目录存放在 `./work_dirs` 下                                                                                   |\n| `--resume [RESUME]`                   | 恢复训练，可以从指定 checkpoint 进行重启，不指定则会使用最近一次的 checkpoint                                                                                       |\n| `--amp`                               | 开启混合精度训练                                                                                                                                                    |\n| `--no-validate`                       | **不建议新手开启**。 训练中不进行评测                                                                                                                               |\n| `--auto-scale-lr`                     | 自动根据当前设置的实际 batch size 和配置文件中的标准 batch size 进行学习率缩放                                                                                      |\n| `--cfg-options CFG_OPTIONS`           | 对当前配置文件中的一些设置进行临时覆盖，字典 key-value 格式为 xxx=yyy。如果需要覆盖的值是一个数组，格式应当为 `key=\"[a,b]\"` 或 `key=a,b`。也允许使用元组，如 `key=\"[(a,b),(c,d)]\"`。注意双引号是**必须的**，且**不允许**使用空格。 |\n| `--show-dir SHOW_DIR`                 | 验证阶段生成的可视化图片存放路径                                                                                                                                    |\n| `--show`                              | 使用窗口显示预测的可视化结果                                                                                                                                        |\n| `--interval INTERVAL`                 | 进行可视化的间隔（每隔多少张图可视化一张）                                                                                                                          |\n| `--wait-time WAIT_TIME`               | 可视化显示时每张图片的持续时间（单位：秒），默认为 1                                                                                                                |\n| `--launcher {none,pytorch,slurm,mpi}` | 可选的启动器                                                                                                                                                        |\n\n### 多卡训练\n\n我们提供了一个脚本来使用 `torch.distributed.launch` 启动多卡训练。\n\n```shell\nbash ./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\n| ARGS          | Description                                        |\n| ------------- | -------------------------------------------------- |\n| `CONFIG_FILE` | 配置文件路径                                       |\n| `GPU_NUM`     | 使用 GPU 数量                                      |\n| `[PYARGS]`    | 其他配置项 `tools/train.py`, 见 [这里](#本地训练). |\n\n你也可以通过环境变量来指定启动器的额外参数。例如，通过以下命令将启动器的通信端口改为 29666：\n\n```shell\nPORT=29666 bash ./tools/dist_train.sh ${CONFIG_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\n如果你想同时启动多个训练任务并使用不同的 GPU，你可以通过指定不同的端口和可见设备来启动它们。\n\n```shell\nCUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 bash ./tools/dist_train.sh ${CONFIG_FILE1} 4 [PY_ARGS]\nCUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 bash ./tools/dist_train.sh ${CONFIG_FILE2} 4 [PY_ARGS]\n```\n\n### 分布式训练\n\n#### 局域网多机训练\n\n如果你使用以太网连接的多台机器启动训练任务，你可以运行以下命令：\n\n在第一台机器上：\n\n```shell\nNNODES=2 NODE_RANK=1 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_train.sh $CONFIG $GPUS\n```\n\n相比于单机多卡，你需要指定一些额外的环境变量：\n\n| 环境变量      | 描述                       |\n| ------------- | -------------------------- |\n| `NNODES`      | 机器总数                   |\n| `NODE_RANK`   | 当前机器序号               |\n| `PORT`        | 通信端口，所有机器必须相同 |\n| `MASTER_ADDR` | 主机地址，所有机器必须相同 |\n\n通常情况下，如果你没有像 InfiniBand 这样的高速网络，那么训练速度会很慢。\n\n#### Slurm 多机训练\n\n如果你在一个使用 [slurm](https://slurm.schedmd.com/) 管理的集群上运行 MMPose，你可以使用 `slurm_train.sh` 脚本。\n\n```shell\n[ENV_VARS] ./tools/slurm_train.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${WORK_DIR} [PY_ARGS]\n```\n\n脚本参数说明：\n\n| 参数          | 描述                                               |\n| ------------- | -------------------------------------------------- |\n| `PARTITION`   | 指定集群分区                                       |\n| `JOB_NAME`    | 任务名，可以任取                                   |\n| `CONFIG_FILE` | 配置文件路径                                       |\n| `WORK_DIR`    | 训练日志存储路径                                   |\n| `[PYARGS]`    | 其他配置项 `tools/train.py`, 见 [这里](#本地训练). |\n\n以下是可以用来配置 slurm 任务的环境变量：\n\n| 环境变量        | 描述                                                                     |\n| --------------- | ------------------------------------------------------------------------ |\n| `GPUS`          | GPU 总数，默认为 8                                                       |\n| `GPUS_PER_NODE` | 每台机器使用的 GPU 总数，默认为 8                                        |\n| `CPUS_PER_TASK` | 每个任务分配的 CPU 总数（通常为 1 张 GPU 对应 1 个任务进程），默认为 5   |\n| `SRUN_ARGS`     | `srun` 的其他参数，可选项见 [这里](https://slurm.schedmd.com/srun.html). |\n\n## 恢复训练\n\n恢复训练意味着从之前的训练中保存的状态继续训练，其中状态包括模型权重、优化器状态和优化器参数调整策略的状态。\n\n### 自动恢复\n\n用户可以在训练命令的末尾添加 `--resume` 来恢复训练。程序会自动从 `work_dirs` 中加载最新的权重文件来恢复训练。如果 `work_dirs` 中有最新的 `checkpoint`（例如在之前的训练中中断了训练），则会从 `checkpoint` 处恢复训练。否则（例如之前的训练没有及时保存 `checkpoint` 或者启动了一个新的训练任务），则会重新开始训练。\n\n以下是一个恢复训练的例子：\n\n```shell\npython tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py --resume\n```\n\n### 指定 checkpoint 恢复\n\n你可以在 `load_from` 中指定 `checkpoint` 的路径，MMPose 会自动读取 `checkpoint` 并从中恢复训练。命令如下：\n\n```shell\npython tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py \\\n    --resume work_dirs/td-hm_res50_8xb64-210e_coco-256x192/latest.pth\n```\n\n如果你希望在配置文件中手动指定 `checkpoint` 路径，除了设置 `resume=True`，还需要设置 `load_from`。\n\n需要注意的是，如果只设置了 `load_from` 而没有设置 `resume=True`，那么只会加载 `checkpoint` 中的权重，而不会从之前的状态继续训练。\n\n以下的例子与上面指定 `--resume` 参数的例子等价：\n\n```Python\nresume = True\nload_from = 'work_dirs/td-hm_res50_8xb64-210e_coco-256x192/latest.pth'\n# model settings\nmodel = dict(\n    ## omitted ##\n    )\n```\n\n## 在训练中冻结部分参数\n\n在某些场景下，我们可能希望在训练过程中冻结模型的某些参数，以便微调特定部分或防止过拟合。在 MMPose 中，你可以通过在 `paramwise_cfg` 中设置 `custom_keys` 来为模型中的任何模块设置不同的超参数。这样可以让你控制模型特定部分的学习率和衰减系数。\n\n例如，如果你想冻结 `backbone.layer0` 和 `backbone.layer1` 的所有参数，你可以在配置文件中添加以下内容：\n\n```Python\noptim_wrapper = dict(\n    optimizer=dict(...),\n    paramwise_cfg=dict(\n        custom_keys={\n            'backbone.layer0': dict(lr_mult=0, decay_mult=0),\n            'backbone.layer0': dict(lr_mult=0, decay_mult=0),\n        }))\n```\n\n以上配置将会通过将学习率和衰减系数设置为 0 来冻结 `backbone.layer0` 和 `backbone.layer1` 中的参数。通过这种方式，你可以有效地控制训练过程，并根据需要微调模型的特定部分。\n\n## 自动混合精度训练（AMP）\n\n混合精度训练可以减少训练时间和存储需求，而不改变模型或降低模型训练精度，从而支持更大的 batch size、更大的模型和更大的输入尺寸。\n\n要启用自动混合精度（AMP）训练，请在训练命令的末尾添加 `--amp`，如下所示：\n\n```shell\npython tools/train.py ${CONFIG_FILE} --amp\n```\n\n具体例子如下：\n\n```shell\npython tools/train.py configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_res50_8xb64-210e_coco-256x192.py  --amp\n```\n\n## 设置随机种子\n\n如果你想指定随机种子，你可以通过如下命令：\n\n```shell\npython ./tools/train.py \\\n    ${CONFIG} \\                               # 配置文件\n    --cfg-options randomness.seed=2023 \\      # 设置 random seed = 2023\n    [randomness.diff_rank_seed=True] \\        # 不同 rank 的进程使用不同的随机种子\n    [randomness.deterministic=True]           # 设置 cudnn.deterministic=True\n# `[]` 表示可选的参数，你不需要输入 `[]`\n```\n\n`randomness` 还有三个参数可以设置，具体含义如下。\n\n- `randomness.seed=2023`，将随机种子设置为 `2023`。\n\n- `randomness.diff_rank_seed=True`，根据全局 `rank` 设置不同的随机种子。默认为 `False`。\n\n- `randomness.deterministic=True`，设置 `cuDNN` 后端的确定性选项，即将 `torch.backends.cudnn.deterministic` 设置为 `True`，将 `torch.backends.cudnn.benchmark` 设置为 `False`。默认为 `False`。更多细节请参考 [Pytorch Randomness](https://pytorch.org/docs/stable/notes/randomness.html)。\n\n## 训练日志说明\n\n在训练中，命令行会实时打印训练日志如下：\n\n```shell\n07/14 08:26:50 - mmengine - INFO - Epoch(train) [38][ 6/38]  base_lr: 5.148343e-04 lr: 5.148343e-04  eta: 0:15:34  time: 0.540754  data_time: 0.394292  memory: 3141  loss: 0.006220  loss_kpt: 0.006220  acc_pose: 1.000000\n```\n\n以上训练日志包括如下内容：\n\n- `07/14 08:26:50`：当前时间\n- `mmengine`：日志前缀，表示日志来自 MMEngine\n- `INFO` or `WARNING`：日志级别，表示该日志为普通信息\n- `Epoch(train)`：当前处于训练阶段，如果处于验证阶段，则为 `Epoch(val)`\n- `[38][ 6/38]`：当前处于第 38 个 epoch，当前 batch 为第 6 个 batch，总共有 38 个 batch\n- `base_lr`：基础学习率\n- `lr`：当前实际使用的学习率\n- `eta`：预计训练剩余时间\n- `time`：当前 batch 的训练时间（单位：分钟）\n- `data_time`：当前 batch 的数据加载（i/o，数据增强）时间（单位：分钟）\n- `memory`：当前进程占用的显存（单位：MB）\n- `loss`：当前 batch 的总 loss\n- `loss_kpt`：当前 batch 的关键点 loss\n- `acc_pose`：当前 batch 的姿态准确率\n\n## 可视化训练进程\n\n监视训练过程对于了解模型的性能并进行必要的调整至关重要。在本节中，我们将介绍两种可视化训练过程的方法：TensorBoard 和 MMEngine Visualizer。\n\n### TensorBoard\n\nTensorBoard 是一个强大的工具，可以让你可视化训练过程中的 loss 变化。要启用 TensorBoard 可视化，你可能需要：\n\n1. 安装 TensorBoard\n\n   ```shell\n   pip install tensorboard\n   ```\n\n2. 在配置文件中开启 TensorBoard 作为可视化后端：\n\n   ```python\n   visualizer = dict(vis_backends=[\n       dict(type='LocalVisBackend'),\n       dict(type='TensorboardVisBackend'),\n   ])\n   ```\n\nTensorboard 生成的 event 文件会保存在实验日志文件夹 `${WORK_DIR}` 下，该文件夹默认为 `work_dir/${CONFIG}`，你也可以通过 `--work-dir` 参数指定。要可视化训练过程，请使用以下命令：\n\n```shell\ntensorboard --logdir ${WORK_DIR}/${TIMESTAMP}/vis_data\n```\n\n### MMEngine Visualizer\n\nMMPose 还支持在验证过程中可视化模型的推理结果。要启用此功能，请在启动训练时使用 `--show` 选项或设置 `--show-dir`。这个功能提供了一种有效的方法来分析模型在特定示例上的性能并进行必要的调整。\n\n## 测试\n\n### 本地测试\n\n你可以使用 `tools/test.py` 在单机上使用 CPU 或单个 GPU 测试模型。\n\n```shell\npython tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [ARGS]\n```\n\n```{note}\n默认情况下，MMPose 会优先使用 GPU 而不是 CPU。如果你想在 CPU 上测试模型，请清空 `CUDA_VISIBLE_DEVICES` 或将其设置为 -1，使 GPU 对程序不可见。\n```\n\n```shell\nCUDA_VISIBLE_DEVICES=-1 python tools/test.py ${CONFIG_FILE} ${CHECKPOINT_FILE} [ARGS]\n```\n\n| ARGS                                  | Description                                                                                                                                                         |\n| ------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG_FILE`                         | 配置文件路径file.                                                                                                                                                   |\n| `CHECKPOINT_FILE`                     | checkpoint 文件路径，可以是本地文件，也可以是网络链接。 [这里](https://MMPose.readthedocs.io/en/latest/model_zoo.html) 是 MMPose 提供的 checkpoint 列表.            |\n| `--work-dir WORK_DIR`                 | 评测结果存储目录                                                                                                                                                    |\n| `--out OUT`                           | 评测结果存放文件                                                                                                                                                    |\n| `--dump DUMP`                         | 导出评测时的模型输出，用于用户自行离线评测                                                                                                                          |\n| `--cfg-options CFG_OPTIONS`           | 对当前配置文件中的一些设置进行临时覆盖，字典 key-value 格式为 xxx=yyy。如果需要覆盖的值是一个数组，格式应当为 `key=\"[a,b]\"` 或 `key=a,b`。也允许使用元组，如 `key=\"[(a,b),(c,d)]\"`。注意双引号是**必须的**，且**不允许**使用空格。 |\n| `--show-dir SHOW_DIR`                 | T验证阶段生成的可视化图片存放路径                                                                                                                                   |\n| `--show`                              | 使用窗口显示预测的可视化结果                                                                                                                                        |\n| `--interval INTERVAL`                 | 进行可视化的间隔（每隔多少张图可视化一张）                                                                                                                          |\n| `--wait-time WAIT_TIME`               | 可视化显示时每张图片的持续时间（单位：秒），默认为 1                                                                                                                |\n| `--launcher {none,pytorch,slurm,mpi}` | 可选的启动器                                                                                                                                                        |\n\n### 多卡测试\n\n我们提供了一个脚本来使用 `torch.distributed.launch` 启动多卡测试。\n\n```shell\nbash ./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\n| ARGS              | Description                                                                                                                                             |\n| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `CONFIG_FILE`     | 配置文件路径                                                                                                                                            |\n| `CHECKPOINT_FILE` | checkpoint 文件路径，可以是本地文件，也可以是网络链接。 [这里](https://MMPose.readthedocs.io/en/latest/model_zoo.html) 是 MMPose 提供的 checkpoint 列表 |\n| `GPU_NUM`         | 使用 GPU 数量                                                                                                                                           |\n| `[PYARGS]`        | 其他配置项 `tools/test.py`, 见 [这里](#本地测试)                                                                                                        |\n\n你也可以通过环境变量来指定启动器的额外参数。例如，通过以下命令将启动器的通信端口改为 29666：\n\n```shell\nPORT=29666 bash ./tools/dist_test.sh ${CONFIG_FILE} ${CHECKPOINT_FILE} ${GPU_NUM} [PY_ARGS]\n```\n\n如果你想同时启动多个测试任务并使用不同的 GPU，你可以通过指定不同的端口和可见设备来启动它们。\n\n```shell\nCUDA_VISIBLE_DEVICES=0,1,2,3 PORT=29500 bash ./tools/dist_test.sh ${CONFIG_FILE1} ${CHECKPOINT_FILE} 4 [PY_ARGS]\nCUDA_VISIBLE_DEVICES=4,5,6,7 PORT=29501 bash ./tools/dist_test.sh ${CONFIG_FILE2} ${CHECKPOINT_FILE} 4 [PY_ARGS]\n```\n\n### 分布式测试\n\n#### 局域网多机测试\n\n如果你使用以太网连接的多台机器启动测试任务，你可以运行以下命令：\n\n在第一台机器上：\n\n```shell\nNNODES=2 NODE_RANK=0 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_test.sh $CONFIG $CHECKPOINT_FILE $GPUS\n```\n\n在第二台机器上：\n\n```shell\nNNODES=2 NODE_RANK=1 PORT=$MASTER_PORT MASTER_ADDR=$MASTER_ADDR bash tools/dist_test.sh $CONFIG $CHECKPOINT_FILE $GPUS\n```\n\n相比于单机多卡，你需要指定一些额外的环境变量：\n\n| 环境变量      | 描述                       |\n| ------------- | -------------------------- |\n| `NNODES`      | 机器总数                   |\n| `NODE_RANK`   | 当前机器序号               |\n| `PORT`        | 通信端口，所有机器必须相同 |\n| `MASTER_ADDR` | 主机地址，所有机器必须相同 |\n\n通常情况下，如果你没有像 InfiniBand 这样的高速网络，那么测试速度会很慢。\n\n#### Slurm 多机测试\n\n如果你在一个使用 [slurm](https://slurm.schedmd.com/) 管理的集群上运行 MMPose，你可以使用 `slurm_test.sh` 脚本。\n\n```shell\n[ENV_VARS] ./tools/slurm_test.sh ${PARTITION} ${JOB_NAME} ${CONFIG_FILE} ${CHECKPOINT_FILE} [PY_ARGS]\n```\n\n脚本参数说明：\n\n| 参数              | 描述                                                                                                                                                    |\n| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------- |\n| `PARTITION`       | 指定集群分区                                                                                                                                            |\n| `JOB_NAME`        | 任务名，可以任取                                                                                                                                        |\n| `CONFIG_FILE`     | 配置文件路径                                                                                                                                            |\n| `CHECKPOINT_FILE` | checkpoint 文件路径，可以是本地文件，也可以是网络链接。 [这里](https://MMPose.readthedocs.io/en/latest/model_zoo.html) 是 MMPose 提供的 checkpoint 列表 |\n| `[PYARGS]`        | 其他配置项 `tools/test.py`, 见 [这里](#本地测试)                                                                                                        |\n\n以下是可以用来配置 slurm 任务的环境变量：\n\n| 环境变量        | 描述                                                                     |\n| --------------- | ------------------------------------------------------------------------ |\n| `GPUS`          | GPU 总数，默认为 8                                                       |\n| `GPUS_PER_NODE` | 每台机器使用的 GPU 总数，默认为 8                                        |\n| `CPUS_PER_TASK` | 每个任务分配的 CPU 总数（通常为 1 张 GPU 对应 1 个任务进程），默认为 5   |\n| `SRUN_ARGS`     | `srun` 的其他参数，可选项见 [这里](https://slurm.schedmd.com/srun.html). |\n\n## 自定义测试\n\n### 用自定义度量进行测试\n\n如果您希望使用 MMPose 中尚未支持的独特度量来评估模型，您将需要自己编写这些度量并将它们包含在您的配置文件中。关于如何实现这一点的指导，请查看我们的 [自定义评估指南](https://mmpose.readthedocs.io/zh_CN/dev-1.x/advanced_guides/customize_evaluation.html)。\n\n### 在多个数据集上进行评估\n\nMMPose 提供了一个名为 `MultiDatasetEvaluator` 的便捷工具，用于在多个数据集上进行简化评估。在配置文件中设置此评估器非常简单。下面是一个快速示例，演示如何使用 COCO 和 AIC 数据集评估模型：\n\n```python\n# 设置验证数据集\ncoco_val = dict(type='CocoDataset', ...)\n\naic_val = dict(type='AicDataset', ...)\n\nval_dataset = dict(\n        type='CombinedDataset',\n        datasets=[coco_val, aic_val],\n        pipeline=val_pipeline,\n        ...)\n\n# 配置评估器\nval_evaluator = dict(\n    type='MultiDatasetEvaluator',\n    metrics=[  # 为每个数据集配置度量\n        dict(type='CocoMetric',\n             ann_file='data/coco/annotations/person_keypoints_val2017.json'),\n        dict(type='CocoMetric',\n            ann_file='data/aic/annotations/aic_val.json',\n            use_area=False,\n            prefix='aic')\n    ],\n    # 数据集个数和顺序与度量必须匹配\n    datasets=[coco_val, aic_val],\n    )\n```\n\n同的数据集（如 COCO 和 AIC）具有不同的关键点定义。然而，模型的输出关键点是标准化的。这导致了模型输出与真值之间关键点顺序的差异。为解决这一问题，您可以使用 `KeypointConverter` 来对齐不同数据集之间的关键点顺序。下面是一个完整示例，展示了如何利用 `KeypointConverter` 来对齐 AIC 关键点与 COCO 关键点：\n\n```python\naic_to_coco_converter = dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n\n# val datasets\ncoco_val = dict(\n    type='CocoDataset',\n    data_root='data/coco/',\n    data_mode='topdown',\n    ann_file='annotations/person_keypoints_val2017.json',\n    bbox_file='data/coco/person_detection_results/'\n    'COCO_val2017_detections_AP_H_56_person.json',\n    data_prefix=dict(img='val2017/'),\n    test_mode=True,\n    pipeline=[],\n)\n\naic_val = dict(\n        type='AicDataset',\n        data_root='data/aic/',\n        data_mode=data_mode,\n        ann_file='annotations/aic_val.json',\n        data_prefix=dict(img='ai_challenger_keypoint_validation_20170911/'\n                         'keypoint_validation_images_20170911/'),\n        test_mode=True,\n        pipeline=[],\n    )\n\nval_dataset = dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[coco_val, aic_val],\n        pipeline=val_pipeline,\n        test_mode=True,\n    )\n\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=val_dataset)\n\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='MultiDatasetEvaluator',\n    metrics=[\n        dict(type='CocoMetric',\n             ann_file=data_root + 'annotations/person_keypoints_val2017.json'),\n        dict(type='CocoMetric',\n            ann_file='data/aic/annotations/aic_val.json',\n            use_area=False,\n            gt_converter=aic_to_coco_converter,\n            prefix='aic')\n    ],\n    datasets=val_dataset['datasets'],\n    )\n\ntest_evaluator = val_evaluator\n```\n\n如需进一步了解如何将 AIC 关键点转换为 COCO 关键点，请查阅 [该指南](https://mmpose.readthedocs.io/zh_CN/dev-1.x/user_guides/mixed_datasets.html#aic-coco)。\n\n### 使用自定义检测器评估 Top-down 模型\n\n要评估 Top-down 模型，您可以使用人工标注的或预先检测到的边界框。 `bbox_file` 提供了由特定检测器生成的这些框。例如，`COCO_val2017_detections_AP_H_56_person.json` 包含了使用具有 56.4 人类 AP 的检测器捕获的 COCO val2017 数据集的边界框。要使用 MMDetection 支持的自定义检测器创建您自己的 `bbox_file`，请运行以下命令：\n\n```sh\npython tools/misc/generate_bbox_file.py \\\n    ${DET_CONFIG} ${DET_WEIGHT} ${OUTPUT_FILE_NAME} \\\n    [--pose-config ${POSE_CONFIG}] \\\n    [--score-thr ${SCORE_THRESHOLD}] [--nms-thr ${NMS_THRESHOLD}]\n```\n\n其中，`DET_CONFIG` 和 `DET_WEIGHT` 用于创建目标检测器。 `POSE_CONFIG` 指定需要边界框检测的测试数据集。`SCORE_THRESHOLD` 和 `NMS_THRESHOLD` 用于边界框过滤。\n"
  },
  {
    "path": "mmpose/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport mmcv\nimport mmengine\nfrom mmengine.utils import digit_version\n\nfrom .version import __version__, short_version\n\nmmcv_minimum_version = '2.0.0rc4'\nmmcv_maximum_version = '3.0.0'\nmmcv_version = digit_version(mmcv.__version__)\n\nmmengine_minimum_version = '0.6.0'\nmmengine_maximum_version = '1.0.0'\nmmengine_version = digit_version(mmengine.__version__)\n\nassert (mmcv_version >= digit_version(mmcv_minimum_version)\n        and mmcv_version <= digit_version(mmcv_maximum_version)), \\\n    f'MMCV=={mmcv.__version__} is used but incompatible. ' \\\n    f'Please install mmcv>={mmcv_minimum_version}, <={mmcv_maximum_version}.'\n\nassert (mmengine_version >= digit_version(mmengine_minimum_version)\n        and mmengine_version <= digit_version(mmengine_maximum_version)), \\\n    f'MMEngine=={mmengine.__version__} is used but incompatible. ' \\\n    f'Please install mmengine>={mmengine_minimum_version}, ' \\\n    f'<={mmengine_maximum_version}.'\n\n__all__ = ['__version__', 'short_version']\n"
  },
  {
    "path": "mmpose/apis/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .inference import (collect_multi_frames, inference_bottomup,\n                        inference_topdown, init_model)\nfrom .inference_3d import (collate_pose_sequence, convert_keypoint_definition,\n                           extract_pose_sequence, inference_pose_lifter_model)\nfrom .inference_tracking import _compute_iou, _track_by_iou, _track_by_oks\nfrom .inferencers import MMPoseInferencer, Pose2DInferencer\nfrom .visualization import visualize\n\n__all__ = [\n    'init_model', 'inference_topdown', 'inference_bottomup',\n    'collect_multi_frames', 'Pose2DInferencer', 'MMPoseInferencer',\n    '_track_by_iou', '_track_by_oks', '_compute_iou',\n    'inference_pose_lifter_model', 'extract_pose_sequence',\n    'convert_keypoint_definition', 'collate_pose_sequence', 'visualize'\n]\n"
  },
  {
    "path": "mmpose/apis/inference.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom pathlib import Path\nfrom typing import List, Optional, Union\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom mmengine.config import Config\nfrom mmengine.dataset import Compose, pseudo_collate\nfrom mmengine.model.utils import revert_sync_batchnorm\nfrom mmengine.registry import init_default_scope\nfrom mmengine.runner import load_checkpoint\nfrom PIL import Image\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.models.builder import build_pose_estimator\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.structures.bbox import bbox_xywh2xyxy\n\n\ndef dataset_meta_from_config(config: Config,\n                             dataset_mode: str = 'train') -> Optional[dict]:\n    \"\"\"Get dataset metainfo from the model config.\n\n    Args:\n        config (str, :obj:`Path`, or :obj:`mmengine.Config`): Config file path,\n            :obj:`Path`, or the config object.\n        dataset_mode (str): Specify the dataset of which to get the metainfo.\n            Options are ``'train'``, ``'val'`` and ``'test'``. Defaults to\n            ``'train'``\n\n    Returns:\n        dict, optional: The dataset metainfo. See\n        ``mmpose.datasets.datasets.utils.parse_pose_metainfo`` for details.\n        Return ``None`` if failing to get dataset metainfo from the config.\n    \"\"\"\n    try:\n        if dataset_mode == 'train':\n            dataset_cfg = config.train_dataloader.dataset\n        elif dataset_mode == 'val':\n            dataset_cfg = config.val_dataloader.dataset\n        elif dataset_mode == 'test':\n            dataset_cfg = config.test_dataloader.dataset\n        else:\n            raise ValueError(\n                f'Invalid dataset {dataset_mode} to get metainfo. '\n                'Should be one of \"train\", \"val\", or \"test\".')\n\n        if 'metainfo' in dataset_cfg:\n            metainfo = dataset_cfg.metainfo\n        else:\n            import mmpose.datasets.datasets  # noqa: F401, F403\n            from mmpose.registry import DATASETS\n\n            dataset_class = dataset_cfg.type if isinstance(\n                dataset_cfg.type, type) else DATASETS.get(dataset_cfg.type)\n            metainfo = dataset_class.METAINFO\n\n        metainfo = parse_pose_metainfo(metainfo)\n\n    except AttributeError:\n        metainfo = None\n\n    return metainfo\n\n\ndef init_model(config: Union[str, Path, Config],\n               checkpoint: Optional[str] = None,\n               device: str = 'cuda:0',\n               cfg_options: Optional[dict] = None) -> nn.Module:\n    \"\"\"Initialize a pose estimator from a config file.\n\n    Args:\n        config (str, :obj:`Path`, or :obj:`mmengine.Config`): Config file path,\n            :obj:`Path`, or the config object.\n        checkpoint (str, optional): Checkpoint path. If left as None, the model\n            will not load any weights. Defaults to ``None``\n        device (str): The device where the anchors will be put on.\n            Defaults to ``'cuda:0'``.\n        cfg_options (dict, optional): Options to override some settings in\n            the used config. Defaults to ``None``\n\n    Returns:\n        nn.Module: The constructed pose estimator.\n    \"\"\"\n\n    if isinstance(config, (str, Path)):\n        config = Config.fromfile(config)\n    elif not isinstance(config, Config):\n        raise TypeError('config must be a filename or Config object, '\n                        f'but got {type(config)}')\n    if cfg_options is not None:\n        config.merge_from_dict(cfg_options)\n    elif 'init_cfg' in config.model.backbone:\n        config.model.backbone.init_cfg = None\n    config.model.train_cfg = None\n\n    # register all modules in mmpose into the registries\n    scope = config.get('default_scope', 'mmpose')\n    if scope is not None:\n        init_default_scope(scope)\n\n    model = build_pose_estimator(config.model)\n    model = revert_sync_batchnorm(model)\n    # get dataset_meta in this priority: checkpoint > config > default (COCO)\n    dataset_meta = None\n\n    if checkpoint is not None:\n        ckpt = load_checkpoint(model, checkpoint, map_location='cpu')\n\n        if 'dataset_meta' in ckpt.get('meta', {}):\n            # checkpoint from mmpose 1.x\n            dataset_meta = ckpt['meta']['dataset_meta']\n\n    if dataset_meta is None:\n        dataset_meta = dataset_meta_from_config(config, dataset_mode='train')\n\n    if dataset_meta is None:\n        warnings.simplefilter('once')\n        warnings.warn('Can not load dataset_meta from the checkpoint or the '\n                      'model config. Use COCO metainfo by default.')\n        dataset_meta = parse_pose_metainfo(\n            dict(from_file='configs/_base_/datasets/coco.py'))\n\n    model.dataset_meta = dataset_meta\n\n    model.cfg = config  # save the config in the model for convenience\n    model.to(device)\n    model.eval()\n    return model\n\n\ndef inference_topdown(model: nn.Module,\n                      img: Union[np.ndarray, str],\n                      bboxes: Optional[Union[List, np.ndarray]] = None,\n                      bbox_format: str = 'xyxy') -> List[PoseDataSample]:\n    \"\"\"Inference image with a top-down pose estimator.\n\n    Args:\n        model (nn.Module): The top-down pose estimator\n        img (np.ndarray | str): The loaded image or image file to inference\n        bboxes (np.ndarray, optional): The bboxes in shape (N, 4), each row\n            represents a bbox. If not given, the entire image will be regarded\n            as a single bbox area. Defaults to ``None``\n        bbox_format (str): The bbox format indicator. Options are ``'xywh'``\n            and ``'xyxy'``. Defaults to ``'xyxy'``\n\n    Returns:\n        List[:obj:`PoseDataSample`]: The inference results. Specifically, the\n        predicted keypoints and scores are saved at\n        ``data_sample.pred_instances.keypoints`` and\n        ``data_sample.pred_instances.keypoint_scores``.\n    \"\"\"\n    scope = model.cfg.get('default_scope', 'mmpose')\n    if scope is not None:\n        init_default_scope(scope)\n    pipeline = Compose(model.cfg.test_dataloader.dataset.pipeline)\n\n    if bboxes is None or len(bboxes) == 0:\n        # get bbox from the image size\n        if isinstance(img, str):\n            w, h = Image.open(img).size\n        else:\n            h, w = img.shape[:2]\n\n        bboxes = np.array([[0, 0, w, h]], dtype=np.float32)\n    else:\n        if isinstance(bboxes, list):\n            bboxes = np.array(bboxes)\n\n        assert bbox_format in {'xyxy', 'xywh'}, \\\n            f'Invalid bbox_format \"{bbox_format}\".'\n\n        if bbox_format == 'xywh':\n            bboxes = bbox_xywh2xyxy(bboxes)\n\n    # construct batch data samples\n    data_list = []\n    for bbox in bboxes:\n        if isinstance(img, str):\n            data_info = dict(img_path=img)\n        else:\n            data_info = dict(img=img)\n        data_info['bbox'] = bbox[None]  # shape (1, 4)\n        data_info['bbox_score'] = np.ones(1, dtype=np.float32)  # shape (1,)\n        data_info.update(model.dataset_meta)\n        data_list.append(pipeline(data_info))\n\n    if data_list:\n        # collate data list into a batch, which is a dict with following keys:\n        # batch['inputs']: a list of input images\n        # batch['data_samples']: a list of :obj:`PoseDataSample`\n        batch = pseudo_collate(data_list)\n        with torch.no_grad():\n            results = model.test_step(batch)\n    else:\n        results = []\n\n    return results\n\n\ndef inference_bottomup(model: nn.Module, img: Union[np.ndarray, str]):\n    \"\"\"Inference image with a bottom-up pose estimator.\n\n    Args:\n        model (nn.Module): The bottom-up pose estimator\n        img (np.ndarray | str): The loaded image or image file to inference\n\n    Returns:\n        List[:obj:`PoseDataSample`]: The inference results. Specifically, the\n        predicted keypoints and scores are saved at\n        ``data_sample.pred_instances.keypoints`` and\n        ``data_sample.pred_instances.keypoint_scores``.\n    \"\"\"\n    pipeline = Compose(model.cfg.test_dataloader.dataset.pipeline)\n\n    # prepare data batch\n    if isinstance(img, str):\n        data_info = dict(img_path=img)\n    else:\n        data_info = dict(img=img)\n    data_info.update(model.dataset_meta)\n    data = pipeline(data_info)\n    batch = pseudo_collate([data])\n\n    with torch.no_grad():\n        results = model.test_step(batch)\n\n    return results\n\n\ndef collect_multi_frames(video, frame_id, indices, online=False):\n    \"\"\"Collect multi frames from the video.\n\n    Args:\n        video (mmcv.VideoReader): A VideoReader of the input video file.\n        frame_id (int): index of the current frame\n        indices (list(int)): index offsets of the frames to collect\n        online (bool): inference mode, if set to True, can not use future\n            frame information.\n\n    Returns:\n        list(ndarray): multi frames collected from the input video file.\n    \"\"\"\n    num_frames = len(video)\n    frames = []\n    # put the current frame at first\n    frames.append(video[frame_id])\n    # use multi frames for inference\n    for idx in indices:\n        # skip current frame\n        if idx == 0:\n            continue\n        support_idx = frame_id + idx\n        # online mode, can not use future frame information\n        if online:\n            support_idx = np.clip(support_idx, 0, frame_id)\n        else:\n            support_idx = np.clip(support_idx, 0, num_frames - 1)\n        frames.append(video[support_idx])\n\n    return frames\n"
  },
  {
    "path": "mmpose/apis/inference_3d.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport numpy as np\nimport torch\nfrom mmengine.dataset import Compose, pseudo_collate\nfrom mmengine.registry import init_default_scope\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.structures import PoseDataSample\n\n\ndef convert_keypoint_definition(keypoints, pose_det_dataset,\n                                pose_lift_dataset):\n    \"\"\"Convert pose det dataset keypoints definition to pose lifter dataset\n    keypoints definition, so that they are compatible with the definitions\n    required for 3D pose lifting.\n\n    Args:\n        keypoints (ndarray[N, K, 2 or 3]): 2D keypoints to be transformed.\n        pose_det_dataset, (str): Name of the dataset for 2D pose detector.\n        pose_lift_dataset (str): Name of the dataset for pose lifter model.\n\n    Returns:\n        ndarray[K, 2 or 3]: the transformed 2D keypoints.\n    \"\"\"\n    assert pose_lift_dataset in [\n        'h36m', 'h3wb'], '`pose_lift_dataset` should be ' \\\n        f'`h36m`, but got {pose_lift_dataset}.'\n\n    keypoints_new = np.zeros((keypoints.shape[0], 17, keypoints.shape[2]),\n                             dtype=keypoints.dtype)\n    if pose_lift_dataset in ['h36m', 'h3wb']:\n        if pose_det_dataset in ['h36m', 'coco_wholebody']:\n            keypoints_new = keypoints\n        elif pose_det_dataset in ['coco', 'posetrack18']:\n            # pelvis (root) is in the middle of l_hip and r_hip\n            keypoints_new[:, 0] = (keypoints[:, 11] + keypoints[:, 12]) / 2\n            # thorax is in the middle of l_shoulder and r_shoulder\n            keypoints_new[:, 8] = (keypoints[:, 5] + keypoints[:, 6]) / 2\n            # spine is in the middle of thorax and pelvis\n            keypoints_new[:,\n                          7] = (keypoints_new[:, 0] + keypoints_new[:, 8]) / 2\n            # in COCO, head is in the middle of l_eye and r_eye\n            # in PoseTrack18, head is in the middle of head_bottom and head_top\n            keypoints_new[:, 10] = (keypoints[:, 1] + keypoints[:, 2]) / 2\n            # rearrange other keypoints\n            keypoints_new[:, [1, 2, 3, 4, 5, 6, 9, 11, 12, 13, 14, 15, 16]] = \\\n                keypoints[:, [12, 14, 16, 11, 13, 15, 0, 5, 7, 9, 6, 8, 10]]\n        elif pose_det_dataset in ['aic']:\n            # pelvis (root) is in the middle of l_hip and r_hip\n            keypoints_new[:, 0] = (keypoints[:, 9] + keypoints[:, 6]) / 2\n            # thorax is in the middle of l_shoulder and r_shoulder\n            keypoints_new[:, 8] = (keypoints[:, 3] + keypoints[:, 0]) / 2\n            # spine is in the middle of thorax and pelvis\n            keypoints_new[:,\n                          7] = (keypoints_new[:, 0] + keypoints_new[:, 8]) / 2\n            # neck base (top end of neck) is 1/4 the way from\n            # neck (bottom end of neck) to head top\n            keypoints_new[:, 9] = (3 * keypoints[:, 13] + keypoints[:, 12]) / 4\n            # head (spherical centre of head) is 7/12 the way from\n            # neck (bottom end of neck) to head top\n            keypoints_new[:, 10] = (5 * keypoints[:, 13] +\n                                    7 * keypoints[:, 12]) / 12\n\n            keypoints_new[:, [1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 16]] = \\\n                keypoints[:, [6, 7, 8, 9, 10, 11, 3, 4, 5, 0, 1, 2]]\n        elif pose_det_dataset in ['crowdpose']:\n            # pelvis (root) is in the middle of l_hip and r_hip\n            keypoints_new[:, 0] = (keypoints[:, 6] + keypoints[:, 7]) / 2\n            # thorax is in the middle of l_shoulder and r_shoulder\n            keypoints_new[:, 8] = (keypoints[:, 0] + keypoints[:, 1]) / 2\n            # spine is in the middle of thorax and pelvis\n            keypoints_new[:,\n                          7] = (keypoints_new[:, 0] + keypoints_new[:, 8]) / 2\n            # neck base (top end of neck) is 1/4 the way from\n            # neck (bottom end of neck) to head top\n            keypoints_new[:, 9] = (3 * keypoints[:, 13] + keypoints[:, 12]) / 4\n            # head (spherical centre of head) is 7/12 the way from\n            # neck (bottom end of neck) to head top\n            keypoints_new[:, 10] = (5 * keypoints[:, 13] +\n                                    7 * keypoints[:, 12]) / 12\n\n            keypoints_new[:, [1, 2, 3, 4, 5, 6, 11, 12, 13, 14, 15, 16]] = \\\n                keypoints[:, [7, 9, 11, 6, 8, 10, 0, 2, 4, 1, 3, 5]]\n        else:\n            raise NotImplementedError(\n                f'unsupported conversion between {pose_lift_dataset} and '\n                f'{pose_det_dataset}')\n\n    return keypoints_new\n\n\ndef extract_pose_sequence(pose_results, frame_idx, causal, seq_len, step=1):\n    \"\"\"Extract the target frame from 2D pose results, and pad the sequence to a\n    fixed length.\n\n    Args:\n        pose_results (List[List[:obj:`PoseDataSample`]]): Multi-frame pose\n            detection results stored in a list.\n        frame_idx (int): The index of the frame in the original video.\n        causal (bool): If True, the target frame is the last frame in\n            a sequence. Otherwise, the target frame is in the middle of\n            a sequence.\n        seq_len (int): The number of frames in the input sequence.\n        step (int): Step size to extract frames from the video.\n\n    Returns:\n        List[List[:obj:`PoseDataSample`]]: Multi-frame pose detection results\n            stored in a nested list with a length of seq_len.\n    \"\"\"\n    if causal:\n        frames_left = seq_len - 1\n        frames_right = 0\n    else:\n        frames_left = (seq_len - 1) // 2\n        frames_right = frames_left\n    num_frames = len(pose_results)\n\n    # get the padded sequence\n    pad_left = max(0, frames_left - frame_idx // step)\n    pad_right = max(0, frames_right - (num_frames - 1 - frame_idx) // step)\n    start = max(frame_idx % step, frame_idx - frames_left * step)\n    end = min(num_frames - (num_frames - 1 - frame_idx) % step,\n              frame_idx + frames_right * step + 1)\n    pose_results_seq = [pose_results[0]] * pad_left + \\\n        pose_results[start:end:step] + [pose_results[-1]] * pad_right\n    return pose_results_seq\n\n\ndef collate_pose_sequence(pose_results_2d,\n                          with_track_id=True,\n                          target_frame=-1):\n    \"\"\"Reorganize multi-frame pose detection results into individual pose\n    sequences.\n\n    Note:\n        - The temporal length of the pose detection results: T\n        - The number of the person instances: N\n        - The number of the keypoints: K\n        - The channel number of each keypoint: C\n\n    Args:\n        pose_results_2d (List[List[:obj:`PoseDataSample`]]): Multi-frame pose\n            detection results stored in a nested list. Each element of the\n            outer list is the pose detection results of a single frame, and\n            each element of the inner list is the pose information of one\n            person, which contains:\n\n                - keypoints (ndarray[K, 2 or 3]): x, y, [score]\n                - track_id (int): unique id of each person, required when\n                    ``with_track_id==True```\n\n        with_track_id (bool): If True, the element in pose_results is expected\n            to contain \"track_id\", which will be used to gather the pose\n            sequence of a person from multiple frames. Otherwise, the pose\n            results in each frame are expected to have a consistent number and\n            order of identities. Default is True.\n        target_frame (int): The index of the target frame. Default: -1.\n\n    Returns:\n        List[:obj:`PoseDataSample`]: Indivisual pose sequence in with length N.\n    \"\"\"\n    T = len(pose_results_2d)\n    assert T > 0\n\n    target_frame = (T + target_frame) % T  # convert negative index to positive\n\n    N = len(\n        pose_results_2d[target_frame])  # use identities in the target frame\n    if N == 0:\n        return []\n\n    B, K, C = pose_results_2d[target_frame][0].pred_instances.keypoints.shape\n\n    track_ids = None\n    if with_track_id:\n        track_ids = [res.track_id for res in pose_results_2d[target_frame]]\n\n    pose_sequences = []\n    for idx in range(N):\n        pose_seq = PoseDataSample()\n        pred_instances = InstanceData()\n\n        gt_instances = pose_results_2d[target_frame][idx].gt_instances.clone()\n        pred_instances = pose_results_2d[target_frame][\n            idx].pred_instances.clone()\n        pose_seq.pred_instances = pred_instances\n        pose_seq.gt_instances = gt_instances\n\n        if not with_track_id:\n            pose_seq.pred_instances.keypoints = np.stack([\n                frame[idx].pred_instances.keypoints\n                for frame in pose_results_2d\n            ],\n                                                         axis=1)\n        else:\n            keypoints = np.zeros((B, T, K, C), dtype=np.float32)\n            keypoints[:, target_frame] = pose_results_2d[target_frame][\n                idx].pred_instances.keypoints\n            # find the left most frame containing track_ids[idx]\n            for frame_idx in range(target_frame - 1, -1, -1):\n                contains_idx = False\n                for res in pose_results_2d[frame_idx]:\n                    if res.track_id == track_ids[idx]:\n                        keypoints[:, frame_idx] = res.pred_instances.keypoints\n                        contains_idx = True\n                        break\n                if not contains_idx:\n                    # replicate the left most frame\n                    keypoints[:, :frame_idx + 1] = keypoints[:, frame_idx + 1]\n                    break\n            # find the right most frame containing track_idx[idx]\n            for frame_idx in range(target_frame + 1, T):\n                contains_idx = False\n                for res in pose_results_2d[frame_idx]:\n                    if res.track_id == track_ids[idx]:\n                        keypoints[:, frame_idx] = res.pred_instances.keypoints\n                        contains_idx = True\n                        break\n                if not contains_idx:\n                    # replicate the right most frame\n                    keypoints[:, frame_idx + 1:] = keypoints[:, frame_idx]\n                    break\n            pose_seq.pred_instances.set_field(keypoints, 'keypoints')\n        pose_sequences.append(pose_seq)\n\n    return pose_sequences\n\n\ndef inference_pose_lifter_model(model,\n                                pose_results_2d,\n                                with_track_id=True,\n                                image_size=None,\n                                norm_pose_2d=False):\n    \"\"\"Inference 3D pose from 2D pose sequences using a pose lifter model.\n\n    Args:\n        model (nn.Module): The loaded pose lifter model\n        pose_results_2d (List[List[:obj:`PoseDataSample`]]): The 2D pose\n            sequences stored in a nested list.\n        with_track_id: If True, the element in pose_results_2d is expected to\n            contain \"track_id\", which will be used to gather the pose sequence\n            of a person from multiple frames. Otherwise, the pose results in\n            each frame are expected to have a consistent number and order of\n            identities. Default is True.\n        image_size (tuple|list): image width, image height. If None, image size\n            will not be contained in dict ``data``.\n        norm_pose_2d (bool): If True, scale the bbox (along with the 2D\n            pose) to the average bbox scale of the dataset, and move the bbox\n            (along with the 2D pose) to the average bbox center of the dataset.\n\n    Returns:\n        List[:obj:`PoseDataSample`]: 3D pose inference results. Specifically,\n        the predicted keypoints and scores are saved at\n        ``data_sample.pred_instances.keypoints_3d``.\n    \"\"\"\n    init_default_scope(model.cfg.get('default_scope', 'mmpose'))\n    pipeline = Compose(model.cfg.test_dataloader.dataset.pipeline)\n\n    causal = model.cfg.test_dataloader.dataset.get('causal', False)\n    target_idx = -1 if causal else len(pose_results_2d) // 2\n\n    dataset_info = model.dataset_meta\n    if dataset_info is not None:\n        if 'stats_info' in dataset_info:\n            bbox_center = dataset_info['stats_info']['bbox_center']\n            bbox_scale = dataset_info['stats_info']['bbox_scale']\n        else:\n            if norm_pose_2d:\n                # compute the average bbox center and scale from the\n                # datasamples in pose_results_2d\n                bbox_center = np.zeros((1, 2), dtype=np.float32)\n                bbox_scale = 0\n                num_bbox = 0\n                for pose_res in pose_results_2d:\n                    for data_sample in pose_res:\n                        for bbox in data_sample.pred_instances.bboxes:\n                            bbox_center += np.array([[(bbox[0] + bbox[2]) / 2,\n                                                      (bbox[1] + bbox[3]) / 2]\n                                                     ])\n                            bbox_scale += max(bbox[2] - bbox[0],\n                                              bbox[3] - bbox[1])\n                            num_bbox += 1\n                bbox_center /= num_bbox\n                bbox_scale /= num_bbox\n            else:\n                bbox_center = None\n                bbox_scale = None\n\n    pose_results_2d_copy = []\n    for i, pose_res in enumerate(pose_results_2d):\n        pose_res_copy = []\n        for j, data_sample in enumerate(pose_res):\n            data_sample_copy = PoseDataSample()\n            data_sample_copy.gt_instances = data_sample.gt_instances.clone()\n            data_sample_copy.pred_instances = data_sample.pred_instances.clone(\n            )\n            data_sample_copy.track_id = data_sample.track_id\n            kpts = data_sample.pred_instances.keypoints\n            bboxes = data_sample.pred_instances.bboxes\n            keypoints = []\n            for k in range(len(kpts)):\n                kpt = kpts[k]\n                if norm_pose_2d:\n                    bbox = bboxes[k]\n                    center = np.array([[(bbox[0] + bbox[2]) / 2,\n                                        (bbox[1] + bbox[3]) / 2]])\n                    scale = max(bbox[2] - bbox[0], bbox[3] - bbox[1])\n                    keypoints.append((kpt[:, :2] - center) / scale *\n                                     bbox_scale + bbox_center)\n                else:\n                    keypoints.append(kpt[:, :2])\n            data_sample_copy.pred_instances.set_field(\n                np.array(keypoints), 'keypoints')\n            pose_res_copy.append(data_sample_copy)\n        pose_results_2d_copy.append(pose_res_copy)\n\n    pose_sequences_2d = collate_pose_sequence(pose_results_2d_copy,\n                                              with_track_id, target_idx)\n\n    if not pose_sequences_2d:\n        return []\n\n    data_list = []\n    for i, pose_seq in enumerate(pose_sequences_2d):\n        data_info = dict()\n\n        keypoints_2d = pose_seq.pred_instances.keypoints\n        keypoints_2d = np.squeeze(\n            keypoints_2d, axis=0) if keypoints_2d.ndim == 4 else keypoints_2d\n\n        T, K, C = keypoints_2d.shape\n\n        data_info['keypoints'] = keypoints_2d\n        data_info['keypoints_visible'] = np.ones((\n            T,\n            K,\n        ), dtype=np.float32)\n        data_info['lifting_target'] = np.zeros((1, K, 3), dtype=np.float32)\n        data_info['factor'] = np.zeros((T, ), dtype=np.float32)\n        data_info['lifting_target_visible'] = np.ones((1, K, 1),\n                                                      dtype=np.float32)\n\n        if image_size is not None:\n            assert len(image_size) == 2\n            data_info['camera_param'] = dict(w=image_size[0], h=image_size[1])\n\n        data_info.update(model.dataset_meta)\n        data_list.append(pipeline(data_info))\n\n    if data_list:\n        # collate data list into a batch, which is a dict with following keys:\n        # batch['inputs']: a list of input images\n        # batch['data_samples']: a list of :obj:`PoseDataSample`\n        batch = pseudo_collate(data_list)\n        with torch.no_grad():\n            results = model.test_step(batch)\n    else:\n        results = []\n\n    return results\n"
  },
  {
    "path": "mmpose/apis/inference_tracking.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\n\nimport numpy as np\n\nfrom mmpose.evaluation.functional.nms import oks_iou\n\n\ndef _compute_iou(bboxA, bboxB):\n    \"\"\"Compute the Intersection over Union (IoU) between two boxes .\n\n    Args:\n        bboxA (list): The first bbox info (left, top, right, bottom, score).\n        bboxB (list): The second bbox info (left, top, right, bottom, score).\n\n    Returns:\n        float: The IoU value.\n    \"\"\"\n\n    x1 = max(bboxA[0], bboxB[0])\n    y1 = max(bboxA[1], bboxB[1])\n    x2 = min(bboxA[2], bboxB[2])\n    y2 = min(bboxA[3], bboxB[3])\n\n    inter_area = max(0, x2 - x1) * max(0, y2 - y1)\n\n    bboxA_area = (bboxA[2] - bboxA[0]) * (bboxA[3] - bboxA[1])\n    bboxB_area = (bboxB[2] - bboxB[0]) * (bboxB[3] - bboxB[1])\n    union_area = float(bboxA_area + bboxB_area - inter_area)\n    if union_area == 0:\n        union_area = 1e-5\n        warnings.warn('union_area=0 is unexpected')\n\n    iou = inter_area / union_area\n\n    return iou\n\n\ndef _track_by_iou(res, results_last, thr):\n    \"\"\"Get track id using IoU tracking greedily.\"\"\"\n\n    bbox = list(np.squeeze(res.pred_instances.bboxes, axis=0))\n\n    max_iou_score = -1\n    max_index = -1\n    match_result = {}\n    for index, res_last in enumerate(results_last):\n        bbox_last = list(np.squeeze(res_last.pred_instances.bboxes, axis=0))\n\n        iou_score = _compute_iou(bbox, bbox_last)\n        if iou_score > max_iou_score:\n            max_iou_score = iou_score\n            max_index = index\n\n    if max_iou_score > thr:\n        track_id = results_last[max_index].track_id\n        match_result = results_last[max_index]\n        del results_last[max_index]\n    else:\n        track_id = -1\n\n    return track_id, results_last, match_result\n\n\ndef _track_by_oks(res, results_last, thr, sigmas=None):\n    \"\"\"Get track id using OKS tracking greedily.\"\"\"\n    keypoint = np.concatenate((res.pred_instances.keypoints,\n                               res.pred_instances.keypoint_scores[:, :, None]),\n                              axis=2)\n    keypoint = np.squeeze(keypoint, axis=0).reshape((-1))\n    area = np.squeeze(res.pred_instances.areas, axis=0)\n    max_index = -1\n    match_result = {}\n\n    if len(results_last) == 0:\n        return -1, results_last, match_result\n\n    keypoints_last = np.array([\n        np.squeeze(\n            np.concatenate(\n                (res_last.pred_instances.keypoints,\n                 res_last.pred_instances.keypoint_scores[:, :, None]),\n                axis=2),\n            axis=0).reshape((-1)) for res_last in results_last\n    ])\n    area_last = np.array([\n        np.squeeze(res_last.pred_instances.areas, axis=0)\n        for res_last in results_last\n    ])\n\n    oks_score = oks_iou(\n        keypoint, keypoints_last, area, area_last, sigmas=sigmas)\n\n    max_index = np.argmax(oks_score)\n\n    if oks_score[max_index] > thr:\n        track_id = results_last[max_index].track_id\n        match_result = results_last[max_index]\n        del results_last[max_index]\n    else:\n        track_id = -1\n\n    return track_id, results_last, match_result\n"
  },
  {
    "path": "mmpose/apis/inferencers/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .hand3d_inferencer import Hand3DInferencer\nfrom .mmpose_inferencer import MMPoseInferencer\nfrom .pose2d_inferencer import Pose2DInferencer\nfrom .pose3d_inferencer import Pose3DInferencer\nfrom .utils import get_model_aliases\n\n__all__ = [\n    'Pose2DInferencer', 'MMPoseInferencer', 'get_model_aliases',\n    'Pose3DInferencer', 'Hand3DInferencer'\n]\n"
  },
  {
    "path": "mmpose/apis/inferencers/base_mmpose_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport inspect\nimport logging\nimport mimetypes\nimport os\nfrom collections import defaultdict\nfrom typing import (Callable, Dict, Generator, Iterable, List, Optional,\n                    Sequence, Tuple, Union)\n\nimport cv2\nimport mmcv\nimport mmengine\nimport numpy as np\nimport torch.nn as nn\nfrom mmengine.config import Config, ConfigDict\nfrom mmengine.dataset import Compose\nfrom mmengine.fileio import (get_file_backend, isdir, join_path,\n                             list_dir_or_file)\nfrom mmengine.infer.infer import BaseInferencer, ModelType\nfrom mmengine.logging import print_log\nfrom mmengine.registry import init_default_scope\nfrom mmengine.runner.checkpoint import _load_checkpoint_to_model\nfrom mmengine.structures import InstanceData\nfrom mmengine.utils import mkdir_or_exist\nfrom rich.progress import track\n\nfrom mmpose.apis.inference import dataset_meta_from_config\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures import PoseDataSample, split_instances\nfrom .utils import default_det_models\n\ntry:\n    from mmdet.apis.det_inferencer import DetInferencer\n    has_mmdet = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmdet = False\n\nInstanceList = List[InstanceData]\nInputType = Union[str, np.ndarray]\nInputsType = Union[InputType, Sequence[InputType]]\nPredType = Union[InstanceData, InstanceList]\nImgType = Union[np.ndarray, Sequence[np.ndarray]]\nConfigType = Union[Config, ConfigDict]\nResType = Union[Dict, List[Dict], InstanceData, List[InstanceData]]\n\n\nclass BaseMMPoseInferencer(BaseInferencer):\n    \"\"\"The base class for MMPose inferencers.\"\"\"\n\n    preprocess_kwargs: set = {'bbox_thr', 'nms_thr', 'bboxes'}\n    forward_kwargs: set = set()\n    visualize_kwargs: set = {\n        'return_vis', 'show', 'wait_time', 'draw_bbox', 'radius', 'thickness',\n        'kpt_thr', 'vis_out_dir', 'black_background'\n    }\n    postprocess_kwargs: set = {'pred_out_dir', 'return_datasample'}\n\n    def __init__(self,\n                 model: Union[ModelType, str, None] = None,\n                 weights: Optional[str] = None,\n                 device: Optional[str] = None,\n                 scope: Optional[str] = None,\n                 show_progress: bool = False) -> None:\n        super().__init__(\n            model, weights, device, scope, show_progress=show_progress)\n\n    def _init_detector(\n        self,\n        det_model: Optional[Union[ModelType, str]] = None,\n        det_weights: Optional[str] = None,\n        det_cat_ids: Optional[Union[int, Tuple]] = None,\n        device: Optional[str] = None,\n    ):\n        object_type = DATASETS.get(self.cfg.dataset_type).__module__.split(\n            'datasets.')[-1].split('.')[0].lower()\n\n        if det_model in ('whole_image', 'whole-image') or \\\n            (det_model is None and\n                object_type not in default_det_models):\n            self.detector = None\n\n        else:\n            det_scope = 'mmdet'\n            if det_model is None:\n                det_info = default_det_models[object_type]\n                det_model, det_weights, det_cat_ids = det_info[\n                    'model'], det_info['weights'], det_info['cat_ids']\n            elif os.path.exists(det_model):\n                det_cfg = Config.fromfile(det_model)\n                det_scope = det_cfg.default_scope\n\n            if has_mmdet:\n                det_kwargs = dict(\n                    model=det_model,\n                    weights=det_weights,\n                    device=device,\n                    scope=det_scope,\n                )\n                # for compatibility with low version of mmdet\n                if 'show_progress' in inspect.signature(\n                        DetInferencer).parameters:\n                    det_kwargs['show_progress'] = False\n\n                self.detector = DetInferencer(**det_kwargs)\n            else:\n                raise RuntimeError(\n                    'MMDetection (v3.0.0 or above) is required to build '\n                    'inferencers for top-down pose estimation models.')\n\n            if isinstance(det_cat_ids, (tuple, list)):\n                self.det_cat_ids = det_cat_ids\n            else:\n                self.det_cat_ids = (det_cat_ids, )\n\n    def _load_weights_to_model(self, model: nn.Module,\n                               checkpoint: Optional[dict],\n                               cfg: Optional[ConfigType]) -> None:\n        \"\"\"Loading model weights and meta information from cfg and checkpoint.\n\n        Subclasses could override this method to load extra meta information\n        from ``checkpoint`` and ``cfg`` to model.\n\n        Args:\n            model (nn.Module): Model to load weights and meta information.\n            checkpoint (dict, optional): The loaded checkpoint.\n            cfg (Config or ConfigDict, optional): The loaded config.\n        \"\"\"\n        if checkpoint is not None:\n            _load_checkpoint_to_model(model, checkpoint)\n            checkpoint_meta = checkpoint.get('meta', {})\n            # save the dataset_meta in the model for convenience\n            if 'dataset_meta' in checkpoint_meta:\n                # mmpose 1.x\n                model.dataset_meta = checkpoint_meta['dataset_meta']\n            else:\n                print_log(\n                    'dataset_meta are not saved in the checkpoint\\'s '\n                    'meta data, load via config.',\n                    logger='current',\n                    level=logging.WARNING)\n                model.dataset_meta = dataset_meta_from_config(\n                    cfg, dataset_mode='train')\n        else:\n            print_log(\n                'Checkpoint is not loaded, and the inference '\n                'result is calculated by the randomly initialized '\n                'model!',\n                logger='current',\n                level=logging.WARNING)\n            model.dataset_meta = dataset_meta_from_config(\n                cfg, dataset_mode='train')\n\n    def _inputs_to_list(self, inputs: InputsType) -> Iterable:\n        \"\"\"Preprocess the inputs to a list.\n\n        Preprocess inputs to a list according to its type:\n\n        - list or tuple: return inputs\n        - str:\n            - Directory path: return all files in the directory\n            - other cases: return a list containing the string. The string\n              could be a path to file, a url or other types of string\n              according to the task.\n\n        Args:\n            inputs (InputsType): Inputs for the inferencer.\n\n        Returns:\n            list: List of input for the :meth:`preprocess`.\n        \"\"\"\n        self._video_input = False\n\n        if isinstance(inputs, str):\n            backend = get_file_backend(inputs)\n            if hasattr(backend, 'isdir') and isdir(inputs):\n                # Backends like HttpsBackend do not implement `isdir`, so only\n                # those backends that implement `isdir` could accept the\n                # inputs as a directory\n                filepath_list = [\n                    join_path(inputs, fname)\n                    for fname in list_dir_or_file(inputs, list_dir=False)\n                ]\n                inputs = []\n                for filepath in filepath_list:\n                    input_type = mimetypes.guess_type(filepath)[0].split(\n                        '/')[0]\n                    if input_type == 'image':\n                        inputs.append(filepath)\n                inputs.sort()\n            else:\n                # if inputs is a path to a video file, it will be converted\n                # to a list containing separated frame filenames\n                input_type = mimetypes.guess_type(inputs)[0].split('/')[0]\n                if input_type == 'video':\n                    self._video_input = True\n                    video = mmcv.VideoReader(inputs)\n                    self.video_info = dict(\n                        fps=video.fps,\n                        name=os.path.basename(inputs),\n                        writer=None,\n                        width=video.width,\n                        height=video.height,\n                        predictions=[])\n                    inputs = video\n                elif input_type == 'image':\n                    inputs = [inputs]\n                else:\n                    raise ValueError(f'Expected input to be an image, video, '\n                                     f'or folder, but received {inputs} of '\n                                     f'type {input_type}.')\n\n        elif isinstance(inputs, np.ndarray):\n            inputs = [inputs]\n\n        return inputs\n\n    def _get_webcam_inputs(self, inputs: str) -> Generator:\n        \"\"\"Sets up and returns a generator function that reads frames from a\n        webcam input. The generator function returns a new frame each time it\n        is iterated over.\n\n        Args:\n            inputs (str): A string describing the webcam input, in the format\n                \"webcam:id\".\n\n        Returns:\n            A generator function that yields frames from the webcam input.\n\n        Raises:\n            ValueError: If the inputs string is not in the expected format.\n        \"\"\"\n\n        # Ensure the inputs string is in the expected format.\n        inputs = inputs.lower()\n        assert inputs.startswith('webcam'), f'Expected input to start with ' \\\n            f'\"webcam\", but got \"{inputs}\"'\n\n        # Parse the camera ID from the inputs string.\n        inputs_ = inputs.split(':')\n        if len(inputs_) == 1:\n            camera_id = 0\n        elif len(inputs_) == 2 and str.isdigit(inputs_[1]):\n            camera_id = int(inputs_[1])\n        else:\n            raise ValueError(\n                f'Expected webcam input to have format \"webcam:id\", '\n                f'but got \"{inputs}\"')\n\n        # Attempt to open the video capture object.\n        vcap = cv2.VideoCapture(camera_id)\n        if not vcap.isOpened():\n            print_log(\n                f'Cannot open camera (ID={camera_id})',\n                logger='current',\n                level=logging.WARNING)\n            return []\n\n        # Set video input flag and metadata.\n        self._video_input = True\n        (major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')\n        if int(major_ver) < 3:\n            fps = vcap.get(cv2.cv.CV_CAP_PROP_FPS)\n            width = vcap.get(cv2.cv.CV_CAP_PROP_FRAME_WIDTH)\n            height = vcap.get(cv2.cv.CV_CAP_PROP_FRAME_HEIGHT)\n        else:\n            fps = vcap.get(cv2.CAP_PROP_FPS)\n            width = vcap.get(cv2.CAP_PROP_FRAME_WIDTH)\n            height = vcap.get(cv2.CAP_PROP_FRAME_HEIGHT)\n        self.video_info = dict(\n            fps=fps,\n            name='webcam.mp4',\n            writer=None,\n            width=width,\n            height=height,\n            predictions=[])\n\n        def _webcam_reader() -> Generator:\n            while True:\n                if cv2.waitKey(5) & 0xFF == 27:\n                    vcap.release()\n                    break\n\n                ret_val, frame = vcap.read()\n                if not ret_val:\n                    break\n\n                yield frame\n\n        return _webcam_reader()\n\n    def _init_pipeline(self, cfg: ConfigType) -> Callable:\n        \"\"\"Initialize the test pipeline.\n\n        Args:\n            cfg (ConfigType): model config path or dict\n\n        Returns:\n            A pipeline to handle various input data, such as ``str``,\n            ``np.ndarray``. The returned pipeline will be used to process\n            a single data.\n        \"\"\"\n        scope = cfg.get('default_scope', 'mmpose')\n        if scope is not None:\n            init_default_scope(scope)\n        return Compose(cfg.test_dataloader.dataset.pipeline)\n\n    def update_model_visualizer_settings(self, **kwargs):\n        \"\"\"Update the settings of models and visualizer according to inference\n        arguments.\"\"\"\n\n        pass\n\n    def preprocess(self,\n                   inputs: InputsType,\n                   batch_size: int = 1,\n                   bboxes: Optional[List] = None,\n                   bbox_thr: float = 0.3,\n                   nms_thr: float = 0.3,\n                   **kwargs):\n        \"\"\"Process the inputs into a model-feedable format.\n\n        Args:\n            inputs (InputsType): Inputs given by user.\n            batch_size (int): batch size. Defaults to 1.\n            bbox_thr (float): threshold for bounding box detection.\n                Defaults to 0.3.\n            nms_thr (float): IoU threshold for bounding box NMS.\n                Defaults to 0.3.\n\n        Yields:\n            Any: Data processed by the ``pipeline`` and ``collate_fn``.\n            List[str or np.ndarray]: List of original inputs in the batch\n        \"\"\"\n\n        # One-stage pose estimators perform prediction filtering within the\n        # head's `predict` method. Here, we set the arguments for filtering\n        if self.cfg.model.type == 'BottomupPoseEstimator':\n            # 1. init with default arguments\n            test_cfg = self.model.head.test_cfg.copy()\n            # 2. update the score_thr and nms_thr in the test_cfg of the head\n            if 'score_thr' in test_cfg:\n                test_cfg['score_thr'] = bbox_thr\n            if 'nms_thr' in test_cfg:\n                test_cfg['nms_thr'] = nms_thr\n            self.model.test_cfg = test_cfg\n\n        for i, input in enumerate(inputs):\n            bbox = bboxes[i] if bboxes else []\n            data_infos = self.preprocess_single(\n                input,\n                index=i,\n                bboxes=bbox,\n                bbox_thr=bbox_thr,\n                nms_thr=nms_thr,\n                **kwargs)\n            # only supports inference with batch size 1\n            yield self.collate_fn(data_infos), [input]\n\n    def __call__(\n        self,\n        inputs: InputsType,\n        return_datasamples: bool = False,\n        batch_size: int = 1,\n        out_dir: Optional[str] = None,\n        **kwargs,\n    ) -> dict:\n        \"\"\"Call the inferencer.\n\n        Args:\n            inputs (InputsType): Inputs for the inferencer.\n            return_datasamples (bool): Whether to return results as\n                :obj:`BaseDataElement`. Defaults to False.\n            batch_size (int): Batch size. Defaults to 1.\n            out_dir (str, optional): directory to save visualization\n                results and predictions. Will be overoden if vis_out_dir or\n                pred_out_dir are given. Defaults to None\n            **kwargs: Key words arguments passed to :meth:`preprocess`,\n                :meth:`forward`, :meth:`visualize` and :meth:`postprocess`.\n                Each key in kwargs should be in the corresponding set of\n                ``preprocess_kwargs``, ``forward_kwargs``,\n                ``visualize_kwargs`` and ``postprocess_kwargs``.\n\n        Returns:\n            dict: Inference and visualization results.\n        \"\"\"\n        if out_dir is not None:\n            if 'vis_out_dir' not in kwargs:\n                kwargs['vis_out_dir'] = f'{out_dir}/visualizations'\n            if 'pred_out_dir' not in kwargs:\n                kwargs['pred_out_dir'] = f'{out_dir}/predictions'\n\n        (\n            preprocess_kwargs,\n            forward_kwargs,\n            visualize_kwargs,\n            postprocess_kwargs,\n        ) = self._dispatch_kwargs(**kwargs)\n\n        self.update_model_visualizer_settings(**kwargs)\n\n        # preprocessing\n        if isinstance(inputs, str) and inputs.startswith('webcam'):\n            inputs = self._get_webcam_inputs(inputs)\n            batch_size = 1\n            if not visualize_kwargs.get('show', False):\n                print_log(\n                    'The display mode is closed when using webcam '\n                    'input. It will be turned on automatically.',\n                    logger='current',\n                    level=logging.WARNING)\n            visualize_kwargs['show'] = True\n        else:\n            inputs = self._inputs_to_list(inputs)\n\n        # check the compatibility between inputs/outputs\n        if not self._video_input and len(inputs) > 0:\n            vis_out_dir = visualize_kwargs.get('vis_out_dir', None)\n            if vis_out_dir is not None:\n                _, file_extension = os.path.splitext(vis_out_dir)\n                assert not file_extension, f'the argument `vis_out_dir` ' \\\n                    f'should be a folder while the input contains multiple ' \\\n                    f'images, but got {vis_out_dir}'\n\n        if 'bbox_thr' in self.forward_kwargs:\n            forward_kwargs['bbox_thr'] = preprocess_kwargs.get('bbox_thr', -1)\n        inputs = self.preprocess(\n            inputs, batch_size=batch_size, **preprocess_kwargs)\n\n        preds = []\n\n        for proc_inputs, ori_inputs in (track(inputs, description='Inference')\n                                        if self.show_progress else inputs):\n            preds = self.forward(proc_inputs, **forward_kwargs)\n\n            visualization = self.visualize(ori_inputs, preds,\n                                           **visualize_kwargs)\n            results = self.postprocess(\n                preds,\n                visualization,\n                return_datasamples=return_datasamples,\n                **postprocess_kwargs)\n            yield results\n\n        if self._video_input:\n            self._finalize_video_processing(\n                postprocess_kwargs.get('pred_out_dir', ''))\n\n        # In 3D Inferencers, some intermediate results (e.g. 2d keypoints)\n        # will be temporarily stored in `self._buffer`. It's essential to\n        # clear this information to prevent any interference with subsequent\n        # inferences.\n        if hasattr(self, '_buffer'):\n            self._buffer.clear()\n\n    def visualize(self,\n                  inputs: list,\n                  preds: List[PoseDataSample],\n                  return_vis: bool = False,\n                  show: bool = False,\n                  draw_bbox: bool = False,\n                  wait_time: float = 0,\n                  radius: int = 3,\n                  thickness: int = 1,\n                  kpt_thr: float = 0.3,\n                  vis_out_dir: str = '',\n                  window_name: str = '',\n                  black_background: bool = False,\n                  **kwargs) -> List[np.ndarray]:\n        \"\"\"Visualize predictions.\n\n        Args:\n            inputs (list): Inputs preprocessed by :meth:`_inputs_to_list`.\n            preds (Any): Predictions of the model.\n            return_vis (bool): Whether to return images with predicted results.\n            show (bool): Whether to display the image in a popup window.\n                Defaults to False.\n            wait_time (float): The interval of show (ms). Defaults to 0\n            draw_bbox (bool): Whether to draw the bounding boxes.\n                Defaults to False\n            radius (int): Keypoint radius for visualization. Defaults to 3\n            thickness (int): Link thickness for visualization. Defaults to 1\n            kpt_thr (float): The threshold to visualize the keypoints.\n                Defaults to 0.3\n            vis_out_dir (str, optional): Directory to save visualization\n                results w/o predictions. If left as empty, no file will\n                be saved. Defaults to ''.\n            window_name (str, optional): Title of display window.\n            black_background (bool, optional): Whether to plot keypoints on a\n                black image instead of the input image. Defaults to False.\n\n        Returns:\n            List[np.ndarray]: Visualization results.\n        \"\"\"\n        if (not return_vis) and (not show) and (not vis_out_dir):\n            return\n\n        if getattr(self, 'visualizer', None) is None:\n            raise ValueError('Visualization needs the \"visualizer\" term'\n                             'defined in the config, but got None.')\n\n        self.visualizer.radius = radius\n        self.visualizer.line_width = thickness\n\n        results = []\n\n        for single_input, pred in zip(inputs, preds):\n            if isinstance(single_input, str):\n                img = mmcv.imread(single_input, channel_order='rgb')\n            elif isinstance(single_input, np.ndarray):\n                img = mmcv.bgr2rgb(single_input)\n            else:\n                raise ValueError('Unsupported input type: '\n                                 f'{type(single_input)}')\n            if black_background:\n                img = img * 0\n\n            img_name = os.path.basename(pred.metainfo['img_path'])\n            window_name = window_name if window_name else img_name\n\n            # since visualization and inference utilize the same process,\n            # the wait time is reduced when a video input is utilized,\n            # thereby eliminating the issue of inference getting stuck.\n            wait_time = 1e-5 if self._video_input else wait_time\n\n            visualization = self.visualizer.add_datasample(\n                window_name,\n                img,\n                pred,\n                draw_gt=False,\n                draw_bbox=draw_bbox,\n                show=show,\n                wait_time=wait_time,\n                kpt_thr=kpt_thr,\n                **kwargs)\n            results.append(visualization)\n\n            if vis_out_dir:\n                self.save_visualization(\n                    visualization,\n                    vis_out_dir,\n                    img_name=img_name,\n                )\n\n        if return_vis:\n            return results\n        else:\n            return []\n\n    def save_visualization(self, visualization, vis_out_dir, img_name=None):\n        out_img = mmcv.rgb2bgr(visualization)\n        _, file_extension = os.path.splitext(vis_out_dir)\n        if file_extension:\n            dir_name = os.path.dirname(vis_out_dir)\n            file_name = os.path.basename(vis_out_dir)\n        else:\n            dir_name = vis_out_dir\n            file_name = None\n        mkdir_or_exist(dir_name)\n\n        if self._video_input:\n\n            if self.video_info['writer'] is None:\n                fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n                if file_name is None:\n                    file_name = os.path.basename(self.video_info['name'])\n                out_file = join_path(dir_name, file_name)\n                self.video_info['output_file'] = out_file\n                self.video_info['writer'] = cv2.VideoWriter(\n                    out_file, fourcc, self.video_info['fps'],\n                    (visualization.shape[1], visualization.shape[0]))\n            self.video_info['writer'].write(out_img)\n\n        else:\n            if file_name is None:\n                file_name = img_name if img_name else 'visualization.jpg'\n\n            out_file = join_path(dir_name, file_name)\n            mmcv.imwrite(out_img, out_file)\n            print_log(\n                f'the output image has been saved at {out_file}',\n                logger='current',\n                level=logging.INFO)\n\n    def postprocess(\n        self,\n        preds: List[PoseDataSample],\n        visualization: List[np.ndarray],\n        return_datasample=None,\n        return_datasamples=False,\n        pred_out_dir: str = '',\n    ) -> dict:\n        \"\"\"Process the predictions and visualization results from ``forward``\n        and ``visualize``.\n\n        This method should be responsible for the following tasks:\n\n        1. Convert datasamples into a json-serializable dict if needed.\n        2. Pack the predictions and visualization results and return them.\n        3. Dump or log the predictions.\n\n        Args:\n            preds (List[Dict]): Predictions of the model.\n            visualization (np.ndarray): Visualized predictions.\n            return_datasamples (bool): Whether to return results as\n                datasamples. Defaults to False.\n            pred_out_dir (str): Directory to save the inference results w/o\n                visualization. If left as empty, no file will be saved.\n                Defaults to ''.\n\n        Returns:\n            dict: Inference and visualization results with key ``predictions``\n            and ``visualization``\n\n            - ``visualization (Any)``: Returned by :meth:`visualize`\n            - ``predictions`` (dict or DataSample): Returned by\n              :meth:`forward` and processed in :meth:`postprocess`.\n              If ``return_datasamples=False``, it usually should be a\n              json-serializable dict containing only basic data elements such\n              as strings and numbers.\n        \"\"\"\n        if return_datasample is not None:\n            print_log(\n                'The `return_datasample` argument is deprecated '\n                'and will be removed in future versions. Please '\n                'use `return_datasamples`.',\n                logger='current',\n                level=logging.WARNING)\n            return_datasamples = return_datasample\n\n        result_dict = defaultdict(list)\n\n        result_dict['visualization'] = visualization\n        for pred in preds:\n            if not return_datasamples:\n                # convert datasamples to list of instance predictions\n                pred = split_instances(pred.pred_instances)\n            result_dict['predictions'].append(pred)\n\n        if pred_out_dir != '':\n            for pred, data_sample in zip(result_dict['predictions'], preds):\n                if self._video_input:\n                    # For video or webcam input, predictions for each frame\n                    # are gathered in the 'predictions' key of 'video_info'\n                    # dictionary. All frame predictions are then stored into\n                    # a single file after processing all frames.\n                    self.video_info['predictions'].append(pred)\n                else:\n                    # For non-video inputs, predictions are stored in separate\n                    # JSON files. The filename is determined by the basename\n                    # of the input image path with a '.json' extension. The\n                    # predictions are then dumped into this file.\n                    fname = os.path.splitext(\n                        os.path.basename(\n                            data_sample.metainfo['img_path']))[0] + '.json'\n                    mmengine.dump(\n                        pred, join_path(pred_out_dir, fname), indent='  ')\n\n        return result_dict\n\n    def _finalize_video_processing(\n        self,\n        pred_out_dir: str = '',\n    ):\n        \"\"\"Finalize video processing by releasing the video writer and saving\n        predictions to a file.\n\n        This method should be called after completing the video processing. It\n        releases the video writer, if it exists, and saves the predictions to a\n        JSON file if a prediction output directory is provided.\n        \"\"\"\n\n        # Release the video writer if it exists\n        if self.video_info['writer'] is not None:\n            out_file = self.video_info['output_file']\n            print_log(\n                f'the output video has been saved at {out_file}',\n                logger='current',\n                level=logging.INFO)\n            self.video_info['writer'].release()\n\n        # Save predictions\n        if pred_out_dir:\n            fname = os.path.splitext(\n                os.path.basename(self.video_info['name']))[0] + '.json'\n            predictions = [\n                dict(frame_id=i, instances=pred)\n                for i, pred in enumerate(self.video_info['predictions'])\n            ]\n\n            mmengine.dump(\n                predictions, join_path(pred_out_dir, fname), indent='  ')\n"
  },
  {
    "path": "mmpose/apis/inferencers/hand3d_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nimport os\nfrom collections import defaultdict\nfrom typing import Dict, List, Optional, Sequence, Tuple, Union\n\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmengine.config import Config, ConfigDict\nfrom mmengine.infer.infer import ModelType\nfrom mmengine.logging import print_log\nfrom mmengine.model import revert_sync_batchnorm\nfrom mmengine.registry import init_default_scope\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.evaluation.functional import nms\nfrom mmpose.registry import INFERENCERS\nfrom mmpose.structures import PoseDataSample, merge_data_samples\nfrom .base_mmpose_inferencer import BaseMMPoseInferencer\n\nInstanceList = List[InstanceData]\nInputType = Union[str, np.ndarray]\nInputsType = Union[InputType, Sequence[InputType]]\nPredType = Union[InstanceData, InstanceList]\nImgType = Union[np.ndarray, Sequence[np.ndarray]]\nConfigType = Union[Config, ConfigDict]\nResType = Union[Dict, List[Dict], InstanceData, List[InstanceData]]\n\n\n@INFERENCERS.register_module()\nclass Hand3DInferencer(BaseMMPoseInferencer):\n    \"\"\"The inferencer for 3D hand pose estimation.\n\n    Args:\n        model (str, optional): Pretrained 2D pose estimation algorithm.\n            It's the path to the config file or the model name defined in\n            metafile. For example, it could be:\n\n            - model alias, e.g. ``'body'``,\n            - config name, e.g. ``'simcc_res50_8xb64-210e_coco-256x192'``,\n            - config path\n\n            Defaults to ``None``.\n        weights (str, optional): Path to the checkpoint. If it is not\n            specified and \"model\" is a model name of metafile, the weights\n            will be loaded from metafile. Defaults to None.\n        device (str, optional): Device to run inference. If None, the\n            available device will be automatically used. Defaults to None.\n        scope (str, optional): The scope of the model. Defaults to \"mmpose\".\n        det_model (str, optional): Config path or alias of detection model.\n            Defaults to None.\n        det_weights (str, optional): Path to the checkpoints of detection\n            model. Defaults to None.\n        det_cat_ids (int or list[int], optional): Category id for\n            detection model. Defaults to None.\n    \"\"\"\n\n    preprocess_kwargs: set = {'bbox_thr', 'nms_thr', 'bboxes'}\n    forward_kwargs: set = {'disable_rebase_keypoint'}\n    visualize_kwargs: set = {\n        'return_vis',\n        'show',\n        'wait_time',\n        'draw_bbox',\n        'radius',\n        'thickness',\n        'kpt_thr',\n        'vis_out_dir',\n        'num_instances',\n    }\n    postprocess_kwargs: set = {'pred_out_dir', 'return_datasample'}\n\n    def __init__(self,\n                 model: Union[ModelType, str],\n                 weights: Optional[str] = None,\n                 device: Optional[str] = None,\n                 scope: Optional[str] = 'mmpose',\n                 det_model: Optional[Union[ModelType, str]] = None,\n                 det_weights: Optional[str] = None,\n                 det_cat_ids: Optional[Union[int, Tuple]] = None,\n                 show_progress: bool = False) -> None:\n\n        init_default_scope(scope)\n        super().__init__(\n            model=model,\n            weights=weights,\n            device=device,\n            scope=scope,\n            show_progress=show_progress)\n        self.model = revert_sync_batchnorm(self.model)\n\n        # assign dataset metainfo to self.visualizer\n        self.visualizer.set_dataset_meta(self.model.dataset_meta)\n\n        # initialize hand detector\n        self._init_detector(\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=det_cat_ids,\n            device=device,\n        )\n\n        self._video_input = False\n        self._buffer = defaultdict(list)\n\n    def preprocess_single(self,\n                          input: InputType,\n                          index: int,\n                          bbox_thr: float = 0.3,\n                          nms_thr: float = 0.3,\n                          bboxes: Union[List[List], List[np.ndarray],\n                                        np.ndarray] = []):\n        \"\"\"Process a single input into a model-feedable format.\n\n        Args:\n            input (InputType): Input given by user.\n            index (int): index of the input\n            bbox_thr (float): threshold for bounding box detection.\n                Defaults to 0.3.\n            nms_thr (float): IoU threshold for bounding box NMS.\n                Defaults to 0.3.\n\n        Yields:\n            Any: Data processed by the ``pipeline`` and ``collate_fn``.\n        \"\"\"\n\n        if isinstance(input, str):\n            data_info = dict(img_path=input)\n        else:\n            data_info = dict(img=input, img_path=f'{index}.jpg'.rjust(10, '0'))\n        data_info.update(self.model.dataset_meta)\n\n        if self.detector is not None:\n            try:\n                det_results = self.detector(\n                    input, return_datasamples=True)['predictions']\n            except ValueError:\n                print_log(\n                    'Support for mmpose and mmdet versions up to 3.1.0 '\n                    'will be discontinued in upcoming releases. To '\n                    'ensure ongoing compatibility, please upgrade to '\n                    'mmdet version 3.2.0 or later.',\n                    logger='current',\n                    level=logging.WARNING)\n                det_results = self.detector(\n                    input, return_datasample=True)['predictions']\n            pred_instance = det_results[0].pred_instances.cpu().numpy()\n            bboxes = np.concatenate(\n                (pred_instance.bboxes, pred_instance.scores[:, None]), axis=1)\n\n            label_mask = np.zeros(len(bboxes), dtype=np.uint8)\n            for cat_id in self.det_cat_ids:\n                label_mask = np.logical_or(label_mask,\n                                           pred_instance.labels == cat_id)\n\n            bboxes = bboxes[np.logical_and(label_mask,\n                                           pred_instance.scores > bbox_thr)]\n            bboxes = bboxes[nms(bboxes, nms_thr)]\n\n        data_infos = []\n        if len(bboxes) > 0:\n            for bbox in bboxes:\n                inst = data_info.copy()\n                inst['bbox'] = bbox[None, :4]\n                inst['bbox_score'] = bbox[4:5]\n                data_infos.append(self.pipeline(inst))\n        else:\n            inst = data_info.copy()\n\n            # get bbox from the image size\n            if isinstance(input, str):\n                input = mmcv.imread(input)\n            h, w = input.shape[:2]\n\n            inst['bbox'] = np.array([[0, 0, w, h]], dtype=np.float32)\n            inst['bbox_score'] = np.ones(1, dtype=np.float32)\n            data_infos.append(self.pipeline(inst))\n\n        return data_infos\n\n    @torch.no_grad()\n    def forward(self,\n                inputs: Union[dict, tuple],\n                disable_rebase_keypoint: bool = False):\n        \"\"\"Performs a forward pass through the model.\n\n        Args:\n            inputs (Union[dict, tuple]): The input data to be processed. Can\n                be either a dictionary or a tuple.\n            disable_rebase_keypoint (bool, optional): Flag to disable rebasing\n                the height of the keypoints. Defaults to False.\n\n        Returns:\n            A list of data samples with prediction instances.\n        \"\"\"\n        data_samples = self.model.test_step(inputs)\n        data_samples_2d = []\n\n        for idx, res in enumerate(data_samples):\n            pred_instances = res.pred_instances\n            keypoints = pred_instances.keypoints\n            rel_root_depth = pred_instances.rel_root_depth\n            scores = pred_instances.keypoint_scores\n            hand_type = pred_instances.hand_type\n\n            res_2d = PoseDataSample()\n            gt_instances = res.gt_instances.clone()\n            pred_instances = pred_instances.clone()\n            res_2d.gt_instances = gt_instances\n            res_2d.pred_instances = pred_instances\n\n            # add relative root depth to left hand joints\n            keypoints[:, 21:, 2] += rel_root_depth\n\n            # set joint scores according to hand type\n            scores[:, :21] *= hand_type[:, [0]]\n            scores[:, 21:] *= hand_type[:, [1]]\n            # normalize kpt score\n            if scores.max() > 1:\n                scores /= 255\n\n            res_2d.pred_instances.set_field(keypoints[..., :2].copy(),\n                                            'keypoints')\n\n            # rotate the keypoint to make z-axis correspondent to height\n            # for better visualization\n            vis_R = np.array([[1, 0, 0], [0, 0, -1], [0, 1, 0]])\n            keypoints[..., :3] = keypoints[..., :3] @ vis_R\n\n            # rebase height (z-axis)\n            if not disable_rebase_keypoint:\n                valid = scores > 0\n                keypoints[..., 2] -= np.min(\n                    keypoints[valid, 2], axis=-1, keepdims=True)\n\n            data_samples[idx].pred_instances.keypoints = keypoints\n            data_samples[idx].pred_instances.keypoint_scores = scores\n            data_samples_2d.append(res_2d)\n\n        data_samples = [merge_data_samples(data_samples)]\n        data_samples_2d = merge_data_samples(data_samples_2d)\n\n        self._buffer['pose2d_results'] = data_samples_2d\n\n        return data_samples\n\n    def visualize(\n        self,\n        inputs: list,\n        preds: List[PoseDataSample],\n        return_vis: bool = False,\n        show: bool = False,\n        draw_bbox: bool = False,\n        wait_time: float = 0,\n        radius: int = 3,\n        thickness: int = 1,\n        kpt_thr: float = 0.3,\n        num_instances: int = 1,\n        vis_out_dir: str = '',\n        window_name: str = '',\n    ) -> List[np.ndarray]:\n        \"\"\"Visualize predictions.\n\n        Args:\n            inputs (list): Inputs preprocessed by :meth:`_inputs_to_list`.\n            preds (Any): Predictions of the model.\n            return_vis (bool): Whether to return images with predicted results.\n            show (bool): Whether to display the image in a popup window.\n                Defaults to False.\n            wait_time (float): The interval of show (ms). Defaults to 0\n            draw_bbox (bool): Whether to draw the bounding boxes.\n                Defaults to False\n            radius (int): Keypoint radius for visualization. Defaults to 3\n            thickness (int): Link thickness for visualization. Defaults to 1\n            kpt_thr (float): The threshold to visualize the keypoints.\n                Defaults to 0.3\n            vis_out_dir (str, optional): Directory to save visualization\n                results w/o predictions. If left as empty, no file will\n                be saved. Defaults to ''.\n            window_name (str, optional): Title of display window.\n            window_close_event_handler (callable, optional):\n\n        Returns:\n            List[np.ndarray]: Visualization results.\n        \"\"\"\n        if (not return_vis) and (not show) and (not vis_out_dir):\n            return\n\n        if getattr(self, 'visualizer', None) is None:\n            raise ValueError('Visualization needs the \"visualizer\" term'\n                             'defined in the config, but got None.')\n\n        self.visualizer.radius = radius\n        self.visualizer.line_width = thickness\n\n        results = []\n\n        for single_input, pred in zip(inputs, preds):\n            if isinstance(single_input, str):\n                img = mmcv.imread(single_input, channel_order='rgb')\n            elif isinstance(single_input, np.ndarray):\n                img = mmcv.bgr2rgb(single_input)\n            else:\n                raise ValueError('Unsupported input type: '\n                                 f'{type(single_input)}')\n            img_name = os.path.basename(pred.metainfo['img_path'])\n\n            # since visualization and inference utilize the same process,\n            # the wait time is reduced when a video input is utilized,\n            # thereby eliminating the issue of inference getting stuck.\n            wait_time = 1e-5 if self._video_input else wait_time\n\n            if num_instances < 0:\n                num_instances = len(pred.pred_instances)\n\n            visualization = self.visualizer.add_datasample(\n                window_name,\n                img,\n                data_sample=pred,\n                det_data_sample=self._buffer['pose2d_results'],\n                draw_gt=False,\n                draw_bbox=draw_bbox,\n                show=show,\n                wait_time=wait_time,\n                convert_keypoint=False,\n                axis_azimuth=-115,\n                axis_limit=200,\n                axis_elev=15,\n                kpt_thr=kpt_thr,\n                num_instances=num_instances)\n            results.append(visualization)\n\n            if vis_out_dir:\n                self.save_visualization(\n                    visualization,\n                    vis_out_dir,\n                    img_name=img_name,\n                )\n\n        if return_vis:\n            return results\n        else:\n            return []\n"
  },
  {
    "path": "mmpose/apis/inferencers/mmpose_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import Dict, List, Optional, Sequence, Union\n\nimport numpy as np\nimport torch\nfrom mmengine.config import Config, ConfigDict\nfrom mmengine.infer.infer import ModelType\nfrom mmengine.structures import InstanceData\nfrom rich.progress import track\n\nfrom .base_mmpose_inferencer import BaseMMPoseInferencer\nfrom .hand3d_inferencer import Hand3DInferencer\nfrom .pose2d_inferencer import Pose2DInferencer\nfrom .pose3d_inferencer import Pose3DInferencer\n\nInstanceList = List[InstanceData]\nInputType = Union[str, np.ndarray]\nInputsType = Union[InputType, Sequence[InputType]]\nPredType = Union[InstanceData, InstanceList]\nImgType = Union[np.ndarray, Sequence[np.ndarray]]\nConfigType = Union[Config, ConfigDict]\nResType = Union[Dict, List[Dict], InstanceData, List[InstanceData]]\n\n\nclass MMPoseInferencer(BaseMMPoseInferencer):\n    \"\"\"MMPose Inferencer. It's a unified inferencer interface for pose\n    estimation task, currently including: Pose2D. and it can be used to perform\n    2D keypoint detection.\n\n    Args:\n        pose2d (str, optional): Pretrained 2D pose estimation algorithm.\n            It's the path to the config file or the model name defined in\n            metafile. For example, it could be:\n\n            - model alias, e.g. ``'body'``,\n            - config name, e.g. ``'simcc_res50_8xb64-210e_coco-256x192'``,\n            - config path\n\n            Defaults to ``None``.\n        pose2d_weights (str, optional): Path to the custom checkpoint file of\n            the selected pose2d model. If it is not specified and \"pose2d\" is\n            a model name of metafile, the weights will be loaded from\n            metafile. Defaults to None.\n        device (str, optional): Device to run inference. If None, the\n            available device will be automatically used. Defaults to None.\n        scope (str, optional): The scope of the model. Defaults to \"mmpose\".\n        det_model(str, optional): Config path or alias of detection model.\n            Defaults to None.\n        det_weights(str, optional): Path to the checkpoints of detection\n            model. Defaults to None.\n        det_cat_ids(int or list[int], optional): Category id for\n            detection model. Defaults to None.\n        output_heatmaps (bool, optional): Flag to visualize predicted\n            heatmaps. If set to None, the default setting from the model\n            config will be used. Default is None.\n    \"\"\"\n\n    preprocess_kwargs: set = {\n        'bbox_thr', 'nms_thr', 'bboxes', 'use_oks_tracking', 'tracking_thr',\n        'disable_norm_pose_2d'\n    }\n    forward_kwargs: set = {\n        'merge_results', 'disable_rebase_keypoint', 'pose_based_nms'\n    }\n    visualize_kwargs: set = {\n        'return_vis', 'show', 'wait_time', 'draw_bbox', 'radius', 'thickness',\n        'kpt_thr', 'vis_out_dir', 'skeleton_style', 'draw_heatmap',\n        'black_background', 'num_instances'\n    }\n    postprocess_kwargs: set = {'pred_out_dir', 'return_datasample'}\n\n    def __init__(self,\n                 pose2d: Optional[str] = None,\n                 pose2d_weights: Optional[str] = None,\n                 pose3d: Optional[str] = None,\n                 pose3d_weights: Optional[str] = None,\n                 device: Optional[str] = None,\n                 scope: str = 'mmpose',\n                 det_model: Optional[Union[ModelType, str]] = None,\n                 det_weights: Optional[str] = None,\n                 det_cat_ids: Optional[Union[int, List]] = None,\n                 show_progress: bool = False) -> None:\n\n        self.visualizer = None\n        self.show_progress = show_progress\n        if pose3d is not None:\n            if 'hand3d' in pose3d:\n                self.inferencer = Hand3DInferencer(pose3d, pose3d_weights,\n                                                   device, scope, det_model,\n                                                   det_weights, det_cat_ids,\n                                                   show_progress)\n            else:\n                self.inferencer = Pose3DInferencer(pose3d, pose3d_weights,\n                                                   pose2d, pose2d_weights,\n                                                   device, scope, det_model,\n                                                   det_weights, det_cat_ids,\n                                                   show_progress)\n        elif pose2d is not None:\n            self.inferencer = Pose2DInferencer(pose2d, pose2d_weights, device,\n                                               scope, det_model, det_weights,\n                                               det_cat_ids, show_progress)\n        else:\n            raise ValueError('Either 2d or 3d pose estimation algorithm '\n                             'should be provided.')\n\n    def preprocess(self, inputs: InputsType, batch_size: int = 1, **kwargs):\n        \"\"\"Process the inputs into a model-feedable format.\n\n        Args:\n            inputs (InputsType): Inputs given by user.\n            batch_size (int): batch size. Defaults to 1.\n\n        Yields:\n            Any: Data processed by the ``pipeline`` and ``collate_fn``.\n            List[str or np.ndarray]: List of original inputs in the batch\n        \"\"\"\n        for data in self.inferencer.preprocess(inputs, batch_size, **kwargs):\n            yield data\n\n    @torch.no_grad()\n    def forward(self, inputs: InputType, **forward_kwargs) -> PredType:\n        \"\"\"Forward the inputs to the model.\n\n        Args:\n            inputs (InputsType): The inputs to be forwarded.\n\n        Returns:\n            Dict: The prediction results. Possibly with keys \"pose2d\".\n        \"\"\"\n        return self.inferencer.forward(inputs, **forward_kwargs)\n\n    def __call__(\n        self,\n        inputs: InputsType,\n        return_datasamples: bool = False,\n        batch_size: int = 1,\n        out_dir: Optional[str] = None,\n        **kwargs,\n    ) -> dict:\n        \"\"\"Call the inferencer.\n\n        Args:\n            inputs (InputsType): Inputs for the inferencer.\n            return_datasamples (bool): Whether to return results as\n                :obj:`BaseDataElement`. Defaults to False.\n            batch_size (int): Batch size. Defaults to 1.\n            out_dir (str, optional): directory to save visualization\n                results and predictions. Will be overoden if vis_out_dir or\n                pred_out_dir are given. Defaults to None\n            **kwargs: Key words arguments passed to :meth:`preprocess`,\n                :meth:`forward`, :meth:`visualize` and :meth:`postprocess`.\n                Each key in kwargs should be in the corresponding set of\n                ``preprocess_kwargs``, ``forward_kwargs``,\n                ``visualize_kwargs`` and ``postprocess_kwargs``.\n\n        Returns:\n            dict: Inference and visualization results.\n        \"\"\"\n        if out_dir is not None:\n            if 'vis_out_dir' not in kwargs:\n                kwargs['vis_out_dir'] = f'{out_dir}/visualizations'\n            if 'pred_out_dir' not in kwargs:\n                kwargs['pred_out_dir'] = f'{out_dir}/predictions'\n\n        kwargs = {\n            key: value\n            for key, value in kwargs.items()\n            if key in set.union(self.inferencer.preprocess_kwargs,\n                                self.inferencer.forward_kwargs,\n                                self.inferencer.visualize_kwargs,\n                                self.inferencer.postprocess_kwargs)\n        }\n        (\n            preprocess_kwargs,\n            forward_kwargs,\n            visualize_kwargs,\n            postprocess_kwargs,\n        ) = self._dispatch_kwargs(**kwargs)\n\n        self.inferencer.update_model_visualizer_settings(**kwargs)\n\n        # preprocessing\n        if isinstance(inputs, str) and inputs.startswith('webcam'):\n            inputs = self.inferencer._get_webcam_inputs(inputs)\n            batch_size = 1\n            if not visualize_kwargs.get('show', False):\n                warnings.warn('The display mode is closed when using webcam '\n                              'input. It will be turned on automatically.')\n            visualize_kwargs['show'] = True\n        else:\n            inputs = self.inferencer._inputs_to_list(inputs)\n        self._video_input = self.inferencer._video_input\n        if self._video_input:\n            self.video_info = self.inferencer.video_info\n\n        inputs = self.preprocess(\n            inputs, batch_size=batch_size, **preprocess_kwargs)\n\n        # forward\n        if 'bbox_thr' in self.inferencer.forward_kwargs:\n            forward_kwargs['bbox_thr'] = preprocess_kwargs.get('bbox_thr', -1)\n\n        preds = []\n\n        for proc_inputs, ori_inputs in (track(inputs, description='Inference')\n                                        if self.show_progress else inputs):\n            preds = self.forward(proc_inputs, **forward_kwargs)\n\n            visualization = self.visualize(ori_inputs, preds,\n                                           **visualize_kwargs)\n            results = self.postprocess(\n                preds,\n                visualization,\n                return_datasamples=return_datasamples,\n                **postprocess_kwargs)\n            yield results\n\n        if self._video_input:\n            self._finalize_video_processing(\n                postprocess_kwargs.get('pred_out_dir', ''))\n\n    def visualize(self, inputs: InputsType, preds: PredType,\n                  **kwargs) -> List[np.ndarray]:\n        \"\"\"Visualize predictions.\n\n        Args:\n            inputs (list): Inputs preprocessed by :meth:`_inputs_to_list`.\n            preds (Any): Predictions of the model.\n            return_vis (bool): Whether to return images with predicted results.\n            show (bool): Whether to display the image in a popup window.\n                Defaults to False.\n            show_interval (int): The interval of show (s). Defaults to 0\n            radius (int): Keypoint radius for visualization. Defaults to 3\n            thickness (int): Link thickness for visualization. Defaults to 1\n            kpt_thr (float): The threshold to visualize the keypoints.\n                Defaults to 0.3\n            vis_out_dir (str, optional): directory to save visualization\n                results w/o predictions. If left as empty, no file will\n                be saved. Defaults to ''.\n\n        Returns:\n            List[np.ndarray]: Visualization results.\n        \"\"\"\n        window_name = ''\n        if self.inferencer._video_input:\n            window_name = self.inferencer.video_info['name']\n\n        return self.inferencer.visualize(\n            inputs, preds, window_name=window_name, **kwargs)\n"
  },
  {
    "path": "mmpose/apis/inferencers/pose2d_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nfrom typing import Dict, List, Optional, Sequence, Tuple, Union\n\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmengine.config import Config, ConfigDict\nfrom mmengine.infer.infer import ModelType\nfrom mmengine.logging import print_log\nfrom mmengine.model import revert_sync_batchnorm\nfrom mmengine.registry import init_default_scope\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.evaluation.functional import nearby_joints_nms, nms\nfrom mmpose.registry import INFERENCERS\nfrom mmpose.structures import merge_data_samples\nfrom .base_mmpose_inferencer import BaseMMPoseInferencer\n\nInstanceList = List[InstanceData]\nInputType = Union[str, np.ndarray]\nInputsType = Union[InputType, Sequence[InputType]]\nPredType = Union[InstanceData, InstanceList]\nImgType = Union[np.ndarray, Sequence[np.ndarray]]\nConfigType = Union[Config, ConfigDict]\nResType = Union[Dict, List[Dict], InstanceData, List[InstanceData]]\n\n\n@INFERENCERS.register_module(name='pose-estimation')\n@INFERENCERS.register_module()\nclass Pose2DInferencer(BaseMMPoseInferencer):\n    \"\"\"The inferencer for 2D pose estimation.\n\n    Args:\n        model (str, optional): Pretrained 2D pose estimation algorithm.\n            It's the path to the config file or the model name defined in\n            metafile. For example, it could be:\n\n            - model alias, e.g. ``'body'``,\n            - config name, e.g. ``'simcc_res50_8xb64-210e_coco-256x192'``,\n            - config path\n\n            Defaults to ``None``.\n        weights (str, optional): Path to the checkpoint. If it is not\n            specified and \"model\" is a model name of metafile, the weights\n            will be loaded from metafile. Defaults to None.\n        device (str, optional): Device to run inference. If None, the\n            available device will be automatically used. Defaults to None.\n        scope (str, optional): The scope of the model. Defaults to \"mmpose\".\n        det_model (str, optional): Config path or alias of detection model.\n            Defaults to None.\n        det_weights (str, optional): Path to the checkpoints of detection\n            model. Defaults to None.\n        det_cat_ids (int or list[int], optional): Category id for\n            detection model. Defaults to None.\n    \"\"\"\n\n    preprocess_kwargs: set = {'bbox_thr', 'nms_thr', 'bboxes'}\n    forward_kwargs: set = {'merge_results', 'pose_based_nms'}\n    visualize_kwargs: set = {\n        'return_vis',\n        'show',\n        'wait_time',\n        'draw_bbox',\n        'radius',\n        'thickness',\n        'kpt_thr',\n        'vis_out_dir',\n        'skeleton_style',\n        'draw_heatmap',\n        'black_background',\n    }\n    postprocess_kwargs: set = {'pred_out_dir', 'return_datasample'}\n\n    def __init__(self,\n                 model: Union[ModelType, str],\n                 weights: Optional[str] = None,\n                 device: Optional[str] = None,\n                 scope: Optional[str] = 'mmpose',\n                 det_model: Optional[Union[ModelType, str]] = None,\n                 det_weights: Optional[str] = None,\n                 det_cat_ids: Optional[Union[int, Tuple]] = None,\n                 show_progress: bool = False) -> None:\n\n        init_default_scope(scope)\n        super().__init__(\n            model=model,\n            weights=weights,\n            device=device,\n            scope=scope,\n            show_progress=show_progress)\n        self.model = revert_sync_batchnorm(self.model)\n\n        # assign dataset metainfo to self.visualizer\n        self.visualizer.set_dataset_meta(self.model.dataset_meta)\n\n        # initialize detector for top-down models\n        if self.cfg.data_mode == 'topdown':\n            self._init_detector(\n                det_model=det_model,\n                det_weights=det_weights,\n                det_cat_ids=det_cat_ids,\n                device=device,\n            )\n\n        self._video_input = False\n\n    def update_model_visualizer_settings(self,\n                                         draw_heatmap: bool = False,\n                                         skeleton_style: str = 'mmpose',\n                                         **kwargs) -> None:\n        \"\"\"Update the settings of models and visualizer according to inference\n        arguments.\n\n        Args:\n            draw_heatmaps (bool, optional): Flag to visualize predicted\n                heatmaps. If not provided, it defaults to False.\n            skeleton_style (str, optional): Skeleton style selection. Valid\n                options are 'mmpose' and 'openpose'. Defaults to 'mmpose'.\n        \"\"\"\n        self.model.test_cfg['output_heatmaps'] = draw_heatmap\n\n        if skeleton_style not in ['mmpose', 'openpose']:\n            raise ValueError('`skeleton_style` must be either \\'mmpose\\' '\n                             'or \\'openpose\\'')\n\n        if skeleton_style == 'openpose':\n            self.visualizer.set_dataset_meta(self.model.dataset_meta,\n                                             skeleton_style)\n\n    def preprocess_single(self,\n                          input: InputType,\n                          index: int,\n                          bbox_thr: float = 0.3,\n                          nms_thr: float = 0.3,\n                          bboxes: Union[List[List], List[np.ndarray],\n                                        np.ndarray] = []):\n        \"\"\"Process a single input into a model-feedable format.\n\n        Args:\n            input (InputType): Input given by user.\n            index (int): index of the input\n            bbox_thr (float): threshold for bounding box detection.\n                Defaults to 0.3.\n            nms_thr (float): IoU threshold for bounding box NMS.\n                Defaults to 0.3.\n\n        Yields:\n            Any: Data processed by the ``pipeline`` and ``collate_fn``.\n        \"\"\"\n\n        if isinstance(input, str):\n            data_info = dict(img_path=input)\n        else:\n            data_info = dict(img=input, img_path=f'{index}.jpg'.rjust(10, '0'))\n        data_info.update(self.model.dataset_meta)\n\n        if self.cfg.data_mode == 'topdown':\n            bboxes = []\n            if self.detector is not None:\n                try:\n                    det_results = self.detector(\n                        input, return_datasamples=True)['predictions']\n                except ValueError:\n                    print_log(\n                        'Support for mmpose and mmdet versions up to 3.1.0 '\n                        'will be discontinued in upcoming releases. To '\n                        'ensure ongoing compatibility, please upgrade to '\n                        'mmdet version 3.2.0 or later.',\n                        logger='current',\n                        level=logging.WARNING)\n                    det_results = self.detector(\n                        input, return_datasample=True)['predictions']\n                pred_instance = det_results[0].pred_instances.cpu().numpy()\n                bboxes = np.concatenate(\n                    (pred_instance.bboxes, pred_instance.scores[:, None]),\n                    axis=1)\n\n                label_mask = np.zeros(len(bboxes), dtype=np.uint8)\n                for cat_id in self.det_cat_ids:\n                    label_mask = np.logical_or(label_mask,\n                                               pred_instance.labels == cat_id)\n\n                bboxes = bboxes[np.logical_and(\n                    label_mask, pred_instance.scores > bbox_thr)]\n                bboxes = bboxes[nms(bboxes, nms_thr)]\n\n            data_infos = []\n            if len(bboxes) > 0:\n                for bbox in bboxes:\n                    inst = data_info.copy()\n                    inst['bbox'] = bbox[None, :4]\n                    inst['bbox_score'] = bbox[4:5]\n                    data_infos.append(self.pipeline(inst))\n            else:\n                inst = data_info.copy()\n\n                # get bbox from the image size\n                if isinstance(input, str):\n                    input = mmcv.imread(input)\n                h, w = input.shape[:2]\n\n                inst['bbox'] = np.array([[0, 0, w, h]], dtype=np.float32)\n                inst['bbox_score'] = np.ones(1, dtype=np.float32)\n                data_infos.append(self.pipeline(inst))\n\n        else:  # bottom-up\n            data_infos = [self.pipeline(data_info)]\n\n        return data_infos\n\n    @torch.no_grad()\n    def forward(self,\n                inputs: Union[dict, tuple],\n                merge_results: bool = True,\n                bbox_thr: float = -1,\n                pose_based_nms: bool = False):\n        \"\"\"Performs a forward pass through the model.\n\n        Args:\n            inputs (Union[dict, tuple]): The input data to be processed. Can\n                be either a dictionary or a tuple.\n            merge_results (bool, optional): Whether to merge data samples,\n                default to True. This is only applicable when the data_mode\n                is 'topdown'.\n            bbox_thr (float, optional): A threshold for the bounding box\n                scores. Bounding boxes with scores greater than this value\n                will be retained. Default value is -1 which retains all\n                bounding boxes.\n\n        Returns:\n            A list of data samples with prediction instances.\n        \"\"\"\n        data_samples = self.model.test_step(inputs)\n        if self.cfg.data_mode == 'topdown' and merge_results:\n            data_samples = [merge_data_samples(data_samples)]\n\n        if bbox_thr > 0:\n            for ds in data_samples:\n                if 'bbox_scores' in ds.pred_instances:\n                    ds.pred_instances = ds.pred_instances[\n                        ds.pred_instances.bbox_scores > bbox_thr]\n\n        if pose_based_nms:\n            for ds in data_samples:\n                if len(ds.pred_instances) == 0:\n                    continue\n\n                kpts = ds.pred_instances.keypoints\n                scores = ds.pred_instances.bbox_scores\n                num_keypoints = kpts.shape[-2]\n\n                kept_indices = nearby_joints_nms(\n                    [\n                        dict(keypoints=kpts[i], score=scores[i])\n                        for i in range(len(kpts))\n                    ],\n                    num_nearby_joints_thr=num_keypoints // 3,\n                )\n                ds.pred_instances = ds.pred_instances[kept_indices]\n\n        return data_samples\n"
  },
  {
    "path": "mmpose/apis/inferencers/pose3d_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nfrom collections import defaultdict\nfrom functools import partial\nfrom typing import Callable, Dict, List, Optional, Sequence, Tuple, Union\n\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmengine.config import Config, ConfigDict\nfrom mmengine.infer.infer import ModelType\nfrom mmengine.model import revert_sync_batchnorm\nfrom mmengine.registry import init_default_scope\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.apis import (_track_by_iou, _track_by_oks, collate_pose_sequence,\n                         convert_keypoint_definition, extract_pose_sequence)\nfrom mmpose.registry import INFERENCERS\nfrom mmpose.structures import PoseDataSample, merge_data_samples\nfrom .base_mmpose_inferencer import BaseMMPoseInferencer\nfrom .pose2d_inferencer import Pose2DInferencer\n\nInstanceList = List[InstanceData]\nInputType = Union[str, np.ndarray]\nInputsType = Union[InputType, Sequence[InputType]]\nPredType = Union[InstanceData, InstanceList]\nImgType = Union[np.ndarray, Sequence[np.ndarray]]\nConfigType = Union[Config, ConfigDict]\nResType = Union[Dict, List[Dict], InstanceData, List[InstanceData]]\n\n\n@INFERENCERS.register_module(name='pose-estimation-3d')\n@INFERENCERS.register_module()\nclass Pose3DInferencer(BaseMMPoseInferencer):\n    \"\"\"The inferencer for 3D pose estimation.\n\n    Args:\n        model (str, optional): Pretrained 2D pose estimation algorithm.\n            It's the path to the config file or the model name defined in\n            metafile. For example, it could be:\n\n            - model alias, e.g. ``'body'``,\n            - config name, e.g. ``'simcc_res50_8xb64-210e_coco-256x192'``,\n            - config path\n\n            Defaults to ``None``.\n        weights (str, optional): Path to the checkpoint. If it is not\n            specified and \"model\" is a model name of metafile, the weights\n            will be loaded from metafile. Defaults to None.\n        device (str, optional): Device to run inference. If None, the\n            available device will be automatically used. Defaults to None.\n        scope (str, optional): The scope of the model. Defaults to \"mmpose\".\n        det_model (str, optional): Config path or alias of detection model.\n            Defaults to None.\n        det_weights (str, optional): Path to the checkpoints of detection\n            model. Defaults to None.\n        det_cat_ids (int or list[int], optional): Category id for\n            detection model. Defaults to None.\n        output_heatmaps (bool, optional): Flag to visualize predicted\n            heatmaps. If set to None, the default setting from the model\n            config will be used. Default is None.\n    \"\"\"\n\n    preprocess_kwargs: set = {\n        'bbox_thr', 'nms_thr', 'bboxes', 'use_oks_tracking', 'tracking_thr',\n        'disable_norm_pose_2d'\n    }\n    forward_kwargs: set = {'disable_rebase_keypoint'}\n    visualize_kwargs: set = {\n        'return_vis',\n        'show',\n        'wait_time',\n        'draw_bbox',\n        'radius',\n        'thickness',\n        'num_instances',\n        'kpt_thr',\n        'vis_out_dir',\n    }\n    postprocess_kwargs: set = {'pred_out_dir', 'return_datasample'}\n\n    def __init__(self,\n                 model: Union[ModelType, str],\n                 weights: Optional[str] = None,\n                 pose2d_model: Optional[Union[ModelType, str]] = None,\n                 pose2d_weights: Optional[str] = None,\n                 device: Optional[str] = None,\n                 scope: Optional[str] = 'mmpose',\n                 det_model: Optional[Union[ModelType, str]] = None,\n                 det_weights: Optional[str] = None,\n                 det_cat_ids: Optional[Union[int, Tuple]] = None,\n                 show_progress: bool = False) -> None:\n\n        init_default_scope(scope)\n        super().__init__(\n            model=model,\n            weights=weights,\n            device=device,\n            scope=scope,\n            show_progress=show_progress)\n        self.model = revert_sync_batchnorm(self.model)\n\n        # assign dataset metainfo to self.visualizer\n        self.visualizer.set_dataset_meta(self.model.dataset_meta)\n\n        # initialize 2d pose estimator\n        self.pose2d_model = Pose2DInferencer(\n            pose2d_model if pose2d_model else 'human', pose2d_weights, device,\n            scope, det_model, det_weights, det_cat_ids)\n\n        # helper functions\n        self._keypoint_converter = partial(\n            convert_keypoint_definition,\n            pose_det_dataset=self.pose2d_model.model.\n            dataset_meta['dataset_name'],\n            pose_lift_dataset=self.model.dataset_meta['dataset_name'],\n        )\n\n        self._pose_seq_extractor = partial(\n            extract_pose_sequence,\n            causal=self.cfg.test_dataloader.dataset.get('causal', False),\n            seq_len=self.cfg.test_dataloader.dataset.get('seq_len', 1),\n            step=self.cfg.test_dataloader.dataset.get('seq_step', 1))\n\n        self._video_input = False\n        self._buffer = defaultdict(list)\n\n    def preprocess_single(self,\n                          input: InputType,\n                          index: int,\n                          bbox_thr: float = 0.3,\n                          nms_thr: float = 0.3,\n                          bboxes: Union[List[List], List[np.ndarray],\n                                        np.ndarray] = [],\n                          use_oks_tracking: bool = False,\n                          tracking_thr: float = 0.3,\n                          disable_norm_pose_2d: bool = False):\n        \"\"\"Process a single input into a model-feedable format.\n\n        Args:\n            input (InputType): The input provided by the user.\n            index (int): The index of the input.\n            bbox_thr (float, optional): The threshold for bounding box\n                detection. Defaults to 0.3.\n            nms_thr (float, optional): The Intersection over Union (IoU)\n                threshold for bounding box Non-Maximum Suppression (NMS).\n                Defaults to 0.3.\n            bboxes (Union[List[List], List[np.ndarray], np.ndarray]):\n                The bounding boxes to use. Defaults to [].\n            use_oks_tracking (bool, optional): A flag that indicates\n                whether OKS-based tracking should be used. Defaults to False.\n            tracking_thr (float, optional): The threshold for tracking.\n                Defaults to 0.3.\n            disable_norm_pose_2d (bool, optional): A flag that indicates\n                whether 2D pose normalization should be used.\n                Defaults to False.\n\n        Yields:\n            Any: The data processed by the pipeline and collate_fn.\n\n        This method first calculates 2D keypoints using the provided\n        pose2d_model. The method also performs instance matching, which\n        can use either OKS-based tracking or IOU-based tracking.\n        \"\"\"\n\n        # calculate 2d keypoints\n        results_pose2d = next(\n            self.pose2d_model(\n                input,\n                bbox_thr=bbox_thr,\n                nms_thr=nms_thr,\n                bboxes=bboxes,\n                merge_results=False,\n                return_datasamples=True))['predictions']\n\n        for ds in results_pose2d:\n            ds.pred_instances.set_field(\n                (ds.pred_instances.bboxes[..., 2:] -\n                 ds.pred_instances.bboxes[..., :2]).prod(-1), 'areas')\n\n        if not self._video_input:\n            height, width = results_pose2d[0].metainfo['ori_shape']\n\n            # Clear the buffer if inputs are individual images to prevent\n            # carryover effects from previous images\n            self._buffer.clear()\n\n        else:\n            height = self.video_info['height']\n            width = self.video_info['width']\n        img_path = results_pose2d[0].metainfo['img_path']\n\n        # instance matching\n        if use_oks_tracking:\n            _track = partial(_track_by_oks)\n        else:\n            _track = _track_by_iou\n\n        for result in results_pose2d:\n            track_id, self._buffer['results_pose2d_last'], _ = _track(\n                result, self._buffer['results_pose2d_last'], tracking_thr)\n            if track_id == -1:\n                pred_instances = result.pred_instances.cpu().numpy()\n                keypoints = pred_instances.keypoints\n                if np.count_nonzero(keypoints[:, :, 1]) >= 3:\n                    next_id = self._buffer.get('next_id', 0)\n                    result.set_field(next_id, 'track_id')\n                    self._buffer['next_id'] = next_id + 1\n                else:\n                    # If the number of keypoints detected is small,\n                    # delete that person instance.\n                    result.pred_instances.keypoints[..., 1] = -10\n                    result.pred_instances.bboxes *= 0\n                    result.set_field(-1, 'track_id')\n            else:\n                result.set_field(track_id, 'track_id')\n        self._buffer['pose2d_results'] = merge_data_samples(results_pose2d)\n\n        # convert keypoints\n        results_pose2d_converted = [ds.cpu().numpy() for ds in results_pose2d]\n        for ds in results_pose2d_converted:\n            ds.pred_instances.keypoints = self._keypoint_converter(\n                ds.pred_instances.keypoints)\n        self._buffer['pose_est_results_list'].append(results_pose2d_converted)\n\n        # extract and pad input pose2d sequence\n        pose_results_2d = self._pose_seq_extractor(\n            self._buffer['pose_est_results_list'],\n            frame_idx=index if self._video_input else 0)\n        causal = self.cfg.test_dataloader.dataset.get('causal', False)\n        target_idx = -1 if causal else len(pose_results_2d) // 2\n\n        stats_info = self.model.dataset_meta.get('stats_info', {})\n        bbox_center = stats_info.get('bbox_center', None)\n        bbox_scale = stats_info.get('bbox_scale', None)\n\n        pose_results_2d_copy = []\n        for pose_res in pose_results_2d:\n            pose_res_copy = []\n            for data_sample in pose_res:\n\n                data_sample_copy = PoseDataSample()\n                data_sample_copy.gt_instances = \\\n                    data_sample.gt_instances.clone()\n                data_sample_copy.pred_instances = \\\n                    data_sample.pred_instances.clone()\n                data_sample_copy.track_id = data_sample.track_id\n\n                kpts = data_sample.pred_instances.keypoints\n                bboxes = data_sample.pred_instances.bboxes\n                keypoints = []\n                for k in range(len(kpts)):\n                    kpt = kpts[k]\n                    if not disable_norm_pose_2d:\n                        bbox = bboxes[k]\n                        center = np.array([[(bbox[0] + bbox[2]) / 2,\n                                            (bbox[1] + bbox[3]) / 2]])\n                        scale = max(bbox[2] - bbox[0], bbox[3] - bbox[1])\n                        keypoints.append((kpt[:, :2] - center) / scale *\n                                         bbox_scale + bbox_center)\n                    else:\n                        keypoints.append(kpt[:, :2])\n                data_sample_copy.pred_instances.set_field(\n                    np.array(keypoints), 'keypoints')\n                pose_res_copy.append(data_sample_copy)\n\n            pose_results_2d_copy.append(pose_res_copy)\n        pose_sequences_2d = collate_pose_sequence(pose_results_2d_copy, True,\n                                                  target_idx)\n        if not pose_sequences_2d:\n            return []\n\n        data_list = []\n        for i, pose_seq in enumerate(pose_sequences_2d):\n            data_info = dict()\n\n            keypoints_2d = pose_seq.pred_instances.keypoints\n            keypoints_2d = np.squeeze(\n                keypoints_2d,\n                axis=0) if keypoints_2d.ndim == 4 else keypoints_2d\n\n            T, K, C = keypoints_2d.shape\n\n            data_info['keypoints'] = keypoints_2d\n            data_info['keypoints_visible'] = np.ones((\n                T,\n                K,\n            ),\n                                                     dtype=np.float32)\n            data_info['lifting_target'] = np.zeros((1, K, 3), dtype=np.float32)\n            data_info['factor'] = np.zeros((T, ), dtype=np.float32)\n            data_info['lifting_target_visible'] = np.ones((1, K, 1),\n                                                          dtype=np.float32)\n            data_info['camera_param'] = dict(w=width, h=height)\n\n            data_info.update(self.model.dataset_meta)\n            data_info = self.pipeline(data_info)\n            data_info['data_samples'].set_field(\n                img_path, 'img_path', field_type='metainfo')\n            data_list.append(data_info)\n\n        return data_list\n\n    @torch.no_grad()\n    def forward(self,\n                inputs: Union[dict, tuple],\n                disable_rebase_keypoint: bool = False):\n        \"\"\"Perform forward pass through the model and process the results.\n\n        Args:\n            inputs (Union[dict, tuple]): The inputs for the model.\n            disable_rebase_keypoint (bool, optional): Flag to disable rebasing\n                the height of the keypoints. Defaults to False.\n\n        Returns:\n            list: A list of data samples, each containing the model's output\n                results.\n        \"\"\"\n        pose_lift_results = self.model.test_step(inputs)\n\n        # Post-processing of pose estimation results\n        pose_est_results_converted = self._buffer['pose_est_results_list'][-1]\n        for idx, pose_lift_res in enumerate(pose_lift_results):\n            # Update track_id from the pose estimation results\n            pose_lift_res.track_id = pose_est_results_converted[idx].get(\n                'track_id', 1e4)\n\n            # align the shape of output keypoints coordinates and scores\n            keypoints = pose_lift_res.pred_instances.keypoints\n            keypoint_scores = pose_lift_res.pred_instances.keypoint_scores\n            if keypoint_scores.ndim == 3:\n                pose_lift_results[idx].pred_instances.keypoint_scores = \\\n                    np.squeeze(keypoint_scores, axis=1)\n            if keypoints.ndim == 4:\n                keypoints = np.squeeze(keypoints, axis=1)\n\n            # Invert x and z values of the keypoints\n            keypoints = keypoints[..., [0, 2, 1]]\n            keypoints[..., 0] = -keypoints[..., 0]\n            keypoints[..., 2] = -keypoints[..., 2]\n\n            # If rebase_keypoint_height is True, adjust z-axis values\n            if not disable_rebase_keypoint:\n                keypoints[..., 2] -= np.min(\n                    keypoints[..., 2], axis=-1, keepdims=True)\n\n            pose_lift_results[idx].pred_instances.keypoints = keypoints\n\n        pose_lift_results = sorted(\n            pose_lift_results, key=lambda x: x.get('track_id', 1e4))\n\n        data_samples = [merge_data_samples(pose_lift_results)]\n        return data_samples\n\n    def visualize(self,\n                  inputs: list,\n                  preds: List[PoseDataSample],\n                  return_vis: bool = False,\n                  show: bool = False,\n                  draw_bbox: bool = False,\n                  wait_time: float = 0,\n                  radius: int = 3,\n                  thickness: int = 1,\n                  kpt_thr: float = 0.3,\n                  num_instances: int = 1,\n                  vis_out_dir: str = '',\n                  window_name: str = '',\n                  window_close_event_handler: Optional[Callable] = None\n                  ) -> List[np.ndarray]:\n        \"\"\"Visualize predictions.\n\n        Args:\n            inputs (list): Inputs preprocessed by :meth:`_inputs_to_list`.\n            preds (Any): Predictions of the model.\n            return_vis (bool): Whether to return images with predicted results.\n            show (bool): Whether to display the image in a popup window.\n                Defaults to False.\n            wait_time (float): The interval of show (ms). Defaults to 0\n            draw_bbox (bool): Whether to draw the bounding boxes.\n                Defaults to False\n            radius (int): Keypoint radius for visualization. Defaults to 3\n            thickness (int): Link thickness for visualization. Defaults to 1\n            kpt_thr (float): The threshold to visualize the keypoints.\n                Defaults to 0.3\n            vis_out_dir (str, optional): Directory to save visualization\n                results w/o predictions. If left as empty, no file will\n                be saved. Defaults to ''.\n            window_name (str, optional): Title of display window.\n            window_close_event_handler (callable, optional):\n\n        Returns:\n            List[np.ndarray]: Visualization results.\n        \"\"\"\n        if (not return_vis) and (not show) and (not vis_out_dir):\n            return\n\n        if getattr(self, 'visualizer', None) is None:\n            raise ValueError('Visualization needs the \"visualizer\" term'\n                             'defined in the config, but got None.')\n\n        self.visualizer.radius = radius\n        self.visualizer.line_width = thickness\n        det_kpt_color = self.pose2d_model.visualizer.kpt_color\n        det_dataset_skeleton = self.pose2d_model.visualizer.skeleton\n        det_dataset_link_color = self.pose2d_model.visualizer.link_color\n        self.visualizer.det_kpt_color = det_kpt_color\n        self.visualizer.det_dataset_skeleton = det_dataset_skeleton\n        self.visualizer.det_dataset_link_color = det_dataset_link_color\n\n        results = []\n\n        for single_input, pred in zip(inputs, preds):\n            if isinstance(single_input, str):\n                img = mmcv.imread(single_input, channel_order='rgb')\n            elif isinstance(single_input, np.ndarray):\n                img = mmcv.bgr2rgb(single_input)\n            else:\n                raise ValueError('Unsupported input type: '\n                                 f'{type(single_input)}')\n\n            # since visualization and inference utilize the same process,\n            # the wait time is reduced when a video input is utilized,\n            # thereby eliminating the issue of inference getting stuck.\n            wait_time = 1e-5 if self._video_input else wait_time\n\n            if num_instances < 0:\n                num_instances = len(pred.pred_instances)\n\n            visualization = self.visualizer.add_datasample(\n                window_name,\n                img,\n                data_sample=pred,\n                det_data_sample=self._buffer['pose2d_results'],\n                draw_gt=False,\n                draw_bbox=draw_bbox,\n                show=show,\n                wait_time=wait_time,\n                dataset_2d=self.pose2d_model.model.\n                dataset_meta['dataset_name'],\n                dataset_3d=self.model.dataset_meta['dataset_name'],\n                kpt_thr=kpt_thr,\n                num_instances=num_instances)\n            results.append(visualization)\n\n            if vis_out_dir:\n                img_name = os.path.basename(pred.metainfo['img_path']) \\\n                    if 'img_path' in pred.metainfo else None\n                self.save_visualization(\n                    visualization,\n                    vis_out_dir,\n                    img_name=img_name,\n                )\n\n        if return_vis:\n            return results\n        else:\n            return []\n"
  },
  {
    "path": "mmpose/apis/inferencers/utils/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .default_det_models import default_det_models\nfrom .get_model_alias import get_model_aliases\n\n__all__ = ['default_det_models', 'get_model_aliases']\n"
  },
  {
    "path": "mmpose/apis/inferencers/utils/default_det_models.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\n\nfrom mmengine.config.utils import MODULE2PACKAGE\nfrom mmengine.utils import get_installed_path\n\nmmpose_path = get_installed_path(MODULE2PACKAGE['mmpose'])\n\ndefault_det_models = dict(\n    human=dict(\n        model=osp.join(\n            mmpose_path, '.mim', 'demo/mmdetection_cfg/'\n            'rtmdet_m_640-8xb32_coco-person.py'),\n        weights='https://download.openmmlab.com/mmpose/v1/projects/'\n        'rtmposev1/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth',\n        cat_ids=(0, )),\n    face=dict(\n        model=osp.join(mmpose_path, '.mim',\n                       'demo/mmdetection_cfg/yolox-s_8xb8-300e_coco-face.py'),\n        weights='https://download.openmmlab.com/mmpose/mmdet_pretrained/'\n        'yolo-x_8xb8-300e_coco-face_13274d7c.pth',\n        cat_ids=(0, )),\n    hand=dict(\n        model=osp.join(mmpose_path, '.mim', 'demo/mmdetection_cfg/'\n                       'rtmdet_nano_320-8xb32_hand.py'),\n        weights='https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/'\n        'rtmdet_nano_8xb32-300e_hand-267f9c8f.pth',\n        cat_ids=(0, )),\n    animal=dict(\n        model='rtmdet-m',\n        weights=None,\n        cat_ids=(15, 16, 17, 18, 19, 20, 21, 22, 23)),\n)\n\ndefault_det_models['body'] = default_det_models['human']\ndefault_det_models['wholebody'] = default_det_models['human']\n"
  },
  {
    "path": "mmpose/apis/inferencers/utils/get_model_alias.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict\n\nfrom mmengine.infer import BaseInferencer\n\n\ndef get_model_aliases(scope: str = 'mmpose') -> Dict[str, str]:\n    \"\"\"Retrieve model aliases and their corresponding configuration names.\n\n    Args:\n        scope (str, optional): The scope for the model aliases. Defaults\n            to 'mmpose'.\n\n    Returns:\n        Dict[str, str]: A dictionary containing model aliases as keys and\n            their corresponding configuration names as values.\n    \"\"\"\n\n    # Get a list of model configurations from the metafile\n    repo_or_mim_dir = BaseInferencer._get_repo_or_mim_dir(scope)\n    model_cfgs = BaseInferencer._get_models_from_metafile(repo_or_mim_dir)\n\n    model_alias_dict = dict()\n    for model_cfg in model_cfgs:\n        if 'Alias' in model_cfg:\n            if isinstance(model_cfg['Alias'], str):\n                model_alias_dict[model_cfg['Alias']] = model_cfg['Name']\n            elif isinstance(model_cfg['Alias'], list):\n                for alias in model_cfg['Alias']:\n                    model_alias_dict[alias] = model_cfg['Name']\n            else:\n                raise ValueError(\n                    'encounter an unexpected alias type. Please raise an '\n                    'issue at https://github.com/open-mmlab/mmpose/issues '\n                    'to announce us')\n\n    return model_alias_dict\n"
  },
  {
    "path": "mmpose/apis/visualization.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\nfrom typing import Union\n\nimport mmcv\nimport numpy as np\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.visualization import PoseLocalVisualizer\n\n\ndef visualize(\n    img: Union[np.ndarray, str],\n    keypoints: np.ndarray,\n    keypoint_score: np.ndarray = None,\n    metainfo: Union[str, dict] = None,\n    visualizer: PoseLocalVisualizer = None,\n    show_kpt_idx: bool = False,\n    skeleton_style: str = 'mmpose',\n    show: bool = False,\n    kpt_thr: float = 0.3,\n):\n    \"\"\"Visualize 2d keypoints on an image.\n\n    Args:\n        img (str | np.ndarray): The image to be displayed.\n        keypoints (np.ndarray): The keypoint to be displayed.\n        keypoint_score (np.ndarray): The score of each keypoint.\n        metainfo (str | dict): The metainfo of dataset.\n        visualizer (PoseLocalVisualizer): The visualizer.\n        show_kpt_idx (bool): Whether to show the index of keypoints.\n        skeleton_style (str): Skeleton style. Options are 'mmpose' and\n            'openpose'.\n        show (bool): Whether to show the image.\n        wait_time (int): Value of waitKey param.\n        kpt_thr (float): Keypoint threshold.\n    \"\"\"\n    assert skeleton_style in [\n        'mmpose', 'openpose'\n    ], (f'Only support skeleton style in {[\"mmpose\", \"openpose\"]}, ')\n\n    if visualizer is None:\n        visualizer = PoseLocalVisualizer()\n    else:\n        visualizer = deepcopy(visualizer)\n\n    if isinstance(metainfo, str):\n        metainfo = parse_pose_metainfo(dict(from_file=metainfo))\n    elif isinstance(metainfo, dict):\n        metainfo = parse_pose_metainfo(metainfo)\n\n    if metainfo is not None:\n        visualizer.set_dataset_meta(metainfo, skeleton_style=skeleton_style)\n\n    if isinstance(img, str):\n        img = mmcv.imread(img, channel_order='rgb')\n    elif isinstance(img, np.ndarray):\n        img = mmcv.bgr2rgb(img)\n\n    if keypoint_score is None:\n        keypoint_score = np.ones(keypoints.shape[0])\n\n    tmp_instances = InstanceData()\n    tmp_instances.keypoints = keypoints\n    tmp_instances.keypoint_score = keypoint_score\n\n    tmp_datasample = PoseDataSample()\n    tmp_datasample.pred_instances = tmp_instances\n\n    visualizer.add_datasample(\n        'visualization',\n        img,\n        tmp_datasample,\n        show_kpt_idx=show_kpt_idx,\n        skeleton_style=skeleton_style,\n        show=show,\n        wait_time=0,\n        kpt_thr=kpt_thr)\n\n    return visualizer.get_image()\n"
  },
  {
    "path": "mmpose/codecs/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .annotation_processors import YOLOXPoseAnnotationProcessor\nfrom .associative_embedding import AssociativeEmbedding\nfrom .decoupled_heatmap import DecoupledHeatmap\nfrom .edpose_label import EDPoseLabel\nfrom .hand_3d_heatmap import Hand3DHeatmap\nfrom .image_pose_lifting import ImagePoseLifting\nfrom .integral_regression_label import IntegralRegressionLabel\nfrom .megvii_heatmap import MegviiHeatmap\nfrom .motionbert_label import MotionBERTLabel\nfrom .msra_heatmap import MSRAHeatmap\nfrom .regression_label import RegressionLabel\nfrom .simcc_label import SimCCLabel\nfrom .spr import SPR\nfrom .udp_heatmap import UDPHeatmap\nfrom .video_pose_lifting import VideoPoseLifting\n\n__all__ = [\n    'MSRAHeatmap', 'MegviiHeatmap', 'UDPHeatmap', 'RegressionLabel',\n    'SimCCLabel', 'IntegralRegressionLabel', 'AssociativeEmbedding', 'SPR',\n    'DecoupledHeatmap', 'VideoPoseLifting', 'ImagePoseLifting',\n    'MotionBERTLabel', 'YOLOXPoseAnnotationProcessor', 'EDPoseLabel',\n    'Hand3DHeatmap'\n]\n"
  },
  {
    "path": "mmpose/codecs/annotation_processors.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, List, Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\n\nINF = 1e6\nNEG_INF = -1e6\n\n\nclass BaseAnnotationProcessor(BaseKeypointCodec):\n    \"\"\"Base class for annotation processors.\"\"\"\n\n    def decode(self, *args, **kwargs):\n        pass\n\n\n@KEYPOINT_CODECS.register_module()\nclass YOLOXPoseAnnotationProcessor(BaseAnnotationProcessor):\n    \"\"\"Convert dataset annotations to the input format of YOLOX-Pose.\n\n    This processor expands bounding boxes and converts category IDs to labels.\n\n    Args:\n        expand_bbox (bool, optional): Whether to expand the bounding box\n            to include all keypoints. Defaults to False.\n        input_size (tuple, optional): The size of the input image for the\n            model, formatted as (h, w). This argument is necessary for the\n            codec in deployment but is not used indeed.\n    \"\"\"\n\n    auxiliary_encode_keys = {'category_id', 'bbox'}\n    label_mapping_table = dict(\n        bbox='bboxes',\n        bbox_labels='labels',\n        keypoints='keypoints',\n        keypoints_visible='keypoints_visible',\n        area='areas',\n    )\n    instance_mapping_table = dict(\n        bbox='bboxes',\n        bbox_score='bbox_scores',\n        keypoints='keypoints',\n        keypoints_visible='keypoints_visible',\n        # remove 'bbox_scales' in default instance_mapping_table to avoid\n        # length mismatch during training with multiple datasets\n    )\n\n    def __init__(self,\n                 expand_bbox: bool = False,\n                 input_size: Optional[Tuple] = None):\n        super().__init__()\n        self.expand_bbox = expand_bbox\n\n    def encode(self,\n               keypoints: Optional[np.ndarray] = None,\n               keypoints_visible: Optional[np.ndarray] = None,\n               bbox: Optional[np.ndarray] = None,\n               category_id: Optional[List[int]] = None\n               ) -> Dict[str, np.ndarray]:\n        \"\"\"Encode keypoints, bounding boxes, and category IDs.\n\n        Args:\n            keypoints (np.ndarray, optional): Keypoints array. Defaults\n                to None.\n            keypoints_visible (np.ndarray, optional): Visibility array for\n                keypoints. Defaults to None.\n            bbox (np.ndarray, optional): Bounding box array. Defaults to None.\n            category_id (List[int], optional): List of category IDs. Defaults\n                to None.\n\n        Returns:\n            Dict[str, np.ndarray]: Encoded annotations.\n        \"\"\"\n        results = {}\n\n        if self.expand_bbox and bbox is not None:\n            # Handle keypoints visibility\n            if keypoints_visible.ndim == 3:\n                keypoints_visible = keypoints_visible[..., 0]\n\n            # Expand bounding box to include keypoints\n            kpts_min = keypoints.copy()\n            kpts_min[keypoints_visible == 0] = INF\n            bbox[..., :2] = np.minimum(bbox[..., :2], kpts_min.min(axis=1))\n\n            kpts_max = keypoints.copy()\n            kpts_max[keypoints_visible == 0] = NEG_INF\n            bbox[..., 2:] = np.maximum(bbox[..., 2:], kpts_max.max(axis=1))\n\n            results['bbox'] = bbox\n\n        if category_id is not None:\n            # Convert category IDs to labels\n            bbox_labels = np.array(category_id).astype(np.int8) - 1\n            results['bbox_labels'] = bbox_labels\n\n        return results\n"
  },
  {
    "path": "mmpose/codecs/associative_embedding.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Any, List, Optional, Tuple\n\nimport numpy as np\nimport torch\nfrom munkres import Munkres\nfrom torch import Tensor\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom .base import BaseKeypointCodec\nfrom .utils import (batch_heatmap_nms, generate_gaussian_heatmaps,\n                    generate_udp_gaussian_heatmaps, refine_keypoints,\n                    refine_keypoints_dark_udp)\n\n\ndef _py_max_match(scores):\n    \"\"\"Apply munkres algorithm to get the best match.\n\n    Args:\n        scores(np.ndarray): cost matrix.\n\n    Returns:\n        np.ndarray: best match.\n    \"\"\"\n    m = Munkres()\n    tmp = m.compute(scores)\n    tmp = np.array(tmp).astype(int)\n    return tmp\n\n\ndef _group_keypoints_by_tags(vals: np.ndarray,\n                             tags: np.ndarray,\n                             locs: np.ndarray,\n                             keypoint_order: List[int],\n                             val_thr: float,\n                             tag_thr: float = 1.0,\n                             max_groups: Optional[int] = None) -> np.ndarray:\n    \"\"\"Group the keypoints by tags using Munkres algorithm.\n\n    Note:\n\n        - keypoint number: K\n        - candidate number: M\n        - tag dimenssion: L\n        - coordinate dimension: D\n        - group number: G\n\n    Args:\n        vals (np.ndarray): The heatmap response values of keypoints in shape\n            (K, M)\n        tags (np.ndarray): The tags of the keypoint candidates in shape\n            (K, M, L)\n        locs (np.ndarray): The locations of the keypoint candidates in shape\n            (K, M, D)\n        keypoint_order (List[int]): The grouping order of the keypoints.\n            The groupping usually starts from a keypoints around the head and\n            torso, and gruadually moves out to the limbs\n        val_thr (float): The threshold of the keypoint response value\n        tag_thr (float): The maximum allowed tag distance when matching a\n            keypoint to a group. A keypoint with larger tag distance to any\n            of the existing groups will initializes a new group\n        max_groups (int, optional): The maximum group number. ``None`` means\n            no limitation. Defaults to ``None``\n\n    Returns:\n        np.ndarray: grouped keypoints in shape (G, K, D+1), where the last\n        dimenssion is the concatenated keypoint coordinates and scores.\n    \"\"\"\n\n    tag_k, loc_k, val_k = tags, locs, vals\n    K, M, D = locs.shape\n    assert vals.shape == tags.shape[:2] == (K, M)\n    assert len(keypoint_order) == K\n\n    default_ = np.zeros((K, 3 + tag_k.shape[2]), dtype=np.float32)\n\n    joint_dict = {}\n    tag_dict = {}\n    for i in range(K):\n        idx = keypoint_order[i]\n\n        tags = tag_k[idx]\n        joints = np.concatenate((loc_k[idx], val_k[idx, :, None], tags), 1)\n        mask = joints[:, 2] > val_thr\n        tags = tags[mask]  # shape: [M, L]\n        joints = joints[mask]  # shape: [M, 3 + L], 3: x, y, val\n\n        if joints.shape[0] == 0:\n            continue\n\n        if i == 0 or len(joint_dict) == 0:\n            for tag, joint in zip(tags, joints):\n                key = tag[0]\n                joint_dict.setdefault(key, np.copy(default_))[idx] = joint\n                tag_dict[key] = [tag]\n        else:\n            # shape: [M]\n            grouped_keys = list(joint_dict.keys())\n            # shape: [M, L]\n            grouped_tags = [np.mean(tag_dict[i], axis=0) for i in grouped_keys]\n\n            # shape: [M, M, L]\n            diff = joints[:, None, 3:] - np.array(grouped_tags)[None, :, :]\n            # shape: [M, M]\n            diff_normed = np.linalg.norm(diff, ord=2, axis=2)\n            diff_saved = np.copy(diff_normed)\n            diff_normed = np.round(diff_normed) * 100 - joints[:, 2:3]\n\n            num_added = diff.shape[0]\n            num_grouped = diff.shape[1]\n\n            if num_added > num_grouped:\n                diff_normed = np.concatenate(\n                    (diff_normed,\n                     np.zeros((num_added, num_added - num_grouped),\n                              dtype=np.float32) + 1e10),\n                    axis=1)\n\n            pairs = _py_max_match(diff_normed)\n            for row, col in pairs:\n                if (row < num_added and col < num_grouped\n                        and diff_saved[row][col] < tag_thr):\n                    key = grouped_keys[col]\n                    joint_dict[key][idx] = joints[row]\n                    tag_dict[key].append(tags[row])\n                else:\n                    key = tags[row][0]\n                    joint_dict.setdefault(key, np.copy(default_))[idx] = \\\n                        joints[row]\n                    tag_dict[key] = [tags[row]]\n\n    joint_dict_keys = list(joint_dict.keys())[:max_groups]\n\n    if joint_dict_keys:\n        results = np.array([joint_dict[i]\n                            for i in joint_dict_keys]).astype(np.float32)\n        results = results[..., :D + 1]\n    else:\n        results = np.empty((0, K, D + 1), dtype=np.float32)\n    return results\n\n\n@KEYPOINT_CODECS.register_module()\nclass AssociativeEmbedding(BaseKeypointCodec):\n    \"\"\"Encode/decode keypoints with the method introduced in \"Associative\n    Embedding\". This is an asymmetric codec, where the keypoints are\n    represented as gaussian heatmaps and position indices during encoding, and\n    restored from predicted heatmaps and group tags.\n\n    See the paper `Associative Embedding: End-to-End Learning for Joint\n    Detection and Grouping`_ by Newell et al (2017) for details\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - embedding tag dimension: L\n        - image size: [w, h]\n        - heatmap size: [W, H]\n\n    Encoded:\n\n        - heatmaps (np.ndarray): The generated heatmap in shape (K, H, W)\n            where [W, H] is the `heatmap_size`\n        - keypoint_indices (np.ndarray): The keypoint position indices in shape\n            (N, K, 2). Each keypoint's index is [i, v], where i is the position\n            index in the heatmap (:math:`i=y*w+x`) and v is the visibility\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        sigma (float): The sigma value of the Gaussian heatmap\n        use_udp (bool): Whether use unbiased data processing. See\n            `UDP (CVPR 2020)`_ for details. Defaults to ``False``\n        decode_keypoint_order (List[int]): The grouping order of the\n            keypoint indices. The groupping usually starts from a keypoints\n            around the head and torso, and gruadually moves out to the limbs\n        decode_keypoint_thr (float): The threshold of keypoint response value\n            in heatmaps. Defaults to 0.1\n        decode_tag_thr (float): The maximum allowed tag distance when matching\n            a keypoint to a group. A keypoint with larger tag distance to any\n            of the existing groups will initializes a new group. Defaults to\n            1.0\n        decode_nms_kernel (int): The kernel size of the NMS during decoding,\n            which should be an odd integer. Defaults to 5\n        decode_gaussian_kernel (int): The kernel size of the Gaussian blur\n            during decoding, which should be an odd integer. It is only used\n            when ``self.use_udp==True``. Defaults to 3\n        decode_topk (int): The number top-k candidates of each keypoints that\n            will be retrieved from the heatmaps during dedocding. Defaults to\n            20\n        decode_max_instances (int, optional): The maximum number of instances\n            to decode. ``None`` means no limitation to the instance number.\n            Defaults to ``None``\n\n    .. _`Associative Embedding: End-to-End Learning for Joint Detection and\n    Grouping`: https://arxiv.org/abs/1611.05424\n    .. _`UDP (CVPR 2020)`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n\n    def __init__(\n        self,\n        input_size: Tuple[int, int],\n        heatmap_size: Tuple[int, int],\n        sigma: Optional[float] = None,\n        use_udp: bool = False,\n        decode_keypoint_order: List[int] = [],\n        decode_nms_kernel: int = 5,\n        decode_gaussian_kernel: int = 3,\n        decode_keypoint_thr: float = 0.1,\n        decode_tag_thr: float = 1.0,\n        decode_topk: int = 30,\n        decode_center_shift=0.0,\n        decode_max_instances: Optional[int] = None,\n    ) -> None:\n        super().__init__()\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.use_udp = use_udp\n        self.decode_nms_kernel = decode_nms_kernel\n        self.decode_gaussian_kernel = decode_gaussian_kernel\n        self.decode_keypoint_thr = decode_keypoint_thr\n        self.decode_tag_thr = decode_tag_thr\n        self.decode_topk = decode_topk\n        self.decode_center_shift = decode_center_shift\n        self.decode_max_instances = decode_max_instances\n        self.decode_keypoint_order = decode_keypoint_order.copy()\n\n        if self.use_udp:\n            self.scale_factor = ((np.array(input_size) - 1) /\n                                 (np.array(heatmap_size) - 1)).astype(\n                                     np.float32)\n        else:\n            self.scale_factor = (np.array(input_size) /\n                                 heatmap_size).astype(np.float32)\n\n        if sigma is None:\n            sigma = (heatmap_size[0] * heatmap_size[1])**0.5 / 64\n        self.sigma = sigma\n\n    def encode(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None\n    ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:\n        \"\"\"Encode keypoints into heatmaps and position indices. Note that the\n        original keypoint coordinates should be in the input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - heatmaps (np.ndarray): The generated heatmap in shape\n                (K, H, W) where [W, H] is the `heatmap_size`\n            - keypoint_indices (np.ndarray): The keypoint position indices\n                in shape (N, K, 2). Each keypoint's index is [i, v], where i\n                is the position index in the heatmap (:math:`i=y*w+x`) and v\n                is the visibility\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        # keypoint coordinates in heatmap\n        _keypoints = keypoints / self.scale_factor\n\n        if self.use_udp:\n            heatmaps, keypoint_weights = generate_udp_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=_keypoints,\n                keypoints_visible=keypoints_visible,\n                sigma=self.sigma)\n        else:\n            heatmaps, keypoint_weights = generate_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=_keypoints,\n                keypoints_visible=keypoints_visible,\n                sigma=self.sigma)\n\n        keypoint_indices = self._encode_keypoint_indices(\n            heatmap_size=self.heatmap_size,\n            keypoints=_keypoints,\n            keypoints_visible=keypoints_visible)\n\n        encoded = dict(\n            heatmaps=heatmaps,\n            keypoint_indices=keypoint_indices,\n            keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def _encode_keypoint_indices(self, heatmap_size: Tuple[int, int],\n                                 keypoints: np.ndarray,\n                                 keypoints_visible: np.ndarray) -> np.ndarray:\n        w, h = heatmap_size\n        N, K, _ = keypoints.shape\n        keypoint_indices = np.zeros((N, K, 2), dtype=np.int64)\n\n        for n, k in product(range(N), range(K)):\n            x, y = (keypoints[n, k] + 0.5).astype(np.int64)\n            index = y * w + x\n            vis = (keypoints_visible[n, k] > 0.5 and 0 <= x < w and 0 <= y < h)\n            keypoint_indices[n, k] = [index, vis]\n\n        return keypoint_indices\n\n    def decode(self, encoded: Any) -> Tuple[np.ndarray, np.ndarray]:\n        raise NotImplementedError()\n\n    def _get_batch_topk(self, batch_heatmaps: Tensor, batch_tags: Tensor,\n                        k: int):\n        \"\"\"Get top-k response values from the heatmaps and corresponding tag\n        values from the tagging heatmaps.\n\n        Args:\n            batch_heatmaps (Tensor): Keypoint detection heatmaps in shape\n                (B, K, H, W)\n            batch_tags (Tensor): Tagging heatmaps in shape (B, C, H, W), where\n                the tag dim C is 2*K when using flip testing, or K otherwise\n            k (int): The number of top responses to get\n\n        Returns:\n            tuple:\n            - topk_vals (Tensor): Top-k response values of each heatmap in\n                shape (B, K, Topk)\n            - topk_tags (Tensor): The corresponding embedding tags of the\n                top-k responses, in shape (B, K, Topk, L)\n            - topk_locs (Tensor): The location of the top-k responses in each\n                heatmap, in shape (B, K, Topk, 2) where last dimension\n                represents x and y coordinates\n        \"\"\"\n        B, K, H, W = batch_heatmaps.shape\n        L = batch_tags.shape[1] // K\n\n        # shape of topk_val, top_indices: (B, K, TopK)\n        topk_vals, topk_indices = batch_heatmaps.flatten(-2, -1).topk(\n            k, dim=-1)\n\n        topk_tags_per_kpts = [\n            torch.gather(_tag, dim=2, index=topk_indices)\n            for _tag in torch.unbind(batch_tags.view(B, L, K, H * W), dim=1)\n        ]\n\n        topk_tags = torch.stack(topk_tags_per_kpts, dim=-1)  # (B, K, TopK, L)\n        topk_locs = torch.stack([topk_indices % W, topk_indices // W],\n                                dim=-1)  # (B, K, TopK, 2)\n\n        return topk_vals, topk_tags, topk_locs\n\n    def _group_keypoints(self, batch_vals: np.ndarray, batch_tags: np.ndarray,\n                         batch_locs: np.ndarray):\n        \"\"\"Group keypoints into groups (each represents an instance) by tags.\n\n        Args:\n            batch_vals (Tensor): Heatmap response values of keypoint\n                candidates in shape (B, K, Topk)\n            batch_tags (Tensor): Tags of keypoint candidates in shape\n                (B, K, Topk, L)\n            batch_locs (Tensor): Locations of keypoint candidates in shape\n                (B, K, Topk, 2)\n\n        Returns:\n            List[np.ndarray]: Grouping results of a batch, each element is a\n            np.ndarray (in shape [N, K, D+1]) that contains the groups\n            detected in an image, including both keypoint coordinates and\n            scores.\n        \"\"\"\n\n        def _group_func(inputs: Tuple):\n            vals, tags, locs = inputs\n            return _group_keypoints_by_tags(\n                vals,\n                tags,\n                locs,\n                keypoint_order=self.decode_keypoint_order,\n                val_thr=self.decode_keypoint_thr,\n                tag_thr=self.decode_tag_thr,\n                max_groups=self.decode_max_instances)\n\n        _results = map(_group_func, zip(batch_vals, batch_tags, batch_locs))\n        results = list(_results)\n        return results\n\n    def _fill_missing_keypoints(self, keypoints: np.ndarray,\n                                keypoint_scores: np.ndarray,\n                                heatmaps: np.ndarray, tags: np.ndarray):\n        \"\"\"Fill the missing keypoints in the initial predictions.\n\n        Args:\n            keypoints (np.ndarray): Keypoint predictions in shape (N, K, D)\n            keypoint_scores (np.ndarray): Keypint score predictions in shape\n                (N, K), in which 0 means the corresponding keypoint is\n                missing in the initial prediction\n            heatmaps (np.ndarry): Heatmaps in shape (K, H, W)\n            tags (np.ndarray): Tagging heatmaps in shape (C, H, W) where\n                C=L*K\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Keypoint predictions with missing\n                ones filled\n            - keypoint_scores (np.ndarray): Keypoint score predictions with\n                missing ones filled\n        \"\"\"\n\n        N, K = keypoints.shape[:2]\n        H, W = heatmaps.shape[1:]\n        L = tags.shape[0] // K\n        keypoint_tags = [tags[k::K] for k in range(K)]\n\n        for n in range(N):\n            # Calculate the instance tag (mean tag of detected keypoints)\n            _tag = []\n            for k in range(K):\n                if keypoint_scores[n, k] > 0:\n                    x, y = keypoints[n, k, :2].astype(np.int64)\n                    x = np.clip(x, 0, W - 1)\n                    y = np.clip(y, 0, H - 1)\n                    _tag.append(keypoint_tags[k][:, y, x])\n\n            tag = np.mean(_tag, axis=0)\n            tag = tag.reshape(L, 1, 1)\n            # Search maximum response of the missing keypoints\n            for k in range(K):\n                if keypoint_scores[n, k] > 0:\n                    continue\n                dist_map = np.linalg.norm(\n                    keypoint_tags[k] - tag, ord=2, axis=0)\n                cost_map = np.round(dist_map) * 100 - heatmaps[k]  # H, W\n                y, x = np.unravel_index(np.argmin(cost_map), shape=(H, W))\n                keypoints[n, k] = [x, y]\n                keypoint_scores[n, k] = heatmaps[k, y, x]\n\n        return keypoints, keypoint_scores\n\n    def batch_decode(self, batch_heatmaps: Tensor, batch_tags: Tensor\n                     ) -> Tuple[List[np.ndarray], List[np.ndarray]]:\n        \"\"\"Decode the keypoint coordinates from a batch of heatmaps and tagging\n        heatmaps. The decoded keypoint coordinates are in the input image\n        space.\n\n        Args:\n            batch_heatmaps (Tensor): Keypoint detection heatmaps in shape\n                (B, K, H, W)\n            batch_tags (Tensor): Tagging heatmaps in shape (B, C, H, W), where\n                :math:`C=L*K`\n\n        Returns:\n            tuple:\n            - batch_keypoints (List[np.ndarray]): Decoded keypoint coordinates\n                of the batch, each is in shape (N, K, D)\n            - batch_scores (List[np.ndarray]): Decoded keypoint scores of the\n                batch, each is in shape (N, K). It usually represents the\n                confidience of the keypoint prediction\n        \"\"\"\n        B, _, H, W = batch_heatmaps.shape\n        assert batch_tags.shape[0] == B and batch_tags.shape[2:4] == (H, W), (\n            f'Mismatched shapes of heatmap ({batch_heatmaps.shape}) and '\n            f'tagging map ({batch_tags.shape})')\n\n        # Heatmap NMS\n        batch_heatmaps_peak = batch_heatmap_nms(batch_heatmaps,\n                                                self.decode_nms_kernel)\n\n        # Get top-k in each heatmap and and convert to numpy\n        batch_topk_vals, batch_topk_tags, batch_topk_locs = to_numpy(\n            self._get_batch_topk(\n                batch_heatmaps_peak, batch_tags, k=self.decode_topk))\n\n        # Group keypoint candidates into groups (instances)\n        batch_groups = self._group_keypoints(batch_topk_vals, batch_topk_tags,\n                                             batch_topk_locs)\n\n        # Convert to numpy\n        batch_heatmaps_np = to_numpy(batch_heatmaps)\n        batch_tags_np = to_numpy(batch_tags)\n\n        # Refine the keypoint prediction\n        batch_keypoints = []\n        batch_keypoint_scores = []\n        batch_instance_scores = []\n        for i, (groups, heatmaps, tags) in enumerate(\n                zip(batch_groups, batch_heatmaps_np, batch_tags_np)):\n\n            keypoints, scores = groups[..., :-1], groups[..., -1]\n            instance_scores = scores.mean(axis=-1)\n\n            if keypoints.size > 0:\n                # refine keypoint coordinates according to heatmap distribution\n                if self.use_udp:\n                    keypoints = refine_keypoints_dark_udp(\n                        keypoints,\n                        heatmaps,\n                        blur_kernel_size=self.decode_gaussian_kernel)\n                else:\n                    keypoints = refine_keypoints(keypoints, heatmaps)\n                keypoints += self.decode_center_shift * \\\n                    (scores > 0).astype(keypoints.dtype)[..., None]\n\n                # identify missing keypoints\n                keypoints, scores = self._fill_missing_keypoints(\n                    keypoints, scores, heatmaps, tags)\n\n            batch_keypoints.append(keypoints)\n            batch_keypoint_scores.append(scores)\n            batch_instance_scores.append(instance_scores)\n\n        # restore keypoint scale\n        batch_keypoints = [\n            kpts * self.scale_factor for kpts in batch_keypoints\n        ]\n\n        return batch_keypoints, batch_keypoint_scores, batch_instance_scores\n"
  },
  {
    "path": "mmpose/codecs/base.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta, abstractmethod\nfrom typing import Any, List, Optional, Tuple\n\nimport numpy as np\nfrom mmengine.utils import is_method_overridden\n\n\nclass BaseKeypointCodec(metaclass=ABCMeta):\n    \"\"\"The base class of the keypoint codec.\n\n    A keypoint codec is a module to encode keypoint coordinates to specific\n    representation (e.g. heatmap) and vice versa. A subclass should implement\n    the methods :meth:`encode` and :meth:`decode`.\n    \"\"\"\n\n    # pass additional encoding arguments to the `encode` method, beyond the\n    # mandatory `keypoints` and `keypoints_visible` arguments.\n    auxiliary_encode_keys = set()\n\n    field_mapping_table = dict()\n    instance_mapping_table = dict()\n    label_mapping_table = dict()\n\n    @abstractmethod\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints.\n\n        Note:\n\n            - instance number: N\n            - keypoint number: K\n            - keypoint dimension: D\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibility in shape\n                (N, K, D)\n\n        Returns:\n            dict: Encoded items.\n        \"\"\"\n\n    @abstractmethod\n    def decode(self, encoded: Any) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoints.\n\n        Args:\n            encoded (any): Encoded keypoint representation using the codec\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            - keypoints_visible (np.ndarray): Keypoint visibility in shape\n                (N, K, D)\n        \"\"\"\n\n    def batch_decode(self, batch_encoded: Any\n                     ) -> Tuple[List[np.ndarray], List[np.ndarray]]:\n        \"\"\"Decode keypoints.\n\n        Args:\n            batch_encoded (any): A batch of encoded keypoint\n                representations\n\n        Returns:\n            tuple:\n            - batch_keypoints (List[np.ndarray]): Each element is keypoint\n                coordinates in shape (N, K, D)\n            - batch_keypoints (List[np.ndarray]): Each element is keypoint\n                visibility in shape (N, K)\n        \"\"\"\n        raise NotImplementedError()\n\n    @property\n    def support_batch_decoding(self) -> bool:\n        \"\"\"Return whether the codec support decoding from batch data.\"\"\"\n        return is_method_overridden('batch_decode', BaseKeypointCodec,\n                                    self.__class__)\n"
  },
  {
    "path": "mmpose/codecs/decoupled_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport random\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils import (generate_gaussian_heatmaps, get_diagonal_lengths,\n                    get_instance_bbox, get_instance_root)\nfrom .utils.post_processing import get_heatmap_maximum\nfrom .utils.refinement import refine_keypoints\n\n\n@KEYPOINT_CODECS.register_module()\nclass DecoupledHeatmap(BaseKeypointCodec):\n    \"\"\"Encode/decode keypoints with the method introduced in the paper CID.\n\n    See the paper Contextual Instance Decoupling for Robust Multi-Person\n    Pose Estimation`_ by Wang et al (2022) for details\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n        - heatmap size: [W, H]\n\n    Encoded:\n        - heatmaps (np.ndarray): The coupled heatmap in shape\n            (1+K, H, W) where [W, H] is the `heatmap_size`.\n        - instance_heatmaps (np.ndarray): The decoupled heatmap in shape\n            (M*K, H, W) where M is the number of instances.\n        - keypoint_weights (np.ndarray): The weight for heatmaps in shape\n            (M*K).\n        - instance_coords (np.ndarray): The coordinates of instance roots\n            in shape (M, 2)\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        root_type (str): The method to generate the instance root. Options\n            are:\n\n            - ``'kpt_center'``: Average coordinate of all visible keypoints.\n            - ``'bbox_center'``: Center point of bounding boxes outlined by\n                all visible keypoints.\n\n            Defaults to ``'kpt_center'``\n\n        heatmap_min_overlap (float): Minimum overlap rate among instances.\n            Used when calculating sigmas for instances. Defaults to 0.7\n        background_weight (float): Loss weight of background pixels.\n            Defaults to 0.1\n        encode_max_instances (int): The maximum number of instances\n            to encode for each sample. Defaults to 30\n\n    .. _`CID`: https://openaccess.thecvf.com/content/CVPR2022/html/Wang_\n    Contextual_Instance_Decoupling_for_Robust_Multi-Person_Pose_Estimation_\n    CVPR_2022_paper.html\n    \"\"\"\n\n    # DecoupledHeatmap requires bounding boxes to determine the size of each\n    # instance, so that it can assign varying sigmas based on their size\n    auxiliary_encode_keys = {'bbox'}\n\n    label_mapping_table = dict(\n        keypoint_weights='keypoint_weights',\n        instance_coords='instance_coords',\n    )\n    field_mapping_table = dict(\n        heatmaps='heatmaps',\n        instance_heatmaps='instance_heatmaps',\n    )\n\n    def __init__(\n        self,\n        input_size: Tuple[int, int],\n        heatmap_size: Tuple[int, int],\n        root_type: str = 'kpt_center',\n        heatmap_min_overlap: float = 0.7,\n        encode_max_instances: int = 30,\n    ):\n        super().__init__()\n\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.root_type = root_type\n        self.encode_max_instances = encode_max_instances\n        self.heatmap_min_overlap = heatmap_min_overlap\n\n        self.scale_factor = (np.array(input_size) /\n                             heatmap_size).astype(np.float32)\n\n    def _get_instance_wise_sigmas(\n        self,\n        bbox: np.ndarray,\n    ) -> np.ndarray:\n        \"\"\"Get sigma values for each instance according to their size.\n\n        Args:\n            bbox (np.ndarray): Bounding box in shape (N, 4, 2)\n\n        Returns:\n            np.ndarray: Array containing the sigma values for each instance.\n        \"\"\"\n        sigmas = np.zeros((bbox.shape[0], ), dtype=np.float32)\n\n        heights = np.sqrt(np.power(bbox[:, 0] - bbox[:, 1], 2).sum(axis=-1))\n        widths = np.sqrt(np.power(bbox[:, 0] - bbox[:, 2], 2).sum(axis=-1))\n\n        for i in range(bbox.shape[0]):\n            h, w = heights[i], widths[i]\n\n            # compute sigma for each instance\n            # condition 1\n            a1, b1 = 1, h + w\n            c1 = w * h * (1 - self.heatmap_min_overlap) / (\n                1 + self.heatmap_min_overlap)\n            sq1 = np.sqrt(b1**2 - 4 * a1 * c1)\n            r1 = (b1 + sq1) / 2\n\n            # condition 2\n            a2 = 4\n            b2 = 2 * (h + w)\n            c2 = (1 - self.heatmap_min_overlap) * w * h\n            sq2 = np.sqrt(b2**2 - 4 * a2 * c2)\n            r2 = (b2 + sq2) / 2\n\n            # condition 3\n            a3 = 4 * self.heatmap_min_overlap\n            b3 = -2 * self.heatmap_min_overlap * (h + w)\n            c3 = (self.heatmap_min_overlap - 1) * w * h\n            sq3 = np.sqrt(b3**2 - 4 * a3 * c3)\n            r3 = (b3 + sq3) / 2\n\n            sigmas[i] = min(r1, r2, r3) / 3\n\n        return sigmas\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None,\n               bbox: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints into heatmaps.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n            bbox (np.ndarray): Bounding box in shape (N, 8) which includes\n                coordinates of 4 corners.\n\n        Returns:\n            dict:\n            - heatmaps (np.ndarray): The coupled heatmap in shape\n                (1+K, H, W) where [W, H] is the `heatmap_size`.\n            - instance_heatmaps (np.ndarray): The decoupled heatmap in shape\n                (N*K, H, W) where M is the number of instances.\n            - keypoint_weights (np.ndarray): The weight for heatmaps in shape\n                (N*K).\n            - instance_coords (np.ndarray): The coordinates of instance roots\n                in shape (N, 2)\n        \"\"\"\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n        if bbox is None:\n            # generate pseudo bbox via visible keypoints\n            bbox = get_instance_bbox(keypoints, keypoints_visible)\n            bbox = np.tile(bbox, 2).reshape(-1, 4, 2)\n            # corner order: left_top, left_bottom, right_top, right_bottom\n            bbox[:, 1:3, 0] = bbox[:, 0:2, 0]\n\n        # keypoint coordinates in heatmap\n        _keypoints = keypoints / self.scale_factor\n        _bbox = bbox.reshape(-1, 4, 2) / self.scale_factor\n\n        # compute the root and scale of each instance\n        roots, roots_visible = get_instance_root(_keypoints, keypoints_visible,\n                                                 self.root_type)\n\n        sigmas = self._get_instance_wise_sigmas(_bbox)\n\n        # generate global heatmaps\n        heatmaps, keypoint_weights = generate_gaussian_heatmaps(\n            heatmap_size=self.heatmap_size,\n            keypoints=np.concatenate((_keypoints, roots[:, None]), axis=1),\n            keypoints_visible=np.concatenate(\n                (keypoints_visible, roots_visible[:, None]), axis=1),\n            sigma=sigmas)\n        roots_visible = keypoint_weights[:, -1]\n\n        # select instances\n        inst_roots, inst_indices = [], []\n        diagonal_lengths = get_diagonal_lengths(_keypoints, keypoints_visible)\n        for i in np.argsort(diagonal_lengths):\n            if roots_visible[i] < 1:\n                continue\n            # rand root point in 3x3 grid\n            x, y = roots[i] + np.random.randint(-1, 2, (2, ))\n            x = max(0, min(x, self.heatmap_size[0] - 1))\n            y = max(0, min(y, self.heatmap_size[1] - 1))\n            if (x, y) not in inst_roots:\n                inst_roots.append((x, y))\n                inst_indices.append(i)\n        if len(inst_indices) > self.encode_max_instances:\n            rand_indices = random.sample(\n                range(len(inst_indices)), self.encode_max_instances)\n            inst_roots = [inst_roots[i] for i in rand_indices]\n            inst_indices = [inst_indices[i] for i in rand_indices]\n\n        # generate instance-wise heatmaps\n        inst_heatmaps, inst_heatmap_weights = [], []\n        for i in inst_indices:\n            inst_heatmap, inst_heatmap_weight = generate_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=_keypoints[i:i + 1],\n                keypoints_visible=keypoints_visible[i:i + 1],\n                sigma=sigmas[i].item())\n            inst_heatmaps.append(inst_heatmap)\n            inst_heatmap_weights.append(inst_heatmap_weight)\n\n        if len(inst_indices) > 0:\n            inst_heatmaps = np.concatenate(inst_heatmaps)\n            inst_heatmap_weights = np.concatenate(inst_heatmap_weights)\n            inst_roots = np.array(inst_roots, dtype=np.int32)\n        else:\n            inst_heatmaps = np.empty((0, *self.heatmap_size[::-1]))\n            inst_heatmap_weights = np.empty((0, ))\n            inst_roots = np.empty((0, 2), dtype=np.int32)\n\n        encoded = dict(\n            heatmaps=heatmaps,\n            instance_heatmaps=inst_heatmaps,\n            keypoint_weights=inst_heatmap_weights,\n            instance_coords=inst_roots)\n\n        return encoded\n\n    def decode(self, instance_heatmaps: np.ndarray,\n               instance_scores: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from decoupled heatmaps. The decoded\n        keypoint coordinates are in the input image space.\n\n        Args:\n            instance_heatmaps (np.ndarray): Heatmaps in shape (N, K, H, W)\n            instance_scores (np.ndarray): Confidence of instance roots\n                prediction in shape (N, 1)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded keypoint coordinates in shape\n                (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K). It\n                usually represents the confidence of the keypoint prediction\n        \"\"\"\n        keypoints, keypoint_scores = [], []\n\n        for i in range(instance_heatmaps.shape[0]):\n            heatmaps = instance_heatmaps[i].copy()\n            kpts, scores = get_heatmap_maximum(heatmaps)\n            keypoints.append(refine_keypoints(kpts[None], heatmaps))\n            keypoint_scores.append(scores[None])\n\n        keypoints = np.concatenate(keypoints)\n        # Restore the keypoint scale\n        keypoints = keypoints * self.scale_factor\n\n        keypoint_scores = np.concatenate(keypoint_scores)\n        keypoint_scores *= instance_scores\n\n        return keypoints, keypoint_scores\n"
  },
  {
    "path": "mmpose/codecs/edpose_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom mmpose.structures import bbox_cs2xyxy, bbox_xyxy2cs\nfrom .base import BaseKeypointCodec\n\n\n@KEYPOINT_CODECS.register_module()\nclass EDPoseLabel(BaseKeypointCodec):\n    r\"\"\"Generate keypoint and label coordinates for `ED-Pose`_ by\n    Yang J. et al (2023).\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n\n    Encoded:\n\n        - keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        - keypoints_visible (np.ndarray): Keypoint visibility in shape\n                (N, K, D)\n        - area (np.ndarray): Area in shape (N)\n        - bbox (np.ndarray): Bbox in shape (N, 4)\n\n    Args:\n        num_select (int): The number of candidate instances\n        num_keypoints (int): The Number of keypoints\n    \"\"\"\n\n    auxiliary_encode_keys = {'area', 'bboxes', 'img_shape'}\n    instance_mapping_table = dict(\n        bbox='bboxes',\n        keypoints='keypoints',\n        keypoints_visible='keypoints_visible',\n        area='areas',\n    )\n\n    def __init__(self, num_select: int = 100, num_keypoints: int = 17):\n        super().__init__()\n\n        self.num_select = num_select\n        self.num_keypoints = num_keypoints\n\n    def encode(\n        self,\n        img_shape,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None,\n        area: Optional[np.ndarray] = None,\n        bboxes: Optional[np.ndarray] = None,\n    ) -> dict:\n        \"\"\"Encoding keypoints, area and bbox from input image space to\n        normalized space.\n\n        Args:\n            - img_shape (Sequence[int]): The shape of image in the format\n                of (width, height).\n            - keypoints (np.ndarray): Keypoint coordinates in\n                shape (N, K, D).\n            - keypoints_visible (np.ndarray): Keypoint visibility in shape\n                (N, K)\n            - area (np.ndarray):\n            - bboxes (np.ndarray):\n\n        Returns:\n            encoded (dict): Contains the following items:\n\n                - keypoint_labels (np.ndarray): The processed keypoints in\n                    shape like (N, K, D).\n                - keypoints_visible (np.ndarray): Keypoint visibility in shape\n                    (N, K, D)\n                - area_labels (np.ndarray): The processed target\n                    area in shape (N).\n                - bboxes_labels: The processed target bbox in\n                    shape (N, 4).\n        \"\"\"\n        w, h = img_shape\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        if bboxes is not None:\n            bboxes = np.concatenate(bbox_xyxy2cs(bboxes), axis=-1)\n            bboxes = bboxes / np.array([w, h, w, h], dtype=np.float32)\n\n        if area is not None:\n            area = area / float(w * h)\n\n        if keypoints is not None:\n            keypoints = keypoints / np.array([w, h], dtype=np.float32)\n\n        encoded = dict(\n            keypoints=keypoints,\n            area=area,\n            bbox=bboxes,\n            keypoints_visible=keypoints_visible)\n\n        return encoded\n\n    def decode(self, input_shapes: np.ndarray, pred_logits: np.ndarray,\n               pred_boxes: np.ndarray, pred_keypoints: np.ndarray):\n        \"\"\"Select the final top-k keypoints, and decode the results from\n        normalize size to origin input size.\n\n        Args:\n            input_shapes (Tensor): The size of input image resize.\n            test_cfg (ConfigType): Config of testing.\n            pred_logits (Tensor): The result of score.\n            pred_boxes (Tensor): The result of bbox.\n            pred_keypoints (Tensor): The result of keypoints.\n\n        Returns:\n            tuple: Decoded boxes, keypoints, and keypoint scores.\n        \"\"\"\n\n        # Initialization\n        num_keypoints = self.num_keypoints\n        prob = pred_logits.reshape(-1)\n\n        # Select top-k instances based on prediction scores\n        topk_indexes = np.argsort(-prob)[:self.num_select]\n        topk_values = np.take_along_axis(prob, topk_indexes, axis=0)\n        scores = np.tile(topk_values[:, np.newaxis], [1, num_keypoints])\n\n        # Decode bounding boxes\n        topk_boxes = topk_indexes // pred_logits.shape[1]\n        boxes = bbox_cs2xyxy(*np.split(pred_boxes, [2], axis=-1))\n        boxes = np.take_along_axis(\n            boxes, np.tile(topk_boxes[:, np.newaxis], [1, 4]), axis=0)\n\n        # Convert from relative to absolute coordinates\n        img_h, img_w = np.split(input_shapes, 2, axis=0)\n        scale_fct = np.hstack([img_w, img_h, img_w, img_h])\n        boxes = boxes * scale_fct[np.newaxis, :]\n\n        # Decode keypoints\n        topk_keypoints = topk_indexes // pred_logits.shape[1]\n        keypoints = np.take_along_axis(\n            pred_keypoints,\n            np.tile(topk_keypoints[:, np.newaxis], [1, num_keypoints * 3]),\n            axis=0)\n        keypoints = keypoints[:, :(num_keypoints * 2)]\n        keypoints = keypoints * np.tile(\n            np.hstack([img_w, img_h]), [num_keypoints])[np.newaxis, :]\n        keypoints = keypoints.reshape(-1, num_keypoints, 2)\n\n        return boxes, keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/hand_3d_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils.gaussian_heatmap import generate_3d_gaussian_heatmaps\nfrom .utils.post_processing import get_heatmap_3d_maximum\n\n\n@KEYPOINT_CODECS.register_module()\nclass Hand3DHeatmap(BaseKeypointCodec):\n    r\"\"\"Generate target 3d heatmap and relative root depth for hand datasets.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n\n    Args:\n        image_size (tuple): Size of image. Default: ``[256, 256]``.\n        root_heatmap_size (int): Size of heatmap of root head.\n            Default: 64.\n        heatmap_size (tuple): Size of heatmap. Default: ``[64, 64, 64]``.\n        heatmap3d_depth_bound (float): Boundary for 3d heatmap depth.\n            Default: 400.0.\n        heatmap_size_root (int): Size of 3d heatmap root. Default: 64.\n        depth_size (int): Number of depth discretization size, used for\n            decoding. Defaults to 64.\n        root_depth_bound (float): Boundary for 3d heatmap root depth.\n            Default: 400.0.\n        use_different_joint_weights (bool): Whether to use different joint\n            weights. Default: ``False``.\n        sigma (int): Sigma of heatmap gaussian. Default: 2.\n        joint_indices (list, optional): Indices of joints used for heatmap\n            generation. If None (default) is given, all joints will be used.\n            Default: ``None``.\n        max_bound (float): The maximal value of heatmap. Default: 1.0.\n    \"\"\"\n\n    auxiliary_encode_keys = {\n        'dataset_keypoint_weights', 'rel_root_depth', 'rel_root_valid',\n        'hand_type', 'hand_type_valid', 'focal', 'principal_pt'\n    }\n\n    instance_mapping_table = {\n        'keypoints': 'keypoints',\n        'keypoints_visible': 'keypoints_visible',\n        'keypoints_cam': 'keypoints_cam',\n    }\n\n    label_mapping_table = {\n        'keypoint_weights': 'keypoint_weights',\n        'root_depth_weight': 'root_depth_weight',\n        'type_weight': 'type_weight',\n        'root_depth': 'root_depth',\n        'type': 'type'\n    }\n\n    def __init__(self,\n                 image_size: Tuple[int, int] = [256, 256],\n                 root_heatmap_size: int = 64,\n                 heatmap_size: Tuple[int, int, int] = [64, 64, 64],\n                 heatmap3d_depth_bound: float = 400.0,\n                 heatmap_size_root: int = 64,\n                 root_depth_bound: float = 400.0,\n                 depth_size: int = 64,\n                 use_different_joint_weights: bool = False,\n                 sigma: int = 2,\n                 joint_indices: Optional[list] = None,\n                 max_bound: float = 1.0):\n        super().__init__()\n\n        self.image_size = np.array(image_size)\n        self.root_heatmap_size = root_heatmap_size\n        self.heatmap_size = np.array(heatmap_size)\n        self.heatmap3d_depth_bound = heatmap3d_depth_bound\n        self.heatmap_size_root = heatmap_size_root\n        self.root_depth_bound = root_depth_bound\n        self.depth_size = depth_size\n        self.use_different_joint_weights = use_different_joint_weights\n\n        self.sigma = sigma\n        self.joint_indices = joint_indices\n        self.max_bound = max_bound\n        self.scale_factor = (np.array(image_size) /\n                             heatmap_size[:-1]).astype(np.float32)\n\n    def encode(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray],\n        dataset_keypoint_weights: Optional[np.ndarray],\n        rel_root_depth: np.float32,\n        rel_root_valid: np.float32,\n        hand_type: np.ndarray,\n        hand_type_valid: np.ndarray,\n        focal: np.ndarray,\n        principal_pt: np.ndarray,\n    ) -> dict:\n        \"\"\"Encoding keypoints from input image space to input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D).\n            keypoints_visible (np.ndarray, optional): Keypoint visibilities in\n                shape (N, K).\n            dataset_keypoint_weights (np.ndarray, optional): Keypoints weight\n                in shape (K, ).\n            rel_root_depth (np.float32): Relative root depth.\n            rel_root_valid (float): Validity of relative root depth.\n            hand_type (np.ndarray): Type of hand encoded as a array.\n            hand_type_valid (np.ndarray): Validity of hand type.\n            focal (np.ndarray): Focal length of camera.\n            principal_pt (np.ndarray): Principal point of camera.\n\n        Returns:\n            encoded (dict): Contains the following items:\n\n                - heatmaps (np.ndarray): The generated heatmap in shape\n                  (K * D, H, W) where [W, H, D] is the `heatmap_size`\n                - keypoint_weights (np.ndarray): The target weights in shape\n                  (N, K)\n                - root_depth (np.ndarray): Encoded relative root depth\n                - root_depth_weight (np.ndarray): The weights of relative root\n                  depth\n                - type (np.ndarray): Encoded hand type\n                - type_weight (np.ndarray): The weights of hand type\n        \"\"\"\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:-1], dtype=np.float32)\n\n        if self.use_different_joint_weights:\n            assert dataset_keypoint_weights is not None, 'To use different ' \\\n                'joint weights,`dataset_keypoint_weights` cannot be None.'\n\n        heatmaps, keypoint_weights = generate_3d_gaussian_heatmaps(\n            heatmap_size=self.heatmap_size,\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            sigma=self.sigma,\n            image_size=self.image_size,\n            heatmap3d_depth_bound=self.heatmap3d_depth_bound,\n            joint_indices=self.joint_indices,\n            max_bound=self.max_bound,\n            use_different_joint_weights=self.use_different_joint_weights,\n            dataset_keypoint_weights=dataset_keypoint_weights)\n\n        rel_root_depth = (rel_root_depth / self.root_depth_bound +\n                          0.5) * self.heatmap_size_root\n        rel_root_valid = rel_root_valid * (rel_root_depth >= 0) * (\n            rel_root_depth <= self.heatmap_size_root)\n\n        encoded = dict(\n            heatmaps=heatmaps,\n            keypoint_weights=keypoint_weights,\n            root_depth=rel_root_depth * np.ones(1, dtype=np.float32),\n            type=hand_type,\n            type_weight=hand_type_valid,\n            root_depth_weight=rel_root_valid * np.ones(1, dtype=np.float32))\n        return encoded\n\n    def decode(self, heatmaps: np.ndarray, root_depth: np.ndarray,\n               hand_type: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from heatmaps. The decoded keypoint\n        coordinates are in the input image space.\n\n        Args:\n            heatmaps (np.ndarray): Heatmaps in shape (K, D, H, W)\n            root_depth (np.ndarray): Root depth prediction.\n            hand_type (np.ndarray): Hand type prediction.\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded keypoint coordinates in shape\n                (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K). It\n                usually represents the confidence of the keypoint prediction\n        \"\"\"\n        heatmap3d = heatmaps.copy()\n\n        keypoints, scores = get_heatmap_3d_maximum(heatmap3d)\n\n        # transform keypoint depth to camera space\n        keypoints[..., 2] = (keypoints[..., 2] / self.depth_size -\n                             0.5) * self.heatmap3d_depth_bound\n\n        # Unsqueeze the instance dimension for single-instance results\n        keypoints, scores = keypoints[None], scores[None]\n\n        # Restore the keypoint scale\n        keypoints[..., :2] = keypoints[..., :2] * self.scale_factor\n\n        # decode relative hand root depth\n        # transform relative root depth to camera space\n        rel_root_depth = ((root_depth / self.root_heatmap_size - 0.5) *\n                          self.root_depth_bound)\n\n        hand_type = (hand_type > 0).reshape(1, -1).astype(int)\n\n        return keypoints, scores, rel_root_depth, hand_type\n"
  },
  {
    "path": "mmpose/codecs/image_pose_lifting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Tuple, Union\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\n\n\n@KEYPOINT_CODECS.register_module()\nclass ImagePoseLifting(BaseKeypointCodec):\n    r\"\"\"Generate keypoint coordinates for pose lifter.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - pose-lifitng target dimension: C\n\n    Args:\n        num_keypoints (int): The number of keypoints in the dataset.\n        root_index (Union[int, List]): Root keypoint index in the pose.\n        remove_root (bool): If true, remove the root keypoint from the pose.\n            Default: ``False``.\n        save_index (bool): If true, store the root position separated from the\n            original pose. Default: ``False``.\n        reshape_keypoints (bool): If true, reshape the keypoints into shape\n            (-1, N). Default: ``True``.\n        concat_vis (bool): If true, concat the visibility item of keypoints.\n            Default: ``False``.\n        keypoints_mean (np.ndarray, optional): Mean values of keypoints\n            coordinates in shape (K, D).\n        keypoints_std (np.ndarray, optional): Std values of keypoints\n            coordinates in shape (K, D).\n        target_mean (np.ndarray, optional): Mean values of pose-lifitng target\n            coordinates in shape (K, C).\n        target_std (np.ndarray, optional): Std values of pose-lifitng target\n            coordinates in shape (K, C).\n    \"\"\"\n\n    auxiliary_encode_keys = {'lifting_target', 'lifting_target_visible'}\n\n    instance_mapping_table = dict(\n        lifting_target='lifting_target',\n        lifting_target_visible='lifting_target_visible',\n    )\n    label_mapping_table = dict(\n        trajectory_weights='trajectory_weights',\n        lifting_target_label='lifting_target_label',\n        lifting_target_weight='lifting_target_weight')\n\n    def __init__(self,\n                 num_keypoints: int,\n                 root_index: Union[int, List] = 0,\n                 remove_root: bool = False,\n                 save_index: bool = False,\n                 reshape_keypoints: bool = True,\n                 concat_vis: bool = False,\n                 keypoints_mean: Optional[np.ndarray] = None,\n                 keypoints_std: Optional[np.ndarray] = None,\n                 target_mean: Optional[np.ndarray] = None,\n                 target_std: Optional[np.ndarray] = None,\n                 additional_encode_keys: Optional[List[str]] = None):\n        super().__init__()\n\n        self.num_keypoints = num_keypoints\n        if isinstance(root_index, int):\n            root_index = [root_index]\n        self.root_index = root_index\n        self.remove_root = remove_root\n        self.save_index = save_index\n        self.reshape_keypoints = reshape_keypoints\n        self.concat_vis = concat_vis\n        if keypoints_mean is not None:\n            assert keypoints_std is not None, 'keypoints_std is None'\n            keypoints_mean = np.array(\n                keypoints_mean,\n                dtype=np.float32).reshape(1, num_keypoints, -1)\n            keypoints_std = np.array(\n                keypoints_std, dtype=np.float32).reshape(1, num_keypoints, -1)\n\n            assert keypoints_mean.shape == keypoints_std.shape, (\n                f'keypoints_mean.shape {keypoints_mean.shape} != '\n                f'keypoints_std.shape {keypoints_std.shape}')\n        if target_mean is not None:\n            assert target_std is not None, 'target_std is None'\n            target_dim = num_keypoints - 1 if remove_root else num_keypoints\n            target_mean = np.array(\n                target_mean, dtype=np.float32).reshape(1, target_dim, -1)\n            target_std = np.array(\n                target_std, dtype=np.float32).reshape(1, target_dim, -1)\n\n            assert target_mean.shape == target_std.shape, (\n                f'target_mean.shape {target_mean.shape} != '\n                f'target_std.shape {target_std.shape}')\n        self.keypoints_mean = keypoints_mean\n        self.keypoints_std = keypoints_std\n        self.target_mean = target_mean\n        self.target_std = target_std\n\n        if additional_encode_keys is not None:\n            self.auxiliary_encode_keys.update(additional_encode_keys)\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None,\n               lifting_target: Optional[np.ndarray] = None,\n               lifting_target_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encoding keypoints from input image space to normalized space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D).\n            keypoints_visible (np.ndarray, optional): Keypoint visibilities in\n                shape (N, K).\n            lifting_target (np.ndarray, optional): 3d target coordinate in\n                shape (T, K, C).\n            lifting_target_visible (np.ndarray, optional): Target coordinate in\n                shape (T, K, ).\n\n        Returns:\n            encoded (dict): Contains the following items:\n\n                - keypoint_labels (np.ndarray): The processed keypoints in\n                  shape like (N, K, D) or (K * D, N).\n                - keypoint_labels_visible (np.ndarray): The processed\n                  keypoints' weights in shape (N, K, ) or (N-1, K, ).\n                - lifting_target_label: The processed target coordinate in\n                  shape (K, C) or (K-1, C).\n                - lifting_target_weight (np.ndarray): The target weights in\n                  shape (K, ) or (K-1, ).\n                - trajectory_weights (np.ndarray): The trajectory weights in\n                  shape (K, ).\n                - target_root (np.ndarray): The root coordinate of target in\n                  shape (C, ).\n\n                In addition, there are some optional items it may contain:\n\n                - target_root (np.ndarray): The root coordinate of target in\n                  shape (C, ). Exists if ``zero_center`` is ``True``.\n                - target_root_removed (bool): Indicate whether the root of\n                  pose-lifitng target is removed. Exists if\n                  ``remove_root`` is ``True``.\n                - target_root_index (int): An integer indicating the index of\n                  root. Exists if ``remove_root`` and ``save_index``\n                  are ``True``.\n        \"\"\"\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        if lifting_target is None:\n            lifting_target = [keypoints[0]]\n\n        # set initial value for `lifting_target_weight`\n        # and `trajectory_weights`\n        if lifting_target_visible is None:\n            lifting_target_visible = np.ones(\n                lifting_target.shape[:-1], dtype=np.float32)\n            lifting_target_weight = lifting_target_visible\n            trajectory_weights = (1 / lifting_target[:, 2])\n        else:\n            valid = lifting_target_visible > 0.5\n            lifting_target_weight = np.where(valid, 1., 0.).astype(np.float32)\n            trajectory_weights = lifting_target_weight\n\n        encoded = dict()\n\n        # Zero-center the target pose around a given root keypoint\n        assert (lifting_target.ndim >= 2 and\n                lifting_target.shape[-2] > max(self.root_index)), \\\n            f'Got invalid joint shape {lifting_target.shape}'\n\n        root = np.mean(\n            lifting_target[..., self.root_index, :], axis=-2, dtype=np.float32)\n        lifting_target_label = lifting_target - root[np.newaxis, ...]\n\n        if self.remove_root and len(self.root_index) == 1:\n            root_index = self.root_index[0]\n            lifting_target_label = np.delete(\n                lifting_target_label, root_index, axis=-2)\n            lifting_target_visible = np.delete(\n                lifting_target_visible, root_index, axis=-2)\n            assert lifting_target_weight.ndim in {\n                2, 3\n            }, (f'lifting_target_weight.ndim {lifting_target_weight.ndim} '\n                'is not in {2, 3}')\n\n            axis_to_remove = -2 if lifting_target_weight.ndim == 3 else -1\n            lifting_target_weight = np.delete(\n                lifting_target_weight, root_index, axis=axis_to_remove)\n            # Add a flag to avoid latter transforms that rely on the root\n            # joint or the original joint index\n            encoded['target_root_removed'] = True\n\n            # Save the root index which is necessary to restore the global pose\n            if self.save_index:\n                encoded['target_root_index'] = root_index\n\n        # Normalize the 2D keypoint coordinate with mean and std\n        keypoint_labels = keypoints.copy()\n\n        if self.keypoints_mean is not None:\n            assert self.keypoints_mean.shape[1:] == keypoints.shape[1:], (\n                f'self.keypoints_mean.shape[1:] {self.keypoints_mean.shape[1:]} '  # noqa\n                f'!= keypoints.shape[1:] {keypoints.shape[1:]}')\n            encoded['keypoints_mean'] = self.keypoints_mean.copy()\n            encoded['keypoints_std'] = self.keypoints_std.copy()\n\n            keypoint_labels = (keypoint_labels -\n                               self.keypoints_mean) / self.keypoints_std\n        if self.target_mean is not None:\n            assert self.target_mean.shape == lifting_target_label.shape, (\n                f'self.target_mean.shape {self.target_mean.shape} '\n                f'!= lifting_target_label.shape {lifting_target_label.shape}'  # noqa\n            )\n            encoded['target_mean'] = self.target_mean.copy()\n            encoded['target_std'] = self.target_std.copy()\n\n            lifting_target_label = (lifting_target_label -\n                                    self.target_mean) / self.target_std\n\n        # Generate reshaped keypoint coordinates\n        assert keypoint_labels.ndim in {\n            2, 3\n        }, (f'keypoint_labels.ndim {keypoint_labels.ndim} is not in {2, 3}')\n        if keypoint_labels.ndim == 2:\n            keypoint_labels = keypoint_labels[None, ...]\n\n        if self.concat_vis:\n            keypoints_visible_ = keypoints_visible\n            if keypoints_visible.ndim == 2:\n                keypoints_visible_ = keypoints_visible[..., None]\n            keypoint_labels = np.concatenate(\n                (keypoint_labels, keypoints_visible_), axis=2)\n\n        if self.reshape_keypoints:\n            N = keypoint_labels.shape[0]\n            keypoint_labels = keypoint_labels.transpose(1, 2, 0).reshape(-1, N)\n\n        encoded['keypoint_labels'] = keypoint_labels\n        encoded['keypoint_labels_visible'] = keypoints_visible\n        encoded['lifting_target_label'] = lifting_target_label\n        encoded['lifting_target_weight'] = lifting_target_weight\n        encoded['trajectory_weights'] = trajectory_weights\n        encoded['target_root'] = root\n\n        return encoded\n\n    def decode(self,\n               encoded: np.ndarray,\n               target_root: Optional[np.ndarray] = None\n               ) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from normalized space to input image\n        space.\n\n        Args:\n            encoded (np.ndarray): Coordinates in shape (N, K, C).\n            target_root (np.ndarray, optional): The target root coordinate.\n                Default: ``None``.\n\n        Returns:\n            keypoints (np.ndarray): Decoded coordinates in shape (N, K, C).\n            scores (np.ndarray): The keypoint scores in shape (N, K).\n        \"\"\"\n        keypoints = encoded.copy()\n\n        if self.target_mean is not None and self.target_std is not None:\n            assert self.target_mean.shape == keypoints.shape, (\n                f'self.target_mean.shape {self.target_mean.shape} '\n                f'!= keypoints.shape {keypoints.shape}')\n            keypoints = keypoints * self.target_std + self.target_mean\n\n        if target_root is not None and target_root.size > 0:\n            keypoints = keypoints + target_root\n            if self.remove_root and len(self.root_index) == 1:\n                keypoints = np.insert(\n                    keypoints, self.root_index, target_root, axis=1)\n        scores = np.ones(keypoints.shape[:-1], dtype=np.float32)\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/integral_regression_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .msra_heatmap import MSRAHeatmap\nfrom .regression_label import RegressionLabel\n\n\n@KEYPOINT_CODECS.register_module()\nclass IntegralRegressionLabel(BaseKeypointCodec):\n    \"\"\"Generate keypoint coordinates and normalized heatmaps. See the paper:\n    `DSNT`_ by Nibali et al(2018).\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n\n    Encoded:\n\n        - keypoint_labels (np.ndarray): The normalized regression labels in\n            shape (N, K, D) where D is 2 for 2d coordinates\n        - heatmaps (np.ndarray): The generated heatmap in shape (K, H, W) where\n            [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Input image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        sigma (float): The sigma value of the Gaussian heatmap\n        unbiased (bool): Whether use unbiased method (DarkPose) in ``'msra'``\n            encoding. See `Dark Pose`_ for details. Defaults to ``False``\n        blur_kernel_size (int): The Gaussian blur kernel size of the heatmap\n            modulation in DarkPose. The kernel size and sigma should follow\n            the expirical formula :math:`sigma = 0.3*((ks-1)*0.5-1)+0.8`.\n            Defaults to 11\n        normalize (bool): Whether to normalize the heatmaps. Defaults to True.\n\n    .. _`DSNT`: https://arxiv.org/abs/1801.07372\n    \"\"\"\n\n    label_mapping_table = dict(\n        keypoint_labels='keypoint_labels',\n        keypoint_weights='keypoint_weights',\n    )\n    field_mapping_table = dict(heatmaps='heatmaps', )\n\n    def __init__(self,\n                 input_size: Tuple[int, int],\n                 heatmap_size: Tuple[int, int],\n                 sigma: float,\n                 unbiased: bool = False,\n                 blur_kernel_size: int = 11,\n                 normalize: bool = True) -> None:\n        super().__init__()\n\n        self.heatmap_codec = MSRAHeatmap(input_size, heatmap_size, sigma,\n                                         unbiased, blur_kernel_size)\n        self.keypoint_codec = RegressionLabel(input_size)\n        self.normalize = normalize\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encoding keypoints to regression labels and heatmaps.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - keypoint_labels (np.ndarray): The normalized regression labels in\n                shape (N, K, D) where D is 2 for 2d coordinates\n            - heatmaps (np.ndarray): The generated heatmap in shape\n                (K, H, W) where [W, H] is the `heatmap_size`\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n        encoded_hm = self.heatmap_codec.encode(keypoints, keypoints_visible)\n        encoded_kp = self.keypoint_codec.encode(keypoints, keypoints_visible)\n\n        heatmaps = encoded_hm['heatmaps']\n        keypoint_labels = encoded_kp['keypoint_labels']\n        keypoint_weights = encoded_kp['keypoint_weights']\n\n        if self.normalize:\n            val_sum = heatmaps.sum(axis=(-1, -2)).reshape(-1, 1, 1) + 1e-24\n            heatmaps = heatmaps / val_sum\n\n        encoded = dict(\n            keypoint_labels=keypoint_labels,\n            heatmaps=heatmaps,\n            keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from normalized space to input image\n        space.\n\n        Args:\n            encoded (np.ndarray): Coordinates in shape (N, K, D)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded coordinates in shape (N, K, D)\n            - socres (np.ndarray): The keypoint scores in shape (N, K).\n                It usually represents the confidence of the keypoint prediction\n        \"\"\"\n\n        keypoints, scores = self.keypoint_codec.decode(encoded)\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/megvii_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Optional, Tuple\n\nimport cv2\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils import gaussian_blur, get_heatmap_maximum\n\n\n@KEYPOINT_CODECS.register_module()\nclass MegviiHeatmap(BaseKeypointCodec):\n    \"\"\"Represent keypoints as heatmaps via \"Megvii\" approach. See `MSPN`_\n    (2019) and `CPN`_ (2018) for details.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n        - heatmap size: [W, H]\n\n    Encoded:\n\n        - heatmaps (np.ndarray): The generated heatmap in shape (K, H, W)\n            where [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        kernel_size (tuple): The kernel size of the heatmap gaussian in\n            [ks_x, ks_y]\n\n    .. _`MSPN`: https://arxiv.org/abs/1901.00148\n    .. _`CPN`: https://arxiv.org/abs/1711.07319\n    \"\"\"\n\n    label_mapping_table = dict(keypoint_weights='keypoint_weights', )\n    field_mapping_table = dict(heatmaps='heatmaps', )\n\n    def __init__(\n        self,\n        input_size: Tuple[int, int],\n        heatmap_size: Tuple[int, int],\n        kernel_size: int,\n    ) -> None:\n\n        super().__init__()\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.kernel_size = kernel_size\n        self.scale_factor = (np.array(input_size) /\n                             heatmap_size).astype(np.float32)\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints into heatmaps. Note that the original keypoint\n        coordinates should be in the input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - heatmaps (np.ndarray): The generated heatmap in shape\n                (K, H, W) where [W, H] is the `heatmap_size`\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n\n        N, K, _ = keypoints.shape\n        W, H = self.heatmap_size\n\n        assert N == 1, (\n            f'{self.__class__.__name__} only support single-instance '\n            'keypoint encoding')\n\n        heatmaps = np.zeros((K, H, W), dtype=np.float32)\n        keypoint_weights = keypoints_visible.copy()\n\n        for n, k in product(range(N), range(K)):\n            # skip unlabled keypoints\n            if keypoints_visible[n, k] < 0.5:\n                continue\n\n            # get center coordinates\n            kx, ky = (keypoints[n, k] / self.scale_factor).astype(np.int64)\n            if kx < 0 or kx >= W or ky < 0 or ky >= H:\n                keypoint_weights[n, k] = 0\n                continue\n\n            heatmaps[k, ky, kx] = 1.\n            kernel_size = (self.kernel_size, self.kernel_size)\n            heatmaps[k] = cv2.GaussianBlur(heatmaps[k], kernel_size, 0)\n\n            # normalize the heatmap\n            heatmaps[k] = heatmaps[k] / heatmaps[k, ky, kx] * 255.\n\n        encoded = dict(heatmaps=heatmaps, keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from heatmaps. The decoded keypoint\n        coordinates are in the input image space.\n\n        Args:\n            encoded (np.ndarray): Heatmaps in shape (K, H, W)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded keypoint coordinates in shape\n                (K, D)\n            - scores (np.ndarray): The keypoint scores in shape (K,). It\n                usually represents the confidence of the keypoint prediction\n        \"\"\"\n        heatmaps = gaussian_blur(encoded.copy(), self.kernel_size)\n        K, H, W = heatmaps.shape\n\n        keypoints, scores = get_heatmap_maximum(heatmaps)\n\n        for k in range(K):\n            heatmap = heatmaps[k]\n            px = int(keypoints[k, 0])\n            py = int(keypoints[k, 1])\n            if 1 < px < W - 1 and 1 < py < H - 1:\n                diff = np.array([\n                    heatmap[py][px + 1] - heatmap[py][px - 1],\n                    heatmap[py + 1][px] - heatmap[py - 1][px]\n                ])\n                keypoints[k] += (np.sign(diff) * 0.25 + 0.5)\n\n        scores = scores / 255.0 + 0.5\n\n        # Unsqueeze the instance dimension for single-instance results\n        # and restore the keypoint scales\n        keypoints = keypoints[None] * self.scale_factor\n        scores = scores[None]\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/motionbert_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom copy import deepcopy\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils import camera_to_image_coord\n\n\n@KEYPOINT_CODECS.register_module()\nclass MotionBERTLabel(BaseKeypointCodec):\n    r\"\"\"Generate keypoint and label coordinates for `MotionBERT`_ by Zhu et al\n    (2022).\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - pose-lifitng target dimension: C\n\n    Args:\n        num_keypoints (int): The number of keypoints in the dataset.\n        root_index (int): Root keypoint index in the pose. Default: 0.\n        remove_root (bool): If true, remove the root keypoint from the pose.\n            Default: ``False``.\n        save_index (bool): If true, store the root position separated from the\n            original pose, only takes effect if ``remove_root`` is ``True``.\n            Default: ``False``.\n        concat_vis (bool): If true, concat the visibility item of keypoints.\n            Default: ``False``.\n        rootrel (bool): If true, the root keypoint will be set to the\n            coordinate origin. Default: ``False``.\n        mode (str): Indicating whether the current mode is 'train' or 'test'.\n            Default: ``'test'``.\n    \"\"\"\n\n    auxiliary_encode_keys = {\n        'lifting_target', 'lifting_target_visible', 'camera_param', 'factor'\n    }\n\n    instance_mapping_table = dict(\n        lifting_target='lifting_target',\n        lifting_target_visible='lifting_target_visible',\n    )\n    label_mapping_table = dict(\n        trajectory_weights='trajectory_weights',\n        lifting_target_label='lifting_target_label',\n        lifting_target_weight='lifting_target_weight')\n\n    def __init__(self,\n                 num_keypoints: int,\n                 root_index: int = 0,\n                 remove_root: bool = False,\n                 save_index: bool = False,\n                 concat_vis: bool = False,\n                 rootrel: bool = False,\n                 mode: str = 'test'):\n        super().__init__()\n\n        self.num_keypoints = num_keypoints\n        self.root_index = root_index\n        self.remove_root = remove_root\n        self.save_index = save_index\n        self.concat_vis = concat_vis\n        self.rootrel = rootrel\n        assert mode.lower() in {'train', 'test'\n                                }, (f'Unsupported mode {mode}, '\n                                    'mode should be one of (\"train\", \"test\").')\n        self.mode = mode.lower()\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None,\n               lifting_target: Optional[np.ndarray] = None,\n               lifting_target_visible: Optional[np.ndarray] = None,\n               camera_param: Optional[dict] = None,\n               factor: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encoding keypoints from input image space to normalized space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (B, T, K, D).\n            keypoints_visible (np.ndarray, optional): Keypoint visibilities in\n                shape (B, T, K).\n            lifting_target (np.ndarray, optional): 3d target coordinate in\n                shape (T, K, C).\n            lifting_target_visible (np.ndarray, optional): Target coordinate in\n                shape (T, K, ).\n            camera_param (dict, optional): The camera parameter dictionary.\n            factor (np.ndarray, optional): The factor mapping camera and image\n                  coordinate in shape (T, ).\n\n        Returns:\n            encoded (dict): Contains the following items:\n\n                - keypoint_labels (np.ndarray): The processed keypoints in\n                  shape like (N, K, D).\n                - keypoint_labels_visible (np.ndarray): The processed\n                  keypoints' weights in shape (N, K, ) or (N, K-1, ).\n                - lifting_target_label: The processed target coordinate in\n                  shape (K, C) or (K-1, C).\n                - lifting_target_weight (np.ndarray): The target weights in\n                  shape (K, ) or (K-1, ).\n                - factor (np.ndarray): The factor mapping camera and image\n                  coordinate in shape (T, 1).\n        \"\"\"\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        # set initial value for `lifting_target_weight`\n        if lifting_target_visible is None:\n            lifting_target_visible = np.ones(\n                lifting_target.shape[:-1], dtype=np.float32)\n            lifting_target_weight = lifting_target_visible\n        else:\n            valid = lifting_target_visible > 0.5\n            lifting_target_weight = np.where(valid, 1., 0.).astype(np.float32)\n\n        if camera_param is None:\n            camera_param = dict()\n\n        encoded = dict()\n\n        assert lifting_target is not None\n        lifting_target_label = lifting_target.copy()\n        keypoint_labels = keypoints.copy()\n\n        assert keypoint_labels.ndim in {\n            2, 3\n        }, (f'Keypoint labels should have 2 or 3 dimensions, '\n            f'but got {keypoint_labels.ndim}.')\n        if keypoint_labels.ndim == 2:\n            keypoint_labels = keypoint_labels[None, ...]\n\n        # Normalize the 2D keypoint coordinate with image width and height\n        _camera_param = deepcopy(camera_param)\n        assert 'w' in _camera_param and 'h' in _camera_param, (\n            'Camera parameters should contain \"w\" and \"h\".')\n        w, h = _camera_param['w'], _camera_param['h']\n        keypoint_labels[\n            ..., :2] = keypoint_labels[..., :2] / w * 2 - [1, h / w]\n\n        # convert target to image coordinate\n        T = keypoint_labels.shape[0]\n        factor_ = np.array([4] * T, dtype=np.float32).reshape(T, )\n        if 'f' in _camera_param and 'c' in _camera_param:\n            lifting_target_label, factor_ = camera_to_image_coord(\n                self.root_index, lifting_target_label, _camera_param)\n        if self.mode == 'train':\n            w, h = w / 1000, h / 1000\n            lifting_target_label[\n                ..., :2] = lifting_target_label[..., :2] / w * 2 - [1, h / w]\n            lifting_target_label[..., 2] = lifting_target_label[..., 2] / w * 2\n        lifting_target_label[..., :, :] = lifting_target_label[\n            ..., :, :] - lifting_target_label[...,\n                                              self.root_index:self.root_index +\n                                              1, :]\n        if factor is None or factor[0] == 0:\n            factor = factor_\n        if factor.ndim == 1:\n            factor = factor[:, None]\n        if self.mode == 'test':\n            lifting_target_label *= factor[..., None]\n\n        if self.concat_vis:\n            keypoints_visible_ = keypoints_visible\n            if keypoints_visible.ndim == 2:\n                keypoints_visible_ = keypoints_visible[..., None]\n            keypoint_labels = np.concatenate(\n                (keypoint_labels, keypoints_visible_), axis=2)\n\n        encoded['keypoint_labels'] = keypoint_labels\n        encoded['keypoint_labels_visible'] = keypoints_visible\n        encoded['lifting_target_label'] = lifting_target_label\n        encoded['lifting_target_weight'] = lifting_target_weight\n        encoded['lifting_target'] = lifting_target_label\n        encoded['lifting_target_visible'] = lifting_target_visible\n        encoded['factor'] = factor\n\n        return encoded\n\n    def decode(\n        self,\n        encoded: np.ndarray,\n        w: Optional[np.ndarray] = None,\n        h: Optional[np.ndarray] = None,\n        factor: Optional[np.ndarray] = None,\n    ) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from normalized space to input image\n        space.\n\n        Args:\n            encoded (np.ndarray): Coordinates in shape (N, K, C).\n            w (np.ndarray, optional): The image widths in shape (N, ).\n                Default: ``None``.\n            h (np.ndarray, optional): The image heights in shape (N, ).\n                Default: ``None``.\n            factor (np.ndarray, optional): The factor for projection in shape\n                (N, ). Default: ``None``.\n\n        Returns:\n            keypoints (np.ndarray): Decoded coordinates in shape (N, K, C).\n            scores (np.ndarray): The keypoint scores in shape (N, K).\n        \"\"\"\n        keypoints = encoded.copy()\n        scores = np.ones(keypoints.shape[:-1], dtype=np.float32)\n\n        if self.rootrel:\n            keypoints[..., 0, :] = 0\n\n        if w is not None and w.size > 0:\n            assert w.shape == h.shape, (f'w and h should have the same shape, '\n                                        f'but got {w.shape} and {h.shape}.')\n            assert w.shape[0] == keypoints.shape[0], (\n                f'w and h should have the same batch size, '\n                f'but got {w.shape[0]} and {keypoints.shape[0]}.')\n            assert w.ndim in {1,\n                              2}, (f'w and h should have 1 or 2 dimensions, '\n                                   f'but got {w.ndim}.')\n            if w.ndim == 1:\n                w = w[:, None]\n                h = h[:, None]\n            trans = np.append(\n                np.ones((w.shape[0], 1)), h / w, axis=1)[:, None, :]\n            keypoints[..., :2] = (keypoints[..., :2] + trans) * w[:, None] / 2\n            keypoints[..., 2:] = keypoints[..., 2:] * w[:, None] / 2\n\n        if factor is not None and factor.size > 0:\n            assert factor.shape[0] == keypoints.shape[0], (\n                f'factor should have the same batch size, '\n                f'but got {factor.shape[0]} and {keypoints.shape[0]}.')\n            keypoints *= factor[..., None]\n\n        keypoints[..., :, :] = keypoints[..., :, :] - keypoints[\n            ..., self.root_index:self.root_index + 1, :]\n        keypoints /= 1000.\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/msra_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils.gaussian_heatmap import (generate_gaussian_heatmaps,\n                                     generate_unbiased_gaussian_heatmaps)\nfrom .utils.post_processing import get_heatmap_maximum\nfrom .utils.refinement import refine_keypoints, refine_keypoints_dark\n\n\n@KEYPOINT_CODECS.register_module()\nclass MSRAHeatmap(BaseKeypointCodec):\n    \"\"\"Represent keypoints as heatmaps via \"MSRA\" approach. See the paper:\n    `Simple Baselines for Human Pose Estimation and Tracking`_ by Xiao et al\n    (2018) for details.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n        - heatmap size: [W, H]\n\n    Encoded:\n\n        - heatmaps (np.ndarray): The generated heatmap in shape (K, H, W)\n            where [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        sigma (float): The sigma value of the Gaussian heatmap\n        unbiased (bool): Whether use unbiased method (DarkPose) in ``'msra'``\n            encoding. See `Dark Pose`_ for details. Defaults to ``False``\n        blur_kernel_size (int): The Gaussian blur kernel size of the heatmap\n            modulation in DarkPose. The kernel size and sigma should follow\n            the expirical formula :math:`sigma = 0.3*((ks-1)*0.5-1)+0.8`.\n            Defaults to 11\n\n    .. _`Simple Baselines for Human Pose Estimation and Tracking`:\n        https://arxiv.org/abs/1804.06208\n    .. _`Dark Pose`: https://arxiv.org/abs/1910.06278\n    \"\"\"\n\n    label_mapping_table = dict(keypoint_weights='keypoint_weights', )\n    field_mapping_table = dict(heatmaps='heatmaps', )\n\n    def __init__(self,\n                 input_size: Tuple[int, int],\n                 heatmap_size: Tuple[int, int],\n                 sigma: float,\n                 unbiased: bool = False,\n                 blur_kernel_size: int = 11) -> None:\n        super().__init__()\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.sigma = sigma\n        self.unbiased = unbiased\n\n        # The Gaussian blur kernel size of the heatmap modulation\n        # in DarkPose and the sigma value follows the expirical\n        # formula :math:`sigma = 0.3*((ks-1)*0.5-1)+0.8`\n        # which gives:\n        #   sigma~=3 if ks=17\n        #   sigma=2 if ks=11;\n        #   sigma~=1.5 if ks=7;\n        #   sigma~=1 if ks=3;\n        self.blur_kernel_size = blur_kernel_size\n        self.scale_factor = (np.array(input_size) /\n                             heatmap_size).astype(np.float32)\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints into heatmaps. Note that the original keypoint\n        coordinates should be in the input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - heatmaps (np.ndarray): The generated heatmap in shape\n                (K, H, W) where [W, H] is the `heatmap_size`\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n\n        assert keypoints.shape[0] == 1, (\n            f'{self.__class__.__name__} only support single-instance '\n            'keypoint encoding')\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        if self.unbiased:\n            heatmaps, keypoint_weights = generate_unbiased_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=keypoints / self.scale_factor,\n                keypoints_visible=keypoints_visible,\n                sigma=self.sigma)\n        else:\n            heatmaps, keypoint_weights = generate_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=keypoints / self.scale_factor,\n                keypoints_visible=keypoints_visible,\n                sigma=self.sigma)\n\n        encoded = dict(heatmaps=heatmaps, keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from heatmaps. The decoded keypoint\n        coordinates are in the input image space.\n\n        Args:\n            encoded (np.ndarray): Heatmaps in shape (K, H, W)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded keypoint coordinates in shape\n                (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K). It\n                usually represents the confidence of the keypoint prediction\n        \"\"\"\n        heatmaps = encoded.copy()\n        K, H, W = heatmaps.shape\n\n        keypoints, scores = get_heatmap_maximum(heatmaps)\n\n        # Unsqueeze the instance dimension for single-instance results\n        keypoints, scores = keypoints[None], scores[None]\n\n        if self.unbiased:\n            # Alleviate biased coordinate\n            keypoints = refine_keypoints_dark(\n                keypoints, heatmaps, blur_kernel_size=self.blur_kernel_size)\n\n        else:\n            keypoints = refine_keypoints(keypoints, heatmaps)\n\n        # Restore the keypoint scale\n        keypoints = keypoints * self.scale_factor\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/regression_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\n\n\n@KEYPOINT_CODECS.register_module()\nclass RegressionLabel(BaseKeypointCodec):\n    r\"\"\"Generate keypoint coordinates.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n\n    Encoded:\n\n        - keypoint_labels (np.ndarray): The normalized regression labels in\n            shape (N, K, D) where D is 2 for 2d coordinates\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Input image size in [w, h]\n\n    \"\"\"\n\n    label_mapping_table = dict(\n        keypoint_labels='keypoint_labels',\n        keypoint_weights='keypoint_weights',\n    )\n\n    def __init__(self, input_size: Tuple[int, int]) -> None:\n        super().__init__()\n\n        self.input_size = input_size\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encoding keypoints from input image space to normalized space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - keypoint_labels (np.ndarray): The normalized regression labels in\n                shape (N, K, D) where D is 2 for 2d coordinates\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        w, h = self.input_size\n        valid = ((keypoints >= 0) &\n                 (keypoints <= [w - 1, h - 1])).all(axis=-1) & (\n                     keypoints_visible > 0.5)\n\n        keypoint_labels = (keypoints / np.array([w, h])).astype(np.float32)\n        keypoint_weights = np.where(valid, 1., 0.).astype(np.float32)\n\n        encoded = dict(\n            keypoint_labels=keypoint_labels, keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from normalized space to input image\n        space.\n\n        Args:\n            encoded (np.ndarray): Coordinates in shape (N, K, D)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded coordinates in shape (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K).\n                It usually represents the confidence of the keypoint prediction\n        \"\"\"\n\n        if encoded.shape[-1] == 2:\n            N, K, _ = encoded.shape\n            normalized_coords = encoded.copy()\n            scores = np.ones((N, K), dtype=np.float32)\n        elif encoded.shape[-1] == 4:\n            # split coords and sigma if outputs contain output_sigma\n            normalized_coords = encoded[..., :2].copy()\n            output_sigma = encoded[..., 2:4].copy()\n\n            scores = (1 - output_sigma).mean(axis=-1)\n        else:\n            raise ValueError(\n                'Keypoint dimension should be 2 or 4 (with sigma), '\n                f'but got {encoded.shape[-1]}')\n\n        w, h = self.input_size\n        keypoints = normalized_coords * np.array([w, h])\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/simcc_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Optional, Tuple, Union\n\nimport numpy as np\n\nfrom mmpose.codecs.utils import get_simcc_maximum\nfrom mmpose.codecs.utils.refinement import refine_simcc_dark\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\n\n\n@KEYPOINT_CODECS.register_module()\nclass SimCCLabel(BaseKeypointCodec):\n    r\"\"\"Generate keypoint representation via \"SimCC\" approach.\n    See the paper: `SimCC: a Simple Coordinate Classification Perspective for\n    Human Pose Estimation`_ by Li et al (2022) for more details.\n    Old name: SimDR\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n\n    Encoded:\n\n        - keypoint_x_labels (np.ndarray): The generated SimCC label for x-axis.\n            The label shape is (N, K, Wx) if ``smoothing_type=='gaussian'``\n            and (N, K) if `smoothing_type=='standard'``, where\n            :math:`Wx=w*simcc_split_ratio`\n        - keypoint_y_labels (np.ndarray): The generated SimCC label for y-axis.\n            The label shape is (N, K, Wy) if ``smoothing_type=='gaussian'``\n            and (N, K) if `smoothing_type=='standard'``, where\n            :math:`Wy=h*simcc_split_ratio`\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Input image size in [w, h]\n        smoothing_type (str): The SimCC label smoothing strategy. Options are\n            ``'gaussian'`` and ``'standard'``. Defaults to ``'gaussian'``\n        sigma (float | int | tuple): The sigma value in the Gaussian SimCC\n            label. Defaults to 6.0\n        simcc_split_ratio (float): The ratio of the label size to the input\n            size. For example, if the input width is ``w``, the x label size\n            will be :math:`w*simcc_split_ratio`. Defaults to 2.0\n        label_smooth_weight (float): Label Smoothing weight. Defaults to 0.0\n        normalize (bool): Whether to normalize the heatmaps. Defaults to True.\n        use_dark (bool): Whether to use the DARK post processing. Defaults to\n            False.\n        decode_visibility (bool): Whether to decode the visibility. Defaults\n            to False.\n        decode_beta (float): The beta value for decoding visibility. Defaults\n            to 150.0.\n\n    .. _`SimCC: a Simple Coordinate Classification Perspective for Human Pose\n    Estimation`: https://arxiv.org/abs/2107.03332\n    \"\"\"\n\n    label_mapping_table = dict(\n        keypoint_x_labels='keypoint_x_labels',\n        keypoint_y_labels='keypoint_y_labels',\n        keypoint_weights='keypoint_weights',\n    )\n\n    def __init__(\n        self,\n        input_size: Tuple[int, int],\n        smoothing_type: str = 'gaussian',\n        sigma: Union[float, int, Tuple[float]] = 6.0,\n        simcc_split_ratio: float = 2.0,\n        label_smooth_weight: float = 0.0,\n        normalize: bool = True,\n        use_dark: bool = False,\n        decode_visibility: bool = False,\n        decode_beta: float = 150.0,\n    ) -> None:\n        super().__init__()\n\n        self.input_size = input_size\n        self.smoothing_type = smoothing_type\n        self.simcc_split_ratio = simcc_split_ratio\n        self.label_smooth_weight = label_smooth_weight\n        self.normalize = normalize\n        self.use_dark = use_dark\n        self.decode_visibility = decode_visibility\n        self.decode_beta = decode_beta\n\n        if isinstance(sigma, (float, int)):\n            self.sigma = np.array([sigma, sigma])\n        else:\n            self.sigma = np.array(sigma)\n\n        if self.smoothing_type not in {'gaussian', 'standard'}:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid `smoothing_type` value'\n                f'{self.smoothing_type}. Should be one of '\n                '{\"gaussian\", \"standard\"}')\n\n        if self.smoothing_type == 'gaussian' and self.label_smooth_weight > 0:\n            raise ValueError('Attribute `label_smooth_weight` is only '\n                             'used for `standard` mode.')\n\n        if self.label_smooth_weight < 0.0 or self.label_smooth_weight > 1.0:\n            raise ValueError('`label_smooth_weight` should be in range [0, 1]')\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encoding keypoints into SimCC labels. Note that the original\n        keypoint coordinates should be in the input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - keypoint_x_labels (np.ndarray): The generated SimCC label for\n                x-axis.\n                The label shape is (N, K, Wx) if ``smoothing_type=='gaussian'``\n                and (N, K) if `smoothing_type=='standard'``, where\n                :math:`Wx=w*simcc_split_ratio`\n            - keypoint_y_labels (np.ndarray): The generated SimCC label for\n                y-axis.\n                The label shape is (N, K, Wy) if ``smoothing_type=='gaussian'``\n                and (N, K) if `smoothing_type=='standard'``, where\n                :math:`Wy=h*simcc_split_ratio`\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        if self.smoothing_type == 'gaussian':\n            x_labels, y_labels, keypoint_weights = self._generate_gaussian(\n                keypoints, keypoints_visible)\n        elif self.smoothing_type == 'standard':\n            x_labels, y_labels, keypoint_weights = self._generate_standard(\n                keypoints, keypoints_visible)\n        else:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid `smoothing_type` value'\n                f'{self.smoothing_type}. Should be one of '\n                '{\"gaussian\", \"standard\"}')\n\n        encoded = dict(\n            keypoint_x_labels=x_labels,\n            keypoint_y_labels=y_labels,\n            keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def decode(self, simcc_x: np.ndarray,\n               simcc_y: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from SimCC representations. The decoded\n        coordinates are in the input image space.\n\n        Args:\n            encoded (Tuple[np.ndarray, np.ndarray]): SimCC labels for x-axis\n                and y-axis\n            simcc_x (np.ndarray): SimCC label for x-axis\n            simcc_y (np.ndarray): SimCC label for y-axis\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded coordinates in shape (N, K, D)\n            - socres (np.ndarray): The keypoint scores in shape (N, K).\n                It usually represents the confidence of the keypoint prediction\n        \"\"\"\n\n        keypoints, scores = get_simcc_maximum(simcc_x, simcc_y)\n\n        # Unsqueeze the instance dimension for single-instance results\n        if keypoints.ndim == 2:\n            keypoints = keypoints[None, :]\n            scores = scores[None, :]\n\n        if self.use_dark:\n            x_blur = int((self.sigma[0] * 20 - 7) // 3)\n            y_blur = int((self.sigma[1] * 20 - 7) // 3)\n            x_blur -= int((x_blur % 2) == 0)\n            y_blur -= int((y_blur % 2) == 0)\n            keypoints[:, :, 0] = refine_simcc_dark(keypoints[:, :, 0], simcc_x,\n                                                   x_blur)\n            keypoints[:, :, 1] = refine_simcc_dark(keypoints[:, :, 1], simcc_y,\n                                                   y_blur)\n\n        keypoints /= self.simcc_split_ratio\n\n        if self.decode_visibility:\n            _, visibility = get_simcc_maximum(\n                simcc_x * self.decode_beta * self.sigma[0],\n                simcc_y * self.decode_beta * self.sigma[1],\n                apply_softmax=True)\n            return keypoints, (scores, visibility)\n        else:\n            return keypoints, scores\n\n    def _map_coordinates(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None\n    ) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Mapping keypoint coordinates into SimCC space.\"\"\"\n\n        keypoints_split = keypoints.copy()\n        keypoints_split = np.around(keypoints_split * self.simcc_split_ratio)\n        keypoints_split = keypoints_split.astype(np.int64)\n        keypoint_weights = keypoints_visible.copy()\n\n        return keypoints_split, keypoint_weights\n\n    def _generate_standard(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None\n    ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:\n        \"\"\"Encoding keypoints into SimCC labels with Standard Label Smoothing\n        strategy.\n\n        Labels will be one-hot vectors if self.label_smooth_weight==0.0\n        \"\"\"\n\n        N, K, _ = keypoints.shape\n        w, h = self.input_size\n        W = np.around(w * self.simcc_split_ratio).astype(int)\n        H = np.around(h * self.simcc_split_ratio).astype(int)\n\n        keypoints_split, keypoint_weights = self._map_coordinates(\n            keypoints, keypoints_visible)\n\n        target_x = np.zeros((N, K, W), dtype=np.float32)\n        target_y = np.zeros((N, K, H), dtype=np.float32)\n\n        for n, k in product(range(N), range(K)):\n            # skip unlabled keypoints\n            if keypoints_visible[n, k] < 0.5:\n                continue\n\n            # get center coordinates\n            mu_x, mu_y = keypoints_split[n, k].astype(np.int64)\n\n            # detect abnormal coords and assign the weight 0\n            if mu_x >= W or mu_y >= H or mu_x < 0 or mu_y < 0:\n                keypoint_weights[n, k] = 0\n                continue\n\n            if self.label_smooth_weight > 0:\n                target_x[n, k] = self.label_smooth_weight / (W - 1)\n                target_y[n, k] = self.label_smooth_weight / (H - 1)\n\n            target_x[n, k, mu_x] = 1.0 - self.label_smooth_weight\n            target_y[n, k, mu_y] = 1.0 - self.label_smooth_weight\n\n        return target_x, target_y, keypoint_weights\n\n    def _generate_gaussian(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None\n    ) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:\n        \"\"\"Encoding keypoints into SimCC labels with Gaussian Label Smoothing\n        strategy.\"\"\"\n\n        N, K, _ = keypoints.shape\n        w, h = self.input_size\n        W = np.around(w * self.simcc_split_ratio).astype(int)\n        H = np.around(h * self.simcc_split_ratio).astype(int)\n\n        keypoints_split, keypoint_weights = self._map_coordinates(\n            keypoints, keypoints_visible)\n\n        target_x = np.zeros((N, K, W), dtype=np.float32)\n        target_y = np.zeros((N, K, H), dtype=np.float32)\n\n        # 3-sigma rule\n        radius = self.sigma * 3\n\n        # xy grid\n        x = np.arange(0, W, 1, dtype=np.float32)\n        y = np.arange(0, H, 1, dtype=np.float32)\n\n        for n, k in product(range(N), range(K)):\n            # skip unlabled keypoints\n            if keypoints_visible[n, k] < 0.5:\n                continue\n\n            mu = keypoints_split[n, k]\n\n            # check that the gaussian has in-bounds part\n            left, top = mu - radius\n            right, bottom = mu + radius + 1\n\n            if left >= W or top >= H or right < 0 or bottom < 0:\n                keypoint_weights[n, k] = 0\n                continue\n\n            mu_x, mu_y = mu\n\n            target_x[n, k] = np.exp(-((x - mu_x)**2) / (2 * self.sigma[0]**2))\n            target_y[n, k] = np.exp(-((y - mu_y)**2) / (2 * self.sigma[1]**2))\n\n        if self.normalize:\n            norm_value = self.sigma * np.sqrt(np.pi * 2)\n            target_x /= norm_value[0]\n            target_y /= norm_value[1]\n\n        return target_x, target_y, keypoint_weights\n"
  },
  {
    "path": "mmpose/codecs/spr.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple, Union\n\nimport numpy as np\nimport torch\nfrom torch import Tensor\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils import (batch_heatmap_nms, generate_displacement_heatmap,\n                    generate_gaussian_heatmaps, get_diagonal_lengths,\n                    get_instance_root)\n\n\n@KEYPOINT_CODECS.register_module()\nclass SPR(BaseKeypointCodec):\n    \"\"\"Encode/decode keypoints with Structured Pose Representation (SPR).\n\n    See the paper `Single-stage multi-person pose machines`_\n    by Nie et al (2017) for details\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n        - heatmap size: [W, H]\n\n    Encoded:\n\n        - heatmaps (np.ndarray): The generated heatmap in shape (1, H, W)\n            where [W, H] is the `heatmap_size`. If the keypoint heatmap is\n            generated together, the output heatmap shape is (K+1, H, W)\n        - heatmap_weights (np.ndarray): The target weights for heatmaps which\n            has same shape with heatmaps.\n        - displacements (np.ndarray): The dense keypoint displacement in\n            shape (K*2, H, W).\n        - displacement_weights (np.ndarray): The target weights for heatmaps\n            which has same shape with displacements.\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        sigma (float or tuple, optional): The sigma values of the Gaussian\n            heatmaps. If sigma is a tuple, it includes both sigmas for root\n            and keypoint heatmaps. ``None`` means the sigmas are computed\n            automatically from the heatmap size. Defaults to ``None``\n        generate_keypoint_heatmaps (bool): Whether to generate Gaussian\n            heatmaps for each keypoint. Defaults to ``False``\n        root_type (str): The method to generate the instance root. Options\n            are:\n\n            - ``'kpt_center'``: Average coordinate of all visible keypoints.\n            - ``'bbox_center'``: Center point of bounding boxes outlined by\n                all visible keypoints.\n\n            Defaults to ``'kpt_center'``\n\n        minimal_diagonal_length (int or float): The threshold of diagonal\n            length of instance bounding box. Small instances will not be\n            used in training. Defaults to 32\n        background_weight (float): Loss weight of background pixels.\n            Defaults to 0.1\n        decode_thr (float): The threshold of keypoint response value in\n            heatmaps. Defaults to 0.01\n        decode_nms_kernel (int): The kernel size of the NMS during decoding,\n            which should be an odd integer. Defaults to 5\n        decode_max_instances (int): The maximum number of instances\n            to decode. Defaults to 30\n\n    .. _`Single-stage multi-person pose machines`:\n        https://arxiv.org/abs/1908.09220\n    \"\"\"\n\n    field_mapping_table = dict(\n        heatmaps='heatmaps',\n        heatmap_weights='heatmap_weights',\n        displacements='displacements',\n        displacement_weights='displacement_weights',\n    )\n\n    def __init__(\n        self,\n        input_size: Tuple[int, int],\n        heatmap_size: Tuple[int, int],\n        sigma: Optional[Union[float, Tuple[float]]] = None,\n        generate_keypoint_heatmaps: bool = False,\n        root_type: str = 'kpt_center',\n        minimal_diagonal_length: Union[int, float] = 5,\n        background_weight: float = 0.1,\n        decode_nms_kernel: int = 5,\n        decode_max_instances: int = 30,\n        decode_thr: float = 0.01,\n    ):\n        super().__init__()\n\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.generate_keypoint_heatmaps = generate_keypoint_heatmaps\n        self.root_type = root_type\n        self.minimal_diagonal_length = minimal_diagonal_length\n        self.background_weight = background_weight\n        self.decode_nms_kernel = decode_nms_kernel\n        self.decode_max_instances = decode_max_instances\n        self.decode_thr = decode_thr\n\n        self.scale_factor = (np.array(input_size) /\n                             heatmap_size).astype(np.float32)\n\n        if sigma is None:\n            sigma = (heatmap_size[0] * heatmap_size[1])**0.5 / 32\n            if generate_keypoint_heatmaps:\n                # sigma for root heatmap and keypoint heatmaps\n                self.sigma = (sigma, sigma // 2)\n            else:\n                self.sigma = (sigma, )\n        else:\n            if not isinstance(sigma, (tuple, list)):\n                sigma = (sigma, )\n            if generate_keypoint_heatmaps:\n                assert len(sigma) == 2, 'sigma for keypoints must be given ' \\\n                                        'if `generate_keypoint_heatmaps` ' \\\n                                        'is True. e.g. sigma=(4, 2)'\n            self.sigma = sigma\n\n    def _get_heatmap_weights(self,\n                             heatmaps,\n                             fg_weight: float = 1,\n                             bg_weight: float = 0):\n        \"\"\"Generate weight array for heatmaps.\n\n        Args:\n            heatmaps (np.ndarray): Root and keypoint (optional) heatmaps\n            fg_weight (float): Weight for foreground pixels. Defaults to 1.0\n            bg_weight (float): Weight for background pixels. Defaults to 0.0\n\n        Returns:\n            np.ndarray: Heatmap weight array in the same shape with heatmaps\n        \"\"\"\n        heatmap_weights = np.ones(heatmaps.shape, dtype=np.float32) * bg_weight\n        heatmap_weights[heatmaps > 0] = fg_weight\n        return heatmap_weights\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints into root heatmaps and keypoint displacement\n        fields. Note that the original keypoint coordinates should be in the\n        input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - heatmaps (np.ndarray): The generated heatmap in shape\n                (1, H, W) where [W, H] is the `heatmap_size`. If keypoint\n                heatmaps are generated together, the shape is (K+1, H, W)\n            - heatmap_weights (np.ndarray): The pixel-wise weight for heatmaps\n                 which has same shape with `heatmaps`\n            - displacements (np.ndarray): The generated displacement fields in\n                shape (K*D, H, W). The vector on each pixels represents the\n                displacement of keypoints belong to the associated instance\n                from this pixel.\n            - displacement_weights (np.ndarray): The pixel-wise weight for\n                displacements which has same shape with `displacements`\n        \"\"\"\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        # keypoint coordinates in heatmap\n        _keypoints = keypoints / self.scale_factor\n\n        # compute the root and scale of each instance\n        roots, roots_visible = get_instance_root(_keypoints, keypoints_visible,\n                                                 self.root_type)\n        diagonal_lengths = get_diagonal_lengths(_keypoints, keypoints_visible)\n\n        # discard the small instances\n        roots_visible[diagonal_lengths < self.minimal_diagonal_length] = 0\n\n        # generate heatmaps\n        heatmaps, _ = generate_gaussian_heatmaps(\n            heatmap_size=self.heatmap_size,\n            keypoints=roots[:, None],\n            keypoints_visible=roots_visible[:, None],\n            sigma=self.sigma[0])\n        heatmap_weights = self._get_heatmap_weights(\n            heatmaps, bg_weight=self.background_weight)\n\n        if self.generate_keypoint_heatmaps:\n            keypoint_heatmaps, _ = generate_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=_keypoints,\n                keypoints_visible=keypoints_visible,\n                sigma=self.sigma[1])\n\n            keypoint_heatmaps_weights = self._get_heatmap_weights(\n                keypoint_heatmaps, bg_weight=self.background_weight)\n\n            heatmaps = np.concatenate((keypoint_heatmaps, heatmaps), axis=0)\n            heatmap_weights = np.concatenate(\n                (keypoint_heatmaps_weights, heatmap_weights), axis=0)\n\n        # generate displacements\n        displacements, displacement_weights = \\\n            generate_displacement_heatmap(\n                self.heatmap_size,\n                _keypoints,\n                keypoints_visible,\n                roots,\n                roots_visible,\n                diagonal_lengths,\n                self.sigma[0],\n            )\n\n        encoded = dict(\n            heatmaps=heatmaps,\n            heatmap_weights=heatmap_weights,\n            displacements=displacements,\n            displacement_weights=displacement_weights)\n\n        return encoded\n\n    def decode(self, heatmaps: Tensor,\n               displacements: Tensor) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode the keypoint coordinates from heatmaps and displacements. The\n        decoded keypoint coordinates are in the input image space.\n\n        Args:\n            heatmaps (Tensor): Encoded root and keypoints (optional) heatmaps\n                in shape (1, H, W) or (K+1, H, W)\n            displacements (Tensor): Encoded keypoints displacement fields\n                in shape (K*D, H, W)\n\n        Returns:\n            tuple:\n            - keypoints (Tensor): Decoded keypoint coordinates in shape\n                (N, K, D)\n            - scores (tuple):\n                - root_scores (Tensor): The root scores in shape (N, )\n                - keypoint_scores (Tensor): The keypoint scores in\n                    shape (N, K). If keypoint heatmaps are not generated,\n                    `keypoint_scores` will be `None`\n        \"\"\"\n        # heatmaps, displacements = encoded\n        _k, h, w = displacements.shape\n        k = _k // 2\n        displacements = displacements.view(k, 2, h, w)\n\n        # convert displacements to a dense keypoint prediction\n        y, x = torch.meshgrid(torch.arange(h), torch.arange(w))\n        regular_grid = torch.stack([x, y], dim=0).to(displacements)\n        posemaps = (regular_grid[None] + displacements).flatten(2)\n\n        # find local maximum on root heatmap\n        root_heatmap_peaks = batch_heatmap_nms(heatmaps[None, -1:],\n                                               self.decode_nms_kernel)\n        root_scores, pos_idx = root_heatmap_peaks.flatten().topk(\n            self.decode_max_instances)\n        mask = root_scores > self.decode_thr\n        root_scores, pos_idx = root_scores[mask], pos_idx[mask]\n\n        keypoints = posemaps[:, :, pos_idx].permute(2, 0, 1).contiguous()\n\n        if self.generate_keypoint_heatmaps and heatmaps.shape[0] == 1 + k:\n            # compute scores for each keypoint\n            keypoint_scores = self.get_keypoint_scores(heatmaps[:k], keypoints)\n        else:\n            keypoint_scores = None\n\n        keypoints = torch.cat([\n            kpt * self.scale_factor[i]\n            for i, kpt in enumerate(keypoints.split(1, -1))\n        ],\n                              dim=-1)\n        return keypoints, (root_scores, keypoint_scores)\n\n    def get_keypoint_scores(self, heatmaps: Tensor, keypoints: Tensor):\n        \"\"\"Calculate the keypoint scores with keypoints heatmaps and\n        coordinates.\n\n        Args:\n            heatmaps (Tensor): Keypoint heatmaps in shape (K, H, W)\n            keypoints (Tensor): Keypoint coordinates in shape (N, K, D)\n\n        Returns:\n            Tensor: Keypoint scores in [N, K]\n        \"\"\"\n        k, h, w = heatmaps.shape\n        keypoints = torch.stack((\n            keypoints[..., 0] / (w - 1) * 2 - 1,\n            keypoints[..., 1] / (h - 1) * 2 - 1,\n        ),\n                                dim=-1)\n        keypoints = keypoints.transpose(0, 1).unsqueeze(1).contiguous()\n\n        keypoint_scores = torch.nn.functional.grid_sample(\n            heatmaps.unsqueeze(1), keypoints,\n            padding_mode='border').view(k, -1).transpose(0, 1).contiguous()\n\n        return keypoint_scores\n"
  },
  {
    "path": "mmpose/codecs/udp_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport cv2\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\nfrom .utils import (generate_offset_heatmap, generate_udp_gaussian_heatmaps,\n                    get_heatmap_maximum, refine_keypoints_dark_udp)\n\n\n@KEYPOINT_CODECS.register_module()\nclass UDPHeatmap(BaseKeypointCodec):\n    r\"\"\"Generate keypoint heatmaps by Unbiased Data Processing (UDP).\n    See the paper: `The Devil is in the Details: Delving into Unbiased Data\n    Processing for Human Pose Estimation`_ by Huang et al (2020) for details.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n        - heatmap size: [W, H]\n\n    Encoded:\n\n        - heatmap (np.ndarray): The generated heatmap in shape (C_out, H, W)\n            where [W, H] is the `heatmap_size`, and the C_out is the output\n            channel number which depends on the `heatmap_type`. If\n            `heatmap_type=='gaussian'`, C_out equals to keypoint number K;\n            if `heatmap_type=='combined'`, C_out equals to K*3\n            (x_offset, y_offset and class label)\n        - keypoint_weights (np.ndarray): The target weights in shape (K,)\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        heatmap_type (str): The heatmap type to encode the keypoitns. Options\n            are:\n\n            - ``'gaussian'``: Gaussian heatmap\n            - ``'combined'``: Combination of a binary label map and offset\n                maps for X and Y axes.\n\n        sigma (float): The sigma value of the Gaussian heatmap when\n            ``heatmap_type=='gaussian'``. Defaults to 2.0\n        radius_factor (float): The radius factor of the binary label\n            map when ``heatmap_type=='combined'``. The positive region is\n            defined as the neighbor of the keypoit with the radius\n            :math:`r=radius_factor*max(W, H)`. Defaults to 0.0546875\n        blur_kernel_size (int): The Gaussian blur kernel size of the heatmap\n            modulation in DarkPose. Defaults to 11\n\n    .. _`The Devil is in the Details: Delving into Unbiased Data Processing for\n    Human Pose Estimation`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n\n    label_mapping_table = dict(keypoint_weights='keypoint_weights', )\n    field_mapping_table = dict(heatmaps='heatmaps', )\n\n    def __init__(self,\n                 input_size: Tuple[int, int],\n                 heatmap_size: Tuple[int, int],\n                 heatmap_type: str = 'gaussian',\n                 sigma: float = 2.,\n                 radius_factor: float = 0.0546875,\n                 blur_kernel_size: int = 11) -> None:\n        super().__init__()\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.sigma = sigma\n        self.radius_factor = radius_factor\n        self.heatmap_type = heatmap_type\n        self.blur_kernel_size = blur_kernel_size\n        self.scale_factor = ((np.array(input_size) - 1) /\n                             (np.array(heatmap_size) - 1)).astype(np.float32)\n\n        if self.heatmap_type not in {'gaussian', 'combined'}:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid `heatmap_type` value'\n                f'{self.heatmap_type}. Should be one of '\n                '{\"gaussian\", \"combined\"}')\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints into heatmaps. Note that the original keypoint\n        coordinates should be in the input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - heatmap (np.ndarray): The generated heatmap in shape\n                (C_out, H, W) where [W, H] is the `heatmap_size`, and the\n                C_out is the output channel number which depends on the\n                `heatmap_type`. If `heatmap_type=='gaussian'`, C_out equals to\n                keypoint number K; if `heatmap_type=='combined'`, C_out\n                equals to K*3 (x_offset, y_offset and class label)\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (K,)\n        \"\"\"\n        assert keypoints.shape[0] == 1, (\n            f'{self.__class__.__name__} only support single-instance '\n            'keypoint encoding')\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        if self.heatmap_type == 'gaussian':\n            heatmaps, keypoint_weights = generate_udp_gaussian_heatmaps(\n                heatmap_size=self.heatmap_size,\n                keypoints=keypoints / self.scale_factor,\n                keypoints_visible=keypoints_visible,\n                sigma=self.sigma)\n        elif self.heatmap_type == 'combined':\n            heatmaps, keypoint_weights = generate_offset_heatmap(\n                heatmap_size=self.heatmap_size,\n                keypoints=keypoints / self.scale_factor,\n                keypoints_visible=keypoints_visible,\n                radius_factor=self.radius_factor)\n        else:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid `heatmap_type` value'\n                f'{self.heatmap_type}. Should be one of '\n                '{\"gaussian\", \"combined\"}')\n\n        encoded = dict(heatmaps=heatmaps, keypoint_weights=keypoint_weights)\n\n        return encoded\n\n    def decode(self, encoded: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from heatmaps. The decoded keypoint\n        coordinates are in the input image space.\n\n        Args:\n            encoded (np.ndarray): Heatmaps in shape (K, H, W)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded keypoint coordinates in shape\n                (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K). It\n                usually represents the confidence of the keypoint prediction\n        \"\"\"\n        heatmaps = encoded.copy()\n\n        if self.heatmap_type == 'gaussian':\n            keypoints, scores = get_heatmap_maximum(heatmaps)\n            # unsqueeze the instance dimension for single-instance results\n            keypoints = keypoints[None]\n            scores = scores[None]\n\n            keypoints = refine_keypoints_dark_udp(\n                keypoints, heatmaps, blur_kernel_size=self.blur_kernel_size)\n\n        elif self.heatmap_type == 'combined':\n            _K, H, W = heatmaps.shape\n            K = _K // 3\n\n            for cls_heatmap in heatmaps[::3]:\n                # Apply Gaussian blur on classification maps\n                ks = 2 * self.blur_kernel_size + 1\n                cv2.GaussianBlur(cls_heatmap, (ks, ks), 0, cls_heatmap)\n\n            # valid radius\n            radius = self.radius_factor * max(W, H)\n\n            x_offset = heatmaps[1::3].flatten() * radius\n            y_offset = heatmaps[2::3].flatten() * radius\n            keypoints, scores = get_heatmap_maximum(heatmaps=heatmaps[::3])\n            index = (keypoints[..., 0] + keypoints[..., 1] * W).flatten()\n            index += W * H * np.arange(0, K)\n            index = index.astype(int)\n            keypoints += np.stack((x_offset[index], y_offset[index]), axis=-1)\n            # unsqueeze the instance dimension for single-instance results\n            keypoints = keypoints[None].astype(np.float32)\n            scores = scores[None]\n\n        W, H = self.heatmap_size\n        keypoints = keypoints / [W - 1, H - 1] * self.input_size\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/codecs/utils/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .camera_image_projection import (camera_to_image_coord, camera_to_pixel,\n                                      pixel_to_camera)\nfrom .gaussian_heatmap import (generate_3d_gaussian_heatmaps,\n                               generate_gaussian_heatmaps,\n                               generate_udp_gaussian_heatmaps,\n                               generate_unbiased_gaussian_heatmaps)\nfrom .instance_property import (get_diagonal_lengths, get_instance_bbox,\n                                get_instance_root)\nfrom .offset_heatmap import (generate_displacement_heatmap,\n                             generate_offset_heatmap)\nfrom .post_processing import (batch_heatmap_nms, gaussian_blur,\n                              gaussian_blur1d, get_heatmap_3d_maximum,\n                              get_heatmap_maximum, get_simcc_maximum,\n                              get_simcc_normalized)\nfrom .refinement import (refine_keypoints, refine_keypoints_dark,\n                         refine_keypoints_dark_udp, refine_simcc_dark)\n\n__all__ = [\n    'generate_gaussian_heatmaps', 'generate_udp_gaussian_heatmaps',\n    'generate_unbiased_gaussian_heatmaps', 'gaussian_blur',\n    'get_heatmap_maximum', 'get_simcc_maximum', 'generate_offset_heatmap',\n    'batch_heatmap_nms', 'refine_keypoints', 'refine_keypoints_dark',\n    'refine_keypoints_dark_udp', 'generate_displacement_heatmap',\n    'refine_simcc_dark', 'gaussian_blur1d', 'get_diagonal_lengths',\n    'get_instance_root', 'get_instance_bbox', 'get_simcc_normalized',\n    'camera_to_image_coord', 'camera_to_pixel', 'pixel_to_camera',\n    'get_heatmap_3d_maximum', 'generate_3d_gaussian_heatmaps'\n]\n"
  },
  {
    "path": "mmpose/codecs/utils/camera_image_projection.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, Tuple\n\nimport numpy as np\n\n\ndef camera_to_image_coord(root_index: int, kpts_3d_cam: np.ndarray,\n                          camera_param: Dict) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Project keypoints from camera space to image space and calculate factor.\n\n    Args:\n        root_index (int): Index for root keypoint.\n        kpts_3d_cam (np.ndarray): Keypoint coordinates in camera space in\n            shape (N, K, D).\n        camera_param (dict): Parameters for the camera.\n\n    Returns:\n        tuple:\n        - kpts_3d_image (np.ndarray): Keypoint coordinates in image space in\n            shape (N, K, D).\n        - factor (np.ndarray): The scaling factor that maps keypoints from\n            image space to camera space in shape (N, ).\n    \"\"\"\n\n    root = kpts_3d_cam[..., root_index, :]\n    tl_kpt = root.copy()\n    tl_kpt[..., :2] -= 1.0\n    br_kpt = root.copy()\n    br_kpt[..., :2] += 1.0\n    tl_kpt = np.reshape(tl_kpt, (-1, 3))\n    br_kpt = np.reshape(br_kpt, (-1, 3))\n    fx, fy = camera_param['f'] / 1000.\n    cx, cy = camera_param['c'] / 1000.\n\n    tl2d = camera_to_pixel(tl_kpt, fx, fy, cx, cy)\n    br2d = camera_to_pixel(br_kpt, fx, fy, cx, cy)\n\n    rectangle_3d_size = 2.0\n    kpts_3d_image = np.zeros_like(kpts_3d_cam)\n    kpts_3d_image[..., :2] = camera_to_pixel(kpts_3d_cam.copy(), fx, fy, cx,\n                                             cy)\n    ratio = (br2d[..., 0] - tl2d[..., 0] + 0.001) / rectangle_3d_size\n    factor = rectangle_3d_size / (br2d[..., 0] - tl2d[..., 0] + 0.001)\n    kpts_3d_depth = ratio[:, None] * (\n        kpts_3d_cam[..., 2] - kpts_3d_cam[..., root_index:root_index + 1, 2])\n    kpts_3d_image[..., 2] = kpts_3d_depth\n    return kpts_3d_image, factor\n\n\ndef camera_to_pixel(kpts_3d: np.ndarray,\n                    fx: float,\n                    fy: float,\n                    cx: float,\n                    cy: float,\n                    shift: bool = False) -> np.ndarray:\n    \"\"\"Project keypoints from camera space to image space.\n\n    Args:\n        kpts_3d (np.ndarray): Keypoint coordinates in camera space.\n        fx (float): x-coordinate of camera's focal length.\n        fy (float): y-coordinate of camera's focal length.\n        cx (float): x-coordinate of image center.\n        cy (float): y-coordinate of image center.\n        shift (bool): Whether to shift the coordinates by 1e-8.\n\n    Returns:\n        pose_2d (np.ndarray): Projected keypoint coordinates in image space.\n    \"\"\"\n    if not shift:\n        pose_2d = kpts_3d[..., :2] / kpts_3d[..., 2:3]\n    else:\n        pose_2d = kpts_3d[..., :2] / (kpts_3d[..., 2:3] + 1e-8)\n    pose_2d[..., 0] *= fx\n    pose_2d[..., 1] *= fy\n    pose_2d[..., 0] += cx\n    pose_2d[..., 1] += cy\n    return pose_2d\n\n\ndef pixel_to_camera(kpts_3d: np.ndarray, fx: float, fy: float, cx: float,\n                    cy: float) -> np.ndarray:\n    \"\"\"Project keypoints from camera space to image space.\n\n    Args:\n        kpts_3d (np.ndarray): Keypoint coordinates in camera space.\n        fx (float): x-coordinate of camera's focal length.\n        fy (float): y-coordinate of camera's focal length.\n        cx (float): x-coordinate of image center.\n        cy (float): y-coordinate of image center.\n        shift (bool): Whether to shift the coordinates by 1e-8.\n\n    Returns:\n        pose_2d (np.ndarray): Projected keypoint coordinates in image space.\n    \"\"\"\n    pose_2d = kpts_3d.copy()\n    pose_2d[..., 0] -= cx\n    pose_2d[..., 1] -= cy\n    pose_2d[..., 0] /= fx\n    pose_2d[..., 1] /= fy\n    pose_2d[..., 0] *= kpts_3d[..., 2]\n    pose_2d[..., 1] *= kpts_3d[..., 2]\n    return pose_2d\n"
  },
  {
    "path": "mmpose/codecs/utils/gaussian_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Optional, Tuple, Union\n\nimport numpy as np\n\n\ndef generate_3d_gaussian_heatmaps(\n    heatmap_size: Tuple[int, int, int],\n    keypoints: np.ndarray,\n    keypoints_visible: np.ndarray,\n    sigma: Union[float, Tuple[float], np.ndarray],\n    image_size: Tuple[int, int],\n    heatmap3d_depth_bound: float = 400.0,\n    joint_indices: Optional[list] = None,\n    max_bound: float = 1.0,\n    use_different_joint_weights: bool = False,\n    dataset_keypoint_weights: Optional[np.ndarray] = None\n) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Generate 3d gaussian heatmaps of keypoints.\n\n    Args:\n        heatmap_size (Tuple[int, int]): Heatmap size in [W, H, D]\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, C)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n        sigma (float or List[float]): A list of sigma values of the Gaussian\n            heatmap for each instance. If sigma is given as a single float\n            value, it will be expanded into a tuple\n        image_size (Tuple[int, int]): Size of input image.\n        heatmap3d_depth_bound (float): Boundary for 3d heatmap depth.\n            Default: 400.0.\n        joint_indices (List[int], optional): Indices of joints used for heatmap\n            generation. If None (default) is given, all joints will be used.\n            Default: ``None``.\n        max_bound (float): The maximal value of heatmap. Default: 1.0.\n        use_different_joint_weights (bool): Whether to use different joint\n            weights. Default: ``False``.\n        dataset_keypoint_weights (np.ndarray, optional): Keypoints weight in\n            shape (K, ).\n\n    Returns:\n        tuple:\n        - heatmaps (np.ndarray): The generated heatmap in shape\n            (K * D, H, W) where [W, H, D] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (N, K)\n    \"\"\"\n\n    W, H, D = heatmap_size\n\n    # select the joints used for target generation\n    if joint_indices is not None:\n        keypoints = keypoints[:, joint_indices, ...]\n        keypoints_visible = keypoints_visible[:, joint_indices, ...]\n    N, K, _ = keypoints.shape\n\n    heatmaps = np.zeros([K, D, H, W], dtype=np.float32)\n    keypoint_weights = keypoints_visible.copy()\n\n    if isinstance(sigma, (int, float)):\n        sigma = (sigma, ) * N\n\n    for n in range(N):\n        # 3-sigma rule\n        radius = sigma[n] * 3\n\n        # joint location in heatmap coordinates\n        mu_x = keypoints[n, :, 0] * W / image_size[0]  # (K, )\n        mu_y = keypoints[n, :, 1] * H / image_size[1]\n        mu_z = (keypoints[n, :, 2] / heatmap3d_depth_bound + 0.5) * D\n\n        keypoint_weights[n, ...] = keypoint_weights[n, ...] * (mu_z >= 0) * (\n            mu_z < D)\n        if use_different_joint_weights:\n            keypoint_weights[\n                n] = keypoint_weights[n] * dataset_keypoint_weights\n        # xy grid\n        gaussian_size = 2 * radius + 1\n\n        # get neighboring voxels coordinates\n        x = y = z = np.arange(gaussian_size, dtype=np.float32) - radius\n        zz, yy, xx = np.meshgrid(z, y, x)\n\n        xx = np.expand_dims(xx, axis=0)\n        yy = np.expand_dims(yy, axis=0)\n        zz = np.expand_dims(zz, axis=0)\n        mu_x = np.expand_dims(mu_x, axis=(-1, -2, -3))\n        mu_y = np.expand_dims(mu_y, axis=(-1, -2, -3))\n        mu_z = np.expand_dims(mu_z, axis=(-1, -2, -3))\n\n        xx, yy, zz = xx + mu_x, yy + mu_y, zz + mu_z\n        local_size = xx.shape[1]\n\n        # round the coordinates\n        xx = xx.round().clip(0, W - 1)\n        yy = yy.round().clip(0, H - 1)\n        zz = zz.round().clip(0, D - 1)\n\n        # compute the target value near joints\n        gaussian = np.exp(-((xx - mu_x)**2 + (yy - mu_y)**2 + (zz - mu_z)**2) /\n                          (2 * sigma[n]**2))\n\n        # put the local target value to the full target heatmap\n        idx_joints = np.tile(\n            np.expand_dims(np.arange(K), axis=(-1, -2, -3)),\n            [1, local_size, local_size, local_size])\n        idx = np.stack([idx_joints, zz, yy, xx],\n                       axis=-1).astype(int).reshape(-1, 4)\n\n        heatmaps[idx[:, 0], idx[:, 1], idx[:, 2], idx[:, 3]] = np.maximum(\n            heatmaps[idx[:, 0], idx[:, 1], idx[:, 2], idx[:, 3]],\n            gaussian.reshape(-1))\n\n    heatmaps = (heatmaps * max_bound).reshape(-1, H, W)\n\n    return heatmaps, keypoint_weights\n\n\ndef generate_gaussian_heatmaps(\n    heatmap_size: Tuple[int, int],\n    keypoints: np.ndarray,\n    keypoints_visible: np.ndarray,\n    sigma: Union[float, Tuple[float], np.ndarray],\n) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Generate gaussian heatmaps of keypoints.\n\n    Args:\n        heatmap_size (Tuple[int, int]): Heatmap size in [W, H]\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n        sigma (float or List[float]): A list of sigma values of the Gaussian\n            heatmap for each instance. If sigma is given as a single float\n            value, it will be expanded into a tuple\n\n    Returns:\n        tuple:\n        - heatmaps (np.ndarray): The generated heatmap in shape\n            (K, H, W) where [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (N, K)\n    \"\"\"\n\n    N, K, _ = keypoints.shape\n    W, H = heatmap_size\n\n    heatmaps = np.zeros((K, H, W), dtype=np.float32)\n    keypoint_weights = keypoints_visible.copy()\n\n    if isinstance(sigma, (int, float)):\n        sigma = (sigma, ) * N\n\n    for n in range(N):\n        # 3-sigma rule\n        radius = sigma[n] * 3\n\n        # xy grid\n        gaussian_size = 2 * radius + 1\n        x = np.arange(0, gaussian_size, 1, dtype=np.float32)\n        y = x[:, None]\n        x0 = y0 = gaussian_size // 2\n\n        for k in range(K):\n            # skip unlabled keypoints\n            if keypoints_visible[n, k] < 0.5:\n                continue\n\n            # get gaussian center coordinates\n            mu = (keypoints[n, k] + 0.5).astype(np.int64)\n\n            # check that the gaussian has in-bounds part\n            left, top = (mu - radius).astype(np.int64)\n            right, bottom = (mu + radius + 1).astype(np.int64)\n\n            if left >= W or top >= H or right < 0 or bottom < 0:\n                keypoint_weights[n, k] = 0\n                continue\n\n            # The gaussian is not normalized,\n            # we want the center value to equal 1\n            gaussian = np.exp(-((x - x0)**2 + (y - y0)**2) / (2 * sigma[n]**2))\n\n            # valid range in gaussian\n            g_x1 = max(0, -left)\n            g_x2 = min(W, right) - left\n            g_y1 = max(0, -top)\n            g_y2 = min(H, bottom) - top\n\n            # valid range in heatmap\n            h_x1 = max(0, left)\n            h_x2 = min(W, right)\n            h_y1 = max(0, top)\n            h_y2 = min(H, bottom)\n\n            heatmap_region = heatmaps[k, h_y1:h_y2, h_x1:h_x2]\n            gaussian_regsion = gaussian[g_y1:g_y2, g_x1:g_x2]\n\n            _ = np.maximum(\n                heatmap_region, gaussian_regsion, out=heatmap_region)\n\n    return heatmaps, keypoint_weights\n\n\ndef generate_unbiased_gaussian_heatmaps(\n    heatmap_size: Tuple[int, int],\n    keypoints: np.ndarray,\n    keypoints_visible: np.ndarray,\n    sigma: float,\n) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Generate gaussian heatmaps of keypoints using `Dark Pose`_.\n\n    Args:\n        heatmap_size (Tuple[int, int]): Heatmap size in [W, H]\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n\n    Returns:\n        tuple:\n        - heatmaps (np.ndarray): The generated heatmap in shape\n            (K, H, W) where [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (N, K)\n\n    .. _`Dark Pose`: https://arxiv.org/abs/1910.06278\n    \"\"\"\n\n    N, K, _ = keypoints.shape\n    W, H = heatmap_size\n\n    heatmaps = np.zeros((K, H, W), dtype=np.float32)\n    keypoint_weights = keypoints_visible.copy()\n\n    # 3-sigma rule\n    radius = sigma * 3\n\n    # xy grid\n    x = np.arange(0, W, 1, dtype=np.float32)\n    y = np.arange(0, H, 1, dtype=np.float32)[:, None]\n\n    for n, k in product(range(N), range(K)):\n        # skip unlabled keypoints\n        if keypoints_visible[n, k] < 0.5:\n            continue\n\n        mu = keypoints[n, k]\n        # check that the gaussian has in-bounds part\n        left, top = mu - radius\n        right, bottom = mu + radius + 1\n\n        if left >= W or top >= H or right < 0 or bottom < 0:\n            keypoint_weights[n, k] = 0\n            continue\n\n        gaussian = np.exp(-((x - mu[0])**2 + (y - mu[1])**2) / (2 * sigma**2))\n\n        _ = np.maximum(gaussian, heatmaps[k], out=heatmaps[k])\n\n    return heatmaps, keypoint_weights\n\n\ndef generate_udp_gaussian_heatmaps(\n    heatmap_size: Tuple[int, int],\n    keypoints: np.ndarray,\n    keypoints_visible: np.ndarray,\n    sigma: float,\n) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Generate gaussian heatmaps of keypoints using `UDP`_.\n\n    Args:\n        heatmap_size (Tuple[int, int]): Heatmap size in [W, H]\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n        sigma (float): The sigma value of the Gaussian heatmap\n\n    Returns:\n        tuple:\n        - heatmaps (np.ndarray): The generated heatmap in shape\n            (K, H, W) where [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (N, K)\n\n    .. _`UDP`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n\n    N, K, _ = keypoints.shape\n    W, H = heatmap_size\n\n    heatmaps = np.zeros((K, H, W), dtype=np.float32)\n    keypoint_weights = keypoints_visible.copy()\n\n    # 3-sigma rule\n    radius = sigma * 3\n\n    # xy grid\n    gaussian_size = 2 * radius + 1\n    x = np.arange(0, gaussian_size, 1, dtype=np.float32)\n    y = x[:, None]\n\n    for n, k in product(range(N), range(K)):\n        # skip unlabled keypoints\n        if keypoints_visible[n, k] < 0.5:\n            continue\n\n        mu = (keypoints[n, k] + 0.5).astype(np.int64)\n        # check that the gaussian has in-bounds part\n        left, top = (mu - radius).astype(np.int64)\n        right, bottom = (mu + radius + 1).astype(np.int64)\n\n        if left >= W or top >= H or right < 0 or bottom < 0:\n            keypoint_weights[n, k] = 0\n            continue\n\n        mu_ac = keypoints[n, k]\n        x0 = y0 = gaussian_size // 2\n        x0 += mu_ac[0] - mu[0]\n        y0 += mu_ac[1] - mu[1]\n        gaussian = np.exp(-((x - x0)**2 + (y - y0)**2) / (2 * sigma**2))\n\n        # valid range in gaussian\n        g_x1 = max(0, -left)\n        g_x2 = min(W, right) - left\n        g_y1 = max(0, -top)\n        g_y2 = min(H, bottom) - top\n\n        # valid range in heatmap\n        h_x1 = max(0, left)\n        h_x2 = min(W, right)\n        h_y1 = max(0, top)\n        h_y2 = min(H, bottom)\n\n        heatmap_region = heatmaps[k, h_y1:h_y2, h_x1:h_x2]\n        gaussian_regsion = gaussian[g_y1:g_y2, g_x1:g_x2]\n\n        _ = np.maximum(heatmap_region, gaussian_regsion, out=heatmap_region)\n\n    return heatmaps, keypoint_weights\n"
  },
  {
    "path": "mmpose/codecs/utils/instance_property.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional\n\nimport numpy as np\n\n\ndef get_instance_root(keypoints: np.ndarray,\n                      keypoints_visible: Optional[np.ndarray] = None,\n                      root_type: str = 'kpt_center') -> np.ndarray:\n    \"\"\"Calculate the coordinates and visibility of instance roots.\n\n    Args:\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n        root_type (str): Calculation of instance roots which should\n            be one of the following options:\n\n                - ``'kpt_center'``: The roots' coordinates are the mean\n                    coordinates of visible keypoints\n                - ``'bbox_center'``: The roots' are the center of bounding\n                    boxes outlined by visible keypoints\n\n            Defaults to ``'kpt_center'``\n\n    Returns:\n        tuple\n        - roots_coordinate(np.ndarray): Coordinates of instance roots in\n            shape [N, D]\n        - roots_visible(np.ndarray): Visibility of instance roots in\n            shape [N]\n    \"\"\"\n\n    roots_coordinate = np.zeros((keypoints.shape[0], 2), dtype=np.float32)\n    roots_visible = np.ones((keypoints.shape[0]), dtype=np.float32) * 2\n\n    for i in range(keypoints.shape[0]):\n\n        # collect visible keypoints\n        if keypoints_visible is not None:\n            visible_keypoints = keypoints[i][keypoints_visible[i] > 0]\n        else:\n            visible_keypoints = keypoints[i]\n        if visible_keypoints.size == 0:\n            roots_visible[i] = 0\n            continue\n\n        # compute the instance root with visible keypoints\n        if root_type == 'kpt_center':\n            roots_coordinate[i] = visible_keypoints.mean(axis=0)\n            roots_visible[i] = 1\n        elif root_type == 'bbox_center':\n            roots_coordinate[i] = (visible_keypoints.max(axis=0) +\n                                   visible_keypoints.min(axis=0)) / 2.0\n            roots_visible[i] = 1\n        else:\n            raise ValueError(\n                f'the value of `root_type` must be \\'kpt_center\\' or '\n                f'\\'bbox_center\\', but got \\'{root_type}\\'')\n\n    return roots_coordinate, roots_visible\n\n\ndef get_instance_bbox(keypoints: np.ndarray,\n                      keypoints_visible: Optional[np.ndarray] = None\n                      ) -> np.ndarray:\n    \"\"\"Calculate the pseudo instance bounding box from visible keypoints. The\n    bounding boxes are in the xyxy format.\n\n    Args:\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n\n    Returns:\n        np.ndarray: bounding boxes in [N, 4]\n    \"\"\"\n    bbox = np.zeros((keypoints.shape[0], 4), dtype=np.float32)\n    for i in range(keypoints.shape[0]):\n        if keypoints_visible is not None:\n            visible_keypoints = keypoints[i][keypoints_visible[i] > 0]\n        else:\n            visible_keypoints = keypoints[i]\n        if visible_keypoints.size == 0:\n            continue\n\n        bbox[i, :2] = visible_keypoints.min(axis=0)\n        bbox[i, 2:] = visible_keypoints.max(axis=0)\n    return bbox\n\n\ndef get_diagonal_lengths(keypoints: np.ndarray,\n                         keypoints_visible: Optional[np.ndarray] = None\n                         ) -> np.ndarray:\n    \"\"\"Calculate the diagonal length of instance bounding box from visible\n    keypoints.\n\n    Args:\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n\n    Returns:\n        np.ndarray: bounding box diagonal length in [N]\n    \"\"\"\n    pseudo_bbox = get_instance_bbox(keypoints, keypoints_visible)\n    pseudo_bbox = pseudo_bbox.reshape(-1, 2, 2)\n    h_w_diff = pseudo_bbox[:, 1] - pseudo_bbox[:, 0]\n    diagonal_length = np.sqrt(np.power(h_w_diff, 2).sum(axis=1))\n\n    return diagonal_length\n"
  },
  {
    "path": "mmpose/codecs/utils/offset_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Tuple\n\nimport numpy as np\n\n\ndef generate_offset_heatmap(\n    heatmap_size: Tuple[int, int],\n    keypoints: np.ndarray,\n    keypoints_visible: np.ndarray,\n    radius_factor: float,\n) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Generate offset heatmaps of keypoints, where each keypoint is\n    represented by 3 maps: one pixel-level class label map (1 for keypoint and\n    0 for non-keypoint) and 2 pixel-level offset maps for x and y directions\n    respectively.\n\n    Args:\n        heatmap_size (Tuple[int, int]): Heatmap size in [W, H]\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n        radius_factor (float): The radius factor of the binary label\n            map. The positive region is defined as the neighbor of the\n            keypoint with the radius :math:`r=radius_factor*max(W, H)`\n\n    Returns:\n        tuple:\n        - heatmap (np.ndarray): The generated heatmap in shape\n            (K*3, H, W) where [W, H] is the `heatmap_size`\n        - keypoint_weights (np.ndarray): The target weights in shape\n            (K,)\n    \"\"\"\n\n    N, K, _ = keypoints.shape\n    W, H = heatmap_size\n\n    heatmaps = np.zeros((K, 3, H, W), dtype=np.float32)\n    keypoint_weights = keypoints_visible.copy()\n\n    # xy grid\n    x = np.arange(0, W, 1)\n    y = np.arange(0, H, 1)[:, None]\n\n    # positive area radius in the classification map\n    radius = radius_factor * max(W, H)\n\n    for n, k in product(range(N), range(K)):\n        if keypoints_visible[n, k] < 0.5:\n            continue\n\n        mu = keypoints[n, k]\n\n        x_offset = (mu[0] - x) / radius\n        y_offset = (mu[1] - y) / radius\n\n        heatmaps[k, 0] = np.where(x_offset**2 + y_offset**2 <= 1, 1., 0.)\n        heatmaps[k, 1] = x_offset\n        heatmaps[k, 2] = y_offset\n\n    heatmaps = heatmaps.reshape(K * 3, H, W)\n\n    return heatmaps, keypoint_weights\n\n\ndef generate_displacement_heatmap(\n    heatmap_size: Tuple[int, int],\n    keypoints: np.ndarray,\n    keypoints_visible: np.ndarray,\n    roots: np.ndarray,\n    roots_visible: np.ndarray,\n    diagonal_lengths: np.ndarray,\n    radius: float,\n):\n    \"\"\"Generate displacement heatmaps of keypoints, where each keypoint is\n    represented by 3 maps: one pixel-level class label map (1 for keypoint and\n    0 for non-keypoint) and 2 pixel-level offset maps for x and y directions\n    respectively.\n\n    Args:\n        heatmap_size (Tuple[int, int]): Heatmap size in [W, H]\n        keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n        keypoints_visible (np.ndarray): Keypoint visibilities in shape\n            (N, K)\n        roots (np.ndarray): Coordinates of instance centers in shape (N, D).\n            The displacement fields of each instance will locate around its\n            center.\n        roots_visible (np.ndarray): Roots visibilities in shape (N,)\n        diagonal_lengths (np.ndarray): Diaginal length of the bounding boxes\n            of each instance in shape (N,)\n        radius (float): The radius factor of the binary label\n            map. The positive region is defined as the neighbor of the\n            keypoint with the radius :math:`r=radius_factor*max(W, H)`\n\n    Returns:\n        tuple:\n        - displacements (np.ndarray): The generated displacement map in\n            shape (K*2, H, W) where [W, H] is the `heatmap_size`\n        - displacement_weights (np.ndarray): The target weights in shape\n            (K*2, H, W)\n    \"\"\"\n    N, K, _ = keypoints.shape\n    W, H = heatmap_size\n\n    displacements = np.zeros((K * 2, H, W), dtype=np.float32)\n    displacement_weights = np.zeros((K * 2, H, W), dtype=np.float32)\n    instance_size_map = np.zeros((H, W), dtype=np.float32)\n\n    for n in range(N):\n        if (roots_visible[n] < 1 or (roots[n, 0] < 0 or roots[n, 1] < 0)\n                or (roots[n, 0] >= W or roots[n, 1] >= H)):\n            continue\n\n        diagonal_length = diagonal_lengths[n]\n\n        for k in range(K):\n            if keypoints_visible[n, k] < 1 or keypoints[n, k, 0] < 0 \\\n                or keypoints[n, k, 1] < 0 or keypoints[n, k, 0] >= W \\\n                    or keypoints[n, k, 1] >= H:\n                continue\n\n            start_x = max(int(roots[n, 0] - radius), 0)\n            start_y = max(int(roots[n, 1] - radius), 0)\n            end_x = min(int(roots[n, 0] + radius), W)\n            end_y = min(int(roots[n, 1] + radius), H)\n\n            for x in range(start_x, end_x):\n                for y in range(start_y, end_y):\n                    if displacements[2 * k, y,\n                                     x] != 0 or displacements[2 * k + 1, y,\n                                                              x] != 0:\n                        if diagonal_length > instance_size_map[y, x]:\n                            # keep the gt displacement of smaller instance\n                            continue\n\n                    displacement_weights[2 * k:2 * k + 2, y,\n                                         x] = 1 / diagonal_length\n                    displacements[2 * k:2 * k + 2, y,\n                                  x] = keypoints[n, k] - [x, y]\n                    instance_size_map[y, x] = diagonal_length\n\n    return displacements, displacement_weights\n"
  },
  {
    "path": "mmpose/codecs/utils/post_processing.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Tuple\n\nimport cv2\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nfrom torch import Tensor\n\n\ndef get_simcc_normalized(batch_pred_simcc, sigma=None):\n    \"\"\"Normalize the predicted SimCC.\n\n    Args:\n        batch_pred_simcc (torch.Tensor): The predicted SimCC.\n        sigma (float): The sigma of the Gaussian distribution.\n\n    Returns:\n        torch.Tensor: The normalized SimCC.\n    \"\"\"\n    B, K, _ = batch_pred_simcc.shape\n\n    # Scale and clamp the tensor\n    if sigma is not None:\n        batch_pred_simcc = batch_pred_simcc / (sigma * np.sqrt(np.pi * 2))\n    batch_pred_simcc = batch_pred_simcc.clamp(min=0)\n\n    # Compute the binary mask\n    mask = (batch_pred_simcc.amax(dim=-1) > 1).reshape(B, K, 1)\n\n    # Normalize the tensor using the maximum value\n    norm = (batch_pred_simcc / batch_pred_simcc.amax(dim=-1).reshape(B, K, 1))\n\n    # Apply normalization\n    batch_pred_simcc = torch.where(mask, norm, batch_pred_simcc)\n\n    return batch_pred_simcc\n\n\ndef get_simcc_maximum(simcc_x: np.ndarray,\n                      simcc_y: np.ndarray,\n                      apply_softmax: bool = False\n                      ) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Get maximum response location and value from simcc representations.\n\n    Note:\n        instance number: N\n        num_keypoints: K\n        heatmap height: H\n        heatmap width: W\n\n    Args:\n        simcc_x (np.ndarray): x-axis SimCC in shape (K, Wx) or (N, K, Wx)\n        simcc_y (np.ndarray): y-axis SimCC in shape (K, Wy) or (N, K, Wy)\n        apply_softmax (bool): whether to apply softmax on the heatmap.\n            Defaults to False.\n\n    Returns:\n        tuple:\n        - locs (np.ndarray): locations of maximum heatmap responses in shape\n            (K, 2) or (N, K, 2)\n        - vals (np.ndarray): values of maximum heatmap responses in shape\n            (K,) or (N, K)\n    \"\"\"\n\n    assert isinstance(simcc_x, np.ndarray), ('simcc_x should be numpy.ndarray')\n    assert isinstance(simcc_y, np.ndarray), ('simcc_y should be numpy.ndarray')\n    assert simcc_x.ndim == 2 or simcc_x.ndim == 3, (\n        f'Invalid shape {simcc_x.shape}')\n    assert simcc_y.ndim == 2 or simcc_y.ndim == 3, (\n        f'Invalid shape {simcc_y.shape}')\n    assert simcc_x.ndim == simcc_y.ndim, (\n        f'{simcc_x.shape} != {simcc_y.shape}')\n\n    if simcc_x.ndim == 3:\n        N, K, Wx = simcc_x.shape\n        simcc_x = simcc_x.reshape(N * K, -1)\n        simcc_y = simcc_y.reshape(N * K, -1)\n    else:\n        N = None\n\n    if apply_softmax:\n        simcc_x = simcc_x - np.max(simcc_x, axis=1, keepdims=True)\n        simcc_y = simcc_y - np.max(simcc_y, axis=1, keepdims=True)\n        ex, ey = np.exp(simcc_x), np.exp(simcc_y)\n        simcc_x = ex / np.sum(ex, axis=1, keepdims=True)\n        simcc_y = ey / np.sum(ey, axis=1, keepdims=True)\n\n    x_locs = np.argmax(simcc_x, axis=1)\n    y_locs = np.argmax(simcc_y, axis=1)\n    locs = np.stack((x_locs, y_locs), axis=-1).astype(np.float32)\n    max_val_x = np.amax(simcc_x, axis=1)\n    max_val_y = np.amax(simcc_y, axis=1)\n\n    mask = max_val_x > max_val_y\n    max_val_x[mask] = max_val_y[mask]\n    vals = max_val_x\n    locs[vals <= 0.] = -1\n\n    if N:\n        locs = locs.reshape(N, K, 2)\n        vals = vals.reshape(N, K)\n\n    return locs, vals\n\n\ndef get_heatmap_3d_maximum(heatmaps: np.ndarray\n                           ) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Get maximum response location and value from heatmaps.\n\n    Note:\n        batch_size: B\n        num_keypoints: K\n        heatmap dimension: D\n        heatmap height: H\n        heatmap width: W\n\n    Args:\n        heatmaps (np.ndarray): Heatmaps in shape (K, D, H, W) or\n            (B, K, D, H, W)\n\n    Returns:\n        tuple:\n        - locs (np.ndarray): locations of maximum heatmap responses in shape\n            (K, 3) or (B, K, 3)\n        - vals (np.ndarray): values of maximum heatmap responses in shape\n            (K,) or (B, K)\n    \"\"\"\n    assert isinstance(heatmaps,\n                      np.ndarray), ('heatmaps should be numpy.ndarray')\n    assert heatmaps.ndim == 4 or heatmaps.ndim == 5, (\n        f'Invalid shape {heatmaps.shape}')\n\n    if heatmaps.ndim == 4:\n        K, D, H, W = heatmaps.shape\n        B = None\n        heatmaps_flatten = heatmaps.reshape(K, -1)\n    else:\n        B, K, D, H, W = heatmaps.shape\n        heatmaps_flatten = heatmaps.reshape(B * K, -1)\n\n    z_locs, y_locs, x_locs = np.unravel_index(\n        np.argmax(heatmaps_flatten, axis=1), shape=(D, H, W))\n    locs = np.stack((x_locs, y_locs, z_locs), axis=-1).astype(np.float32)\n    vals = np.amax(heatmaps_flatten, axis=1)\n    locs[vals <= 0.] = -1\n\n    if B:\n        locs = locs.reshape(B, K, 3)\n        vals = vals.reshape(B, K)\n\n    return locs, vals\n\n\ndef get_heatmap_maximum(heatmaps: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Get maximum response location and value from heatmaps.\n\n    Note:\n        batch_size: B\n        num_keypoints: K\n        heatmap height: H\n        heatmap width: W\n\n    Args:\n        heatmaps (np.ndarray): Heatmaps in shape (K, H, W) or (B, K, H, W)\n\n    Returns:\n        tuple:\n        - locs (np.ndarray): locations of maximum heatmap responses in shape\n            (K, 2) or (B, K, 2)\n        - vals (np.ndarray): values of maximum heatmap responses in shape\n            (K,) or (B, K)\n    \"\"\"\n    assert isinstance(heatmaps,\n                      np.ndarray), ('heatmaps should be numpy.ndarray')\n    assert heatmaps.ndim == 3 or heatmaps.ndim == 4, (\n        f'Invalid shape {heatmaps.shape}')\n\n    if heatmaps.ndim == 3:\n        K, H, W = heatmaps.shape\n        B = None\n        heatmaps_flatten = heatmaps.reshape(K, -1)\n    else:\n        B, K, H, W = heatmaps.shape\n        heatmaps_flatten = heatmaps.reshape(B * K, -1)\n\n    y_locs, x_locs = np.unravel_index(\n        np.argmax(heatmaps_flatten, axis=1), shape=(H, W))\n    locs = np.stack((x_locs, y_locs), axis=-1).astype(np.float32)\n    vals = np.amax(heatmaps_flatten, axis=1)\n    locs[vals <= 0.] = -1\n\n    if B:\n        locs = locs.reshape(B, K, 2)\n        vals = vals.reshape(B, K)\n\n    return locs, vals\n\n\ndef gaussian_blur(heatmaps: np.ndarray, kernel: int = 11) -> np.ndarray:\n    \"\"\"Modulate heatmap distribution with Gaussian.\n\n    Note:\n        - num_keypoints: K\n        - heatmap height: H\n        - heatmap width: W\n\n    Args:\n        heatmaps (np.ndarray[K, H, W]): model predicted heatmaps.\n        kernel (int): Gaussian kernel size (K) for modulation, which should\n            match the heatmap gaussian sigma when training.\n            K=17 for sigma=3 and k=11 for sigma=2.\n\n    Returns:\n        np.ndarray ([K, H, W]): Modulated heatmap distribution.\n    \"\"\"\n    assert kernel % 2 == 1\n\n    border = (kernel - 1) // 2\n    K, H, W = heatmaps.shape\n\n    for k in range(K):\n        origin_max = np.max(heatmaps[k])\n        dr = np.zeros((H + 2 * border, W + 2 * border), dtype=np.float32)\n        dr[border:-border, border:-border] = heatmaps[k].copy()\n        dr = cv2.GaussianBlur(dr, (kernel, kernel), 0)\n        heatmaps[k] = dr[border:-border, border:-border].copy()\n        heatmaps[k] *= origin_max / np.max(heatmaps[k])\n    return heatmaps\n\n\ndef gaussian_blur1d(simcc: np.ndarray, kernel: int = 11) -> np.ndarray:\n    \"\"\"Modulate simcc distribution with Gaussian.\n\n    Note:\n        - num_keypoints: K\n        - simcc length: Wx\n\n    Args:\n        simcc (np.ndarray[K, Wx]): model predicted simcc.\n        kernel (int): Gaussian kernel size (K) for modulation, which should\n            match the simcc gaussian sigma when training.\n            K=17 for sigma=3 and k=11 for sigma=2.\n\n    Returns:\n        np.ndarray ([K, Wx]): Modulated simcc distribution.\n    \"\"\"\n    assert kernel % 2 == 1\n\n    border = (kernel - 1) // 2\n    N, K, Wx = simcc.shape\n\n    for n, k in product(range(N), range(K)):\n        origin_max = np.max(simcc[n, k])\n        dr = np.zeros((1, Wx + 2 * border), dtype=np.float32)\n        dr[0, border:-border] = simcc[n, k].copy()\n        dr = cv2.GaussianBlur(dr, (kernel, 1), 0)\n        simcc[n, k] = dr[0, border:-border].copy()\n        simcc[n, k] *= origin_max / np.max(simcc[n, k])\n    return simcc\n\n\ndef batch_heatmap_nms(batch_heatmaps: Tensor, kernel_size: int = 5):\n    \"\"\"Apply NMS on a batch of heatmaps.\n\n    Args:\n        batch_heatmaps (Tensor): batch heatmaps in shape (B, K, H, W)\n        kernel_size (int): The kernel size of the NMS which should be\n            a odd integer. Defaults to 5\n\n    Returns:\n        Tensor: The batch heatmaps after NMS.\n    \"\"\"\n\n    assert isinstance(kernel_size, int) and kernel_size % 2 == 1, \\\n        f'The kernel_size should be an odd integer, got {kernel_size}'\n\n    padding = (kernel_size - 1) // 2\n\n    maximum = F.max_pool2d(\n        batch_heatmaps, kernel_size, stride=1, padding=padding)\n    maximum_indicator = torch.eq(batch_heatmaps, maximum)\n    batch_heatmaps = batch_heatmaps * maximum_indicator.float()\n\n    return batch_heatmaps\n"
  },
  {
    "path": "mmpose/codecs/utils/refinement.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\n\nimport numpy as np\n\nfrom .post_processing import gaussian_blur, gaussian_blur1d\n\n\ndef refine_keypoints(keypoints: np.ndarray,\n                     heatmaps: np.ndarray) -> np.ndarray:\n    \"\"\"Refine keypoint predictions by moving from the maximum towards the\n    second maximum by 0.25 pixel. The operation is in-place.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - heatmap size: [W, H]\n\n    Args:\n        keypoints (np.ndarray): The keypoint coordinates in shape (N, K, D)\n        heatmaps (np.ndarray): The heatmaps in shape (K, H, W)\n\n    Returns:\n        np.ndarray: Refine keypoint coordinates in shape (N, K, D)\n    \"\"\"\n    N, K = keypoints.shape[:2]\n    H, W = heatmaps.shape[1:]\n\n    for n, k in product(range(N), range(K)):\n        x, y = keypoints[n, k, :2].astype(int)\n\n        if 1 < x < W - 1 and 0 < y < H:\n            dx = heatmaps[k, y, x + 1] - heatmaps[k, y, x - 1]\n        else:\n            dx = 0.\n\n        if 1 < y < H - 1 and 0 < x < W:\n            dy = heatmaps[k, y + 1, x] - heatmaps[k, y - 1, x]\n        else:\n            dy = 0.\n\n        keypoints[n, k] += np.sign([dx, dy], dtype=np.float32) * 0.25\n\n    return keypoints\n\n\ndef refine_keypoints_dark(keypoints: np.ndarray, heatmaps: np.ndarray,\n                          blur_kernel_size: int) -> np.ndarray:\n    \"\"\"Refine keypoint predictions using distribution aware coordinate\n    decoding. See `Dark Pose`_ for details. The operation is in-place.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - heatmap size: [W, H]\n\n    Args:\n        keypoints (np.ndarray): The keypoint coordinates in shape (N, K, D)\n        heatmaps (np.ndarray): The heatmaps in shape (K, H, W)\n        blur_kernel_size (int): The Gaussian blur kernel size of the heatmap\n            modulation\n\n    Returns:\n        np.ndarray: Refine keypoint coordinates in shape (N, K, D)\n\n    .. _`Dark Pose`: https://arxiv.org/abs/1910.06278\n    \"\"\"\n    N, K = keypoints.shape[:2]\n    H, W = heatmaps.shape[1:]\n\n    # modulate heatmaps\n    heatmaps = gaussian_blur(heatmaps, blur_kernel_size)\n    np.maximum(heatmaps, 1e-10, heatmaps)\n    np.log(heatmaps, heatmaps)\n\n    for n, k in product(range(N), range(K)):\n        x, y = keypoints[n, k, :2].astype(int)\n        if 1 < x < W - 2 and 1 < y < H - 2:\n            dx = 0.5 * (heatmaps[k, y, x + 1] - heatmaps[k, y, x - 1])\n            dy = 0.5 * (heatmaps[k, y + 1, x] - heatmaps[k, y - 1, x])\n\n            dxx = 0.25 * (\n                heatmaps[k, y, x + 2] - 2 * heatmaps[k, y, x] +\n                heatmaps[k, y, x - 2])\n            dxy = 0.25 * (\n                heatmaps[k, y + 1, x + 1] - heatmaps[k, y - 1, x + 1] -\n                heatmaps[k, y + 1, x - 1] + heatmaps[k, y - 1, x - 1])\n            dyy = 0.25 * (\n                heatmaps[k, y + 2, x] - 2 * heatmaps[k, y, x] +\n                heatmaps[k, y - 2, x])\n            derivative = np.array([[dx], [dy]])\n            hessian = np.array([[dxx, dxy], [dxy, dyy]])\n            if dxx * dyy - dxy**2 != 0:\n                hessianinv = np.linalg.inv(hessian)\n                offset = -hessianinv @ derivative\n                offset = np.squeeze(np.array(offset.T), axis=0)\n                keypoints[n, k, :2] += offset\n    return keypoints\n\n\ndef refine_keypoints_dark_udp(keypoints: np.ndarray, heatmaps: np.ndarray,\n                              blur_kernel_size: int) -> np.ndarray:\n    \"\"\"Refine keypoint predictions using distribution aware coordinate decoding\n    for UDP. See `UDP`_ for details. The operation is in-place.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - heatmap size: [W, H]\n\n    Args:\n        keypoints (np.ndarray): The keypoint coordinates in shape (N, K, D)\n        heatmaps (np.ndarray): The heatmaps in shape (K, H, W)\n        blur_kernel_size (int): The Gaussian blur kernel size of the heatmap\n            modulation\n\n    Returns:\n        np.ndarray: Refine keypoint coordinates in shape (N, K, D)\n\n    .. _`UDP`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n    N, K = keypoints.shape[:2]\n    H, W = heatmaps.shape[1:]\n\n    # modulate heatmaps\n    heatmaps = gaussian_blur(heatmaps, blur_kernel_size)\n    np.clip(heatmaps, 1e-3, 50., heatmaps)\n    np.log(heatmaps, heatmaps)\n\n    heatmaps_pad = np.pad(\n        heatmaps, ((0, 0), (1, 1), (1, 1)), mode='edge').flatten()\n\n    for n in range(N):\n        index = keypoints[n, :, 0] + 1 + (keypoints[n, :, 1] + 1) * (W + 2)\n        index += (W + 2) * (H + 2) * np.arange(0, K)\n        index = index.astype(int).reshape(-1, 1)\n        i_ = heatmaps_pad[index]\n        ix1 = heatmaps_pad[index + 1]\n        iy1 = heatmaps_pad[index + W + 2]\n        ix1y1 = heatmaps_pad[index + W + 3]\n        ix1_y1_ = heatmaps_pad[index - W - 3]\n        ix1_ = heatmaps_pad[index - 1]\n        iy1_ = heatmaps_pad[index - 2 - W]\n\n        dx = 0.5 * (ix1 - ix1_)\n        dy = 0.5 * (iy1 - iy1_)\n        derivative = np.concatenate([dx, dy], axis=1)\n        derivative = derivative.reshape(K, 2, 1)\n\n        dxx = ix1 - 2 * i_ + ix1_\n        dyy = iy1 - 2 * i_ + iy1_\n        dxy = 0.5 * (ix1y1 - ix1 - iy1 + i_ + i_ - ix1_ - iy1_ + ix1_y1_)\n        hessian = np.concatenate([dxx, dxy, dxy, dyy], axis=1)\n        hessian = hessian.reshape(K, 2, 2)\n        hessian = np.linalg.inv(hessian + np.finfo(np.float32).eps * np.eye(2))\n        keypoints[n] -= np.einsum('imn,ink->imk', hessian,\n                                  derivative).squeeze()\n\n    return keypoints\n\n\ndef refine_simcc_dark(keypoints: np.ndarray, simcc: np.ndarray,\n                      blur_kernel_size: int) -> np.ndarray:\n    \"\"\"SimCC version. Refine keypoint predictions using distribution aware\n    coordinate decoding for UDP. See `UDP`_ for details. The operation is in-\n    place.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n\n    Args:\n        keypoints (np.ndarray): The keypoint coordinates in shape (N, K, D)\n        simcc (np.ndarray): The heatmaps in shape (N, K, Wx)\n        blur_kernel_size (int): The Gaussian blur kernel size of the heatmap\n            modulation\n\n    Returns:\n        np.ndarray: Refine keypoint coordinates in shape (N, K, D)\n\n    .. _`UDP`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n    N = simcc.shape[0]\n\n    # modulate simcc\n    simcc = gaussian_blur1d(simcc, blur_kernel_size)\n    np.clip(simcc, 1e-3, 50., simcc)\n    np.log(simcc, simcc)\n\n    simcc = np.pad(simcc, ((0, 0), (0, 0), (2, 2)), 'edge')\n\n    for n in range(N):\n        px = (keypoints[n] + 2.5).astype(np.int64).reshape(-1, 1)  # K, 1\n\n        dx0 = np.take_along_axis(simcc[n], px, axis=1)  # K, 1\n        dx1 = np.take_along_axis(simcc[n], px + 1, axis=1)\n        dx_1 = np.take_along_axis(simcc[n], px - 1, axis=1)\n        dx2 = np.take_along_axis(simcc[n], px + 2, axis=1)\n        dx_2 = np.take_along_axis(simcc[n], px - 2, axis=1)\n\n        dx = 0.5 * (dx1 - dx_1)\n        dxx = 1e-9 + 0.25 * (dx2 - 2 * dx0 + dx_2)\n\n        offset = dx / dxx\n        keypoints[n] -= offset.reshape(-1)\n\n    return keypoints\n"
  },
  {
    "path": "mmpose/codecs/video_pose_lifting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom copy import deepcopy\nfrom typing import List, Optional, Tuple, Union\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .base import BaseKeypointCodec\n\n\n@KEYPOINT_CODECS.register_module()\nclass VideoPoseLifting(BaseKeypointCodec):\n    r\"\"\"Generate keypoint coordinates for pose lifter.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - pose-lifitng target dimension: C\n\n    Args:\n        num_keypoints (int): The number of keypoints in the dataset.\n        zero_center: Whether to zero-center the target around root. Default:\n            ``True``.\n        root_index (Union[int, List]): Root keypoint index in the pose.\n            Default: 0.\n        remove_root (bool): If true, remove the root keypoint from the pose.\n            Default: ``False``.\n        save_index (bool): If true, store the root position separated from the\n            original pose, only takes effect if ``remove_root`` is ``True``.\n            Default: ``False``.\n        reshape_keypoints (bool): If true, reshape the keypoints into shape\n            (-1, N). Default: ``True``.\n        concat_vis (bool): If true, concat the visibility item of keypoints.\n            Default: ``False``.\n        normalize_camera (bool): Whether to normalize camera intrinsics.\n            Default: ``False``.\n    \"\"\"\n\n    auxiliary_encode_keys = {\n        'lifting_target', 'lifting_target_visible', 'camera_param'\n    }\n\n    instance_mapping_table = dict(\n        lifting_target='lifting_target',\n        lifting_target_visible='lifting_target_visible',\n    )\n    label_mapping_table = dict(\n        trajectory_weights='trajectory_weights',\n        lifting_target_label='lifting_target_label',\n        lifting_target_weight='lifting_target_weight')\n\n    def __init__(self,\n                 num_keypoints: int,\n                 zero_center: bool = True,\n                 root_index: Union[int, List] = 0,\n                 remove_root: bool = False,\n                 save_index: bool = False,\n                 reshape_keypoints: bool = True,\n                 concat_vis: bool = False,\n                 normalize_camera: bool = False):\n        super().__init__()\n\n        self.num_keypoints = num_keypoints\n        self.zero_center = zero_center\n        if isinstance(root_index, int):\n            root_index = [root_index]\n        self.root_index = root_index\n        self.remove_root = remove_root\n        self.save_index = save_index\n        self.reshape_keypoints = reshape_keypoints\n        self.concat_vis = concat_vis\n        self.normalize_camera = normalize_camera\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None,\n               lifting_target: Optional[np.ndarray] = None,\n               lifting_target_visible: Optional[np.ndarray] = None,\n               camera_param: Optional[dict] = None) -> dict:\n        \"\"\"Encoding keypoints from input image space to normalized space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D).\n            keypoints_visible (np.ndarray, optional): Keypoint visibilities in\n                shape (N, K).\n            lifting_target (np.ndarray, optional): 3d target coordinate in\n                shape (T, K, C).\n            lifting_target_visible (np.ndarray, optional): Target coordinate in\n                shape (T, K, ).\n            camera_param (dict, optional): The camera parameter dictionary.\n\n        Returns:\n            encoded (dict): Contains the following items:\n\n                - keypoint_labels (np.ndarray): The processed keypoints in\n                  shape like (N, K, D) or (K * D, N).\n                - keypoint_labels_visible (np.ndarray): The processed\n                  keypoints' weights in shape (N, K, ) or (N-1, K, ).\n                - lifting_target_label: The processed target coordinate in\n                  shape (K, C) or (K-1, C).\n                - lifting_target_weight (np.ndarray): The target weights in\n                  shape (K, ) or (K-1, ).\n                - trajectory_weights (np.ndarray): The trajectory weights in\n                  shape (K, ).\n\n                In addition, there are some optional items it may contain:\n\n                - target_root (np.ndarray): The root coordinate of target in\n                  shape (C, ). Exists if ``zero_center`` is ``True``.\n                - target_root_removed (bool): Indicate whether the root of\n                  pose-lifitng target is removed. Exists if\n                  ``remove_root`` is ``True``.\n                - target_root_index (int): An integer indicating the index of\n                  root. Exists if ``remove_root`` and ``save_index``\n                  are ``True``.\n                - camera_param (dict): The updated camera parameter dictionary.\n                  Exists if ``normalize_camera`` is ``True``.\n        \"\"\"\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        if lifting_target is None:\n            lifting_target = [keypoints[0]]\n\n        # set initial value for `lifting_target_weight`\n        # and `trajectory_weights`\n        if lifting_target_visible is None:\n            lifting_target_visible = np.ones(\n                lifting_target.shape[:-1], dtype=np.float32)\n            lifting_target_weight = lifting_target_visible\n            trajectory_weights = (1 / lifting_target[:, 2])\n        else:\n            valid = lifting_target_visible > 0.5\n            lifting_target_weight = np.where(valid, 1., 0.).astype(np.float32)\n            trajectory_weights = lifting_target_weight\n\n        if camera_param is None:\n            camera_param = dict()\n\n        encoded = dict()\n\n        lifting_target_label = lifting_target.copy()\n        # Zero-center the target pose around a given root keypoint\n        if self.zero_center:\n            assert (lifting_target.ndim >= 2 and\n                    lifting_target.shape[-2] > max(self.root_index)), \\\n                f'Got invalid joint shape {lifting_target.shape}'\n\n            root = np.mean(lifting_target[..., self.root_index, :], axis=-2)\n            lifting_target_label -= root[..., np.newaxis, :]\n            encoded['target_root'] = root\n\n            if self.remove_root and len(self.root_index) == 1:\n                root_index = self.root_index[0]\n                lifting_target_label = np.delete(\n                    lifting_target_label, root_index, axis=-2)\n                lifting_target_visible = np.delete(\n                    lifting_target_visible, root_index, axis=-2)\n                assert lifting_target_weight.ndim in {\n                    2, 3\n                }, (f'Got invalid lifting target weights shape '\n                    f'{lifting_target_weight.shape}')\n\n                axis_to_remove = -2 if lifting_target_weight.ndim == 3 else -1\n                lifting_target_weight = np.delete(\n                    lifting_target_weight, root_index, axis=axis_to_remove)\n                # Add a flag to avoid latter transforms that rely on the root\n                # joint or the original joint index\n                encoded['target_root_removed'] = True\n\n                # Save the root index for restoring the global pose\n                if self.save_index:\n                    encoded['target_root_index'] = root_index\n\n        # Normalize the 2D keypoint coordinate with image width and height\n        _camera_param = deepcopy(camera_param)\n        assert 'w' in _camera_param and 'h' in _camera_param, (\n            'Camera parameter `w` and `h` should be provided.')\n\n        center = np.array([0.5 * _camera_param['w'], 0.5 * _camera_param['h']],\n                          dtype=np.float32)\n        scale = np.array(0.5 * _camera_param['w'], dtype=np.float32)\n\n        keypoint_labels = (keypoints - center) / scale\n\n        assert keypoint_labels.ndim in {\n            2, 3\n        }, (f'Got invalid keypoint labels shape {keypoint_labels.shape}')\n        if keypoint_labels.ndim == 2:\n            keypoint_labels = keypoint_labels[None, ...]\n\n        if self.normalize_camera:\n            assert 'f' in _camera_param and 'c' in _camera_param, (\n                'Camera parameter `f` and `c` should be provided.')\n            _camera_param['f'] = _camera_param['f'] / scale\n            _camera_param['c'] = (_camera_param['c'] - center[:, None]) / scale\n            encoded['camera_param'] = _camera_param\n\n        if self.concat_vis:\n            keypoints_visible_ = keypoints_visible\n            if keypoints_visible.ndim == 2:\n                keypoints_visible_ = keypoints_visible[..., None]\n            keypoint_labels = np.concatenate(\n                (keypoint_labels, keypoints_visible_), axis=2)\n\n        if self.reshape_keypoints:\n            N = keypoint_labels.shape[0]\n            keypoint_labels = keypoint_labels.transpose(1, 2, 0).reshape(-1, N)\n\n        encoded['keypoint_labels'] = keypoint_labels\n        encoded['keypoints_visible'] = keypoints_visible\n        encoded['lifting_target_label'] = lifting_target_label\n        encoded['lifting_target_weight'] = lifting_target_weight\n        encoded['trajectory_weights'] = trajectory_weights\n\n        return encoded\n\n    def decode(self,\n               encoded: np.ndarray,\n               target_root: Optional[np.ndarray] = None\n               ) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from normalized space to input image\n        space.\n\n        Args:\n            encoded (np.ndarray): Coordinates in shape (N, K, C).\n            target_root (np.ndarray, optional): The pose-lifitng target root\n                coordinate. Default: ``None``.\n\n        Returns:\n            keypoints (np.ndarray): Decoded coordinates in shape (N, K, C).\n            scores (np.ndarray): The keypoint scores in shape (N, K).\n        \"\"\"\n        keypoints = encoded.copy()\n\n        if target_root is not None and target_root.size > 0:\n            keypoints = keypoints + target_root\n            if self.remove_root and len(self.root_index) == 1:\n                keypoints = np.insert(\n                    keypoints, self.root_index, target_root, axis=1)\n        scores = np.ones(keypoints.shape[:-1], dtype=np.float32)\n\n        return keypoints, scores\n"
  },
  {
    "path": "mmpose/configs/_base_/default_runtime.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.hooks import (CheckpointHook, DistSamplerSeedHook, IterTimerHook,\n                            LoggerHook, ParamSchedulerHook, SyncBuffersHook)\nfrom mmengine.runner import LogProcessor\nfrom mmengine.visualization import LocalVisBackend\n\nfrom mmpose.engine.hooks import PoseVisualizationHook\nfrom mmpose.visualization import PoseLocalVisualizer\n\ndefault_scope = None\n\n# hooks\ndefault_hooks = dict(\n    timer=dict(type=IterTimerHook),\n    logger=dict(type=LoggerHook, interval=50),\n    param_scheduler=dict(type=ParamSchedulerHook),\n    checkpoint=dict(type=CheckpointHook, interval=10),\n    sampler_seed=dict(type=DistSamplerSeedHook),\n    visualization=dict(type=PoseVisualizationHook, enable=False),\n)\n\n# custom hooks\ncustom_hooks = [\n    # Synchronize model buffers such as running_mean and running_var in BN\n    # at the end of each epoch\n    dict(type=SyncBuffersHook)\n]\n\n# multi-processing backend\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'),\n)\n\n# visualizer\nvis_backends = [dict(type=LocalVisBackend)]\nvisualizer = dict(\n    type=PoseLocalVisualizer, vis_backends=vis_backends, name='visualizer')\n\n# logger\nlog_processor = dict(\n    type=LogProcessor, window_size=50, by_epoch=True, num_digits=6)\nlog_level = 'INFO'\nload_from = None\nresume = False\n\n# file I/O backend\nbackend_args = dict(backend='local')\n\n# training/validation/testing progress\ntrain_cfg = dict(by_epoch=True)\nval_cfg = dict()\ntest_cfg = dict()\n"
  },
  {
    "path": "mmpose/configs/body_2d_keypoint/rtmpose/coco/rtmpose_m_8xb256-420e_coco-256x192.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.datasets.transforms import YOLOXHSVRandomAug\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmdet.models import CSPNeXt\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (CocoDataset, GenerateTarget, GetBBoxCenterScale,\n                             LoadImage, PackPoseInputs, RandomFlip,\n                             RandomHalfBody, TopdownAffine)\nfrom mmpose.datasets.transforms.common_transforms import (Albumentation,\n                                                          RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoMetric\nfrom mmpose.models import (KLDiscretLoss, PoseDataPreprocessor, RTMCCHead,\n                           TopdownPoseEstimator)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type=PretrainedInit,\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmpose/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type=RTMCCHead,\n        in_channels=768,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = CocoDataset\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=YOLOXHSVRandomAug),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type=GenerateTarget, encoder=codec),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\n\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=YOLOXHSVRandomAug),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type=GenerateTarget, encoder=codec),\n    dict(type=PackPoseInputs)\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoMetric,\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/body_2d_keypoint/rtmpose/coco/rtmpose_s_8xb256_420e_aic_coco_256x192.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.datasets.transforms import YOLOXHSVRandomAug\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmdet.models import CSPNeXt\nfrom mmengine.dataset import DefaultSampler, RepeatDataset\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (AicDataset, CocoDataset, CombinedDataset,\n                             GenerateTarget, GetBBoxCenterScale,\n                             KeypointConverter, LoadImage, PackPoseInputs,\n                             RandomFlip, RandomHalfBody, TopdownAffine)\nfrom mmpose.datasets.transforms.common_transforms import (Albumentation,\n                                                          RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoMetric\nfrom mmpose.models import (KLDiscretLoss, PoseDataPreprocessor, RTMCCHead,\n                           TopdownPoseEstimator)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.0),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        # use cosine lr from 210 to 420 epoch\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=(192, 256),\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type=PretrainedInit,\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type=RTMCCHead,\n        in_channels=512,\n        out_channels=17,\n        input_size=codec['input_size'],\n        in_featuremap_size=(6, 8),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = CocoDataset\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/',\n#         f'{data_root}': 's3://openmmlab/datasets/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=YOLOXHSVRandomAug),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type=GenerateTarget, encoder=codec),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\n\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=YOLOXHSVRandomAug),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type=GenerateTarget, encoder=codec),\n    dict(type=PackPoseInputs)\n]\n\n# train datasets\ndataset_coco = dict(\n    type=RepeatDataset,\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='detection/coco/train2017/'),\n        pipeline=[],\n    ),\n    times=3)\n\ndataset_aic = dict(\n    type=AicDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128 * 2,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=CombinedDataset,\n        metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n        datasets=[dataset_coco, dataset_aic],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='coco/annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='detection/coco/val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoMetric,\n    ann_file=data_root + 'coco/annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w48_udp-8xb32-210e_coco-256x192.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *\n\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import LinearLR, MultiStepLR\nfrom torch.optim import Adam\n\nfrom mmpose.codecs import UDPHeatmap\nfrom mmpose.datasets import (CocoDataset, GenerateTarget, GetBBoxCenterScale,\n                             LoadImage, PackPoseInputs, RandomFlip,\n                             RandomHalfBody, TopdownAffine)\nfrom mmpose.datasets.transforms.common_transforms import RandomBBoxTransform\nfrom mmpose.evaluation import CocoMetric\nfrom mmpose.models import (HeatmapHead, HRNet, KeypointMSELoss,\n                           PoseDataPreprocessor, TopdownPoseEstimator)\n\n# runtime\ntrain_cfg.update(max_epochs=210, val_interval=10)\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type=Adam,\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(type=LinearLR, begin=0, end=500, start_factor=0.001,\n         by_epoch=False),  # warm-up\n    dict(\n        type=MultiStepLR,\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks.update(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type=UDPHeatmap, input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=HRNet,\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(48, 96)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(48, 96, 192)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(48, 96, 192, 384))),\n        init_cfg=dict(\n            type=PretrainedInit,\n            checkpoint='https://download.openmmlab.com/mmpose/'\n            'pretrain_models/hrnet_w48-8ef0771d.pth'),\n    ),\n    head=dict(\n        type=HeatmapHead,\n        in_channels=48,\n        out_channels=17,\n        deconv_out_channels=None,\n        loss=dict(type=KeypointMSELoss, use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = CocoDataset\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform),\n    dict(type=TopdownAffine, input_size=codec['input_size'], use_udp=True),\n    dict(type=GenerateTarget, encoder=codec),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size'], use_udp=True),\n    dict(type=PackPoseInputs)\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type=CocoMetric,\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/wholebody_2d_keypoint/rtmpose/cocktail13/rtmw-l_8xb1024-270e_cocktail14-256x192.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *  # noqa\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (AicDataset, CocoWholeBodyDataset, COFWDataset,\n                             CombinedDataset, CrowdPoseDataset,\n                             Face300WDataset, GenerateTarget,\n                             GetBBoxCenterScale, HalpeDataset,\n                             HumanArt21Dataset, InterHand2DDoubleDataset,\n                             JhmdbDataset, KeypointConverter, LapaDataset,\n                             LoadImage, MpiiDataset, PackPoseInputs,\n                             PoseTrack18Dataset, RandomFlip, RandomHalfBody,\n                             TopdownAffine, UBody2dDataset, WFLWDataset)\nfrom mmpose.datasets.transforms.common_transforms import (\n    Albumentation, PhotometricDistortion, RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoWholeBodyMetric\nfrom mmpose.models import (CSPNeXt, CSPNeXtPAFPN, KLDiscretLoss,\n                           PoseDataPreprocessor, RTMWHead,\n                           TopdownPoseEstimator)\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 1024\nval_batch_size = 32\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)  # noqa\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=8192)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type=PretrainedInit,\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type=CSPNeXtPAFPN,\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU, inplace=True)),\n    head=dict(\n        type=RTMWHead,\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = CocoWholeBodyDataset\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PhotometricDistortion),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type=AicDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type=CrowdPoseDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type=MpiiDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type=JhmdbDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type=HalpeDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type=PoseTrack18Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type=HumanArt21Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type=UBody2dDataset,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale, padding=1.25),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type=WFLWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type=Face300WDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type=COFWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type=LapaDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type=InterHand2DDoubleDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=CombinedDataset,\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=CocoWholeBodyDataset,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(  # noqa\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoWholeBodyMetric,\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/wholebody_2d_keypoint/rtmpose/cocktail13/rtmw-l_8xb320-270e_cocktail14-384x288.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *  # noqa\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (AicDataset, CocoWholeBodyDataset, COFWDataset,\n                             CombinedDataset, CrowdPoseDataset,\n                             Face300WDataset, GenerateTarget,\n                             GetBBoxCenterScale, HalpeDataset,\n                             HumanArt21Dataset, InterHand2DDoubleDataset,\n                             JhmdbDataset, KeypointConverter, LapaDataset,\n                             LoadImage, MpiiDataset, PackPoseInputs,\n                             PoseTrack18Dataset, RandomFlip, RandomHalfBody,\n                             TopdownAffine, UBody2dDataset, WFLWDataset)\nfrom mmpose.datasets.transforms.common_transforms import (\n    Albumentation, PhotometricDistortion, RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoWholeBodyMetric\nfrom mmpose.models import (CSPNeXt, CSPNeXtPAFPN, KLDiscretLoss,\n                           PoseDataPreprocessor, RTMWHead,\n                           TopdownPoseEstimator)\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 320\nval_batch_size = 32\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)  # noqa\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=2560)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type=CSPNeXtPAFPN,\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU, inplace=True)),\n    head=dict(\n        type=RTMWHead,\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = CocoWholeBodyDataset\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PhotometricDistortion),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type=AicDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type=CrowdPoseDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type=MpiiDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type=JhmdbDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type=HalpeDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type=PoseTrack18Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type=HumanArt21Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type=UBody2dDataset,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale, padding=1.25),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type=WFLWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type=Face300WDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type=COFWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type=LapaDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type=InterHand2DDoubleDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=CombinedDataset,\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=CocoWholeBodyDataset,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(  # noqa\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoWholeBodyMetric,\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/wholebody_2d_keypoint/rtmpose/cocktail13/rtmw-m_8xb1024-270e_cocktail14-256x192.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *  # noqa\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (AicDataset, CocoWholeBodyDataset, COFWDataset,\n                             CombinedDataset, CrowdPoseDataset,\n                             Face300WDataset, GenerateTarget,\n                             GetBBoxCenterScale, HalpeDataset,\n                             HumanArt21Dataset, InterHand2DDoubleDataset,\n                             JhmdbDataset, KeypointConverter, LapaDataset,\n                             LoadImage, MpiiDataset, PackPoseInputs,\n                             PoseTrack18Dataset, RandomFlip, RandomHalfBody,\n                             TopdownAffine, UBody2dDataset, WFLWDataset)\nfrom mmpose.datasets.transforms.common_transforms import (\n    Albumentation, PhotometricDistortion, RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoWholeBodyMetric\nfrom mmpose.models import (CSPNeXt, CSPNeXtPAFPN, KLDiscretLoss,\n                           PoseDataPreprocessor, RTMWHead,\n                           TopdownPoseEstimator)\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 1024\nval_batch_size = 32\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)  # noqa\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=8192)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type=PretrainedInit,\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type=CSPNeXtPAFPN,\n        in_channels=[192, 384, 768],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU, inplace=True)),\n    head=dict(\n        type=RTMWHead,\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = CocoWholeBodyDataset\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PhotometricDistortion),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type=AicDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type=CrowdPoseDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type=MpiiDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type=JhmdbDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type=HalpeDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type=PoseTrack18Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type=HumanArt21Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type=UBody2dDataset,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale, padding=1.25),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type=WFLWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type=Face300WDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type=COFWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type=LapaDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type=InterHand2DDoubleDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=CombinedDataset,\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=CocoWholeBodyDataset,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(  # noqa\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoWholeBodyMetric,\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/wholebody_2d_keypoint/rtmpose/cocktail13/rtmw-x_8xb320-270e_cocktail14-384x288.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *  # noqa\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (AicDataset, CocoWholeBodyDataset, COFWDataset,\n                             CombinedDataset, CrowdPoseDataset,\n                             Face300WDataset, GenerateTarget,\n                             GetBBoxCenterScale, HalpeDataset,\n                             HumanArt21Dataset, InterHand2DDoubleDataset,\n                             JhmdbDataset, KeypointConverter, LapaDataset,\n                             LoadImage, MpiiDataset, PackPoseInputs,\n                             PoseTrack18Dataset, RandomFlip, RandomHalfBody,\n                             TopdownAffine, UBody2dDataset, WFLWDataset)\nfrom mmpose.datasets.transforms.common_transforms import (\n    Albumentation, PhotometricDistortion, RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoWholeBodyMetric\nfrom mmpose.models import (CSPNeXt, CSPNeXtPAFPN, KLDiscretLoss,\n                           PoseDataPreprocessor, RTMWHead,\n                           TopdownPoseEstimator)\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 320\nval_batch_size = 32\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)  # noqa\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=2560)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type=PretrainedInit,\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-384x288-f5b50679_20230822.pth'  # noqa\n        )),\n    neck=dict(\n        type=CSPNeXtPAFPN,\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU, inplace=True)),\n    head=dict(\n        type=RTMWHead,\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = CocoWholeBodyDataset\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PhotometricDistortion),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type=AicDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type=CrowdPoseDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type=MpiiDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type=JhmdbDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type=HalpeDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type=PoseTrack18Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type=HumanArt21Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type=UBody2dDataset,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale, padding=1.25),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type=WFLWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type=Face300WDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type=COFWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type=LapaDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type=InterHand2DDoubleDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=CombinedDataset,\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=CocoWholeBodyDataset,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(  # noqa\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoWholeBodyMetric,\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/configs/wholebody_2d_keypoint/rtmpose/cocktail13/rtmw-x_8xb704-270e_cocktail14-256x192.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.config import read_base\n\nwith read_base():\n    from mmpose.configs._base_.default_runtime import *  # noqa\n\nfrom albumentations.augmentations import Blur, CoarseDropout, MedianBlur\nfrom mmdet.engine.hooks import PipelineSwitchHook\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import CosineAnnealingLR, LinearLR, OptimWrapper\nfrom torch.nn import SiLU, SyncBatchNorm\nfrom torch.optim import AdamW\n\nfrom mmpose.codecs import SimCCLabel\nfrom mmpose.datasets import (AicDataset, CocoWholeBodyDataset, COFWDataset,\n                             CombinedDataset, CrowdPoseDataset,\n                             Face300WDataset, GenerateTarget,\n                             GetBBoxCenterScale, HalpeDataset,\n                             HumanArt21Dataset, InterHand2DDoubleDataset,\n                             JhmdbDataset, KeypointConverter, LapaDataset,\n                             LoadImage, MpiiDataset, PackPoseInputs,\n                             PoseTrack18Dataset, RandomFlip, RandomHalfBody,\n                             TopdownAffine, UBody2dDataset, WFLWDataset)\nfrom mmpose.datasets.transforms.common_transforms import (\n    Albumentation, PhotometricDistortion, RandomBBoxTransform)\nfrom mmpose.engine.hooks import ExpMomentumEMA\nfrom mmpose.evaluation import CocoWholeBodyMetric\nfrom mmpose.models import (CSPNeXt, CSPNeXtPAFPN, KLDiscretLoss,\n                           PoseDataPreprocessor, RTMWHead,\n                           TopdownPoseEstimator)\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 704\nval_batch_size = 32\n\ntrain_cfg.update(max_epochs=max_epochs, val_interval=10)  # noqa\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type=LinearLR, start_factor=1.0e-5, by_epoch=False, begin=0, end=1000),\n    dict(\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=5632)\n\n# codec settings\ncodec = dict(\n    type=SimCCLabel,\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type=TopdownPoseEstimator,\n    data_preprocessor=dict(\n        type=PoseDataPreprocessor,\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type=CSPNeXt,\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type=SiLU),\n        init_cfg=dict(\n            type=PretrainedInit,\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-256x192-05f5bcb7_20230822.pth'  # noqa\n        )),\n    neck=dict(\n        type=CSPNeXtPAFPN,\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type=SyncBatchNorm),\n        act_cfg=dict(type=SiLU, inplace=True)),\n    head=dict(\n        type=RTMWHead,\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type=KLDiscretLoss,\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = CocoWholeBodyDataset\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(type=RandomBBoxTransform, scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PhotometricDistortion),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n            dict(\n                type=CoarseDropout,\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\nval_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(type=PackPoseInputs)\n]\ntrain_pipeline_stage2 = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(type=RandomFlip, direction='horizontal'),\n    dict(type=RandomHalfBody),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type=TopdownAffine, input_size=codec['input_size']),\n    dict(\n        type=Albumentation,\n        transforms=[\n            dict(type=Blur, p=0.1),\n            dict(type=MedianBlur, p=0.1),\n        ]),\n    dict(\n        type=GenerateTarget, encoder=codec, use_dataset_keypoint_weights=True),\n    dict(type=PackPoseInputs)\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type=AicDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type=CrowdPoseDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type=MpiiDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type=JhmdbDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type=HalpeDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type=PoseTrack18Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type=HumanArt21Dataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type=UBody2dDataset,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale, padding=1.25),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type=WFLWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type=Face300WDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type=COFWDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type=LapaDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=GetBBoxCenterScale),\n    dict(\n        type=RandomBBoxTransform,\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type=InterHand2DDoubleDataset,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type=KeypointConverter,\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type=CombinedDataset,\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=CombinedDataset,\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False, round_up=False),\n    dataset=dict(\n        type=CocoWholeBodyDataset,\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks.update(  # noqa\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type=PipelineSwitchHook,\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type=CocoWholeBodyMetric,\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "mmpose/datasets/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .builder import build_dataset\nfrom .dataset_wrappers import CombinedDataset\nfrom .datasets import *  # noqa\nfrom .samplers import MultiSourceSampler\nfrom .transforms import *  # noqa\n\n__all__ = ['build_dataset', 'CombinedDataset', 'MultiSourceSampler']\n"
  },
  {
    "path": "mmpose/datasets/builder.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport platform\nimport random\n\nimport numpy as np\nimport torch\nfrom mmengine import build_from_cfg, is_seq_of\nfrom mmengine.dataset import ConcatDataset, RepeatDataset\n\nfrom mmpose.registry import DATASETS\n\nif platform.system() != 'Windows':\n    # https://github.com/pytorch/pytorch/issues/973\n    import resource\n    rlimit = resource.getrlimit(resource.RLIMIT_NOFILE)\n    base_soft_limit = rlimit[0]\n    hard_limit = rlimit[1]\n    soft_limit = min(max(4096, base_soft_limit), hard_limit)\n    resource.setrlimit(resource.RLIMIT_NOFILE, (soft_limit, hard_limit))\n\n\ndef _concat_dataset(cfg, default_args=None):\n    types = cfg['type']\n    ann_files = cfg['ann_file']\n    img_prefixes = cfg.get('img_prefix', None)\n    dataset_infos = cfg.get('dataset_info', None)\n\n    num_joints = cfg['data_cfg'].get('num_joints', None)\n    dataset_channel = cfg['data_cfg'].get('dataset_channel', None)\n\n    datasets = []\n    num_dset = len(ann_files)\n    for i in range(num_dset):\n        cfg_copy = copy.deepcopy(cfg)\n        cfg_copy['ann_file'] = ann_files[i]\n\n        if isinstance(types, (list, tuple)):\n            cfg_copy['type'] = types[i]\n        if isinstance(img_prefixes, (list, tuple)):\n            cfg_copy['img_prefix'] = img_prefixes[i]\n        if isinstance(dataset_infos, (list, tuple)):\n            cfg_copy['dataset_info'] = dataset_infos[i]\n\n        if isinstance(num_joints, (list, tuple)):\n            cfg_copy['data_cfg']['num_joints'] = num_joints[i]\n\n        if is_seq_of(dataset_channel, list):\n            cfg_copy['data_cfg']['dataset_channel'] = dataset_channel[i]\n\n        datasets.append(build_dataset(cfg_copy, default_args))\n\n    return ConcatDataset(datasets)\n\n\ndef build_dataset(cfg, default_args=None):\n    \"\"\"Build a dataset from config dict.\n\n    Args:\n        cfg (dict): Config dict. It should at least contain the key \"type\".\n        default_args (dict, optional): Default initialization arguments.\n            Default: None.\n\n    Returns:\n        Dataset: The constructed dataset.\n    \"\"\"\n\n    if isinstance(cfg, (list, tuple)):\n        dataset = ConcatDataset([build_dataset(c, default_args) for c in cfg])\n    elif cfg['type'] == 'ConcatDataset':\n        dataset = ConcatDataset(\n            [build_dataset(c, default_args) for c in cfg['datasets']])\n    elif cfg['type'] == 'RepeatDataset':\n        dataset = RepeatDataset(\n            build_dataset(cfg['dataset'], default_args), cfg['times'])\n    elif isinstance(cfg.get('ann_file'), (list, tuple)):\n        dataset = _concat_dataset(cfg, default_args)\n    else:\n        dataset = build_from_cfg(cfg, DATASETS, default_args)\n    return dataset\n\n\ndef worker_init_fn(worker_id, num_workers, rank, seed):\n    \"\"\"Init the random seed for various workers.\"\"\"\n    # The seed of each worker equals to\n    # num_worker * rank + worker_id + user_seed\n    worker_seed = num_workers * rank + worker_id + seed\n    np.random.seed(worker_seed)\n    random.seed(worker_seed)\n    torch.manual_seed(worker_seed)\n"
  },
  {
    "path": "mmpose/datasets/dataset_wrappers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom copy import deepcopy\nfrom typing import Any, Callable, List, Optional, Tuple, Union\n\nimport numpy as np\nfrom mmengine.dataset import BaseDataset\nfrom mmengine.registry import build_from_cfg\n\nfrom mmpose.registry import DATASETS\nfrom .datasets.utils import parse_pose_metainfo\n\n\n@DATASETS.register_module()\nclass CombinedDataset(BaseDataset):\n    \"\"\"A wrapper of combined dataset.\n\n    Args:\n        metainfo (dict): The meta information of combined dataset.\n        datasets (list): The configs of datasets to be combined.\n        pipeline (list, optional): Processing pipeline. Defaults to [].\n        sample_ratio_factor (list, optional): A list of sampling ratio\n            factors for each dataset. Defaults to None\n    \"\"\"\n\n    def __init__(self,\n                 metainfo: dict,\n                 datasets: list,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 sample_ratio_factor: Optional[List[float]] = None,\n                 **kwargs):\n\n        self.datasets = []\n        self.resample = sample_ratio_factor is not None\n\n        for cfg in datasets:\n            dataset = build_from_cfg(cfg, DATASETS)\n            self.datasets.append(dataset)\n\n        self._lens = [len(dataset) for dataset in self.datasets]\n        if self.resample:\n            assert len(sample_ratio_factor) == len(datasets), f'the length ' \\\n                f'of `sample_ratio_factor` {len(sample_ratio_factor)} does ' \\\n                f'not match the length of `datasets` {len(datasets)}'\n            assert min(sample_ratio_factor) >= 0.0, 'the ratio values in ' \\\n                '`sample_ratio_factor` should not be negative.'\n            self._lens_ori = self._lens\n            self._lens = [\n                round(l * sample_ratio_factor[i])\n                for i, l in enumerate(self._lens_ori)\n            ]\n\n        self._len = sum(self._lens)\n\n        super(CombinedDataset, self).__init__(pipeline=pipeline, **kwargs)\n        self._metainfo = parse_pose_metainfo(metainfo)\n\n    @property\n    def metainfo(self):\n        return deepcopy(self._metainfo)\n\n    @property\n    def lens(self):\n        return deepcopy(self._lens)\n\n    def __len__(self):\n        return self._len\n\n    def _get_subset_index(self, index: int) -> Tuple[int, int]:\n        \"\"\"Given a data sample's global index, return the index of the sub-\n        dataset the data sample belongs to, and the local index within that\n        sub-dataset.\n\n        Args:\n            index (int): The global data sample index\n\n        Returns:\n            tuple[int, int]:\n            - subset_index (int): The index of the sub-dataset\n            - local_index (int): The index of the data sample within\n                the sub-dataset\n        \"\"\"\n        if index >= len(self) or index < -len(self):\n            raise ValueError(\n                f'index({index}) is out of bounds for dataset with '\n                f'length({len(self)}).')\n\n        if index < 0:\n            index = index + len(self)\n\n        subset_index = 0\n        while index >= self._lens[subset_index]:\n            index -= self._lens[subset_index]\n            subset_index += 1\n\n        if self.resample:\n            gap = (self._lens_ori[subset_index] -\n                   1e-4) / self._lens[subset_index]\n            index = round(gap * index + np.random.rand() * gap - 0.5)\n\n        return subset_index, index\n\n    def prepare_data(self, idx: int) -> Any:\n        \"\"\"Get data processed by ``self.pipeline``.The source dataset is\n        depending on the index.\n\n        Args:\n            idx (int): The index of ``data_info``.\n\n        Returns:\n            Any: Depends on ``self.pipeline``.\n        \"\"\"\n\n        data_info = self.get_data_info(idx)\n\n        # the assignment of 'dataset' should not be performed within the\n        # `get_data_info` function. Otherwise, it can lead to the mixed\n        # data augmentation process getting stuck.\n        data_info['dataset'] = self\n\n        return self.pipeline(data_info)\n\n    def get_data_info(self, idx: int) -> dict:\n        \"\"\"Get annotation by index.\n\n        Args:\n            idx (int): Global index of ``CombinedDataset``.\n        Returns:\n            dict: The idx-th annotation of the datasets.\n        \"\"\"\n        subset_idx, sample_idx = self._get_subset_index(idx)\n        # Get data sample processed by ``subset.pipeline``\n        data_info = self.datasets[subset_idx][sample_idx]\n\n        if 'dataset' in data_info:\n            data_info.pop('dataset')\n\n        # Add metainfo items that are required in the pipeline and the model\n        metainfo_keys = [\n            'upper_body_ids', 'lower_body_ids', 'flip_pairs',\n            'dataset_keypoint_weights', 'flip_indices'\n        ]\n\n        for key in metainfo_keys:\n            data_info[key] = deepcopy(self._metainfo[key])\n\n        return data_info\n\n    def full_init(self):\n        \"\"\"Fully initialize all sub datasets.\"\"\"\n\n        if self._fully_initialized:\n            return\n\n        for dataset in self.datasets:\n            dataset.full_init()\n        self._fully_initialized = True\n"
  },
  {
    "path": "mmpose/datasets/datasets/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .animal import *  # noqa: F401, F403\nfrom .base import *  # noqa: F401, F403\nfrom .body import *  # noqa: F401, F403\nfrom .body3d import *  # noqa: F401, F403\nfrom .face import *  # noqa: F401, F403\nfrom .fashion import *  # noqa: F401, F403\nfrom .hand import *  # noqa: F401, F403\nfrom .hand3d import *  # noqa: F401, F403\nfrom .wholebody import *  # noqa: F401, F403\nfrom .wholebody3d import *  # noqa: F401, F403\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .animalkingdom_dataset import AnimalKingdomDataset\nfrom .animalpose_dataset import AnimalPoseDataset\nfrom .ap10k_dataset import AP10KDataset\nfrom .atrw_dataset import ATRWDataset\nfrom .fly_dataset import FlyDataset\nfrom .horse10_dataset import Horse10Dataset\nfrom .locust_dataset import LocustDataset\nfrom .macaque_dataset import MacaqueDataset\nfrom .zebra_dataset import ZebraDataset\n\n__all__ = [\n    'AnimalPoseDataset', 'AP10KDataset', 'Horse10Dataset', 'MacaqueDataset',\n    'FlyDataset', 'LocustDataset', 'ZebraDataset', 'ATRWDataset',\n    'AnimalKingdomDataset'\n]\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/animalkingdom_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass AnimalKingdomDataset(BaseCocoStyleDataset):\n    \"\"\"Animal Kingdom dataset for animal pose estimation.\n\n    \"[CVPR2022] Animal Kingdom:\n     A Large and Diverse Dataset for Animal Behavior Understanding\"\n    More details can be found in the `paper\n    <https://www.researchgate.net/publication/\n    359816954_Animal_Kingdom_A_Large_and_Diverse\n    _Dataset_for_Animal_Behavior_Understanding>`__ .\n\n    Website: <https://sutdcv.github.io/Animal-Kingdom>\n\n    The dataset loads raw features and apply specified transforms\n    to return a dict containing the image tensors and other information.\n\n    Animal Kingdom keypoint indexes::\n\n        0: 'Head_Mid_Top',\n        1: 'Eye_Left',\n        2: 'Eye_Right',\n        3: 'Mouth_Front_Top',\n        4: 'Mouth_Back_Left',\n        5: 'Mouth_Back_Right',\n        6: 'Mouth_Front_Bottom',\n        7: 'Shoulder_Left',\n        8: 'Shoulder_Right',\n        9: 'Elbow_Left',\n        10: 'Elbow_Right',\n        11: 'Wrist_Left',\n        12: 'Wrist_Right',\n        13: 'Torso_Mid_Back',\n        14: 'Hip_Left',\n        15: 'Hip_Right',\n        16: 'Knee_Left',\n        17: 'Knee_Right',\n        18: 'Ankle_Left ',\n        19: 'Ankle_Right',\n        20: 'Tail_Top_Back',\n        21: 'Tail_Mid_Back',\n        22: 'Tail_End_Back\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/ak.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/animalpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass AnimalPoseDataset(BaseCocoStyleDataset):\n    \"\"\"Animal-Pose dataset for animal pose estimation.\n\n    \"Cross-domain Adaptation For Animal Pose Estimation\" ICCV'2019\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1908.05806>`__ .\n\n    Animal-Pose keypoints::\n\n        0: 'L_Eye',\n        1: 'R_Eye',\n        2: 'L_EarBase',\n        3: 'R_EarBase',\n        4: 'Nose',\n        5: 'Throat',\n        6: 'TailBase',\n        7: 'Withers',\n        8: 'L_F_Elbow',\n        9: 'R_F_Elbow',\n        10: 'L_B_Elbow',\n        11: 'R_B_Elbow',\n        12: 'L_F_Knee',\n        13: 'R_F_Knee',\n        14: 'L_B_Knee',\n        15: 'R_B_Knee',\n        16: 'L_F_Paw',\n        17: 'R_F_Paw',\n        18: 'L_B_Paw',\n        19: 'R_B_Paw'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/animalpose.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/ap10k_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass AP10KDataset(BaseCocoStyleDataset):\n    \"\"\"AP-10K dataset for animal pose estimation.\n\n    \"AP-10K: A Benchmark for Animal Pose Estimation in the Wild\"\n    Neurips Dataset Track'2021.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2108.12617>`__ .\n\n    AP-10K keypoints::\n\n        0: 'L_Eye',\n        1: 'R_Eye',\n        2: 'Nose',\n        3: 'Neck',\n        4: 'root of tail',\n        5: 'L_Shoulder',\n        6: 'L_Elbow',\n        7: 'L_F_Paw',\n        8: 'R_Shoulder',\n        9: 'R_Elbow',\n        10: 'R_F_Paw,\n        11: 'L_Hip',\n        12: 'L_Knee',\n        13: 'L_B_Paw',\n        14: 'R_Hip',\n        15: 'R_Knee',\n        16: 'R_B_Paw'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/ap10k.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/atrw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass ATRWDataset(BaseCocoStyleDataset):\n    \"\"\"ATRW dataset for animal pose estimation.\n\n    \"ATRW: A Benchmark for Amur Tiger Re-identification in the Wild\"\n    ACM MM'2020.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1906.05586>`__ .\n\n    ATRW keypoints::\n\n        0: \"left_ear\",\n        1: \"right_ear\",\n        2: \"nose\",\n        3: \"right_shoulder\",\n        4: \"right_front_paw\",\n        5: \"left_shoulder\",\n        6: \"left_front_paw\",\n        7: \"right_hip\",\n        8: \"right_knee\",\n        9: \"right_back_paw\",\n        10: \"left_hip\",\n        11: \"left_knee\",\n        12: \"left_back_paw\",\n        13: \"tail\",\n        14: \"center\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/atrw.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/fly_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass FlyDataset(BaseCocoStyleDataset):\n    \"\"\"FlyDataset for animal pose estimation.\n\n    \"Fast animal pose estimation using deep neural networks\"\n    Nature methods'2019. More details can be found in the `paper\n    <https://www.biorxiv.org/content/biorxiv/\\\n    early/2018/05/25/331181.full.pdf>`__ .\n\n    Vinegar Fly keypoints::\n\n        0: \"head\",\n        1: \"eyeL\",\n        2: \"eyeR\",\n        3: \"neck\",\n        4: \"thorax\",\n        5: \"abdomen\",\n        6: \"forelegR1\",\n        7: \"forelegR2\",\n        8: \"forelegR3\",\n        9: \"forelegR4\",\n        10: \"midlegR1\",\n        11: \"midlegR2\",\n        12: \"midlegR3\",\n        13: \"midlegR4\",\n        14: \"hindlegR1\",\n        15: \"hindlegR2\",\n        16: \"hindlegR3\",\n        17: \"hindlegR4\",\n        18: \"forelegL1\",\n        19: \"forelegL2\",\n        20: \"forelegL3\",\n        21: \"forelegL4\",\n        22: \"midlegL1\",\n        23: \"midlegL2\",\n        24: \"midlegL3\",\n        25: \"midlegL4\",\n        26: \"hindlegL1\",\n        27: \"hindlegL2\",\n        28: \"hindlegL3\",\n        29: \"hindlegL4\",\n        30: \"wingL\",\n        31: \"wingR\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/fly.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/horse10_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass Horse10Dataset(BaseCocoStyleDataset):\n    \"\"\"Horse10Dataset for animal pose estimation.\n\n    \"Pretraining boosts out-of-domain robustness for pose estimation\"\n    WACV'2021. More details can be found in the `paper\n    <https://arxiv.org/pdf/1909.11229.pdf>`__ .\n\n    Horse-10 keypoints::\n\n        0: 'Nose',\n        1: 'Eye',\n        2: 'Nearknee',\n        3: 'Nearfrontfetlock',\n        4: 'Nearfrontfoot',\n        5: 'Offknee',\n        6: 'Offfrontfetlock',\n        7: 'Offfrontfoot',\n        8: 'Shoulder',\n        9: 'Midshoulder',\n        10: 'Elbow',\n        11: 'Girth',\n        12: 'Wither',\n        13: 'Nearhindhock',\n        14: 'Nearhindfetlock',\n        15: 'Nearhindfoot',\n        16: 'Hip',\n        17: 'Stifle',\n        18: 'Offhindhock',\n        19: 'Offhindfetlock',\n        20: 'Offhindfoot',\n        21: 'Ischium'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/horse10.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/locust_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass LocustDataset(BaseCocoStyleDataset):\n    \"\"\"LocustDataset for animal pose estimation.\n\n    \"DeepPoseKit, a software toolkit for fast and robust animal\n    pose estimation using deep learning\" Elife'2019.\n    More details can be found in the `paper\n    <https://elifesciences.org/articles/47994>`__ .\n\n    Desert Locust keypoints::\n\n        0: \"head\",\n        1: \"neck\",\n        2: \"thorax\",\n        3: \"abdomen1\",\n        4: \"abdomen2\",\n        5: \"anttipL\",\n        6: \"antbaseL\",\n        7: \"eyeL\",\n        8: \"forelegL1\",\n        9: \"forelegL2\",\n        10: \"forelegL3\",\n        11: \"forelegL4\",\n        12: \"midlegL1\",\n        13: \"midlegL2\",\n        14: \"midlegL3\",\n        15: \"midlegL4\",\n        16: \"hindlegL1\",\n        17: \"hindlegL2\",\n        18: \"hindlegL3\",\n        19: \"hindlegL4\",\n        20: \"anttipR\",\n        21: \"antbaseR\",\n        22: \"eyeR\",\n        23: \"forelegR1\",\n        24: \"forelegR2\",\n        25: \"forelegR3\",\n        26: \"forelegR4\",\n        27: \"midlegR1\",\n        28: \"midlegR2\",\n        29: \"midlegR3\",\n        30: \"midlegR4\",\n        31: \"hindlegR1\",\n        32: \"hindlegR2\",\n        33: \"hindlegR3\",\n        34: \"hindlegR4\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/locust.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw Locust annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # get bbox in shape [1, 4], formatted as xywh\n        # use the entire image which is 160x160\n        bbox = np.array([0, 0, 160, 160], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': ann['num_keypoints'],\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/macaque_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass MacaqueDataset(BaseCocoStyleDataset):\n    \"\"\"MacaquePose dataset for animal pose estimation.\n\n    \"MacaquePose: A novel 'in the wild' macaque monkey pose dataset\n    for markerless motion capture\" bioRxiv'2020.\n    More details can be found in the `paper\n    <https://www.biorxiv.org/content/10.1101/2020.07.30.229989v1>`__ .\n\n    Macaque keypoints::\n\n        0: 'nose',\n        1: 'left_eye',\n        2: 'right_eye',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/macaque.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/animal/zebra_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass ZebraDataset(BaseCocoStyleDataset):\n    \"\"\"ZebraDataset for animal pose estimation.\n\n    \"DeepPoseKit, a software toolkit for fast and robust animal\n    pose estimation using deep learning\" Elife'2019.\n    More details can be found in the `paper\n    <https://elifesciences.org/articles/47994>`__ .\n\n    Zebra keypoints::\n\n        0: \"snout\",\n        1: \"head\",\n        2: \"neck\",\n        3: \"forelegL1\",\n        4: \"forelegR1\",\n        5: \"hindlegL1\",\n        6: \"hindlegR1\",\n        7: \"tailbase\",\n        8: \"tailtip\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/zebra.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw Zebra annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # get bbox in shape [1, 4], formatted as xywh\n        # use the entire image which is 160x160\n        bbox = np.array([0, 0, 160, 160], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = ann['num_keypoints']\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/base/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .base_coco_style_dataset import BaseCocoStyleDataset\nfrom .base_mocap_dataset import BaseMocapDataset\n\n__all__ = ['BaseCocoStyleDataset', 'BaseMocapDataset']\n"
  },
  {
    "path": "mmpose/datasets/datasets/base/base_coco_style_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport os.path as osp\nfrom copy import deepcopy\nfrom itertools import chain, filterfalse, groupby\nfrom typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\nfrom mmengine.dataset import BaseDataset, force_full_init\nfrom mmengine.fileio import exists, get_local_path, load\nfrom mmengine.logging import MessageHub\nfrom mmengine.utils import is_list_of\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_xywh2xyxy\nfrom ..utils import parse_pose_metainfo\n\n\n@DATASETS.register_module()\nclass BaseCocoStyleDataset(BaseDataset):\n    \"\"\"Base class for COCO-style datasets.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n        sample_interval (int, optional): The sample interval of the dataset.\n            Default: 1.\n    \"\"\"\n\n    METAINFO: dict = dict()\n\n    def __init__(self,\n                 ann_file: str = '',\n                 bbox_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000,\n                 sample_interval: int = 1):\n\n        if data_mode not in {'topdown', 'bottomup'}:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid data_mode: '\n                f'{data_mode}. Should be \"topdown\" or \"bottomup\".')\n        self.data_mode = data_mode\n\n        if bbox_file:\n            if self.data_mode != 'topdown':\n                raise ValueError(\n                    f'{self.__class__.__name__} is set to {self.data_mode}: '\n                    'mode, while \"bbox_file\" is only '\n                    'supported in topdown mode.')\n\n            if not test_mode:\n                raise ValueError(\n                    f'{self.__class__.__name__} has `test_mode==False` '\n                    'while \"bbox_file\" is only '\n                    'supported when `test_mode==True`.')\n        self.bbox_file = bbox_file\n        self.sample_interval = sample_interval\n\n        super().__init__(\n            ann_file=ann_file,\n            metainfo=metainfo,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n        if self.test_mode:\n            # save the ann_file into MessageHub for CocoMetric\n            message = MessageHub.get_current_instance()\n            dataset_name = self.metainfo['dataset_name']\n            message.update_info_dict(\n                {f'{dataset_name}_ann_file': self.ann_file})\n\n    @classmethod\n    def _load_metainfo(cls, metainfo: dict = None) -> dict:\n        \"\"\"Collect meta information from the dictionary of meta.\n\n        Args:\n            metainfo (dict): Raw data of pose meta information.\n\n        Returns:\n            dict: Parsed meta information.\n        \"\"\"\n\n        if metainfo is None:\n            metainfo = deepcopy(cls.METAINFO)\n\n        if not isinstance(metainfo, dict):\n            raise TypeError(\n                f'metainfo should be a dict, but got {type(metainfo)}')\n\n        # parse pose metainfo if it has been assigned\n        if metainfo:\n            metainfo = parse_pose_metainfo(metainfo)\n        return metainfo\n\n    @force_full_init\n    def prepare_data(self, idx) -> Any:\n        \"\"\"Get data processed by ``self.pipeline``.\n\n        :class:`BaseCocoStyleDataset` overrides this method from\n        :class:`mmengine.dataset.BaseDataset` to add the metainfo into\n        the ``data_info`` before it is passed to the pipeline.\n\n        Args:\n            idx (int): The index of ``data_info``.\n\n        Returns:\n            Any: Depends on ``self.pipeline``.\n        \"\"\"\n        data_info = self.get_data_info(idx)\n\n        # Mixed image transformations require multiple source images for\n        # effective blending. Therefore, we assign the 'dataset' field in\n        # `data_info` to provide these auxiliary images.\n        # Note: The 'dataset' assignment should not occur within the\n        # `get_data_info` function, as doing so may cause the mixed image\n        # transformations to stall or hang.\n        data_info['dataset'] = self\n\n        return self.pipeline(data_info)\n\n    def get_data_info(self, idx: int) -> dict:\n        \"\"\"Get data info by index.\n\n        Args:\n            idx (int): Index of data info.\n\n        Returns:\n            dict: Data info.\n        \"\"\"\n        data_info = super().get_data_info(idx)\n\n        # Add metainfo items that are required in the pipeline and the model\n        metainfo_keys = [\n            'dataset_name', 'upper_body_ids', 'lower_body_ids', 'flip_pairs',\n            'dataset_keypoint_weights', 'flip_indices', 'skeleton_links'\n        ]\n\n        for key in metainfo_keys:\n            assert key not in data_info, (\n                f'\"{key}\" is a reserved key for `metainfo`, but already '\n                'exists in the `data_info`.')\n\n            data_info[key] = deepcopy(self._metainfo[key])\n\n        return data_info\n\n    def load_data_list(self) -> List[dict]:\n        \"\"\"Load data list from COCO annotation file or person detection result\n        file.\"\"\"\n\n        if self.bbox_file:\n            data_list = self._load_detection_results()\n        else:\n            instance_list, image_list = self._load_annotations()\n\n            if self.data_mode == 'topdown':\n                data_list = self._get_topdown_data_infos(instance_list)\n            else:\n                data_list = self._get_bottomup_data_infos(\n                    instance_list, image_list)\n\n        if hasattr(self, 'coco'):\n            del self.coco\n        return data_list\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in COCO format.\"\"\"\n\n        assert exists(self.ann_file), (\n            f'Annotation file `{self.ann_file}`does not exist')\n\n        with get_local_path(self.ann_file) as local_path:\n            self.coco = COCO(local_path)\n        # set the metainfo about categories, which is a list of dict\n        # and each dict contains the 'id', 'name', etc. about this category\n        if 'categories' in self.coco.dataset:\n            self._metainfo['CLASSES'] = self.coco.loadCats(\n                self.coco.getCatIds())\n\n        instance_list = []\n        image_list = []\n\n        for img_id in self.coco.getImgIds():\n            if img_id % self.sample_interval != 0:\n                continue\n            img = self.coco.loadImgs(img_id)[0]\n            img.update({\n                'img_id':\n                img_id,\n                'img_path':\n                osp.join(self.data_prefix['img'], img['file_name']),\n            })\n            image_list.append(img)\n\n            ann_ids = self.coco.getAnnIds(imgIds=img_id)\n            for ann in self.coco.loadAnns(ann_ids):\n\n                instance_info = self.parse_data_info(\n                    dict(raw_ann_info=ann, raw_img_info=img))\n\n                # skip invalid instance annotation.\n                if not instance_info:\n                    continue\n\n                instance_list.append(instance_info)\n        return instance_list, image_list\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict | None: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        # filter invalid instance\n        if 'bbox' not in ann or 'keypoints' not in ann:\n            return None\n\n        img_w, img_h = img['width'], img['height']\n\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['bbox']\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        if 'num_keypoints' in ann:\n            num_keypoints = ann['num_keypoints']\n        else:\n            num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n\n        if 'area' in ann:\n            area = np.array(ann['area'], dtype=np.float32)\n        else:\n            area = np.clip((x2 - x1) * (y2 - y1) * 0.53, a_min=1.0, a_max=None)\n            area = np.array(area, dtype=np.float32)\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img['img_path'],\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'area': area,\n            'iscrowd': ann.get('iscrowd', 0),\n            'segmentation': ann.get('segmentation', None),\n            'id': ann['id'],\n            'category_id': np.array(ann['category_id']),\n            # store the raw annotation of the instance\n            # it is useful for evaluation without providing ann_file\n            'raw_ann_info': copy.deepcopy(ann),\n        }\n\n        if 'crowdIndex' in img:\n            data_info['crowd_index'] = img['crowdIndex']\n\n        return data_info\n\n    @staticmethod\n    def _is_valid_instance(data_info: Dict) -> bool:\n        \"\"\"Check a data info is an instance with valid bbox and keypoint\n        annotations.\"\"\"\n        # crowd annotation\n        if 'iscrowd' in data_info and data_info['iscrowd']:\n            return False\n        # invalid keypoints\n        if 'num_keypoints' in data_info and data_info['num_keypoints'] == 0:\n            return False\n        # invalid bbox\n        if 'bbox' in data_info:\n            bbox = data_info['bbox'][0]\n            w, h = bbox[2:4] - bbox[:2]\n            if w <= 0 or h <= 0:\n                return False\n        # invalid keypoints\n        if 'keypoints' in data_info:\n            if np.max(data_info['keypoints']) <= 0:\n                return False\n        return True\n\n    def _get_topdown_data_infos(self, instance_list: List[Dict]) -> List[Dict]:\n        \"\"\"Organize the data list in top-down mode.\"\"\"\n        # sanitize data samples\n        data_list_tp = list(filter(self._is_valid_instance, instance_list))\n\n        return data_list_tp\n\n    def _get_bottomup_data_infos(self, instance_list: List[Dict],\n                                 image_list: List[Dict]) -> List[Dict]:\n        \"\"\"Organize the data list in bottom-up mode.\"\"\"\n\n        # bottom-up data list\n        data_list_bu = []\n\n        used_img_ids = set()\n\n        # group instances by img_id\n        for img_id, data_infos in groupby(instance_list,\n                                          lambda x: x['img_id']):\n            used_img_ids.add(img_id)\n            data_infos = list(data_infos)\n\n            # image data\n            img_path = data_infos[0]['img_path']\n            data_info_bu = {\n                'img_id': img_id,\n                'img_path': img_path,\n            }\n\n            for key in data_infos[0].keys():\n                if key not in data_info_bu:\n                    seq = [d[key] for d in data_infos]\n                    if isinstance(seq[0], np.ndarray):\n                        if seq[0].ndim > 0:\n                            seq = np.concatenate(seq, axis=0)\n                        else:\n                            seq = np.stack(seq, axis=0)\n                    elif isinstance(seq[0], (tuple, list)):\n                        seq = list(chain.from_iterable(seq))\n\n                    data_info_bu[key] = seq\n\n            # The segmentation annotation of invalid objects will be used\n            # to generate valid region mask in the pipeline.\n            invalid_segs = []\n            for data_info_invalid in filterfalse(self._is_valid_instance,\n                                                 data_infos):\n                if 'segmentation' in data_info_invalid:\n                    invalid_segs.append(data_info_invalid['segmentation'])\n            data_info_bu['invalid_segs'] = invalid_segs\n\n            data_list_bu.append(data_info_bu)\n\n        # add images without instance for evaluation\n        if self.test_mode:\n            for img_info in image_list:\n                if img_info['img_id'] not in used_img_ids:\n                    data_info_bu = {\n                        'img_id': img_info['img_id'],\n                        'img_path': img_info['img_path'],\n                        'id': list(),\n                        'raw_ann_info': None,\n                    }\n                    data_list_bu.append(data_info_bu)\n\n        return data_list_bu\n\n    def _load_detection_results(self) -> List[dict]:\n        \"\"\"Load data from detection results with dummy keypoint annotations.\"\"\"\n\n        assert exists(self.ann_file), (\n            f'Annotation file `{self.ann_file}` does not exist')\n        assert exists(\n            self.bbox_file), (f'Bbox file `{self.bbox_file}` does not exist')\n        # load detection results\n        det_results = load(self.bbox_file)\n        assert is_list_of(\n            det_results,\n            dict), (f'BBox file `{self.bbox_file}` should be a list of dict, '\n                    f'but got {type(det_results)}')\n\n        # load coco annotations to build image id-to-name index\n        with get_local_path(self.ann_file) as local_path:\n            self.coco = COCO(local_path)\n        # set the metainfo about categories, which is a list of dict\n        # and each dict contains the 'id', 'name', etc. about this category\n        self._metainfo['CLASSES'] = self.coco.loadCats(self.coco.getCatIds())\n\n        num_keypoints = self.metainfo['num_keypoints']\n        data_list = []\n        id_ = 0\n        for det in det_results:\n            # remove non-human instances\n            if det['category_id'] != 1:\n                continue\n\n            img = self.coco.loadImgs(det['image_id'])[0]\n\n            img_path = osp.join(self.data_prefix['img'], img['file_name'])\n            bbox_xywh = np.array(\n                det['bbox'][:4], dtype=np.float32).reshape(1, 4)\n            bbox = bbox_xywh2xyxy(bbox_xywh)\n            bbox_score = np.array(det['score'], dtype=np.float32).reshape(1)\n\n            # use dummy keypoint location and visibility\n            keypoints = np.zeros((1, num_keypoints, 2), dtype=np.float32)\n            keypoints_visible = np.ones((1, num_keypoints), dtype=np.float32)\n\n            data_list.append({\n                'img_id': det['image_id'],\n                'img_path': img_path,\n                'img_shape': (img['height'], img['width']),\n                'bbox': bbox,\n                'bbox_score': bbox_score,\n                'keypoints': keypoints,\n                'keypoints_visible': keypoints_visible,\n                'id': id_,\n            })\n\n            id_ += 1\n\n        return data_list\n\n    def filter_data(self) -> List[dict]:\n        \"\"\"Filter annotations according to filter_cfg. Defaults return full\n        ``data_list``.\n\n        If 'bbox_score_thr` in filter_cfg, the annotation with bbox_score below\n        the threshold `bbox_score_thr` will be filtered out.\n        \"\"\"\n\n        data_list = self.data_list\n\n        if self.filter_cfg is None:\n            return data_list\n\n        # filter out annotations with a bbox_score below the threshold\n        if 'bbox_score_thr' in self.filter_cfg:\n\n            if self.data_mode != 'topdown':\n                raise ValueError(\n                    f'{self.__class__.__name__} is set to {self.data_mode} '\n                    'mode, while \"bbox_score_thr\" is only supported in '\n                    'topdown mode.')\n\n            thr = self.filter_cfg['bbox_score_thr']\n            data_list = list(\n                filterfalse(lambda ann: ann['bbox_score'] < thr, data_list))\n\n        return data_list\n"
  },
  {
    "path": "mmpose/datasets/datasets/base/base_mocap_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport itertools\nimport logging\nimport os.path as osp\nfrom copy import deepcopy\nfrom itertools import filterfalse, groupby\nfrom typing import Any, Callable, Dict, List, Optional, Sequence, Tuple, Union\n\nimport cv2\nimport numpy as np\nfrom mmengine.dataset import BaseDataset, force_full_init\nfrom mmengine.fileio import exists, get_local_path, load\nfrom mmengine.logging import print_log\nfrom mmengine.utils import is_abs\n\nfrom mmpose.registry import DATASETS\nfrom ..utils import parse_pose_metainfo\n\n\n@DATASETS.register_module()\nclass BaseMocapDataset(BaseDataset):\n    \"\"\"Base class for 3d body datasets.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        seq_len (int): Number of frames in a sequence. Default: 1.\n        multiple_target (int): If larger than 0, merge every\n            ``multiple_target`` sequence together. Default: 0.\n        causal (bool): If set to ``True``, the rightmost input frame will be\n            the target frame. Otherwise, the middle input frame will be the\n            target frame. Default: ``True``.\n        subset_frac (float): The fraction to reduce dataset size. If set to 1,\n            the dataset size is not reduced. Default: 1.\n        camera_param_file (str): Cameras' parameters file. Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict()\n\n    def __init__(self,\n                 ann_file: str = '',\n                 seq_len: int = 1,\n                 multiple_target: int = 0,\n                 causal: bool = True,\n                 subset_frac: float = 1.0,\n                 camera_param_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000):\n\n        if data_mode not in {'topdown', 'bottomup'}:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid data_mode: '\n                f'{data_mode}. Should be \"topdown\" or \"bottomup\".')\n        self.data_mode = data_mode\n\n        _ann_file = ann_file\n        if not is_abs(_ann_file):\n            _ann_file = osp.join(data_root, _ann_file)\n        assert exists(_ann_file), (\n            f'Annotation file `{_ann_file}` does not exist.')\n\n        self._load_ann_file(_ann_file)\n\n        self.camera_param_file = camera_param_file\n        if self.camera_param_file:\n            if not is_abs(self.camera_param_file):\n                self.camera_param_file = osp.join(data_root,\n                                                  self.camera_param_file)\n            assert exists(self.camera_param_file), (\n                f'Camera parameters file `{self.camera_param_file}` does not '\n                'exist.')\n            self.camera_param = load(self.camera_param_file)\n\n        self.seq_len = seq_len\n        self.causal = causal\n\n        self.multiple_target = multiple_target\n        if self.multiple_target:\n            assert (self.seq_len == 1), (\n                'Multi-target data sample only supports seq_len=1.')\n\n        assert 0 < subset_frac <= 1, (\n            f'Unsupported `subset_frac` {subset_frac}. Supported range '\n            'is (0, 1].')\n        self.subset_frac = subset_frac\n\n        self.sequence_indices = self.get_sequence_indices()\n\n        super().__init__(\n            ann_file=ann_file,\n            metainfo=metainfo,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n    def _load_ann_file(self, ann_file: str) -> dict:\n        \"\"\"Load annotation file to get image information.\n\n        Args:\n            ann_file (str): Annotation file path.\n\n        Returns:\n            dict: Annotation information.\n        \"\"\"\n\n        with get_local_path(ann_file) as local_path:\n            self.ann_data = np.load(local_path)\n\n    @classmethod\n    def _load_metainfo(cls, metainfo: dict = None) -> dict:\n        \"\"\"Collect meta information from the dictionary of meta.\n\n        Args:\n            metainfo (dict): Raw data of pose meta information.\n\n        Returns:\n            dict: Parsed meta information.\n        \"\"\"\n\n        if metainfo is None:\n            metainfo = deepcopy(cls.METAINFO)\n\n        if not isinstance(metainfo, dict):\n            raise TypeError(\n                f'metainfo should be a dict, but got {type(metainfo)}')\n\n        # parse pose metainfo if it has been assigned\n        if metainfo:\n            metainfo = parse_pose_metainfo(metainfo)\n        return metainfo\n\n    @force_full_init\n    def prepare_data(self, idx) -> Any:\n        \"\"\"Get data processed by ``self.pipeline``.\n\n        :class:`BaseCocoStyleDataset` overrides this method from\n        :class:`mmengine.dataset.BaseDataset` to add the metainfo into\n        the ``data_info`` before it is passed to the pipeline.\n\n        Args:\n            idx (int): The index of ``data_info``.\n\n        Returns:\n            Any: Depends on ``self.pipeline``.\n        \"\"\"\n        data_info = self.get_data_info(idx)\n\n        return self.pipeline(data_info)\n\n    def get_data_info(self, idx: int) -> dict:\n        \"\"\"Get data info by index.\n\n        Args:\n            idx (int): Index of data info.\n\n        Returns:\n            dict: Data info.\n        \"\"\"\n        data_info = super().get_data_info(idx)\n\n        # Add metainfo items that are required in the pipeline and the model\n        metainfo_keys = [\n            'upper_body_ids', 'lower_body_ids', 'flip_pairs',\n            'dataset_keypoint_weights', 'flip_indices', 'skeleton_links'\n        ]\n\n        for key in metainfo_keys:\n            assert key not in data_info, (\n                f'\"{key}\" is a reserved key for `metainfo`, but already '\n                'exists in the `data_info`.')\n\n            data_info[key] = deepcopy(self._metainfo[key])\n\n        return data_info\n\n    def load_data_list(self) -> List[dict]:\n        \"\"\"Load data list from COCO annotation file or person detection result\n        file.\"\"\"\n\n        instance_list, image_list = self._load_annotations()\n\n        if self.data_mode == 'topdown':\n            data_list = self._get_topdown_data_infos(instance_list)\n        else:\n            data_list = self._get_bottomup_data_infos(instance_list,\n                                                      image_list)\n\n        return data_list\n\n    def get_img_info(self, img_idx, img_name):\n        try:\n            with get_local_path(osp.join(self.data_prefix['img'],\n                                         img_name)) as local_path:\n                im = cv2.imread(local_path)\n                h, w, _ = im.shape\n        except:  # noqa: E722\n            print_log(\n                f'Failed to read image {img_name}.',\n                logger='current',\n                level=logging.DEBUG)\n            return None\n\n        img = {\n            'file_name': img_name,\n            'height': h,\n            'width': w,\n            'id': img_idx,\n            'img_id': img_idx,\n            'img_path': osp.join(self.data_prefix['img'], img_name),\n        }\n        return img\n\n    def get_sequence_indices(self) -> List[List[int]]:\n        \"\"\"Build sequence indices.\n\n        The default method creates sample indices that each sample is a single\n        frame (i.e. seq_len=1). Override this method in the subclass to define\n        how frames are sampled to form data samples.\n\n        Outputs:\n            sample_indices: the frame indices of each sample.\n                For a sample, all frames will be treated as an input sequence,\n                and the ground-truth pose of the last frame will be the target.\n        \"\"\"\n        sequence_indices = []\n        if self.seq_len == 1:\n            num_imgs = len(self.ann_data['imgname'])\n            sequence_indices = [[idx] for idx in range(num_imgs)]\n        else:\n            raise NotImplementedError('Multi-frame data sample unsupported!')\n\n        if self.multiple_target > 0:\n            sequence_indices_merged = []\n            for i in range(0, len(sequence_indices), self.multiple_target):\n                if i + self.multiple_target > len(sequence_indices):\n                    break\n                sequence_indices_merged.append(\n                    list(\n                        itertools.chain.from_iterable(\n                            sequence_indices[i:i + self.multiple_target])))\n            sequence_indices = sequence_indices_merged\n        return sequence_indices\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in COCO format.\"\"\"\n        num_keypoints = self.metainfo['num_keypoints']\n\n        img_names = self.ann_data['imgname']\n        num_imgs = len(img_names)\n\n        if 'S' in self.ann_data.keys():\n            kpts_3d = self.ann_data['S']\n        else:\n            kpts_3d = np.zeros((num_imgs, num_keypoints, 4), dtype=np.float32)\n\n        if 'part' in self.ann_data.keys():\n            kpts_2d = self.ann_data['part']\n        else:\n            kpts_2d = np.zeros((num_imgs, num_keypoints, 3), dtype=np.float32)\n\n        if 'center' in self.ann_data.keys():\n            centers = self.ann_data['center']\n        else:\n            centers = np.zeros((num_imgs, 2), dtype=np.float32)\n\n        if 'scale' in self.ann_data.keys():\n            scales = self.ann_data['scale'].astype(np.float32)\n        else:\n            scales = np.zeros(num_imgs, dtype=np.float32)\n\n        instance_list = []\n        image_list = []\n\n        for idx, frame_ids in enumerate(self.sequence_indices):\n            expected_num_frames = self.seq_len\n            if self.multiple_target:\n                expected_num_frames = self.multiple_target\n\n            assert len(frame_ids) == (expected_num_frames), (\n                f'Expected `frame_ids` == {expected_num_frames}, but '\n                f'got {len(frame_ids)} ')\n\n            _img_names = img_names[frame_ids]\n\n            _keypoints = kpts_2d[frame_ids].astype(np.float32)\n            keypoints = _keypoints[..., :2]\n            keypoints_visible = _keypoints[..., 2]\n\n            _keypoints_3d = kpts_3d[frame_ids].astype(np.float32)\n            keypoints_3d = _keypoints_3d[..., :3]\n            keypoints_3d_visible = _keypoints_3d[..., 3]\n\n            target_idx = [-1] if self.causal else [int(self.seq_len) // 2]\n            if self.multiple_target:\n                target_idx = list(range(self.multiple_target))\n\n            instance_info = {\n                'num_keypoints': num_keypoints,\n                'keypoints': keypoints,\n                'keypoints_visible': keypoints_visible,\n                'keypoints_3d': keypoints_3d,\n                'keypoints_3d_visible': keypoints_3d_visible,\n                'scale': scales[idx],\n                'center': centers[idx].astype(np.float32).reshape(1, -1),\n                'id': idx,\n                'category_id': 1,\n                'iscrowd': 0,\n                'img_paths': list(_img_names),\n                'img_ids': frame_ids,\n                'lifting_target': keypoints_3d[target_idx],\n                'lifting_target_visible': keypoints_3d_visible[target_idx],\n                'target_img_path': _img_names[target_idx],\n            }\n\n            if self.camera_param_file:\n                _cam_param = self.get_camera_param(_img_names[0])\n                instance_info['camera_param'] = _cam_param\n\n            instance_list.append(instance_info)\n\n        if self.data_mode == 'bottomup':\n            for idx, imgname in enumerate(img_names):\n                img_info = self.get_img_info(idx, imgname)\n                image_list.append(img_info)\n\n        return instance_list, image_list\n\n    def get_camera_param(self, imgname):\n        \"\"\"Get camera parameters of a frame by its image name.\n\n        Override this method to specify how to get camera parameters.\n        \"\"\"\n        raise NotImplementedError\n\n    @staticmethod\n    def _is_valid_instance(data_info: Dict) -> bool:\n        \"\"\"Check a data info is an instance with valid bbox and keypoint\n        annotations.\"\"\"\n        # crowd annotation\n        if 'iscrowd' in data_info and data_info['iscrowd']:\n            return False\n        # invalid keypoints\n        if 'num_keypoints' in data_info and data_info['num_keypoints'] == 0:\n            return False\n        # invalid keypoints\n        if 'keypoints' in data_info:\n            if np.max(data_info['keypoints']) <= 0:\n                return False\n        return True\n\n    def _get_topdown_data_infos(self, instance_list: List[Dict]) -> List[Dict]:\n        \"\"\"Organize the data list in top-down mode.\"\"\"\n        # sanitize data samples\n        data_list_tp = list(filter(self._is_valid_instance, instance_list))\n\n        return data_list_tp\n\n    def _get_bottomup_data_infos(self, instance_list: List[Dict],\n                                 image_list: List[Dict]) -> List[Dict]:\n        \"\"\"Organize the data list in bottom-up mode.\"\"\"\n\n        # bottom-up data list\n        data_list_bu = []\n\n        used_img_ids = set()\n\n        # group instances by img_id\n        for img_ids, data_infos in groupby(instance_list,\n                                           lambda x: x['img_ids']):\n            for img_id in img_ids:\n                used_img_ids.add(img_id)\n            data_infos = list(data_infos)\n\n            # image data\n            img_paths = data_infos[0]['img_paths']\n            data_info_bu = {\n                'img_ids': img_ids,\n                'img_paths': img_paths,\n            }\n\n            for key in data_infos[0].keys():\n                if key not in data_info_bu:\n                    seq = [d[key] for d in data_infos]\n                    if isinstance(seq[0], np.ndarray):\n                        seq = np.concatenate(seq, axis=0)\n                    data_info_bu[key] = seq\n\n            # The segmentation annotation of invalid objects will be used\n            # to generate valid region mask in the pipeline.\n            invalid_segs = []\n            for data_info_invalid in filterfalse(self._is_valid_instance,\n                                                 data_infos):\n                if 'segmentation' in data_info_invalid:\n                    invalid_segs.append(data_info_invalid['segmentation'])\n            data_info_bu['invalid_segs'] = invalid_segs\n\n            data_list_bu.append(data_info_bu)\n\n        # add images without instance for evaluation\n        if self.test_mode:\n            for img_info in image_list:\n                if img_info['img_id'] not in used_img_ids:\n                    data_info_bu = {\n                        'img_ids': [img_info['img_id']],\n                        'img_path': [img_info['img_path']],\n                        'id': list(),\n                    }\n                    data_list_bu.append(data_info_bu)\n\n        return data_list_bu\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .aic_dataset import AicDataset\nfrom .coco_dataset import CocoDataset\nfrom .crowdpose_dataset import CrowdPoseDataset\nfrom .exlpose_dataset import ExlposeDataset\nfrom .humanart21_dataset import HumanArt21Dataset\nfrom .humanart_dataset import HumanArtDataset\nfrom .jhmdb_dataset import JhmdbDataset\nfrom .mhp_dataset import MhpDataset\nfrom .mpii_dataset import MpiiDataset\nfrom .mpii_trb_dataset import MpiiTrbDataset\nfrom .ochuman_dataset import OCHumanDataset\nfrom .posetrack18_dataset import PoseTrack18Dataset\nfrom .posetrack18_video_dataset import PoseTrack18VideoDataset\n\n__all__ = [\n    'CocoDataset', 'MpiiDataset', 'MpiiTrbDataset', 'AicDataset',\n    'CrowdPoseDataset', 'OCHumanDataset', 'MhpDataset', 'PoseTrack18Dataset',\n    'JhmdbDataset', 'PoseTrack18VideoDataset', 'HumanArtDataset',\n    'HumanArt21Dataset', 'ExlposeDataset'\n]\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/aic_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass AicDataset(BaseCocoStyleDataset):\n    \"\"\"AIC dataset for pose estimation.\n\n    \"AI Challenger : A Large-scale Dataset for Going Deeper\n    in Image Understanding\", arXiv'2017.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1711.06475>`__\n\n    AIC keypoints::\n\n        0: \"right_shoulder\",\n        1: \"right_elbow\",\n        2: \"right_wrist\",\n        3: \"left_shoulder\",\n        4: \"left_elbow\",\n        5: \"left_wrist\",\n        6: \"right_hip\",\n        7: \"right_knee\",\n        8: \"right_ankle\",\n        9: \"left_hip\",\n        10: \"left_knee\",\n        11: \"left_ankle\",\n        12: \"head_top\",\n        13: \"neck\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/aic.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/coco_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass CocoDataset(BaseCocoStyleDataset):\n    \"\"\"COCO dataset for pose estimation.\n\n    \"Microsoft COCO: Common Objects in Context\", ECCV'2014.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1405.0312>`__ .\n\n    COCO keypoints::\n\n        0: 'nose',\n        1: 'left_eye',\n        2: 'right_eye',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/coco.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/crowdpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass CrowdPoseDataset(BaseCocoStyleDataset):\n    \"\"\"CrowdPose dataset for pose estimation.\n\n    \"CrowdPose: Efficient Crowded Scenes Pose Estimation and\n    A New Benchmark\", CVPR'2019.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1812.00324>`__.\n\n    CrowdPose keypoints::\n\n        0: 'left_shoulder',\n        1: 'right_shoulder',\n        2: 'left_elbow',\n        3: 'right_elbow',\n        4: 'left_wrist',\n        5: 'right_wrist',\n        6: 'left_hip',\n        7: 'right_hip',\n        8: 'left_knee',\n        9: 'right_knee',\n        10: 'left_ankle',\n        11: 'right_ankle',\n        12: 'top_head',\n        13: 'neck'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/crowdpose.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/exlpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass ExlposeDataset(BaseCocoStyleDataset):\n    \"\"\"Exlpose dataset for pose estimation.\n\n    \"Human Pose Estimation in Extremely Low-Light Conditions\",\n    CVPR'2023.\n    More details can be found in the `paper\n    <http://cg.postech.ac.kr/research/ExLPose/>`__.\n\n    ExLPose keypoints:\n        0: \"left_shoulder\",\n        1: \"right_shoulder\",\n        2: \"left_elbow\",\n        3: \"right_elbow\",\n        4: \"left_wrist\",\n        5: \"right_wrist\",\n        6: \"left_hip\",\n        7: \"right_hip\",\n        8: \"left_knee\",\n        9: \"right_knee\",\n        10: \"left_ankle\",\n        11: \"right_ankle\",\n        12: \"head\",\n        13: \"neck\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/exlpose.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/humanart21_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom .humanart_dataset import HumanArtDataset\n\n\n@DATASETS.register_module()\nclass HumanArt21Dataset(HumanArtDataset):\n    \"\"\"Human-Art dataset for pose estimation with 21 kpts.\n\n    \"Human-Art: A Versatile Human-Centric Dataset\n    Bridging Natural and Artificial Scenes\", CVPR'2023.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2303.02760>`__ .\n\n    Human-Art keypoints::\n\n        0: 'nose',\n        1: 'left_eye',\n        2: 'right_eye',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle',\n        17: 'left_finger',\n        18: 'right_finger',\n        19: 'left_toe',\n        20: 'right_toe',\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/humanart21.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict | None: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        # filter invalid instance\n        if 'bbox' not in ann or 'keypoints' not in ann:\n            return None\n\n        img_w, img_h = img['width'], img['height']\n\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['bbox']\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints_21'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        if 'num_keypoints' in ann:\n            num_keypoints = ann['num_keypoints']\n        else:\n            num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img['img_path'],\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann.get('iscrowd', 0),\n            'segmentation': ann.get('segmentation', None),\n            'id': ann['id'],\n            'category_id': ann['category_id'],\n            # store the raw annotation of the instance\n            # it is useful for evaluation without providing ann_file\n            'raw_ann_info': copy.deepcopy(ann),\n        }\n\n        if 'crowdIndex' in img:\n            data_info['crowd_index'] = img['crowdIndex']\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/humanart_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass HumanArtDataset(BaseCocoStyleDataset):\n    \"\"\"Human-Art dataset for pose estimation with 17 kpts.\n\n    \"Human-Art: A Versatile Human-Centric Dataset\n    Bridging Natural and Artificial Scenes\", CVPR'2023.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2303.02760>`__ .\n\n    Human-Art keypoints::\n\n        0: 'nose',\n        1: 'left_eye',\n        2: 'right_eye',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/humanart.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/jhmdb_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass JhmdbDataset(BaseCocoStyleDataset):\n    \"\"\"JhmdbDataset dataset for pose estimation.\n\n    \"Towards understanding action recognition\", ICCV'2013.\n    More details can be found in the `paper\n    <https://openaccess.thecvf.com/content_iccv_2013/papers/\\\n    Jhuang_Towards_Understanding_Action_2013_ICCV_paper.pdf>`__\n\n    sub-JHMDB keypoints::\n\n        0: \"neck\",\n        1: \"belly\",\n        2: \"head\",\n        3: \"right_shoulder\",\n        4: \"left_shoulder\",\n        5: \"right_hip\",\n        6: \"left_hip\",\n        7: \"right_elbow\",\n        8: \"left_elbow\",\n        9: \"right_knee\",\n        10: \"left_knee\",\n        11: \"right_wrist\",\n        12: \"left_wrist\",\n        13: \"right_ankle\",\n        14: \"left_ankle\"\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/jhmdb.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n        img_w, img_h = img['width'], img['height']\n\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['bbox']\n        # JHMDB uses matlab format, index is 1-based,\n        # we should first convert to 0-based index\n        x -= 1\n        y -= 1\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        # JHMDB uses matlab format, index is 1-based,\n        # we should first convert to 0-based index\n        keypoints = _keypoints[..., :2] - 1\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n        area = np.clip((x2 - x1) * (y2 - y1) * 0.53, a_min=1.0, a_max=None)\n        category_id = ann.get('category_id', [1] * len(keypoints))\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'area': np.array(area, dtype=np.float32),\n            'iscrowd': ann.get('iscrowd', 0),\n            'segmentation': ann.get('segmentation', None),\n            'id': ann['id'],\n            'category_id': category_id,\n        }\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/mhp_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass MhpDataset(BaseCocoStyleDataset):\n    \"\"\"MHPv2.0 dataset for pose estimation.\n\n    \"Understanding Humans in Crowded Scenes: Deep Nested Adversarial\n    Learning and A New Benchmark for Multi-Human Parsing\", ACM MM'2018.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1804.03287>`__\n\n    MHP keypoints::\n\n        0: \"right ankle\",\n        1: \"right knee\",\n        2: \"right hip\",\n        3: \"left hip\",\n        4: \"left knee\",\n        5: \"left ankle\",\n        6: \"pelvis\",\n        7: \"thorax\",\n        8: \"upper neck\",\n        9: \"head top\",\n        10: \"right wrist\",\n        11: \"right elbow\",\n        12: \"right shoulder\",\n        13: \"left shoulder\",\n        14: \"left elbow\",\n        15: \"left wrist\",\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/mhp.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/mpii_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os.path as osp\nfrom typing import Callable, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path\nfrom scipy.io import loadmat\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_cs2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass MpiiDataset(BaseCocoStyleDataset):\n    \"\"\"MPII Dataset for pose estimation.\n\n    \"2D Human Pose Estimation: New Benchmark and State of the Art Analysis\"\n    ,CVPR'2014. More details can be found in the `paper\n    <http://human-pose.mpi-inf.mpg.de/contents/andriluka14cvpr.pdf>`__ .\n\n    MPII keypoints::\n\n        0: 'right_ankle'\n        1: 'right_knee',\n        2: 'right_hip',\n        3: 'left_hip',\n        4: 'left_knee',\n        5: 'left_ankle',\n        6: 'pelvis',\n        7: 'thorax',\n        8: 'upper_neck',\n        9: 'head_top',\n        10: 'right_wrist',\n        11: 'right_elbow',\n        12: 'right_shoulder',\n        13: 'left_shoulder',\n        14: 'left_elbow',\n        15: 'left_wrist'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        headbox_file (str, optional): The path of ``mpii_gt_val.mat`` which\n            provides the headboxes information used for ``PCKh``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/mpii.py')\n\n    def __init__(self,\n                 ann_file: str = '',\n                 bbox_file: Optional[str] = None,\n                 headbox_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000):\n\n        if headbox_file:\n            if data_mode != 'topdown':\n                raise ValueError(\n                    f'{self.__class__.__name__} is set to {data_mode}: '\n                    'mode, while \"headbox_file\" is only '\n                    'supported in topdown mode.')\n\n            if not test_mode:\n                raise ValueError(\n                    f'{self.__class__.__name__} has `test_mode==False` '\n                    'while \"headbox_file\" is only '\n                    'supported when `test_mode==True`.')\n\n            headbox_file_type = headbox_file[-3:]\n            allow_headbox_file_type = ['mat']\n            if headbox_file_type not in allow_headbox_file_type:\n                raise KeyError(\n                    f'The head boxes file type {headbox_file_type} is not '\n                    f'supported. Should be `mat` but got {headbox_file_type}.')\n        self.headbox_file = headbox_file\n\n        super().__init__(\n            ann_file=ann_file,\n            bbox_file=bbox_file,\n            data_mode=data_mode,\n            metainfo=metainfo,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in MPII format.\"\"\"\n\n        assert exists(self.ann_file), (\n            f'Annotation file `{self.ann_file}` does not exist')\n\n        with get_local_path(self.ann_file) as local_path:\n            with open(local_path) as anno_file:\n                self.anns = json.load(anno_file)\n\n        if self.headbox_file:\n            assert exists(self.headbox_file), (\n                f'Headbox file `{self.headbox_file}` does not exist')\n\n            with get_local_path(self.headbox_file) as local_path:\n                self.headbox_dict = loadmat(local_path)\n            headboxes_src = np.transpose(self.headbox_dict['headboxes_src'],\n                                         [2, 0, 1])\n            SC_BIAS = 0.6\n\n        instance_list = []\n        image_list = []\n        used_img_ids = set()\n        ann_id = 0\n\n        # mpii bbox scales are normalized with factor 200.\n        pixel_std = 200.\n\n        for idx, ann in enumerate(self.anns):\n            center = np.array(ann['center'], dtype=np.float32)\n            scale = np.array([ann['scale'], ann['scale']],\n                             dtype=np.float32) * pixel_std\n\n            # Adjust center/scale slightly to avoid cropping limbs\n            if center[0] != -1:\n                center[1] = center[1] + 15. / pixel_std * scale[1]\n\n            # MPII uses matlab format, index is 1-based,\n            # we should first convert to 0-based index\n            center = center - 1\n\n            # unify shape with coco datasets\n            center = center.reshape(1, -1)\n            scale = scale.reshape(1, -1)\n            bbox = bbox_cs2xyxy(center, scale)\n\n            # load keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n            keypoints = np.array(\n                ann['joints'], dtype=np.float32).reshape(1, -1, 2)\n            keypoints_visible = np.array(ann['joints_vis']).reshape(1, -1)\n\n            x1, y1, x2, y2 = np.split(bbox, axis=1, indices_or_sections=4)\n            area = np.clip((x2 - x1) * (y2 - y1) * 0.53, a_min=1.0, a_max=None)\n            area = area[..., 0].astype(np.float32)\n\n            category_id = ann.get('category_id', [1] * len(bbox))\n\n            instance_info = {\n                'id': ann_id,\n                'img_id': int(ann['image'].split('.')[0]),\n                'img_path': osp.join(self.data_prefix['img'], ann['image']),\n                'bbox_center': center,\n                'bbox_scale': scale,\n                'bbox': bbox,\n                'bbox_score': np.ones(1, dtype=np.float32),\n                'keypoints': keypoints,\n                'keypoints_visible': keypoints_visible,\n                'area': area,\n                'category_id': category_id,\n            }\n\n            if self.headbox_file:\n                # calculate the diagonal length of head box as norm_factor\n                headbox = headboxes_src[idx]\n                head_size = np.linalg.norm(headbox[1] - headbox[0], axis=0)\n                head_size *= SC_BIAS\n                instance_info['head_size'] = head_size.reshape(1, -1)\n\n            if instance_info['img_id'] not in used_img_ids:\n                used_img_ids.add(instance_info['img_id'])\n                image_list.append({\n                    'img_id': instance_info['img_id'],\n                    'img_path': instance_info['img_path'],\n                })\n\n            instance_list.append(instance_info)\n            ann_id = ann_id + 1\n        del self.anns\n        self.coco = None\n        return instance_list, image_list\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/mpii_trb_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os.path as osp\nfrom typing import List, Tuple\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_cs2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass MpiiTrbDataset(BaseCocoStyleDataset):\n    \"\"\"MPII-TRB Dataset dataset for pose estimation.\n\n    \"TRB: A Novel Triplet Representation for Understanding 2D Human Body\",\n    ICCV'2019. More details can be found in the `paper\n    <https://arxiv.org/abs/1910.11535>`__ .\n\n    MPII-TRB keypoints::\n\n        0: 'left_shoulder'\n        1: 'right_shoulder'\n        2: 'left_elbow'\n        3: 'right_elbow'\n        4: 'left_wrist'\n        5: 'right_wrist'\n        6: 'left_hip'\n        7: 'right_hip'\n        8: 'left_knee'\n        9: 'right_knee'\n        10: 'left_ankle'\n        11: 'right_ankle'\n        12: 'head'\n        13: 'neck'\n\n        14: 'right_neck'\n        15: 'left_neck'\n        16: 'medial_right_shoulder'\n        17: 'lateral_right_shoulder'\n        18: 'medial_right_bow'\n        19: 'lateral_right_bow'\n        20: 'medial_right_wrist'\n        21: 'lateral_right_wrist'\n        22: 'medial_left_shoulder'\n        23: 'lateral_left_shoulder'\n        24: 'medial_left_bow'\n        25: 'lateral_left_bow'\n        26: 'medial_left_wrist'\n        27: 'lateral_left_wrist'\n        28: 'medial_right_hip'\n        29: 'lateral_right_hip'\n        30: 'medial_right_knee'\n        31: 'lateral_right_knee'\n        32: 'medial_right_ankle'\n        33: 'lateral_right_ankle'\n        34: 'medial_left_hip'\n        35: 'lateral_left_hip'\n        36: 'medial_left_knee'\n        37: 'lateral_left_knee'\n        38: 'medial_left_ankle'\n        39: 'lateral_left_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/mpii_trb.py')\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in MPII-TRB format.\"\"\"\n\n        assert exists(self.ann_file), (\n            f'Annotation file `{self.ann_file}` does not exist')\n\n        with get_local_path(self.ann_file) as local_path:\n            with open(local_path) as anno_file:\n                self.data = json.load(anno_file)\n\n        imgid2info = {img['id']: img for img in self.data['images']}\n\n        instance_list = []\n        image_list = []\n        used_img_ids = set()\n\n        # mpii-trb bbox scales are normalized with factor 200.\n        pixel_std = 200.\n\n        for ann in self.data['annotations']:\n            img_id = ann['image_id']\n\n            # center, scale in shape [1, 2] and bbox in [1, 4]\n            center = np.array([ann['center']], dtype=np.float32)\n            scale = np.array([[ann['scale'], ann['scale']]],\n                             dtype=np.float32) * pixel_std\n            bbox = bbox_cs2xyxy(center, scale)\n\n            # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n            _keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n            keypoints = _keypoints[..., :2]\n            keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n            img_path = osp.join(self.data_prefix['img'],\n                                imgid2info[img_id]['file_name'])\n\n            instance_info = {\n                'id': ann['id'],\n                'img_id': img_id,\n                'img_path': img_path,\n                'bbox_center': center,\n                'bbox_scale': scale,\n                'bbox': bbox,\n                'bbox_score': np.ones(1, dtype=np.float32),\n                'num_keypoints': ann['num_joints'],\n                'keypoints': keypoints,\n                'keypoints_visible': keypoints_visible,\n                'iscrowd': ann['iscrowd'],\n            }\n\n            # val set\n            if 'headbox' in ann:\n                instance_info['headbox'] = np.array(\n                    ann['headbox'], dtype=np.float32)\n\n            instance_list.append(instance_info)\n            if instance_info['img_id'] not in used_img_ids:\n                used_img_ids.add(instance_info['img_id'])\n                image_list.append({\n                    'img_id': instance_info['img_id'],\n                    'img_path': instance_info['img_path'],\n                })\n\n        instance_list = sorted(instance_list, key=lambda x: x['id'])\n        return instance_list, image_list\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/ochuman_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass OCHumanDataset(BaseCocoStyleDataset):\n    \"\"\"OChuman dataset for pose estimation.\n\n    \"Pose2Seg: Detection Free Human Instance Segmentation\", CVPR'2019.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1803.10683>`__ .\n\n    \"Occluded Human (OCHuman)\" dataset contains 8110 heavily occluded\n    human instances within 4731 images. OCHuman dataset is designed for\n    validation and testing. To evaluate on OCHuman, the model should be\n    trained on COCO training set, and then test the robustness of the\n    model to occlusion using OCHuman.\n\n    OCHuman keypoints (same as COCO)::\n\n        0: 'nose',\n        1: 'left_eye',\n        2: 'right_eye',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/ochuman.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/posetrack18_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass PoseTrack18Dataset(BaseCocoStyleDataset):\n    \"\"\"PoseTrack18 dataset for pose estimation.\n\n    \"Posetrack: A benchmark for human pose estimation and tracking\", CVPR'2018.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1710.10000>`__ .\n\n    PoseTrack2018 keypoints::\n\n        0: 'nose',\n        1: 'head_bottom',\n        2: 'head_top',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/posetrack18.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/body/posetrack18_video_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Callable, List, Optional, Sequence, Union\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path, load\nfrom mmengine.utils import is_list_of\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_xywh2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass PoseTrack18VideoDataset(BaseCocoStyleDataset):\n    \"\"\"PoseTrack18 dataset for video pose estimation.\n\n    \"Posetrack: A benchmark for human pose estimation and tracking\", CVPR'2018.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1710.10000>`__ .\n\n    PoseTrack2018 keypoints::\n\n        0: 'nose',\n        1: 'head_bottom',\n        2: 'head_top',\n        3: 'left_ear',\n        4: 'right_ear',\n        5: 'left_shoulder',\n        6: 'right_shoulder',\n        7: 'left_elbow',\n        8: 'right_elbow',\n        9: 'left_wrist',\n        10: 'right_wrist',\n        11: 'left_hip',\n        12: 'right_hip',\n        13: 'left_knee',\n        14: 'right_knee',\n        15: 'left_ankle',\n        16: 'right_ankle'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        frame_weights (List[Union[int, float]] ): The weight of each frame\n            for aggregation. The first weight is for the center frame, then on\n            ascending order of frame indices. Note that the length of\n            ``frame_weights`` should be consistent with the number of sampled\n            frames. Default: [0.0, 1.0]\n        frame_sampler_mode (str): Specifies the mode of frame sampler:\n            ``'fixed'`` or ``'random'``. In ``'fixed'`` mode, each frame\n            index relative to the center frame is fixed, specified by\n            ``frame_indices``, while in ``'random'`` mode, each frame index\n            relative to the center frame is sampled from ``frame_range``\n            with certain randomness. Default: ``'random'``.\n        frame_range (int | List[int], optional): The sampling range of\n            supporting frames in the same video for center frame.\n            Only valid when ``frame_sampler_mode`` is ``'random'``.\n            Default: ``None``.\n        num_sampled_frame(int, optional): The number of sampled frames, except\n            the center frame. Only valid when ``frame_sampler_mode`` is\n            ``'random'``. Default: 1.\n        frame_indices (Sequence[int], optional): The sampled frame indices,\n            including the center frame indicated by 0. Only valid when\n            ``frame_sampler_mode`` is ``'fixed'``. Default: ``None``.\n        ph_fill_len (int): The length of the placeholder to fill in the\n            image filenames.  Default: 6\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/posetrack18.py')\n\n    def __init__(self,\n                 ann_file: str = '',\n                 bbox_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 frame_weights: List[Union[int, float]] = [0.0, 1.0],\n                 frame_sampler_mode: str = 'random',\n                 frame_range: Optional[Union[int, List[int]]] = None,\n                 num_sampled_frame: Optional[int] = None,\n                 frame_indices: Optional[Sequence[int]] = None,\n                 ph_fill_len: int = 6,\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000):\n        assert sum(frame_weights) == 1, 'Invalid `frame_weights`: should sum'\\\n            f' to 1.0, but got {frame_weights}.'\n        for weight in frame_weights:\n            assert weight >= 0, 'frame_weight can not be a negative value.'\n        self.frame_weights = np.array(frame_weights)\n\n        if frame_sampler_mode not in {'fixed', 'random'}:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid frame_sampler_mode: '\n                f'{frame_sampler_mode}. Should be `\"fixed\"` or `\"random\"`.')\n        self.frame_sampler_mode = frame_sampler_mode\n\n        if frame_sampler_mode == 'random':\n            assert frame_range is not None, \\\n                '`frame_sampler_mode` is set as `random`, ' \\\n                'please specify the `frame_range`.'\n\n            if isinstance(frame_range, int):\n                assert frame_range >= 0, \\\n                    'frame_range can not be a negative value.'\n                self.frame_range = [-frame_range, frame_range]\n\n            elif isinstance(frame_range, Sequence):\n                assert len(frame_range) == 2, 'The length must be 2.'\n                assert frame_range[0] <= 0 and frame_range[\n                    1] >= 0 and frame_range[1] > frame_range[\n                        0], 'Invalid `frame_range`'\n                for i in frame_range:\n                    assert isinstance(i, int), 'Each element must be int.'\n                self.frame_range = frame_range\n            else:\n                raise TypeError(\n                    f'The type of `frame_range` must be int or Sequence, '\n                    f'but got {type(frame_range)}.')\n\n            assert num_sampled_frame is not None, \\\n                '`frame_sampler_mode` is set as `random`, please specify ' \\\n                '`num_sampled_frame`, e.g. the number of sampled frames.'\n\n            assert len(frame_weights) == num_sampled_frame + 1, \\\n                f'the length of frame_weights({len(frame_weights)}) '\\\n                f'does not match the number of sampled adjacent '\\\n                f'frames({num_sampled_frame})'\n            self.frame_indices = None\n            self.num_sampled_frame = num_sampled_frame\n\n        if frame_sampler_mode == 'fixed':\n            assert frame_indices is not None, \\\n                '`frame_sampler_mode` is set as `fixed`, ' \\\n                'please specify the `frame_indices`.'\n            assert len(frame_weights) == len(frame_indices), \\\n                f'the length of frame_weights({len(frame_weights)}) does not '\\\n                f'match the length of frame_indices({len(frame_indices)}).'\n            frame_indices.sort()\n            self.frame_indices = frame_indices\n            self.frame_range = None\n            self.num_sampled_frame = None\n\n        self.ph_fill_len = ph_fill_len\n\n        super().__init__(\n            ann_file=ann_file,\n            bbox_file=bbox_file,\n            data_mode=data_mode,\n            metainfo=metainfo,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        # filter invalid instance\n        if 'bbox' not in ann or 'keypoints' not in ann or max(\n                ann['keypoints']) == 0:\n            return None\n\n        img_w, img_h = img['width'], img['height']\n        # get the bbox of the center frame\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['bbox']\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # get the keypoints of the center frame\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        # deal with multiple image paths\n        img_paths: list = []\n        # get the image path of the center frame\n        center_img_path = osp.join(self.data_prefix['img'], img['file_name'])\n        # append the center image path first\n        img_paths.append(center_img_path)\n\n        # select the frame indices\n        if self.frame_sampler_mode == 'fixed':\n            indices = self.frame_indices\n        else:  # self.frame_sampler_mode == 'random':\n            low, high = self.frame_range\n            indices = np.random.randint(low, high + 1, self.num_sampled_frame)\n\n        nframes = int(img['nframes'])\n        file_name = img['file_name']\n        ref_idx = int(osp.splitext(osp.basename(file_name))[0])\n\n        for idx in indices:\n            if self.test_mode and idx == 0:\n                continue\n            # the supporting frame index\n            support_idx = ref_idx + idx\n            # clip the frame index to make sure that it does not exceed\n            # the boundings of frame indices\n            support_idx = np.clip(support_idx, 0, nframes - 1)\n            sup_img_path = osp.join(\n                osp.dirname(center_img_path),\n                str(support_idx).zfill(self.ph_fill_len) + '.jpg')\n\n            img_paths.append(sup_img_path)\n\n        data_info = {\n            'img_id': int(img['frame_id']),\n            'img_path': img_paths,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': ann['num_keypoints'],\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'frame_weights': self.frame_weights,\n            'id': ann['id'],\n        }\n\n        return data_info\n\n    def _load_detection_results(self) -> List[dict]:\n        \"\"\"Load data from detection results with dummy keypoint annotations.\"\"\"\n        assert exists(self.ann_file), (\n            f'Annotation file `{self.ann_file}` does not exist')\n        assert exists(\n            self.bbox_file), (f'Bbox file `{self.bbox_file}` does not exist')\n\n        # load detection results\n        det_results = load(self.bbox_file)\n        assert is_list_of(det_results, dict), (\n            f'annotation file `{self.bbox_file}` should be a list of dicts, '\n            f'but got type {type(det_results)}')\n\n        # load coco annotations to build image id-to-name index\n        with get_local_path(self.ann_file) as local_path:\n            self.coco = COCO(local_path)\n\n        # mapping image name to id\n        name2id = {}\n        # mapping image id to name\n        id2name = {}\n        for img_id, image in self.coco.imgs.items():\n            file_name = image['file_name']\n            id2name[img_id] = file_name\n            name2id[file_name] = img_id\n\n        num_keypoints = self.metainfo['num_keypoints']\n        data_list = []\n        id_ = 0\n        for det in det_results:\n            # remove non-human instances\n            if det['category_id'] != 1:\n                continue\n\n            # get the predicted bbox and bbox_score\n            bbox_xywh = np.array(\n                det['bbox'][:4], dtype=np.float32).reshape(1, 4)\n            bbox = bbox_xywh2xyxy(bbox_xywh)\n            bbox_score = np.array(det['score'], dtype=np.float32).reshape(1)\n\n            # use dummy keypoint location and visibility\n            keypoints = np.zeros((1, num_keypoints, 2), dtype=np.float32)\n            keypoints_visible = np.ones((1, num_keypoints), dtype=np.float32)\n\n            # deal with different bbox file formats\n            if 'nframes' in det:\n                nframes = int(det['nframes'])\n            else:\n                if 'image_name' in det:\n                    img_id = name2id[det['image_name']]\n                else:\n                    img_id = det['image_id']\n                img_ann = self.coco.loadImgs(img_id)[0]\n                nframes = int(img_ann['nframes'])\n\n            # deal with multiple image paths\n            img_paths: list = []\n            if 'image_name' in det:\n                image_name = det['image_name']\n            else:\n                image_name = id2name[det['image_id']]\n            # get the image path of the center frame\n            center_img_path = osp.join(self.data_prefix['img'], image_name)\n            # append the center image path first\n            img_paths.append(center_img_path)\n\n            # \"images/val/012834_mpii_test/000000.jpg\" -->> \"000000.jpg\"\n            center_image_name = image_name.split('/')[-1]\n            ref_idx = int(center_image_name.replace('.jpg', ''))\n\n            # select the frame indices\n            if self.frame_sampler_mode == 'fixed':\n                indices = self.frame_indices\n            else:  # self.frame_sampler_mode == 'random':\n                low, high = self.frame_range\n                indices = np.random.randint(low, high + 1,\n                                            self.num_sampled_frame)\n\n            for idx in indices:\n                if self.test_mode and idx == 0:\n                    continue\n                # the supporting frame index\n                support_idx = ref_idx + idx\n                # clip the frame index to make sure that it does not exceed\n                # the boundings of frame indices\n                support_idx = np.clip(support_idx, 0, nframes - 1)\n                sup_img_path = center_img_path.replace(\n                    center_image_name,\n                    str(support_idx).zfill(self.ph_fill_len) + '.jpg')\n\n                img_paths.append(sup_img_path)\n\n            data_list.append({\n                'img_id': det['image_id'],\n                'img_path': img_paths,\n                'frame_weights': self.frame_weights,\n                'bbox': bbox,\n                'bbox_score': bbox_score,\n                'keypoints': keypoints,\n                'keypoints_visible': keypoints_visible,\n                'id': id_,\n            })\n\n            id_ += 1\n\n        return data_list\n"
  },
  {
    "path": "mmpose/datasets/datasets/body3d/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .h36m_dataset import Human36mDataset\n\n__all__ = ['Human36mDataset']\n"
  },
  {
    "path": "mmpose/datasets/datasets/body3d/h36m_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom collections import defaultdict\nfrom typing import Callable, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path\nfrom mmengine.utils import is_abs\n\nfrom mmpose.datasets.datasets import BaseMocapDataset\nfrom mmpose.registry import DATASETS\n\n\n@DATASETS.register_module()\nclass Human36mDataset(BaseMocapDataset):\n    \"\"\"Human3.6M dataset for 3D human pose estimation.\n\n    \"Human3.6M: Large Scale Datasets and Predictive Methods for 3D Human\n    Sensing in Natural Environments\", TPAMI`2014.\n    More details can be found in the `paper\n    <http://vision.imar.ro/human3.6m/pami-h36m.pdf>`__.\n\n    Human3.6M keypoint indexes::\n\n        0: 'root (pelvis)',\n        1: 'right_hip',\n        2: 'right_knee',\n        3: 'right_foot',\n        4: 'left_hip',\n        5: 'left_knee',\n        6: 'left_foot',\n        7: 'spine',\n        8: 'thorax',\n        9: 'neck_base',\n        10: 'head',\n        11: 'left_shoulder',\n        12: 'left_elbow',\n        13: 'left_wrist',\n        14: 'right_shoulder',\n        15: 'right_elbow',\n        16: 'right_wrist'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        seq_len (int): Number of frames in a sequence. Default: 1.\n        seq_step (int): The interval for extracting frames from the video.\n            Default: 1.\n        multiple_target (int): If larger than 0, merge every\n            ``multiple_target`` sequence together. Default: 0.\n        multiple_target_step (int): The interval for merging sequence. Only\n            valid when ``multiple_target`` is larger than 0. Default: 0.\n        pad_video_seq (bool): Whether to pad the video so that poses will be\n            predicted for every frame in the video. Default: ``False``.\n        causal (bool): If set to ``True``, the rightmost input frame will be\n            the target frame. Otherwise, the middle input frame will be the\n            target frame. Default: ``True``.\n        subset_frac (float): The fraction to reduce dataset size. If set to 1,\n            the dataset size is not reduced. Default: 1.\n        keypoint_2d_src (str): Specifies 2D keypoint information options, which\n            should be one of the following options:\n\n            - ``'gt'``: load from the annotation file\n            - ``'detection'``: load from a detection\n              result file of 2D keypoint\n            - 'pipeline': the information will be generated by the pipeline\n\n            Default: ``'gt'``.\n        keypoint_2d_det_file (str, optional): The 2D keypoint detection file.\n            If set, 2d keypoint loaded from this file will be used instead of\n            ground-truth keypoints. This setting is only when\n            ``keypoint_2d_src`` is ``'detection'``. Default: ``None``.\n        factor_file (str, optional): The projection factors' file. If set,\n            factor loaded from this file will be used instead of calculated\n            factors. Default: ``None``.\n        camera_param_file (str): Cameras' parameters file. Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/h36m.py')\n    SUPPORTED_keypoint_2d_src = {'gt', 'detection', 'pipeline'}\n\n    def __init__(self,\n                 ann_file: str = '',\n                 seq_len: int = 1,\n                 seq_step: int = 1,\n                 multiple_target: int = 0,\n                 multiple_target_step: int = 0,\n                 pad_video_seq: bool = False,\n                 causal: bool = True,\n                 subset_frac: float = 1.0,\n                 keypoint_2d_src: str = 'gt',\n                 keypoint_2d_det_file: Optional[str] = None,\n                 factor_file: Optional[str] = None,\n                 camera_param_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000):\n        # check keypoint_2d_src\n        self.keypoint_2d_src = keypoint_2d_src\n        if self.keypoint_2d_src not in self.SUPPORTED_keypoint_2d_src:\n            raise ValueError(\n                f'Unsupported `keypoint_2d_src` \"{self.keypoint_2d_src}\". '\n                f'Supported options are {self.SUPPORTED_keypoint_2d_src}')\n\n        if keypoint_2d_det_file:\n            if not is_abs(keypoint_2d_det_file):\n                self.keypoint_2d_det_file = osp.join(data_root,\n                                                     keypoint_2d_det_file)\n            else:\n                self.keypoint_2d_det_file = keypoint_2d_det_file\n\n        self.seq_step = seq_step\n        self.pad_video_seq = pad_video_seq\n\n        if factor_file:\n            if not is_abs(factor_file):\n                factor_file = osp.join(data_root, factor_file)\n            assert exists(factor_file), (f'`factor_file`: {factor_file}'\n                                         'does not exist.')\n        self.factor_file = factor_file\n\n        if multiple_target > 0 and multiple_target_step == 0:\n            multiple_target_step = multiple_target\n        self.multiple_target_step = multiple_target_step\n\n        super().__init__(\n            ann_file=ann_file,\n            seq_len=seq_len,\n            multiple_target=multiple_target,\n            causal=causal,\n            subset_frac=subset_frac,\n            camera_param_file=camera_param_file,\n            data_mode=data_mode,\n            metainfo=metainfo,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n    def get_sequence_indices(self) -> List[List[int]]:\n        \"\"\"Split original videos into sequences and build frame indices.\n\n        This method overrides the default one in the base class.\n        \"\"\"\n        imgnames = self.ann_data['imgname']\n        video_frames = defaultdict(list)\n        for idx, imgname in enumerate(imgnames):\n            subj, action, camera = self._parse_h36m_imgname(imgname)\n            video_frames[(subj, action, camera)].append(idx)\n\n        # build sample indices\n        sequence_indices = []\n        _len = (self.seq_len - 1) * self.seq_step + 1\n        _step = self.seq_step\n\n        if self.multiple_target:\n            for _, _indices in sorted(video_frames.items()):\n                n_frame = len(_indices)\n                seqs_from_video = [\n                    _indices[i:(i + self.multiple_target):_step]\n                    for i in range(0, n_frame, self.multiple_target_step)\n                ][:(n_frame + self.multiple_target_step -\n                    self.multiple_target) // self.multiple_target_step]\n                sequence_indices.extend(seqs_from_video)\n\n        else:\n            for _, _indices in sorted(video_frames.items()):\n                n_frame = len(_indices)\n\n                if self.pad_video_seq:\n                    # Pad the sequence so that every frame in the sequence will\n                    # be predicted.\n                    if self.causal:\n                        frames_left = self.seq_len - 1\n                        frames_right = 0\n                    else:\n                        frames_left = (self.seq_len - 1) // 2\n                        frames_right = frames_left\n                    for i in range(n_frame):\n                        pad_left = max(0, frames_left - i // _step)\n                        pad_right = max(\n                            0, frames_right - (n_frame - 1 - i) // _step)\n                        start = max(i % _step, i - frames_left * _step)\n                        end = min(n_frame - (n_frame - 1 - i) % _step,\n                                  i + frames_right * _step + 1)\n                        sequence_indices.append([_indices[0]] * pad_left +\n                                                _indices[start:end:_step] +\n                                                [_indices[-1]] * pad_right)\n                else:\n                    seqs_from_video = [\n                        _indices[i:(i + _len):_step]\n                        for i in range(0, n_frame - _len + 1)\n                    ]\n                    sequence_indices.extend(seqs_from_video)\n\n        # reduce dataset size if needed\n        subset_size = int(len(sequence_indices) * self.subset_frac)\n        start = np.random.randint(0, len(sequence_indices) - subset_size + 1)\n        end = start + subset_size\n\n        sequence_indices = sequence_indices[start:end]\n\n        return sequence_indices\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        instance_list, image_list = super()._load_annotations()\n\n        h36m_data = self.ann_data\n        kpts_3d = h36m_data['S']\n\n        if self.keypoint_2d_src == 'detection':\n            assert exists(self.keypoint_2d_det_file), (\n                f'`keypoint_2d_det_file`: `{self.keypoint_2d_det_file}`'\n                'does not exist.')\n            kpts_2d = self._load_keypoint_2d_detection(\n                self.keypoint_2d_det_file)\n            assert kpts_2d.shape[0] == kpts_3d.shape[0], (\n                f'Number of `kpts_2d` ({kpts_2d.shape[0]}) does not match '\n                f'number of `kpts_3d` ({kpts_3d.shape[0]}).')\n\n            assert kpts_2d.shape[2] == 3, (\n                f'Expect `kpts_2d.shape[2]` == 3, but got '\n                f'{kpts_2d.shape[2]}. Please check the format of '\n                f'{self.keypoint_2d_det_file}')\n\n            for idx, frame_ids in enumerate(self.sequence_indices):\n                kpt_2d = kpts_2d[frame_ids].astype(np.float32)\n                keypoints = kpt_2d[..., :2]\n                keypoints_visible = kpt_2d[..., 2]\n                instance_list[idx].update({\n                    'keypoints':\n                    keypoints,\n                    'keypoints_visible':\n                    keypoints_visible\n                })\n        if self.factor_file:\n            with get_local_path(self.factor_file) as local_path:\n                factors = np.load(local_path).astype(np.float32)\n        else:\n            factors = np.zeros((kpts_3d.shape[0], ), dtype=np.float32)\n        assert factors.shape[0] == kpts_3d.shape[0], (\n            f'Number of `factors` ({factors.shape[0]}) does not match '\n            f'number of `kpts_3d` ({kpts_3d.shape[0]}).')\n\n        for idx, frame_ids in enumerate(self.sequence_indices):\n            factor = factors[frame_ids].astype(np.float32)\n            instance_list[idx].update({'factor': factor})\n\n        return instance_list, image_list\n\n    @staticmethod\n    def _parse_h36m_imgname(imgname) -> Tuple[str, str, str]:\n        \"\"\"Parse imgname to get information of subject, action and camera.\n\n        A typical h36m image filename is like:\n        S1_Directions_1.54138969_000001.jpg\n        \"\"\"\n        subj, rest = osp.basename(imgname).split('_', 1)\n        action, rest = rest.split('.', 1)\n        camera, rest = rest.split('_', 1)\n        return subj, action, camera\n\n    def get_camera_param(self, imgname) -> dict:\n        \"\"\"Get camera parameters of a frame by its image name.\"\"\"\n        assert hasattr(self, 'camera_param')\n        subj, _, camera = self._parse_h36m_imgname(imgname)\n        return self.camera_param[(subj, camera)]\n\n    def _load_keypoint_2d_detection(self, det_file):\n        \"\"\"\"Load 2D joint detection results from file.\"\"\"\n        with get_local_path(det_file) as local_path:\n            kpts_2d = np.load(local_path).astype(np.float32)\n\n        return kpts_2d\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .aflw_dataset import AFLWDataset\nfrom .coco_wholebody_face_dataset import CocoWholeBodyFaceDataset\nfrom .cofw_dataset import COFWDataset\nfrom .face_300vw_dataset import Face300VWDataset\nfrom .face_300w_dataset import Face300WDataset\nfrom .face_300wlp_dataset import Face300WLPDataset\nfrom .lapa_dataset import LapaDataset\nfrom .wflw_dataset import WFLWDataset\n\n__all__ = [\n    'Face300WDataset', 'WFLWDataset', 'AFLWDataset', 'COFWDataset',\n    'CocoWholeBodyFaceDataset', 'LapaDataset', 'Face300WLPDataset',\n    'Face300VWDataset'\n]\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/aflw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_cs2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass AFLWDataset(BaseCocoStyleDataset):\n    \"\"\"AFLW dataset for face keypoint localization.\n\n    \"Annotated Facial Landmarks in the Wild: A Large-scale,\n    Real-world Database for Facial Landmark Localization\".\n    In Proc. First IEEE International Workshop on Benchmarking\n    Facial Image Analysis Technologies, 2011.\n\n    The landmark annotations follow the 19 points mark-up. The definition\n    can be found in `https://www.tugraz.at/institute/icg/research`\n    `/team-bischof/lrs/downloads/aflw/`\n\n        Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/aflw.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw Face AFLW annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # aflw bbox scales are normalized with factor 200.\n        pixel_std = 200.\n\n        # center, scale in shape [1, 2] and bbox in [1, 4]\n        center = np.array([ann['center']], dtype=np.float32)\n        scale = np.array([[ann['scale'], ann['scale']]],\n                         dtype=np.float32) * pixel_std\n        bbox = bbox_cs2xyxy(center, scale)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = ann['num_keypoints']\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_center': center,\n            'bbox_scale': scale,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n\n        if self.test_mode:\n            # 'box_size' is used as normalization factor\n            assert 'box_size' in ann, '\"box_size\" is missing in annotation, '\\\n                                      'which is required for evaluation.'\n            data_info['box_size'] = ann['box_size']\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/coco_wholebody_face_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass CocoWholeBodyFaceDataset(BaseCocoStyleDataset):\n    \"\"\"CocoWholeBodyDataset for face keypoint localization.\n\n    `Whole-Body Human Pose Estimation in the Wild', ECCV'2020.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2007.11858>`__ .\n\n    The face landmark annotations follow the 68 points mark-up.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(\n        from_file='configs/_base_/datasets/coco_wholebody_face.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw CocoWholeBody Face annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        # filter invalid instance\n        if not ann['face_valid'] or max(ann['face_kpts']) <= 0:\n            return None\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n        img_w, img_h = img['width'], img['height']\n\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['face_box']\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['face_kpts'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/cofw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass COFWDataset(BaseCocoStyleDataset):\n    \"\"\"COFW dataset for face keypoint localization.\n\n    \"Robust face landmark estimation under occlusion\", ICCV'2013.\n\n    The landmark annotations follow the 29 points mark-up. The definition\n    can be found in `http://www.vision.caltech.edu/xpburgos/ICCV13/`__ .\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/cofw.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/face_300vw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_cs2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass Face300VWDataset(BaseCocoStyleDataset):\n    \"\"\"300VW dataset for face keypoint tracking.\n\n    \"The First Facial Landmark Tracking in-the-Wild Challenge:\n     Benchmark and Results\",\n    Proceedings of the IEEE\n    international conference on computer vision workshops.\n\n    The landmark annotations follow the 68 points mark-up. The definition\n    can be found in `https://ibug.doc.ic.ac.uk/resources/300-VW/`.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/300vw.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw Face300VW annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # 300vw bbox scales are normalized with factor 200.\n        pixel_std = 200.\n\n        # center, scale in shape [1, 2] and bbox in [1, 4]\n        center = np.array([ann['center']], dtype=np.float32)\n        scale = np.array([[ann['scale'], ann['scale']]],\n                         dtype=np.float32) * pixel_std\n        bbox = bbox_cs2xyxy(center, scale)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = ann['num_keypoints']\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_center': center,\n            'bbox_scale': scale,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/face_300w_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_cs2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass Face300WDataset(BaseCocoStyleDataset):\n    \"\"\"300W dataset for face keypoint localization.\n\n    \"300 faces In-the-wild challenge: Database and results\",\n    Image and Vision Computing (IMAVIS) 2019.\n\n    The landmark annotations follow the 68 points mark-up. The definition\n    can be found in `https://ibug.doc.ic.ac.uk/resources/300-W/`.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/300w.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw Face300W annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # 300w bbox scales are normalized with factor 200.\n        pixel_std = 200.\n\n        # center, scale in shape [1, 2] and bbox in [1, 4]\n        center = np.array([ann['center']], dtype=np.float32)\n        scale = np.array([[ann['scale'], ann['scale']]],\n                         dtype=np.float32) * pixel_std\n        bbox = bbox_cs2xyxy(center, scale)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = ann['num_keypoints']\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_center': center,\n            'bbox_scale': scale,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/face_300wlp_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass Face300WLPDataset(BaseCocoStyleDataset):\n    \"\"\"300W dataset for face keypoint localization.\n\n    \"300 faces In-the-wild challenge: Database and results\",\n    Image and Vision Computing (IMAVIS) 2019.\n\n    The landmark annotations follow the 68 points mark-up. The definition\n    can be found in `https://ibug.doc.ic.ac.uk/resources/300-W/`.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/300wlp.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/lapa_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass LapaDataset(BaseCocoStyleDataset):\n    \"\"\"LaPa dataset for face keypoint localization.\n\n    \"A New Dataset and Boundary-Attention Semantic Segmentation\n    for Face Parsing\", AAAI'2020.\n\n    The landmark annotations follow the 106 points mark-up. The definition\n    can be found in `https://github.com/JDAI-CV/lapa-dataset/`__ .\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/lapa.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/face/wflw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_cs2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass WFLWDataset(BaseCocoStyleDataset):\n    \"\"\"WFLW dataset for face keypoint localization.\n\n    \"Look at Boundary: A Boundary-Aware Face Alignment Algorithm\",\n    CVPR'2018.\n\n    The landmark annotations follow the 98 points mark-up. The definition\n    can be found in `https://wywu.github.io/projects/LAB/WFLW.html`__ .\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/wflw.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw Face WFLW annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # wflw bbox scales are normalized with factor 200.\n        pixel_std = 200.\n\n        # center, scale in shape [1, 2] and bbox in [1, 4]\n        center = np.array([ann['center']], dtype=np.float32)\n        scale = np.array([[ann['scale'], ann['scale']]],\n                         dtype=np.float32) * pixel_std\n        bbox = bbox_cs2xyxy(center, scale)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = ann['num_keypoints']\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_center': center,\n            'bbox_scale': scale,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'id': ann['id'],\n        }\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/fashion/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .deepfashion2_dataset import DeepFashion2Dataset\nfrom .deepfashion_dataset import DeepFashionDataset\n\n__all__ = ['DeepFashionDataset', 'DeepFashion2Dataset']\n"
  },
  {
    "path": "mmpose/datasets/datasets/fashion/deepfashion2_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module(name='DeepFashion2Dataset')\nclass DeepFashion2Dataset(BaseCocoStyleDataset):\n    \"\"\"DeepFashion2 dataset for fashion landmark detection.\"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/deepfashion2.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/fashion/deepfashion_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Callable, List, Optional, Sequence, Union\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass DeepFashionDataset(BaseCocoStyleDataset):\n    \"\"\"DeepFashion dataset (full-body clothes) for fashion landmark detection.\n\n    \"DeepFashion: Powering Robust Clothes Recognition\n    and Retrieval with Rich Annotations\", CVPR'2016.\n    \"Fashion Landmark Detection in the Wild\", ECCV'2016.\n\n    The dataset contains 3 categories for full-body, upper-body and lower-body.\n\n    Fashion landmark indexes for upper-body clothes::\n\n        0: 'left collar',\n        1: 'right collar',\n        2: 'left sleeve',\n        3: 'right sleeve',\n        4: 'left hem',\n        5: 'right hem'\n\n    Fashion landmark indexes for lower-body clothes::\n\n        0: 'left waistline',\n        1: 'right waistline',\n        2: 'left hem',\n        3: 'right hem'\n\n    Fashion landmark indexes for full-body clothes::\n\n        0: 'left collar',\n        1: 'right collar',\n        2: 'left sleeve',\n        3: 'right sleeve',\n        4: 'left waistline',\n        5: 'right waistline',\n        6: 'left hem',\n        7: 'right hem'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        subset (str): Specifies the subset of body: ``'full'``, ``'upper'`` or\n            ``'lower'``. Default: '', which means ``'full'``.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    def __init__(self,\n                 ann_file: str = '',\n                 subset: str = '',\n                 bbox_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000):\n        self._check_subset_and_metainfo(subset)\n\n        super().__init__(\n            ann_file=ann_file,\n            bbox_file=bbox_file,\n            data_mode=data_mode,\n            metainfo=metainfo,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n    @classmethod\n    def _check_subset_and_metainfo(cls, subset: str = '') -> None:\n        \"\"\"Check the subset of body and set the corresponding metainfo.\n\n        Args:\n            subset(str): the subset of body: could be ``'full'``, ``'upper'``\n            or ``'lower'``. Default: '', which means ``'full'``.\n        \"\"\"\n        if subset == '' or subset == 'full':\n            cls.METAINFO = dict(\n                from_file='configs/_base_/datasets/deepfashion_full.py')\n        elif subset == 'upper':\n            cls.METAINFO = dict(\n                from_file='configs/_base_/datasets/deepfashion_upper.py')\n        elif subset == 'lower':\n            cls.METAINFO = dict(\n                from_file='configs/_base_/datasets/deepfashion_lower.py')\n        else:\n            raise ValueError(\n                f'{cls.__class__.__name__} got invalid subset: '\n                f'{subset}. Should be \"full\", \"lower\" or \"upper\".')\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .coco_wholebody_hand_dataset import CocoWholeBodyHandDataset\nfrom .freihand_dataset import FreiHandDataset\nfrom .interhand2d_double_dataset import InterHand2DDoubleDataset\nfrom .onehand10k_dataset import OneHand10KDataset\nfrom .panoptic_hand2d_dataset import PanopticHand2DDataset\nfrom .rhd2d_dataset import Rhd2DDataset\n\n__all__ = [\n    'OneHand10KDataset', 'FreiHandDataset', 'PanopticHand2DDataset',\n    'Rhd2DDataset', 'CocoWholeBodyHandDataset', 'InterHand2DDoubleDataset'\n]\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/coco_wholebody_hand_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import List, Tuple\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_xywh2xyxy\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass CocoWholeBodyHandDataset(BaseCocoStyleDataset):\n    \"\"\"CocoWholeBodyDataset for hand pose estimation.\n\n    \"Whole-Body Human Pose Estimation in the Wild\", ECCV'2020.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2007.11858>`__ .\n\n    COCO-WholeBody Hand keypoints::\n\n        0: 'wrist',\n        1: 'thumb1',\n        2: 'thumb2',\n        3: 'thumb3',\n        4: 'thumb4',\n        5: 'forefinger1',\n        6: 'forefinger2',\n        7: 'forefinger3',\n        8: 'forefinger4',\n        9: 'middle_finger1',\n        10: 'middle_finger2',\n        11: 'middle_finger3',\n        12: 'middle_finger4',\n        13: 'ring_finger1',\n        14: 'ring_finger2',\n        15: 'ring_finger3',\n        16: 'ring_finger4',\n        17: 'pinky_finger1',\n        18: 'pinky_finger2',\n        19: 'pinky_finger3',\n        20: 'pinky_finger4'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(\n        from_file='configs/_base_/datasets/coco_wholebody_hand.py')\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in COCO format.\"\"\"\n\n        assert exists(self.ann_file), (\n            f'Annotation file `{self.ann_file}` does not exist')\n\n        with get_local_path(self.ann_file) as local_path:\n            self.coco = COCO(local_path)\n        instance_list = []\n        image_list = []\n        id = 0\n\n        for img_id in self.coco.getImgIds():\n            img = self.coco.loadImgs(img_id)[0]\n\n            img.update({\n                'img_id':\n                img_id,\n                'img_path':\n                osp.join(self.data_prefix['img'], img['file_name']),\n            })\n            image_list.append(img)\n\n            ann_ids = self.coco.getAnnIds(imgIds=img_id, iscrowd=False)\n            anns = self.coco.loadAnns(ann_ids)\n            for ann in anns:\n                for type in ['left', 'right']:\n                    # filter invalid hand annotations, there might be two\n                    # valid instances (left and right hand) in one image\n                    if ann[f'{type}hand_valid'] and max(\n                            ann[f'{type}hand_kpts']) > 0:\n\n                        bbox_xywh = np.array(\n                            ann[f'{type}hand_box'],\n                            dtype=np.float32).reshape(1, 4)\n\n                        bbox = bbox_xywh2xyxy(bbox_xywh)\n\n                        _keypoints = np.array(\n                            ann[f'{type}hand_kpts'],\n                            dtype=np.float32).reshape(1, -1, 3)\n                        keypoints = _keypoints[..., :2]\n                        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n                        num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n\n                        instance_info = {\n                            'img_id': ann['image_id'],\n                            'img_path': img['img_path'],\n                            'bbox': bbox,\n                            'bbox_score': np.ones(1, dtype=np.float32),\n                            'num_keypoints': num_keypoints,\n                            'keypoints': keypoints,\n                            'keypoints_visible': keypoints_visible,\n                            'iscrowd': ann['iscrowd'],\n                            'segmentation': ann['segmentation'],\n                            'id': id,\n                        }\n                        instance_list.append(instance_info)\n                        id = id + 1\n\n        instance_list = sorted(instance_list, key=lambda x: x['id'])\n        return instance_list, image_list\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/freihand_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass FreiHandDataset(BaseCocoStyleDataset):\n    \"\"\"FreiHand dataset for hand pose estimation.\n\n    \"FreiHAND: A Dataset for Markerless Capture of Hand Pose\n    and Shape from Single RGB Images\", ICCV'2019.\n    More details can be found in the `paper\n    <https://arxiv.org/pdf/1909.04349.pdf>`__ .\n\n    FreiHand keypoints::\n\n        0: 'wrist',\n        1: 'thumb1',\n        2: 'thumb2',\n        3: 'thumb3',\n        4: 'thumb4',\n        5: 'forefinger1',\n        6: 'forefinger2',\n        7: 'forefinger3',\n        8: 'forefinger4',\n        9: 'middle_finger1',\n        10: 'middle_finger2',\n        11: 'middle_finger3',\n        12: 'middle_finger4',\n        13: 'ring_finger1',\n        14: 'ring_finger2',\n        15: 'ring_finger3',\n        16: 'ring_finger4',\n        17: 'pinky_finger1',\n        18: 'pinky_finger2',\n        19: 'pinky_finger3',\n        20: 'pinky_finger4'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/freihand2d.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n\n        # use the entire image which is 224x224\n        bbox = np.array([0, 0, 224, 224], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'segmentation': ann['segmentation'],\n            'id': ann['id'],\n        }\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/interhand2d_double_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport json\nimport os.path as osp\nfrom typing import Callable, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path\nfrom mmengine.utils import is_abs\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.codecs.utils import camera_to_pixel\nfrom mmpose.datasets.datasets import BaseCocoStyleDataset\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_xywh2xyxy\n\n\n@DATASETS.register_module()\nclass InterHand2DDoubleDataset(BaseCocoStyleDataset):\n    \"\"\"InterHand2.6M dataset for 2d double hands.\n\n    \"InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose\n    Estimation from a Single RGB Image\", ECCV'2020.\n    More details can be found in the `paper\n    <https://arxiv.org/pdf/2008.09309.pdf>`__ .\n\n    The dataset loads raw features and apply specified transforms\n    to return a dict containing the image tensors and other information.\n\n    InterHand2.6M keypoint indexes::\n\n        0: 'r_thumb4',\n        1: 'r_thumb3',\n        2: 'r_thumb2',\n        3: 'r_thumb1',\n        4: 'r_index4',\n        5: 'r_index3',\n        6: 'r_index2',\n        7: 'r_index1',\n        8: 'r_middle4',\n        9: 'r_middle3',\n        10: 'r_middle2',\n        11: 'r_middle1',\n        12: 'r_ring4',\n        13: 'r_ring3',\n        14: 'r_ring2',\n        15: 'r_ring1',\n        16: 'r_pinky4',\n        17: 'r_pinky3',\n        18: 'r_pinky2',\n        19: 'r_pinky1',\n        20: 'r_wrist',\n        21: 'l_thumb4',\n        22: 'l_thumb3',\n        23: 'l_thumb2',\n        24: 'l_thumb1',\n        25: 'l_index4',\n        26: 'l_index3',\n        27: 'l_index2',\n        28: 'l_index1',\n        29: 'l_middle4',\n        30: 'l_middle3',\n        31: 'l_middle2',\n        32: 'l_middle1',\n        33: 'l_ring4',\n        34: 'l_ring3',\n        35: 'l_ring2',\n        36: 'l_ring1',\n        37: 'l_pinky4',\n        38: 'l_pinky3',\n        39: 'l_pinky2',\n        40: 'l_pinky1',\n        41: 'l_wrist'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        camera_param_file (str): Cameras' parameters file. Default: ''.\n        joint_file (str): Path to the joint file. Default: ''.\n        use_gt_root_depth (bool): Using the ground truth depth of the wrist\n            or given depth from rootnet_result_file. Default: ``True``.\n        rootnet_result_file (str): Path to the wrist depth file.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n        sample_interval (int, optional): The sample interval of the dataset.\n            Default: 1.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/interhand3d.py')\n\n    def __init__(self,\n                 ann_file: str = '',\n                 camera_param_file: str = '',\n                 joint_file: str = '',\n                 use_gt_root_depth: bool = True,\n                 rootnet_result_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000,\n                 sample_interval: int = 1):\n        _ann_file = ann_file\n        if data_root is not None and not is_abs(_ann_file):\n            _ann_file = osp.join(data_root, _ann_file)\n        assert exists(_ann_file), 'Annotation file does not exist.'\n        self.ann_file = _ann_file\n\n        _camera_param_file = camera_param_file\n        if data_root is not None and not is_abs(_camera_param_file):\n            _camera_param_file = osp.join(data_root, _camera_param_file)\n        assert exists(_camera_param_file), 'Camera file does not exist.'\n        self.camera_param_file = _camera_param_file\n\n        _joint_file = joint_file\n        if data_root is not None and not is_abs(_joint_file):\n            _joint_file = osp.join(data_root, _joint_file)\n        assert exists(_joint_file), 'Joint file does not exist.'\n        self.joint_file = _joint_file\n\n        self.use_gt_root_depth = use_gt_root_depth\n        if not self.use_gt_root_depth:\n            assert rootnet_result_file is not None\n            _rootnet_result_file = rootnet_result_file\n            if data_root is not None and not is_abs(_rootnet_result_file):\n                _rootnet_result_file = osp.join(data_root,\n                                                _rootnet_result_file)\n            assert exists(\n                _rootnet_result_file), 'Rootnet result file does not exist.'\n            self.rootnet_result_file = _rootnet_result_file\n\n        super().__init__(\n            ann_file=ann_file,\n            metainfo=metainfo,\n            data_mode=data_mode,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch,\n            sample_interval=sample_interval)\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in COCO format.\"\"\"\n\n        assert exists(self.ann_file), 'Annotation file does not exist'\n\n        with get_local_path(self.ann_file) as local_path:\n            self.coco = COCO(local_path)\n        # set the metainfo about categories, which is a list of dict\n        # and each dict contains the 'id', 'name', etc. about this category\n        if 'categories' in self.coco.dataset:\n            self._metainfo['CLASSES'] = self.coco.loadCats(\n                self.coco.getCatIds())\n\n        with get_local_path(self.camera_param_file) as local_path:\n            with open(local_path, 'r') as f:\n                self.cameras = json.load(f)\n        with get_local_path(self.joint_file) as local_path:\n            with open(local_path, 'r') as f:\n                self.joints = json.load(f)\n\n        instance_list = []\n        image_list = []\n\n        for idx, img_id in enumerate(self.coco.getImgIds()):\n            if idx % self.sample_interval != 0:\n                continue\n            img = self.coco.loadImgs(img_id)[0]\n            img.update({\n                'img_id':\n                img_id,\n                'img_path':\n                osp.join(self.data_prefix['img'], img['file_name']),\n            })\n            image_list.append(img)\n\n            ann_ids = self.coco.getAnnIds(imgIds=img_id)\n            ann = self.coco.loadAnns(ann_ids)[0]\n\n            instance_info = self.parse_data_info(\n                dict(raw_ann_info=ann, raw_img_info=img))\n\n            # skip invalid instance annotation.\n            if not instance_info:\n                continue\n\n            instance_list.append(instance_info)\n        return instance_list, image_list\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict | None: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        if not self.use_gt_root_depth:\n            rootnet_result = {}\n            with get_local_path(self.rootnet_result_file) as local_path:\n                rootnet_annot = json.load(local_path)\n            for i in range(len(rootnet_annot)):\n                rootnet_result[str(\n                    rootnet_annot[i]['annot_id'])] = rootnet_annot[i]\n\n        num_keypoints = self.metainfo['num_keypoints']\n\n        capture_id = str(img['capture'])\n        camera_name = img['camera']\n        frame_idx = str(img['frame_idx'])\n        camera_pos = np.array(\n            self.cameras[capture_id]['campos'][camera_name], dtype=np.float32)\n        camera_rot = np.array(\n            self.cameras[capture_id]['camrot'][camera_name], dtype=np.float32)\n        focal = np.array(\n            self.cameras[capture_id]['focal'][camera_name], dtype=np.float32)\n        principal_pt = np.array(\n            self.cameras[capture_id]['princpt'][camera_name], dtype=np.float32)\n        joint_world = np.array(\n            self.joints[capture_id][frame_idx]['world_coord'],\n            dtype=np.float32)\n        joint_valid = np.array(ann['joint_valid'], dtype=np.float32).flatten()\n\n        keypoints_cam = np.dot(\n            camera_rot,\n            joint_world.transpose(1, 0) -\n            camera_pos.reshape(3, 1)).transpose(1, 0)\n\n        if self.use_gt_root_depth:\n            bbox_xywh = np.array(ann['bbox'], dtype=np.float32).reshape(1, 4)\n\n        else:\n            rootnet_ann_data = rootnet_result[str(ann['id'])]\n            bbox_xywh = np.array(\n                rootnet_ann_data['bbox'], dtype=np.float32).reshape(1, 4)\n\n        bbox = bbox_xywh2xyxy(bbox_xywh)\n\n        # 41: 'l_wrist', left hand root\n        # 20: 'r_wrist', right hand root\n\n        # if root is not valid -> root-relative 3D pose is also not valid.\n        # Therefore, mark all joints as invalid\n        joint_valid[:20] *= joint_valid[20]\n        joint_valid[21:] *= joint_valid[41]\n\n        joints_3d_visible = np.minimum(1,\n                                       joint_valid.reshape(-1,\n                                                           1)).reshape(1, -1)\n        keypoints_img = camera_to_pixel(\n            keypoints_cam,\n            focal[0],\n            focal[1],\n            principal_pt[0],\n            principal_pt[1],\n            shift=True)[..., :2]\n        joints_3d = np.zeros((keypoints_cam.shape[-2], 3),\n                             dtype=np.float32).reshape(1, -1, 3)\n        joints_3d[..., :2] = keypoints_img\n        joints_3d[..., :21,\n                  2] = keypoints_cam[..., :21, 2] - keypoints_cam[..., 20, 2]\n        joints_3d[..., 21:,\n                  2] = keypoints_cam[..., 21:, 2] - keypoints_cam[..., 41, 2]\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img['img_path'],\n            'keypoints': joints_3d[:, :, :2],\n            'keypoints_visible': joints_3d_visible,\n            'hand_type': self.encode_handtype(ann['hand_type']),\n            'hand_type_valid': np.array([ann['hand_type_valid']]),\n            'dataset': self.metainfo['dataset_name'],\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'iscrowd': ann.get('iscrowd', False),\n            'id': ann['id'],\n            # store the raw annotation of the instance\n            # it is useful for evaluation without providing ann_file\n            'raw_ann_info': copy.deepcopy(ann),\n        }\n\n        return data_info\n\n    @staticmethod\n    def encode_handtype(hand_type):\n        if hand_type == 'right':\n            return np.array([[1, 0]], dtype=np.float32)\n        elif hand_type == 'left':\n            return np.array([[0, 1]], dtype=np.float32)\n        elif hand_type == 'interacting':\n            return np.array([[1, 1]], dtype=np.float32)\n        else:\n            assert 0, f'Not support hand type: {hand_type}'\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/onehand10k_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass OneHand10KDataset(BaseCocoStyleDataset):\n    \"\"\"OneHand10K dataset for hand pose estimation.\n\n    \"Mask-pose Cascaded CNN for 2D Hand Pose Estimation from\n    Single Color Images\", TCSVT'2019.\n    More details can be found in the `paper\n    <https://www.yangangwang.com/papers/WANG-MCC-2018-10.pdf>`__ .\n\n    OneHand10K keypoints::\n\n        0: 'wrist',\n        1: 'thumb1',\n        2: 'thumb2',\n        3: 'thumb3',\n        4: 'thumb4',\n        5: 'forefinger1',\n        6: 'forefinger2',\n        7: 'forefinger3',\n        8: 'forefinger4',\n        9: 'middle_finger1',\n        10: 'middle_finger2',\n        11: 'middle_finger3',\n        12: 'middle_finger4',\n        13: 'ring_finger1',\n        14: 'ring_finger2',\n        15: 'ring_finger3',\n        16: 'ring_finger4',\n        17: 'pinky_finger1',\n        18: 'pinky_finger2',\n        19: 'pinky_finger3',\n        20: 'pinky_finger4'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/onehand10k.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/panoptic_hand2d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass PanopticHand2DDataset(BaseCocoStyleDataset):\n    \"\"\"Panoptic 2D dataset for hand pose estimation.\n\n    \"Hand Keypoint Detection in Single Images using Multiview\n    Bootstrapping\", CVPR'2017.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1704.07809>`__ .\n\n    Panoptic keypoints::\n\n        0: 'wrist',\n        1: 'thumb1',\n        2: 'thumb2',\n        3: 'thumb3',\n        4: 'thumb4',\n        5: 'forefinger1',\n        6: 'forefinger2',\n        7: 'forefinger3',\n        8: 'forefinger4',\n        9: 'middle_finger1',\n        10: 'middle_finger2',\n        11: 'middle_finger3',\n        12: 'middle_finger4',\n        13: 'ring_finger1',\n        14: 'ring_finger2',\n        15: 'ring_finger3',\n        16: 'ring_finger4',\n        17: 'pinky_finger1',\n        18: 'pinky_finger2',\n        19: 'pinky_finger3',\n        20: 'pinky_finger4'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(\n        from_file='configs/_base_/datasets/panoptic_hand2d.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n        img_w, img_h = img['width'], img['height']\n\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['bbox']\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        _keypoints = np.array(\n            ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2])\n\n        num_keypoints = np.count_nonzero(keypoints.max(axis=2))\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'segmentation': ann['segmentation'],\n            'head_size': ann['head_size'],\n            'id': ann['id'],\n        }\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand/rhd2d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass Rhd2DDataset(BaseCocoStyleDataset):\n    \"\"\"Rendered Handpose Dataset for hand pose estimation.\n\n    \"Learning to Estimate 3D Hand Pose from Single RGB Images\",\n    ICCV'2017.\n    More details can be found in the `paper\n    <https://arxiv.org/pdf/1705.01389.pdf>`__ .\n\n    Rhd keypoints::\n\n        0: 'wrist',\n        1: 'thumb4',\n        2: 'thumb3',\n        3: 'thumb2',\n        4: 'thumb1',\n        5: 'forefinger4',\n        6: 'forefinger3',\n        7: 'forefinger2',\n        8: 'forefinger1',\n        9: 'middle_finger4',\n        10: 'middle_finger3',\n        11: 'middle_finger2',\n        12: 'middle_finger1',\n        13: 'ring_finger4',\n        14: 'ring_finger3',\n        15: 'ring_finger2',\n        16: 'ring_finger1',\n        17: 'pinky_finger4',\n        18: 'pinky_finger3',\n        19: 'pinky_finger2',\n        20: 'pinky_finger1'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/rhd2d.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand3d/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .interhand_3d_dataset import InterHand3DDataset\n\n__all__ = ['InterHand3DDataset']\n"
  },
  {
    "path": "mmpose/datasets/datasets/hand3d/interhand_3d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport json\nimport os.path as osp\nfrom typing import Callable, List, Optional, Sequence, Tuple, Union\n\nimport numpy as np\nfrom mmengine.fileio import exists, get_local_path\nfrom mmengine.utils import is_abs\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.codecs.utils import camera_to_pixel\nfrom mmpose.datasets.datasets import BaseCocoStyleDataset\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures.bbox import bbox_xywh2xyxy\n\n\n@DATASETS.register_module()\nclass InterHand3DDataset(BaseCocoStyleDataset):\n    \"\"\"InterHand2.6M dataset for 3d hand.\n\n    \"InterHand2.6M: A Dataset and Baseline for 3D Interacting Hand Pose\n    Estimation from a Single RGB Image\", ECCV'2020.\n    More details can be found in the `paper\n    <https://arxiv.org/pdf/2008.09309.pdf>`__ .\n\n    The dataset loads raw features and apply specified transforms\n    to return a dict containing the image tensors and other information.\n\n    InterHand2.6M keypoint indexes::\n\n        0: 'r_thumb4',\n        1: 'r_thumb3',\n        2: 'r_thumb2',\n        3: 'r_thumb1',\n        4: 'r_index4',\n        5: 'r_index3',\n        6: 'r_index2',\n        7: 'r_index1',\n        8: 'r_middle4',\n        9: 'r_middle3',\n        10: 'r_middle2',\n        11: 'r_middle1',\n        12: 'r_ring4',\n        13: 'r_ring3',\n        14: 'r_ring2',\n        15: 'r_ring1',\n        16: 'r_pinky4',\n        17: 'r_pinky3',\n        18: 'r_pinky2',\n        19: 'r_pinky1',\n        20: 'r_wrist',\n        21: 'l_thumb4',\n        22: 'l_thumb3',\n        23: 'l_thumb2',\n        24: 'l_thumb1',\n        25: 'l_index4',\n        26: 'l_index3',\n        27: 'l_index2',\n        28: 'l_index1',\n        29: 'l_middle4',\n        30: 'l_middle3',\n        31: 'l_middle2',\n        32: 'l_middle1',\n        33: 'l_ring4',\n        34: 'l_ring3',\n        35: 'l_ring2',\n        36: 'l_ring1',\n        37: 'l_pinky4',\n        38: 'l_pinky3',\n        39: 'l_pinky2',\n        40: 'l_pinky1',\n        41: 'l_wrist'\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        camera_param_file (str): Cameras' parameters file. Default: ''.\n        joint_file (str): Path to the joint file. Default: ''.\n        use_gt_root_depth (bool): Using the ground truth depth of the wrist\n            or given depth from rootnet_result_file. Default: ``True``.\n        rootnet_result_file (str): Path to the wrist depth file.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/interhand3d.py')\n\n    def __init__(self,\n                 ann_file: str = '',\n                 camera_param_file: str = '',\n                 joint_file: str = '',\n                 use_gt_root_depth: bool = True,\n                 rootnet_result_file: Optional[str] = None,\n                 data_mode: str = 'topdown',\n                 metainfo: Optional[dict] = None,\n                 data_root: Optional[str] = None,\n                 data_prefix: dict = dict(img=''),\n                 filter_cfg: Optional[dict] = None,\n                 indices: Optional[Union[int, Sequence[int]]] = None,\n                 serialize_data: bool = True,\n                 pipeline: List[Union[dict, Callable]] = [],\n                 test_mode: bool = False,\n                 lazy_init: bool = False,\n                 max_refetch: int = 1000):\n\n        _ann_file = ann_file\n        if not is_abs(_ann_file):\n            _ann_file = osp.join(data_root, _ann_file)\n        assert exists(_ann_file), 'Annotation file does not exist.'\n        self.ann_file = _ann_file\n\n        _camera_param_file = camera_param_file\n        if not is_abs(_camera_param_file):\n            _camera_param_file = osp.join(data_root, _camera_param_file)\n        assert exists(_camera_param_file), 'Camera file does not exist.'\n        self.camera_param_file = _camera_param_file\n\n        _joint_file = joint_file\n        if not is_abs(_joint_file):\n            _joint_file = osp.join(data_root, _joint_file)\n        assert exists(_joint_file), 'Joint file does not exist.'\n        self.joint_file = _joint_file\n\n        self.use_gt_root_depth = use_gt_root_depth\n        if not self.use_gt_root_depth:\n            assert rootnet_result_file is not None\n            _rootnet_result_file = rootnet_result_file\n            if not is_abs(_rootnet_result_file):\n                _rootnet_result_file = osp.join(data_root,\n                                                _rootnet_result_file)\n            assert exists(\n                _rootnet_result_file), 'Rootnet result file does not exist.'\n            self.rootnet_result_file = _rootnet_result_file\n\n        super().__init__(\n            ann_file=ann_file,\n            metainfo=metainfo,\n            data_mode=data_mode,\n            data_root=data_root,\n            data_prefix=data_prefix,\n            filter_cfg=filter_cfg,\n            indices=indices,\n            serialize_data=serialize_data,\n            pipeline=pipeline,\n            test_mode=test_mode,\n            lazy_init=lazy_init,\n            max_refetch=max_refetch)\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n        \"\"\"Load data from annotations in COCO format.\"\"\"\n\n        assert exists(self.ann_file), 'Annotation file does not exist'\n\n        with get_local_path(self.ann_file) as local_path:\n            self.coco = COCO(local_path)\n        # set the metainfo about categories, which is a list of dict\n        # and each dict contains the 'id', 'name', etc. about this category\n        if 'categories' in self.coco.dataset:\n            self._metainfo['CLASSES'] = self.coco.loadCats(\n                self.coco.getCatIds())\n\n        with get_local_path(self.camera_param_file) as local_path:\n            with open(local_path, 'r') as f:\n                self.cameras = json.load(f)\n        with get_local_path(self.joint_file) as local_path:\n            with open(local_path, 'r') as f:\n                self.joints = json.load(f)\n\n        instance_list = []\n        image_list = []\n\n        for idx, img_id in enumerate(self.coco.getImgIds()):\n            img = self.coco.loadImgs(img_id)[0]\n            img.update({\n                'img_id':\n                img_id,\n                'img_path':\n                osp.join(self.data_prefix['img'], img['file_name']),\n            })\n            image_list.append(img)\n\n            ann_ids = self.coco.getAnnIds(imgIds=img_id)\n            ann = self.coco.loadAnns(ann_ids)[0]\n\n            instance_info = self.parse_data_info(\n                dict(raw_ann_info=ann, raw_img_info=img))\n\n            # skip invalid instance annotation.\n            if not instance_info:\n                continue\n\n            instance_list.append(instance_info)\n        return instance_list, image_list\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict | None: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        if not self.use_gt_root_depth:\n            rootnet_result = {}\n            with get_local_path(self.rootnet_result_file) as local_path:\n                rootnet_annot = json.load(local_path)\n            for i in range(len(rootnet_annot)):\n                rootnet_result[str(\n                    rootnet_annot[i]['annot_id'])] = rootnet_annot[i]\n\n        num_keypoints = self.metainfo['num_keypoints']\n\n        capture_id = str(img['capture'])\n        camera_name = img['camera']\n        frame_idx = str(img['frame_idx'])\n        camera_pos = np.array(\n            self.cameras[capture_id]['campos'][camera_name], dtype=np.float32)\n        camera_rot = np.array(\n            self.cameras[capture_id]['camrot'][camera_name], dtype=np.float32)\n        focal = np.array(\n            self.cameras[capture_id]['focal'][camera_name], dtype=np.float32)\n        principal_pt = np.array(\n            self.cameras[capture_id]['princpt'][camera_name], dtype=np.float32)\n        joint_world = np.array(\n            self.joints[capture_id][frame_idx]['world_coord'],\n            dtype=np.float32)\n        joint_valid = np.array(ann['joint_valid'], dtype=np.float32).flatten()\n\n        keypoints_cam = np.dot(\n            camera_rot,\n            joint_world.transpose(1, 0) -\n            camera_pos.reshape(3, 1)).transpose(1, 0)\n\n        if self.use_gt_root_depth:\n            bbox_xywh = np.array(ann['bbox'], dtype=np.float32).reshape(1, 4)\n            abs_depth = [keypoints_cam[20, 2], keypoints_cam[41, 2]]\n        else:\n            rootnet_ann_data = rootnet_result[str(ann['id'])]\n            bbox_xywh = np.array(\n                rootnet_ann_data['bbox'], dtype=np.float32).reshape(1, 4)\n            abs_depth = rootnet_ann_data['abs_depth']\n        bbox = bbox_xywh2xyxy(bbox_xywh)\n\n        # 41: 'l_wrist', left hand root\n        # 20: 'r_wrist', right hand root\n        rel_root_depth = keypoints_cam[41, 2] - keypoints_cam[20, 2]\n        # if root is not valid, root-relative 3D depth is also invalid.\n        rel_root_valid = joint_valid[20] * joint_valid[41]\n\n        # if root is not valid -> root-relative 3D pose is also not valid.\n        # Therefore, mark all joints as invalid\n        joint_valid[:20] *= joint_valid[20]\n        joint_valid[21:] *= joint_valid[41]\n\n        joints_3d_visible = np.minimum(1,\n                                       joint_valid.reshape(-1,\n                                                           1)).reshape(1, -1)\n        keypoints_img = camera_to_pixel(\n            keypoints_cam,\n            focal[0],\n            focal[1],\n            principal_pt[0],\n            principal_pt[1],\n            shift=True)[..., :2]\n        joints_3d = np.zeros((keypoints_cam.shape[-2], 3),\n                             dtype=np.float32).reshape(1, -1, 3)\n        joints_3d[..., :2] = keypoints_img\n        joints_3d[..., :21,\n                  2] = keypoints_cam[..., :21, 2] - keypoints_cam[..., 20, 2]\n        joints_3d[..., 21:,\n                  2] = keypoints_cam[..., 21:, 2] - keypoints_cam[..., 41, 2]\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img['img_path'],\n            'rotation': 0,\n            'keypoints': joints_3d,\n            'keypoints_cam': keypoints_cam.reshape(1, -1, 3),\n            'keypoints_visible': joints_3d_visible,\n            'hand_type': self.encode_handtype(ann['hand_type']),\n            'hand_type_valid': np.array([ann['hand_type_valid']]),\n            'rel_root_depth': rel_root_depth,\n            'rel_root_valid': rel_root_valid,\n            'abs_depth': abs_depth,\n            'focal': focal,\n            'principal_pt': principal_pt,\n            'dataset': self.metainfo['dataset_name'],\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'iscrowd': ann.get('iscrowd', False),\n            'id': ann['id'],\n            # store the raw annotation of the instance\n            # it is useful for evaluation without providing ann_file\n            'raw_ann_info': copy.deepcopy(ann),\n        }\n\n        return data_info\n\n    @staticmethod\n    def encode_handtype(hand_type):\n        if hand_type == 'right':\n            return np.array([[1, 0]], dtype=np.float32)\n        elif hand_type == 'left':\n            return np.array([[0, 1]], dtype=np.float32)\n        elif hand_type == 'interacting':\n            return np.array([[1, 1]], dtype=np.float32)\n        else:\n            assert 0, f'Not support hand type: {hand_type}'\n"
  },
  {
    "path": "mmpose/datasets/datasets/utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nimport warnings\n\nimport numpy as np\nfrom mmengine import Config\n\n\ndef parse_pose_metainfo(metainfo: dict):\n    \"\"\"Load meta information of pose dataset and check its integrity.\n\n    Args:\n        metainfo (dict): Raw data of pose meta information, which should\n            contain following contents:\n\n            - \"dataset_name\" (str): The name of the dataset\n            - \"keypoint_info\" (dict): The keypoint-related meta information,\n                e.g., name, upper/lower body, and symmetry\n            - \"skeleton_info\" (dict): The skeleton-related meta information,\n                e.g., start/end keypoint of limbs\n            - \"joint_weights\" (list[float]): The loss weights of keypoints\n            - \"sigmas\" (list[float]): The keypoint distribution parameters\n                to calculate OKS score. See `COCO keypoint evaluation\n                <https://cocodataset.org/#keypoints-eval>`__.\n\n            An example of metainfo is shown as follows.\n\n            .. code-block:: none\n                {\n                    \"dataset_name\": \"coco\",\n                    \"keypoint_info\":\n                    {\n                        0:\n                        {\n                            \"name\": \"nose\",\n                            \"type\": \"upper\",\n                            \"swap\": \"\",\n                            \"color\": [51, 153, 255],\n                        },\n                        1:\n                        {\n                            \"name\": \"right_eye\",\n                            \"type\": \"upper\",\n                            \"swap\": \"left_eye\",\n                            \"color\": [51, 153, 255],\n                        },\n                        ...\n                    },\n                    \"skeleton_info\":\n                    {\n                        0:\n                        {\n                            \"link\": (\"left_ankle\", \"left_knee\"),\n                            \"color\": [0, 255, 0],\n                        },\n                        ...\n                    },\n                    \"joint_weights\": [1., 1., ...],\n                    \"sigmas\": [0.026, 0.025, ...],\n                }\n\n\n            A special case is that `metainfo` can have the key \"from_file\",\n            which should be the path of a config file. In this case, the\n            actual metainfo will be loaded by:\n\n            .. code-block:: python\n                metainfo = mmengine.Config.fromfile(metainfo['from_file'])\n\n    Returns:\n        Dict: pose meta information that contains following contents:\n\n        - \"dataset_name\" (str): Same as ``\"dataset_name\"`` in the input\n        - \"num_keypoints\" (int): Number of keypoints\n        - \"keypoint_id2name\" (dict): Mapping from keypoint id to name\n        - \"keypoint_name2id\" (dict): Mapping from keypoint name to id\n        - \"upper_body_ids\" (list): Ids of upper-body keypoint\n        - \"lower_body_ids\" (list): Ids of lower-body keypoint\n        - \"flip_indices\" (list): The Id of each keypoint's symmetric keypoint\n        - \"flip_pairs\" (list): The Ids of symmetric keypoint pairs\n        - \"keypoint_colors\" (numpy.ndarray): The keypoint color matrix of\n            shape [K, 3], where each row is the color of one keypint in bgr\n        - \"num_skeleton_links\" (int): The number of links\n        - \"skeleton_links\" (list): The links represented by Id pairs of start\n             and end points\n        - \"skeleton_link_colors\" (numpy.ndarray): The link color matrix\n        - \"dataset_keypoint_weights\" (numpy.ndarray): Same as the\n            ``\"joint_weights\"`` in the input\n        - \"sigmas\" (numpy.ndarray): Same as the ``\"sigmas\"`` in the input\n    \"\"\"\n\n    if 'from_file' in metainfo:\n        cfg_file = metainfo['from_file']\n        if not osp.isfile(cfg_file):\n            # Search configs in 'mmpose/.mim/configs/' in case that mmpose\n            # is installed in non-editable mode.\n            import mmpose\n            mmpose_path = osp.dirname(mmpose.__file__)\n            _cfg_file = osp.join(mmpose_path, '.mim', 'configs', '_base_',\n                                 'datasets', osp.basename(cfg_file))\n            if osp.isfile(_cfg_file):\n                warnings.warn(\n                    f'The metainfo config file \"{cfg_file}\" does not exist. '\n                    f'A matched config file \"{_cfg_file}\" will be used '\n                    'instead.')\n                cfg_file = _cfg_file\n            else:\n                raise FileNotFoundError(\n                    f'The metainfo config file \"{cfg_file}\" does not exist.')\n\n        # TODO: remove the nested structure of dataset_info\n        # metainfo = Config.fromfile(metainfo['from_file'])\n        metainfo = Config.fromfile(cfg_file).dataset_info\n\n    # check data integrity\n    assert 'dataset_name' in metainfo\n    assert 'keypoint_info' in metainfo\n    assert 'skeleton_info' in metainfo\n    assert 'joint_weights' in metainfo\n    assert 'sigmas' in metainfo\n\n    # parse metainfo\n    parsed = dict(\n        dataset_name=None,\n        num_keypoints=None,\n        keypoint_id2name={},\n        keypoint_name2id={},\n        upper_body_ids=[],\n        lower_body_ids=[],\n        flip_indices=[],\n        flip_pairs=[],\n        keypoint_colors=[],\n        num_skeleton_links=None,\n        skeleton_links=[],\n        skeleton_link_colors=[],\n        dataset_keypoint_weights=None,\n        sigmas=None,\n    )\n\n    parsed['dataset_name'] = metainfo['dataset_name']\n\n    # parse keypoint information\n    parsed['num_keypoints'] = len(metainfo['keypoint_info'])\n\n    for kpt_id, kpt in metainfo['keypoint_info'].items():\n        kpt_name = kpt['name']\n        parsed['keypoint_id2name'][kpt_id] = kpt_name\n        parsed['keypoint_name2id'][kpt_name] = kpt_id\n        parsed['keypoint_colors'].append(kpt.get('color', [255, 128, 0]))\n\n        kpt_type = kpt.get('type', '')\n        if kpt_type == 'upper':\n            parsed['upper_body_ids'].append(kpt_id)\n        elif kpt_type == 'lower':\n            parsed['lower_body_ids'].append(kpt_id)\n\n        swap_kpt = kpt.get('swap', '')\n        if swap_kpt == kpt_name or swap_kpt == '':\n            parsed['flip_indices'].append(kpt_name)\n        else:\n            parsed['flip_indices'].append(swap_kpt)\n            pair = (swap_kpt, kpt_name)\n            if pair not in parsed['flip_pairs']:\n                parsed['flip_pairs'].append(pair)\n\n    # parse skeleton information\n    parsed['num_skeleton_links'] = len(metainfo['skeleton_info'])\n    for _, sk in metainfo['skeleton_info'].items():\n        parsed['skeleton_links'].append(sk['link'])\n        parsed['skeleton_link_colors'].append(sk.get('color', [96, 96, 255]))\n\n    # parse extra information\n    parsed['dataset_keypoint_weights'] = np.array(\n        metainfo['joint_weights'], dtype=np.float32)\n    parsed['sigmas'] = np.array(metainfo['sigmas'], dtype=np.float32)\n\n    if 'stats_info' in metainfo:\n        parsed['stats_info'] = {}\n        for name, val in metainfo['stats_info'].items():\n            parsed['stats_info'][name] = np.array(val, dtype=np.float32)\n\n    # formatting\n    def _map(src, mapping: dict):\n        if isinstance(src, (list, tuple)):\n            cls = type(src)\n            return cls(_map(s, mapping) for s in src)\n        else:\n            return mapping[src]\n\n    parsed['flip_pairs'] = _map(\n        parsed['flip_pairs'], mapping=parsed['keypoint_name2id'])\n    parsed['flip_indices'] = _map(\n        parsed['flip_indices'], mapping=parsed['keypoint_name2id'])\n    parsed['skeleton_links'] = _map(\n        parsed['skeleton_links'], mapping=parsed['keypoint_name2id'])\n\n    parsed['keypoint_colors'] = np.array(\n        parsed['keypoint_colors'], dtype=np.uint8)\n    parsed['skeleton_link_colors'] = np.array(\n        parsed['skeleton_link_colors'], dtype=np.uint8)\n\n    return parsed\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .coco_wholebody_dataset import CocoWholeBodyDataset\nfrom .halpe_dataset import HalpeDataset\nfrom .ubody2d_dataset import UBody2dDataset\n\n__all__ = ['CocoWholeBodyDataset', 'HalpeDataset', 'UBody2dDataset']\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody/coco_wholebody_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport os.path as osp\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass CocoWholeBodyDataset(BaseCocoStyleDataset):\n    \"\"\"CocoWholeBody dataset for pose estimation.\n\n    \"Whole-Body Human Pose Estimation in the Wild\", ECCV'2020.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2007.11858>`__ .\n\n    COCO-WholeBody keypoints::\n\n        0-16: 17 body keypoints,\n        17-22: 6 foot keypoints,\n        23-90: 68 face keypoints,\n        91-132: 42 hand keypoints\n\n        In total, we have 133 keypoints for wholebody pose estimation.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(\n        from_file='configs/_base_/datasets/coco_wholebody.py')\n\n    def parse_data_info(self, raw_data_info: dict) -> Optional[dict]:\n        \"\"\"Parse raw COCO annotation of an instance.\n\n        Args:\n            raw_data_info (dict): Raw data information loaded from\n                ``ann_file``. It should have following contents:\n\n                - ``'raw_ann_info'``: Raw annotation of an instance\n                - ``'raw_img_info'``: Raw information of the image that\n                    contains the instance\n\n        Returns:\n            dict: Parsed instance annotation\n        \"\"\"\n\n        ann = raw_data_info['raw_ann_info']\n        img = raw_data_info['raw_img_info']\n\n        img_path = osp.join(self.data_prefix['img'], img['file_name'])\n        img_w, img_h = img['width'], img['height']\n\n        # get bbox in shape [1, 4], formatted as xywh\n        x, y, w, h = ann['bbox']\n        x1 = np.clip(x, 0, img_w - 1)\n        y1 = np.clip(y, 0, img_h - 1)\n        x2 = np.clip(x + w, 0, img_w - 1)\n        y2 = np.clip(y + h, 0, img_h - 1)\n\n        bbox = np.array([x1, y1, x2, y2], dtype=np.float32).reshape(1, 4)\n\n        # keypoints in shape [1, K, 2] and keypoints_visible in [1, K]\n        # COCO-Wholebody: consisting of body, foot, face and hand keypoints\n        _keypoints = np.array(ann['keypoints'] + ann['foot_kpts'] +\n                              ann['face_kpts'] + ann['lefthand_kpts'] +\n                              ann['righthand_kpts']).reshape(1, -1, 3)\n        keypoints = _keypoints[..., :2]\n        keypoints_visible = np.minimum(1, _keypoints[..., 2] > 0)\n\n        if 'area' in ann:\n            area = np.array(ann['area'], dtype=np.float32)\n        else:\n            area = np.clip((x2 - x1) * (y2 - y1) * 0.53, a_min=1.0, a_max=None)\n            area = np.array(area, dtype=np.float32)\n\n        num_keypoints = ann['num_keypoints']\n\n        data_info = {\n            'img_id': ann['image_id'],\n            'img_path': img_path,\n            'bbox': bbox,\n            'bbox_score': np.ones(1, dtype=np.float32),\n            'num_keypoints': num_keypoints,\n            'keypoints': keypoints,\n            'keypoints_3d': None,\n            'keypoints_visible': keypoints_visible,\n            'iscrowd': ann['iscrowd'],\n            'segmentation': ann['segmentation'],\n            'area': area,\n            'id': ann['id'],\n            'category_id': ann['category_id'],\n            # store the raw annotation of the instance\n            # it is useful for evaluation without providing ann_file\n            'raw_ann_info': copy.deepcopy(ann),\n        }\n\n        return data_info\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody/halpe_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom ..base import BaseCocoStyleDataset\n\n\n@DATASETS.register_module()\nclass HalpeDataset(BaseCocoStyleDataset):\n    \"\"\"Halpe dataset for pose estimation.\n\n    'https://github.com/Fang-Haoshu/Halpe-FullBody'\n\n    Halpe keypoints::\n\n        0-19: 20 body keypoints,\n        20-25: 6 foot keypoints,\n        26-93: 68 face keypoints,\n        94-135: 42 hand keypoints\n\n    In total, we have 136 keypoints for wholebody pose estimation.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/halpe.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody/ubody2d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.registry import DATASETS\nfrom .coco_wholebody_dataset import CocoWholeBodyDataset\n\n\n@DATASETS.register_module()\nclass UBody2dDataset(CocoWholeBodyDataset):\n    \"\"\"Ubody2d dataset for pose estimation.\n\n    \"One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer\",\n    CVPR'2023. More details can be found in the `paper\n    <https://arxiv.org/abs/2303.16160>`__ .\n\n    Ubody2D keypoints::\n\n        0-16: 17 body keypoints,\n        17-22: 6 foot keypoints,\n        23-90: 68 face keypoints,\n        91-132: 42 hand keypoints\n\n        In total, we have 133 keypoints for wholebody pose estimation.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        bbox_file (str, optional): Detection result file path. If\n            ``bbox_file`` is set, detected bboxes loaded from this file will\n            be used instead of ground-truth bboxes. This setting is only for\n            evaluation, i.e., ignored when ``test_mode`` is ``False``.\n            Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data. Default:\n            ``dict(img=None, ann=None)``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n        sample_interval (int, optional): The sample interval of the dataset.\n            Default: 1.\n    \"\"\"\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/ubody2d.py')\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody3d/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .h3wb_dataset import H36MWholeBodyDataset\nfrom .ubody3d_dataset import UBody3dDataset\n\n__all__ = ['UBody3dDataset', 'H36MWholeBodyDataset']\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody3d/h3wb_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom typing import List, Tuple\n\nimport numpy as np\nfrom mmengine.fileio import get_local_path\n\nfrom mmpose.registry import DATASETS\nfrom ..body3d import Human36mDataset\n\n\n@DATASETS.register_module()\nclass H36MWholeBodyDataset(Human36mDataset):\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/h3wb.py')\n    \"\"\"Human3.6M 3D WholeBody Dataset.\n\n    \"H3WB: Human3.6M 3D WholeBody Dataset and Benchmark\", ICCV'2023.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2211.15692>`__.\n\n    H36M-WholeBody keypoints::\n\n        0-16: 17 body keypoints,\n        17-22: 6 foot keypoints,\n        23-90: 68 face keypoints,\n        91-132: 42 hand keypoints\n\n        In total, we have 133 keypoints for wholebody pose estimation.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        seq_len (int): Number of frames in a sequence. Default: 1.\n        seq_step (int): The interval for extracting frames from the video.\n            Default: 1.\n        multiple_target (int): If larger than 0, merge every\n            ``multiple_target`` sequence together. Default: 0.\n        multiple_target_step (int): The interval for merging sequence. Only\n            valid when ``multiple_target`` is larger than 0. Default: 0.\n        pad_video_seq (bool): Whether to pad the video so that poses will be\n            predicted for every frame in the video. Default: ``False``.\n        causal (bool): If set to ``True``, the rightmost input frame will be\n            the target frame. Otherwise, the middle input frame will be the\n            target frame. Default: ``True``.\n        subset_frac (float): The fraction to reduce dataset size. If set to 1,\n            the dataset size is not reduced. Default: 1.\n        keypoint_2d_src (str): Specifies 2D keypoint information options, which\n            should be one of the following options:\n\n            - ``'gt'``: load from the annotation file\n            - ``'detection'``: load from a detection\n              result file of 2D keypoint\n            - 'pipeline': the information will be generated by the pipeline\n\n            Default: ``'gt'``.\n        keypoint_2d_det_file (str, optional): The 2D keypoint detection file.\n            If set, 2d keypoint loaded from this file will be used instead of\n            ground-truth keypoints. This setting is only when\n            ``keypoint_2d_src`` is ``'detection'``. Default: ``None``.\n        factor_file (str, optional): The projection factors' file. If set,\n            factor loaded from this file will be used instead of calculated\n            factors. Default: ``None``.\n        camera_param_file (str): Cameras' parameters file. Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    def __init__(self, test_mode: bool = False, **kwargs):\n\n        self.camera_order_id = ['54138969', '55011271', '58860488', '60457274']\n        if not test_mode:\n            self.subjects = ['S1', 'S5', 'S6']\n        else:\n            self.subjects = ['S7']\n\n        super().__init__(test_mode=test_mode, **kwargs)\n\n    def _load_ann_file(self, ann_file: str) -> dict:\n        with get_local_path(ann_file) as local_path:\n            data = np.load(local_path, allow_pickle=True)\n\n        self.ann_data = data['train_data'].item()\n        self.camera_data = data['metadata'].item()\n        self.bboxes = data['bbox'].item()\n\n    def get_sequence_indices(self) -> List[List[int]]:\n        return []\n\n    def _load_annotations(self) -> Tuple[List[dict], List[dict]]:\n\n        instance_list = []\n        image_list = []\n\n        instance_id = 0\n        for subject in self.subjects:\n            if subject not in self.ann_data:\n                continue\n            actions = self.ann_data[subject].keys()\n            for act in actions:\n                for cam in self.camera_order_id:\n                    if cam not in self.ann_data[subject][act]:\n                        continue\n                    keypoints_2d = self.ann_data[subject][act][cam]['pose_2d']\n                    keypoints_3d = self.ann_data[subject][act][cam][\n                        'camera_3d']\n                    num_keypoints = keypoints_2d.shape[1]\n\n                    camera_param = self.camera_data[subject][cam]\n                    camera_param = {\n                        'K': camera_param['K'][0, :2, ...],\n                        'R': camera_param['R'][0],\n                        'T': camera_param['T'].reshape(3, 1),\n                        'Distortion': camera_param['Distortion'][0],\n                    }\n                    camera_param['f'] = (camera_param['K'][0, 0] * 1000,\n                                         camera_param['K'][1, 1] * 1000)\n                    camera_param['c'] = (camera_param['K'][0, 2] * 1000,\n                                         camera_param['K'][1, 2] * 1000)\n\n                    seq_step = 1\n                    _len = (self.seq_len - 1) * seq_step + 1\n                    _indices = list(\n                        range(len(self.ann_data[subject][act]['frame_id'])))\n\n                    seq_indices = [\n                        _indices[i:(i + _len):seq_step]\n                        for i in list(range(0,\n                                            len(_indices) - _len + 1))\n                    ]\n\n                    frames = self.ann_data[subject][act]['frame_id']\n\n                    for idx, frame_ids in enumerate(seq_indices):\n                        expected_num_frames = self.seq_len\n                        if self.multiple_target:\n                            expected_num_frames = self.multiple_target\n\n                        assert len(frame_ids) == (expected_num_frames), (\n                            f'Expected `frame_ids` == {expected_num_frames}, but '  # noqa\n                            f'got {len(frame_ids)} ')\n\n                        _kpts_2d = keypoints_2d[frame_ids]\n                        _kpts_3d = keypoints_3d[frame_ids]\n\n                        target_idx = [-1] if self.causal else [\n                            int(self.seq_len) // 2\n                        ]\n                        if self.multiple_target > 0:\n                            target_idx = list(range(self.multiple_target))\n\n                        bbox = self.bboxes[(subject, act, cam,\n                                            frames[frame_ids[-1]])]\n                        bbox = np.array([[\n                            bbox['x_min'], bbox['y_min'], bbox['x_max'],\n                            bbox['y_max']\n                        ]],\n                                        dtype=np.float32)\n\n                        img_paths = [\n                            osp.join(self.data_root, 'original', subject,\n                                     'Images', f'{act}.{cam}',\n                                     f'frame_{frames[i]}.jpg')  # noqa\n                            for i in frame_ids\n                        ]\n\n                        instance_info = {\n                            'num_keypoints':\n                            num_keypoints,\n                            'keypoints':\n                            _kpts_2d,\n                            'keypoints_3d':\n                            _kpts_3d / 1000,\n                            'keypoints_visible':\n                            np.ones_like(_kpts_2d[..., 0], dtype=np.float32),\n                            'keypoints_3d_visible':\n                            np.ones_like(_kpts_2d[..., 0], dtype=np.float32),\n                            'bbox':\n                            bbox,\n                            'bbox_score':\n                            np.ones((len(frame_ids), )),\n                            'scale':\n                            np.zeros((1, 1), dtype=np.float32),\n                            'center':\n                            np.zeros((1, 2), dtype=np.float32),\n                            'factor':\n                            np.zeros((1, 1), dtype=np.float32),\n                            'id':\n                            instance_id,\n                            'category_id':\n                            1,\n                            'iscrowd':\n                            0,\n                            'camera_param': [camera_param],\n                            'img_paths':\n                            img_paths,\n                            'img_path':\n                            img_paths[-1],\n                            'img_ids':\n                            frame_ids,\n                            'lifting_target':\n                            _kpts_3d[target_idx] / 1000,\n                            'lifting_target_visible':\n                            np.ones_like(_kpts_2d[..., 0],\n                                         dtype=np.float32)[target_idx],\n                        }\n                        instance_list.append(instance_info)\n\n                        if self.data_mode == 'bottomup':\n                            for idx, img_name in enumerate(\n                                    instance_info['img_paths']):\n                                img_info = self.get_img_info(idx, img_name)\n                                image_list.append(img_info)\n\n                        instance_id += 1\n        del self.ann_data\n        return instance_list, image_list\n"
  },
  {
    "path": "mmpose/datasets/datasets/wholebody3d/ubody3d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom collections import defaultdict\nfrom typing import List, Tuple\n\nimport numpy as np\nfrom mmengine.fileio import get_local_path\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets.datasets import BaseMocapDataset\nfrom mmpose.registry import DATASETS\n\n\n@DATASETS.register_module()\nclass UBody3dDataset(BaseMocapDataset):\n    \"\"\"Ubody3d dataset for 3D human pose estimation.\n\n    \"One-Stage 3D Whole-Body Mesh Recovery with Component Aware Transformer\",\n    CVPR'2023. More details can be found in the `paper\n    <https://arxiv.org/abs/2303.16160>`__ .\n\n    Ubody3D keypoints::\n\n        0-24: 25 body keypoints,\n        25-64: 40 hand keypoints,\n        65-136: 72 face keypoints,\n\n        In total, we have 137 keypoints for wholebody 3D pose estimation.\n\n    Args:\n        ann_file (str): Annotation file path. Default: ''.\n        seq_len (int): Number of frames in a sequence. Default: 1.\n        multiple_target (int): If larger than 0, merge every\n            ``multiple_target`` sequence together. Default: 0.\n        causal (bool): If set to ``True``, the rightmost input frame will be\n            the target frame. Otherwise, the middle input frame will be the\n            target frame. Default: ``True``.\n        subset_frac (float): The fraction to reduce dataset size. If set to 1,\n            the dataset size is not reduced. Default: 1.\n        camera_param_file (str): Cameras' parameters file. Default: ``None``.\n        data_mode (str): Specifies the mode of data samples: ``'topdown'`` or\n            ``'bottomup'``. In ``'topdown'`` mode, each data sample contains\n            one instance; while in ``'bottomup'`` mode, each data sample\n            contains all instances in a image. Default: ``'topdown'``\n        metainfo (dict, optional): Meta information for dataset, such as class\n            information. Default: ``None``.\n        data_root (str, optional): The root directory for ``data_prefix`` and\n            ``ann_file``. Default: ``None``.\n        data_prefix (dict, optional): Prefix for training data.\n            Default: ``dict(img='')``.\n        filter_cfg (dict, optional): Config for filter data. Default: `None`.\n        indices (int or Sequence[int], optional): Support using first few\n            data in annotation file to facilitate training/testing on a smaller\n            dataset. Default: ``None`` which means using all ``data_infos``.\n        serialize_data (bool, optional): Whether to hold memory using\n            serialized objects, when enabled, data loader workers can use\n            shared RAM from master process instead of making a copy.\n            Default: ``True``.\n        pipeline (list, optional): Processing pipeline. Default: [].\n        test_mode (bool, optional): ``test_mode=True`` means in test phase.\n            Default: ``False``.\n        lazy_init (bool, optional): Whether to load annotation during\n            instantiation. In some cases, such as visualization, only the meta\n            information of the dataset is needed, which is not necessary to\n            load annotation file. ``Basedataset`` can skip load annotations to\n            save time by set ``lazy_init=False``. Default: ``False``.\n        max_refetch (int, optional): If ``Basedataset.prepare_data`` get a\n            None img. The maximum extra number of cycles to get a valid\n            image. Default: 1000.\n    \"\"\"\n\n    def __init__(self,\n                 multiple_target: int = 0,\n                 multiple_target_step: int = 0,\n                 seq_step: int = 1,\n                 pad_video_seq: bool = False,\n                 **kwargs):\n        self.seq_step = seq_step\n        self.pad_video_seq = pad_video_seq\n\n        if multiple_target > 0 and multiple_target_step == 0:\n            multiple_target_step = multiple_target\n        self.multiple_target_step = multiple_target_step\n\n        super().__init__(multiple_target=multiple_target, **kwargs)\n\n    METAINFO: dict = dict(from_file='configs/_base_/datasets/ubody3d.py')\n\n    def _load_ann_file(self, ann_file: str) -> dict:\n        \"\"\"Load annotation file.\"\"\"\n        with get_local_path(ann_file) as local_path:\n            self.ann_data = COCO(local_path)\n\n    def get_sequence_indices(self) -> List[List[int]]:\n        video_frames = defaultdict(list)\n        img_ids = self.ann_data.getImgIds()\n        for img_id in img_ids:\n            img_info = self.ann_data.loadImgs(img_id)[0]\n            subj, _, _ = self._parse_image_name(img_info['file_name'])\n            video_frames[subj].append(img_id)\n\n        sequence_indices = []\n        _len = (self.seq_len - 1) * self.seq_step + 1\n        _step = self.seq_step\n\n        if self.multiple_target:\n            for _, _img_ids in sorted(video_frames.items()):\n                n_frame = len(_img_ids)\n                _ann_ids = self.ann_data.getAnnIds(imgIds=_img_ids)\n                seqs_from_video = [\n                    _ann_ids[i:(i + self.multiple_target):_step]\n                    for i in range(0, n_frame, self.multiple_target_step)\n                ][:(n_frame + self.multiple_target_step -\n                    self.multiple_target) // self.multiple_target_step]\n                sequence_indices.extend(seqs_from_video)\n        else:\n            for _, _img_ids in sorted(video_frames.items()):\n                n_frame = len(_img_ids)\n                _ann_ids = self.ann_data.getAnnIds(imgIds=_img_ids)\n                if self.pad_video_seq:\n                    # Pad the sequence so that every frame in the sequence will\n                    # be predicted.\n                    if self.causal:\n                        frames_left = self.seq_len - 1\n                        frames_right = 0\n                    else:\n                        frames_left = (self.seq_len - 1) // 2\n                        frames_right = frames_left\n                    for i in range(n_frame):\n                        pad_left = max(0, frames_left - i // _step)\n                        pad_right = max(\n                            0, frames_right - (n_frame - 1 - i) // _step)\n                        start = max(i % _step, i - frames_left * _step)\n                        end = min(n_frame - (n_frame - 1 - i) % _step,\n                                  i + frames_right * _step + 1)\n                        sequence_indices.append([_ann_ids[0]] * pad_left +\n                                                _ann_ids[start:end:_step] +\n                                                [_ann_ids[-1]] * pad_right)\n                else:\n                    seqs_from_video = [\n                        _ann_ids[i:(i + _len):_step]\n                        for i in range(0, n_frame - _len + 1, _step)\n                    ]\n                    sequence_indices.extend(seqs_from_video)\n\n        # reduce dataset size if needed\n        subset_size = int(len(sequence_indices) * self.subset_frac)\n        start = np.random.randint(0, len(sequence_indices) - subset_size + 1)\n        end = start + subset_size\n\n        sequence_indices = sequence_indices[start:end]\n\n        return sequence_indices\n\n    def _parse_image_name(self, image_path: str) -> Tuple[str, int]:\n        \"\"\"Parse image name to get video name and frame index.\n\n        Args:\n            image_name (str): Image name.\n\n        Returns:\n            tuple[str, int]: Video name and frame index.\n        \"\"\"\n        trim, file_name = image_path.split('/')[-2:]\n        frame_id, suffix = file_name.split('.')\n        return trim, frame_id, suffix\n\n    def _load_annotations(self):\n        \"\"\"Load data from annotations in COCO format.\"\"\"\n        num_keypoints = 133\n        self._metainfo['CLASSES'] = self.ann_data.loadCats(\n            self.ann_data.getCatIds())\n\n        instance_list = []\n        image_list = []\n\n        for i, _ann_ids in enumerate(self.sequence_indices):\n            expected_num_frames = self.seq_len\n            if self.multiple_target:\n                expected_num_frames = self.multiple_target\n\n            assert len(_ann_ids) == (expected_num_frames), (\n                f'Expected `frame_ids` == {expected_num_frames}, but '\n                f'got {len(_ann_ids)} ')\n\n            anns = self.ann_data.loadAnns(_ann_ids)\n            num_anns = len(anns)\n            img_ids = []\n            kpts = np.zeros((num_anns, num_keypoints, 2), dtype=np.float32)\n            kpts_3d = np.zeros((num_anns, num_keypoints, 3), dtype=np.float32)\n            keypoints_visible = np.zeros((num_anns, num_keypoints),\n                                         dtype=np.float32)\n            scales = np.zeros((num_anns, 2), dtype=np.float32)\n            centers = np.zeros((num_anns, 2), dtype=np.float32)\n            bboxes = np.zeros((num_anns, 4), dtype=np.float32)\n            bbox_scores = np.zeros((num_anns, ), dtype=np.float32)\n            bbox_scales = np.zeros((num_anns, 2), dtype=np.float32)\n\n            for j, ann in enumerate(anns):\n                img_ids.append(ann['image_id'])\n                kpts[j] = np.array(ann['keypoints'], dtype=np.float32)\n                kpts_3d[j] = np.array(ann['keypoints_3d'], dtype=np.float32)\n                keypoints_visible[j] = np.array(\n                    ann['keypoints_valid'], dtype=np.float32)\n                if 'scale' in ann:\n                    scales[j] = np.array(ann['scale'])\n                if 'center' in ann:\n                    centers[j] = np.array(ann['center'])\n                bboxes[j] = np.array(ann['bbox'], dtype=np.float32)\n                bbox_scores[j] = np.array([1], dtype=np.float32)\n                bbox_scales[j] = np.array([1, 1], dtype=np.float32)\n\n            imgs = self.ann_data.loadImgs(img_ids)\n\n            img_paths = np.array([\n                f'{self.data_root}/images/' + img['file_name'] for img in imgs\n            ])\n            factors = np.zeros((kpts_3d.shape[0], ), dtype=np.float32)\n\n            target_idx = [-1] if self.causal else [int(self.seq_len // 2)]\n            if self.multiple_target:\n                target_idx = list(range(self.multiple_target))\n\n            cam_param = anns[-1]['camera_param']\n            if 'w' not in cam_param or 'h' not in cam_param:\n                cam_param['w'] = 1000\n                cam_param['h'] = 1000\n\n            cam_param = {'f': cam_param['focal'], 'c': cam_param['princpt']}\n\n            instance_info = {\n                'num_keypoints': num_keypoints,\n                'keypoints': kpts,\n                'keypoints_3d': kpts_3d,\n                'keypoints_visible': keypoints_visible,\n                'scale': scales,\n                'center': centers,\n                'id': i,\n                'category_id': 1,\n                'iscrowd': 0,\n                'img_paths': list(img_paths),\n                'img_path': img_paths[-1],\n                'img_ids': [img['id'] for img in imgs],\n                'lifting_target': kpts_3d[target_idx],\n                'lifting_target_visible': keypoints_visible[target_idx],\n                'target_img_paths': list(img_paths[target_idx]),\n                'camera_param': [cam_param],\n                'factor': factors,\n                'target_idx': target_idx,\n                'bbox': bboxes,\n                'bbox_scales': bbox_scales,\n                'bbox_scores': bbox_scores\n            }\n\n            instance_list.append(instance_info)\n\n        if self.data_mode == 'bottomup':\n            for img_id in self.ann_data.getImgIds():\n                img = self.ann_data.loadImgs(img_id)[0]\n                img.update({\n                    'img_id':\n                    img_id,\n                    'img_path':\n                    osp.join(self.data_prefix['img'], img['file_name']),\n                })\n                image_list.append(img)\n        del self.ann_data\n        return instance_list, image_list\n\n    def load_data_list(self) -> List[dict]:\n        data_list = super().load_data_list()\n        self.ann_data = None\n        return data_list\n"
  },
  {
    "path": "mmpose/datasets/samplers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport itertools\nimport math\nfrom typing import Iterator, List, Optional, Sized, Union\n\nimport torch\nfrom mmengine.dist import get_dist_info, sync_random_seed\nfrom torch.utils.data import Sampler\n\nfrom mmpose.datasets import CombinedDataset\nfrom mmpose.registry import DATA_SAMPLERS\n\n\n@DATA_SAMPLERS.register_module()\nclass MultiSourceSampler(Sampler):\n    \"\"\"Multi-Source Sampler. According to the sampling ratio, sample data from\n    different datasets to form batches.\n\n    Args:\n        dataset (Sized): The dataset\n        batch_size (int): Size of mini-batch\n        source_ratio (list[int | float]): The sampling ratio of different\n            source datasets in a mini-batch\n        shuffle (bool): Whether shuffle the dataset or not. Defaults to\n            ``True``\n        round_up (bool): Whether to add extra samples to make the number of\n            samples evenly divisible by the world size. Defaults to True.\n        seed (int, optional): Random seed. If ``None``, set a random seed.\n            Defaults to ``None``\n    \"\"\"\n\n    def __init__(self,\n                 dataset: Sized,\n                 batch_size: int,\n                 source_ratio: List[Union[int, float]],\n                 shuffle: bool = True,\n                 round_up: bool = True,\n                 seed: Optional[int] = None) -> None:\n\n        assert isinstance(dataset, CombinedDataset),\\\n            f'The dataset must be CombinedDataset, but get {dataset}'\n        assert isinstance(batch_size, int) and batch_size > 0, \\\n            'batch_size must be a positive integer value, ' \\\n            f'but got batch_size={batch_size}'\n        assert isinstance(source_ratio, list), \\\n            f'source_ratio must be a list, but got source_ratio={source_ratio}'\n        assert len(source_ratio) == len(dataset._lens), \\\n            'The length of source_ratio must be equal to ' \\\n            f'the number of datasets, but got source_ratio={source_ratio}'\n\n        rank, world_size = get_dist_info()\n        self.rank = rank\n        self.world_size = world_size\n\n        self.dataset = dataset\n        self.cumulative_sizes = [0] + list(itertools.accumulate(dataset._lens))\n        self.batch_size = batch_size\n        self.source_ratio = source_ratio\n        self.num_samples = int(math.ceil(len(self.dataset) * 1.0 / world_size))\n        self.num_per_source = [\n            int(batch_size * sr / sum(source_ratio)) for sr in source_ratio\n        ]\n        self.num_per_source[0] = batch_size - sum(self.num_per_source[1:])\n\n        assert sum(self.num_per_source) == batch_size, \\\n            'The sum of num_per_source must be equal to ' \\\n            f'batch_size, but get {self.num_per_source}'\n\n        self.seed = sync_random_seed() if seed is None else seed\n        self.shuffle = shuffle\n        self.round_up = round_up\n        self.source2inds = {\n            source: self._indices_of_rank(len(ds))\n            for source, ds in enumerate(dataset.datasets)\n        }\n\n    def _infinite_indices(self, sample_size: int) -> Iterator[int]:\n        \"\"\"Infinitely yield a sequence of indices.\"\"\"\n        g = torch.Generator()\n        g.manual_seed(self.seed)\n        while True:\n            if self.shuffle:\n                yield from torch.randperm(sample_size, generator=g).tolist()\n            else:\n                yield from torch.arange(sample_size).tolist()\n\n    def _indices_of_rank(self, sample_size: int) -> Iterator[int]:\n        \"\"\"Slice the infinite indices by rank.\"\"\"\n        yield from itertools.islice(\n            self._infinite_indices(sample_size), self.rank, None,\n            self.world_size)\n\n    def __iter__(self) -> Iterator[int]:\n        batch_buffer = []\n        num_iters = self.num_samples // self.batch_size\n        if self.round_up and self.num_samples > num_iters * self.batch_size:\n            num_iters += 1\n        for i in range(num_iters):\n            for source, num in enumerate(self.num_per_source):\n                batch_buffer_per_source = []\n                for idx in self.source2inds[source]:\n                    idx += self.cumulative_sizes[source]\n                    batch_buffer_per_source.append(idx)\n                    if len(batch_buffer_per_source) == num:\n                        batch_buffer += batch_buffer_per_source\n                        break\n        return iter(batch_buffer)\n\n    def __len__(self) -> int:\n        return self.num_samples\n\n    def set_epoch(self, epoch: int) -> None:\n        \"\"\"Compatible in `epoch-based runner.\"\"\"\n        pass\n"
  },
  {
    "path": "mmpose/datasets/transforms/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .bottomup_transforms import (BottomupGetHeatmapMask, BottomupRandomAffine,\n                                  BottomupRandomChoiceResize,\n                                  BottomupRandomCrop, BottomupResize)\nfrom .common_transforms import (Albumentation, FilterAnnotations,\n                                GenerateTarget, GetBBoxCenterScale,\n                                PhotometricDistortion, RandomBBoxTransform,\n                                RandomFlip, RandomHalfBody, YOLOXHSVRandomAug)\nfrom .converting import KeypointConverter, SingleHandConverter\nfrom .formatting import PackPoseInputs\nfrom .hand_transforms import HandRandomFlip\nfrom .loading import LoadImage\nfrom .mix_img_transforms import Mosaic, YOLOXMixUp\nfrom .pose3d_transforms import RandomFlipAroundRoot\nfrom .topdown_transforms import TopdownAffine\n\n__all__ = [\n    'GetBBoxCenterScale', 'RandomBBoxTransform', 'RandomFlip',\n    'RandomHalfBody', 'TopdownAffine', 'Albumentation',\n    'PhotometricDistortion', 'PackPoseInputs', 'LoadImage',\n    'BottomupGetHeatmapMask', 'BottomupRandomAffine', 'BottomupResize',\n    'GenerateTarget', 'KeypointConverter', 'RandomFlipAroundRoot',\n    'FilterAnnotations', 'YOLOXHSVRandomAug', 'YOLOXMixUp', 'Mosaic',\n    'BottomupRandomCrop', 'BottomupRandomChoiceResize', 'HandRandomFlip',\n    'SingleHandConverter'\n]\n"
  },
  {
    "path": "mmpose/datasets/transforms/bottomup_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom functools import partial\nfrom typing import Dict, List, Optional, Sequence, Tuple, Union\n\nimport cv2\nimport numpy as np\nimport xtcocotools.mask as cocomask\nfrom mmcv.image import imflip_, imresize\nfrom mmcv.image.geometric import imrescale\nfrom mmcv.transforms import BaseTransform\nfrom mmcv.transforms.utils import cache_randomness\nfrom scipy.stats import truncnorm\n\nfrom mmpose.registry import TRANSFORMS\nfrom mmpose.structures.bbox import (bbox_clip_border, bbox_corner2xyxy,\n                                    bbox_xyxy2corner, get_pers_warp_matrix,\n                                    get_udp_warp_matrix, get_warp_matrix)\nfrom mmpose.structures.keypoint import keypoint_clip_border\n\n\n@TRANSFORMS.register_module()\nclass BottomupGetHeatmapMask(BaseTransform):\n    \"\"\"Generate the mask of valid regions from the segmentation annotation.\n\n    Required Keys:\n\n        - img_shape\n        - invalid_segs (optional)\n        - warp_mat (optional)\n        - flip (optional)\n        - flip_direction (optional)\n        - heatmaps (optional)\n\n    Added Keys:\n\n        - heatmap_mask\n    \"\"\"\n\n    def __init__(self, get_invalid: bool = False):\n        super().__init__()\n        self.get_invalid = get_invalid\n\n    def _segs_to_mask(self, segs: list, img_shape: Tuple[int,\n                                                         int]) -> np.ndarray:\n        \"\"\"Calculate mask from object segmentations.\n\n        Args:\n            segs (List): The object segmentation annotations in COCO format\n            img_shape (Tuple): The image shape in (h, w)\n\n        Returns:\n            np.ndarray: The binary object mask in size (h, w), where the\n            object pixels are 1 and background pixels are 0\n        \"\"\"\n\n        # RLE is a simple yet efficient format for storing binary masks.\n        # details can be found at `COCO tools <https://github.com/\n        # cocodataset/cocoapi/blob/master/PythonAPI/pycocotools/\n        # mask.py>`__\n        rles = []\n        for seg in segs:\n            if isinstance(seg, (tuple, list)):\n                rle = cocomask.frPyObjects(seg, img_shape[0], img_shape[1])\n                if isinstance(rle, list):\n                    # For non-crowded objects (e.g. human with no visible\n                    # keypoints), the results is a list of rles\n                    rles.extend(rle)\n                else:\n                    # For crowded objects, the result is a single rle\n                    rles.append(rle)\n\n        if rles:\n            mask = cocomask.decode(cocomask.merge(rles))\n        else:\n            mask = np.zeros(img_shape, dtype=np.uint8)\n\n        return mask\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`BottomupGetHeatmapMask` to perform\n        photometric distortion on images.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n\n        Args:\n            results (dict): Result dict from the data pipeline.\n\n        Returns:\n            dict: Result dict with images distorted.\n        \"\"\"\n\n        invalid_segs = results.get('invalid_segs', [])\n        img_shape = results['img_shape']  # (img_h, img_w)\n        input_size = results['input_size']\n        mask = self._segs_to_mask(invalid_segs, img_shape)\n\n        if not self.get_invalid:\n            # Calculate the mask of the valid region by negating the\n            # segmentation mask of invalid objects\n            mask = np.logical_not(mask)\n\n        # Apply an affine transform to the mask if the image has been\n        # transformed\n        if 'warp_mat' in results:\n            warp_mat = results['warp_mat']\n\n            mask = mask.astype(np.float32)\n            mask = cv2.warpAffine(\n                mask, warp_mat, input_size, flags=cv2.INTER_LINEAR)\n\n        # Flip the mask if the image has been flipped\n        if results.get('flip', False):\n            flip_dir = results['flip_direction']\n            if flip_dir is not None:\n                mask = imflip_(mask, flip_dir)\n\n        # Resize the mask to the same size of heatmaps\n        if 'heatmaps' in results:\n            heatmaps = results['heatmaps']\n            if isinstance(heatmaps, list):\n                # Multi-level heatmaps\n                heatmap_mask = []\n                for hm in results['heatmaps']:\n                    h, w = hm.shape[1:3]\n                    _mask = imresize(\n                        mask, size=(w, h), interpolation='bilinear')\n                    heatmap_mask.append(_mask)\n            else:\n                h, w = heatmaps.shape[1:3]\n                heatmap_mask = imresize(\n                    mask, size=(w, h), interpolation='bilinear')\n        else:\n            heatmap_mask = mask\n\n        # Binarize the mask(s)\n        if isinstance(heatmap_mask, list):\n            results['heatmap_mask'] = [hm > 0.5 for hm in heatmap_mask]\n        else:\n            results['heatmap_mask'] = heatmap_mask > 0.5\n\n        return results\n\n\n@TRANSFORMS.register_module()\nclass BottomupRandomAffine(BaseTransform):\n    r\"\"\"Randomly shift, resize and rotate the image.\n\n    Required Keys:\n\n        - img\n        - img_shape\n        - keypoints (optional)\n\n    Modified Keys:\n\n        - img\n        - keypoints (optional)\n\n    Added Keys:\n\n        - input_size\n        - warp_mat\n\n    Args:\n        input_size (Tuple[int, int]): The input image size of the model in\n            [w, h]\n        shift_factor (float): Randomly shift the image in range\n            :math:`[-dx, dx]` and :math:`[-dy, dy]` in X and Y directions,\n            where :math:`dx(y) = img_w(h) \\cdot shift_factor` in pixels.\n            Defaults to 0.2\n        shift_prob (float): Probability of applying random shift. Defaults to\n            1.0\n        scale_factor (Tuple[float, float]): Randomly resize the image in range\n            :math:`[scale_factor[0], scale_factor[1]]`. Defaults to\n            (0.75, 1.5)\n        scale_prob (float): Probability of applying random resizing. Defaults\n            to 1.0\n        scale_type (str): wrt ``long`` or ``short`` length of the image.\n            Defaults to ``short``\n        rotate_factor (float): Randomly rotate the bbox in\n            :math:`[-rotate_factor, rotate_factor]` in degrees. Defaults\n            to 40.0\n        use_udp (bool): Whether use unbiased data processing. See\n            `UDP (CVPR 2020)`_ for details. Defaults to ``False``\n\n    .. _`UDP (CVPR 2020)`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n\n    def __init__(self,\n                 input_size: Optional[Tuple[int, int]] = None,\n                 shift_factor: float = 0.2,\n                 shift_prob: float = 1.,\n                 scale_factor: Tuple[float, float] = (0.75, 1.5),\n                 scale_prob: float = 1.,\n                 scale_type: str = 'short',\n                 rotate_factor: float = 30.,\n                 rotate_prob: float = 1,\n                 shear_factor: float = 2.0,\n                 shear_prob: float = 1.0,\n                 use_udp: bool = False,\n                 pad_val: Union[float, Tuple[float]] = 0,\n                 border: Tuple[int, int] = (0, 0),\n                 distribution='trunc_norm',\n                 transform_mode='affine',\n                 bbox_keep_corner: bool = True,\n                 clip_border: bool = False) -> None:\n        super().__init__()\n\n        assert transform_mode in ('affine', 'affine_udp', 'perspective'), \\\n            f'the argument transform_mode should be either \\'affine\\', ' \\\n            f'\\'affine_udp\\' or \\'perspective\\', but got \\'{transform_mode}\\''\n\n        self.input_size = input_size\n        self.shift_factor = shift_factor\n        self.shift_prob = shift_prob\n        self.scale_factor = scale_factor\n        self.scale_prob = scale_prob\n        self.scale_type = scale_type\n        self.rotate_factor = rotate_factor\n        self.rotate_prob = rotate_prob\n        self.shear_factor = shear_factor\n        self.shear_prob = shear_prob\n\n        self.use_udp = use_udp\n        self.distribution = distribution\n        self.clip_border = clip_border\n        self.bbox_keep_corner = bbox_keep_corner\n\n        self.transform_mode = transform_mode\n\n        if isinstance(pad_val, (int, float)):\n            pad_val = (pad_val, pad_val, pad_val)\n\n        if 'affine' in transform_mode:\n            self._transform = partial(\n                cv2.warpAffine, flags=cv2.INTER_LINEAR, borderValue=pad_val)\n        else:\n            self._transform = partial(cv2.warpPerspective, borderValue=pad_val)\n\n    def _random(self,\n                low: float = -1.,\n                high: float = 1.,\n                size: tuple = ()) -> np.ndarray:\n        if self.distribution == 'trunc_norm':\n            \"\"\"Sample from a truncated normal distribution.\"\"\"\n            return truncnorm.rvs(low, high, size=size).astype(np.float32)\n        elif self.distribution == 'uniform':\n            x = np.random.rand(*size)\n            return x * (high - low) + low\n        else:\n            raise ValueError(f'the argument `distribution` should be either'\n                             f'\\'trunc_norn\\' or \\'uniform\\', but got '\n                             f'{self.distribution}.')\n\n    def _fix_aspect_ratio(self, scale: np.ndarray, aspect_ratio: float):\n        \"\"\"Extend the scale to match the given aspect ratio.\n\n        Args:\n            scale (np.ndarray): The image scale (w, h) in shape (2, )\n            aspect_ratio (float): The ratio of ``w/h``\n\n        Returns:\n            np.ndarray: The reshaped image scale in (2, )\n        \"\"\"\n        w, h = scale\n        if w > h * aspect_ratio:\n            if self.scale_type == 'long':\n                _w, _h = w, w / aspect_ratio\n            elif self.scale_type == 'short':\n                _w, _h = h * aspect_ratio, h\n            else:\n                raise ValueError(f'Unknown scale type: {self.scale_type}')\n        else:\n            if self.scale_type == 'short':\n                _w, _h = w, w / aspect_ratio\n            elif self.scale_type == 'long':\n                _w, _h = h * aspect_ratio, h\n            else:\n                raise ValueError(f'Unknown scale type: {self.scale_type}')\n        return np.array([_w, _h], dtype=scale.dtype)\n\n    @cache_randomness\n    def _get_transform_params(self) -> Tuple:\n        \"\"\"Get random transform parameters.\n\n        Returns:\n            tuple:\n            - offset (np.ndarray): Image offset rate in shape (2, )\n            - scale (np.ndarray): Image scaling rate factor in shape (1, )\n            - rotate (np.ndarray): Image rotation degree in shape (1, )\n        \"\"\"\n        # get offset\n        if np.random.rand() < self.shift_prob:\n            offset = self._random(size=(2, )) * self.shift_factor\n        else:\n            offset = np.zeros((2, ), dtype=np.float32)\n\n        # get scale\n        if np.random.rand() < self.scale_prob:\n            scale_min, scale_max = self.scale_factor\n            scale = scale_min + (scale_max - scale_min) * (\n                self._random(size=(1, )) + 1) / 2\n        else:\n            scale = np.ones(1, dtype=np.float32)\n\n        # get rotation\n        if np.random.rand() < self.rotate_prob:\n            rotate = self._random() * self.rotate_factor\n        else:\n            rotate = 0\n\n        # get shear\n        if 'perspective' in self.transform_mode and np.random.rand(\n        ) < self.shear_prob:\n            shear = self._random(size=(2, )) * self.shear_factor\n        else:\n            shear = np.zeros((2, ), dtype=np.float32)\n\n        return offset, scale, rotate, shear\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`BottomupRandomAffine` to perform\n        photometric distortion on images.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n\n        Args:\n            results (dict): Result dict from the data pipeline.\n\n        Returns:\n            dict: Result dict with images distorted.\n        \"\"\"\n\n        img_h, img_w = results['img_shape'][:2]\n        w, h = self.input_size\n\n        offset_rate, scale_rate, rotate, shear = self._get_transform_params()\n\n        if 'affine' in self.transform_mode:\n            offset = offset_rate * [img_w, img_h]\n            scale = scale_rate * [img_w, img_h]\n            # adjust the scale to match the target aspect ratio\n            scale = self._fix_aspect_ratio(scale, aspect_ratio=w / h)\n\n            if self.transform_mode == 'affine_udp':\n                center = np.array([(img_w - 1.0) / 2, (img_h - 1.0) / 2],\n                                  dtype=np.float32)\n                warp_mat = get_udp_warp_matrix(\n                    center=center + offset,\n                    scale=scale,\n                    rot=rotate,\n                    output_size=(w, h))\n            else:\n                center = np.array([img_w / 2, img_h / 2], dtype=np.float32)\n                warp_mat = get_warp_matrix(\n                    center=center + offset,\n                    scale=scale,\n                    rot=rotate,\n                    output_size=(w, h))\n\n        else:\n            offset = offset_rate * [w, h]\n            center = np.array([w / 2, h / 2], dtype=np.float32)\n            warp_mat = get_pers_warp_matrix(\n                center=center,\n                translate=offset,\n                scale=scale_rate[0],\n                rot=rotate,\n                shear=shear)\n\n        # warp image and keypoints\n        results['img'] = self._transform(results['img'], warp_mat,\n                                         (int(w), int(h)))\n\n        if 'keypoints' in results:\n            # Only transform (x, y) coordinates\n            kpts = cv2.transform(results['keypoints'], warp_mat)\n            if kpts.shape[-1] == 3:\n                kpts = kpts[..., :2] / kpts[..., 2:3]\n            results['keypoints'] = kpts\n\n            if self.clip_border:\n                results['keypoints'], results[\n                    'keypoints_visible'] = keypoint_clip_border(\n                        results['keypoints'], results['keypoints_visible'],\n                        (w, h))\n\n        if 'bbox' in results:\n            bbox = bbox_xyxy2corner(results['bbox'])\n            bbox = cv2.transform(bbox, warp_mat)\n            if bbox.shape[-1] == 3:\n                bbox = bbox[..., :2] / bbox[..., 2:3]\n            if not self.bbox_keep_corner:\n                bbox = bbox_corner2xyxy(bbox)\n            if self.clip_border:\n                bbox = bbox_clip_border(bbox, (w, h))\n            results['bbox'] = bbox\n\n        if 'area' in results:\n            warp_mat_for_area = warp_mat\n            if warp_mat.shape[0] == 2:\n                aux_row = np.array([[0.0, 0.0, 1.0]], dtype=warp_mat.dtype)\n                warp_mat_for_area = np.concatenate((warp_mat, aux_row))\n            results['area'] *= np.linalg.det(warp_mat_for_area)\n\n        results['input_size'] = self.input_size\n        results['warp_mat'] = warp_mat\n\n        return results\n\n\n@TRANSFORMS.register_module()\nclass BottomupResize(BaseTransform):\n    \"\"\"Resize the image to the input size of the model. Optionally, the image\n    can be resized to multiple sizes to build a image pyramid for multi-scale\n    inference.\n\n    Required Keys:\n\n        - img\n        - ori_shape\n\n    Modified Keys:\n\n        - img\n        - img_shape\n\n    Added Keys:\n\n        - input_size\n        - warp_mat\n        - aug_scale\n\n    Args:\n        input_size (Tuple[int, int]): The input size of the model in [w, h].\n            Note that the actually size of the resized image will be affected\n            by ``resize_mode`` and ``size_factor``, thus may not exactly equals\n            to the ``input_size``\n        aug_scales (List[float], optional): The extra input scales for\n            multi-scale testing. If given, the input image will be resized\n            to different scales to build a image pyramid. And heatmaps from\n            all scales will be aggregated to make final prediction. Defaults\n            to ``None``\n        size_factor (int): The actual input size will be ceiled to\n                a multiple of the `size_factor` value at both sides.\n                Defaults to 16\n        resize_mode (str): The method to resize the image to the input size.\n            Options are:\n\n                - ``'fit'``: The image will be resized according to the\n                    relatively longer side with the aspect ratio kept. The\n                    resized image will entirely fits into the range of the\n                    input size\n                - ``'expand'``: The image will be resized according to the\n                    relatively shorter side with the aspect ratio kept. The\n                    resized image will exceed the given input size at the\n                    longer side\n        use_udp (bool): Whether use unbiased data processing. See\n            `UDP (CVPR 2020)`_ for details. Defaults to ``False``\n\n    .. _`UDP (CVPR 2020)`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n\n    def __init__(self,\n                 input_size: Tuple[int, int],\n                 aug_scales: Optional[List[float]] = None,\n                 size_factor: int = 32,\n                 resize_mode: str = 'fit',\n                 pad_val: tuple = (0, 0, 0),\n                 use_udp: bool = False):\n        super().__init__()\n\n        self.input_size = input_size\n        self.aug_scales = aug_scales\n        self.resize_mode = resize_mode\n        self.size_factor = size_factor\n        self.use_udp = use_udp\n        self.pad_val = pad_val\n\n    @staticmethod\n    def _ceil_to_multiple(size: Tuple[int, int], base: int):\n        \"\"\"Ceil the given size (tuple of [w, h]) to a multiple of the base.\"\"\"\n        return tuple(int(np.ceil(s / base) * base) for s in size)\n\n    def _get_input_size(self, img_size: Tuple[int, int],\n                        input_size: Tuple[int, int]) -> Tuple:\n        \"\"\"Calculate the actual input size (which the original image will be\n        resized to) and the padded input size (which the resized image will be\n        padded to, or which is the size of the model input).\n\n        Args:\n            img_size (Tuple[int, int]): The original image size in [w, h]\n            input_size (Tuple[int, int]): The expected input size in [w, h]\n\n        Returns:\n            tuple:\n            - actual_input_size (Tuple[int, int]): The target size to resize\n                the image\n            - padded_input_size (Tuple[int, int]): The target size to generate\n                the model input which will contain the resized image\n        \"\"\"\n        img_w, img_h = img_size\n        ratio = img_w / img_h\n\n        if self.resize_mode == 'fit':\n            padded_input_size = self._ceil_to_multiple(input_size,\n                                                       self.size_factor)\n            if padded_input_size != input_size:\n                raise ValueError(\n                    'When ``resize_mode==\\'fit\\', the input size (height and'\n                    ' width) should be mulitples of the size_factor('\n                    f'{self.size_factor}) at all scales. Got invalid input '\n                    f'size {input_size}.')\n\n            pad_w, pad_h = padded_input_size\n            rsz_w = min(pad_w, pad_h * ratio)\n            rsz_h = min(pad_h, pad_w / ratio)\n            actual_input_size = (rsz_w, rsz_h)\n\n        elif self.resize_mode == 'expand':\n            _padded_input_size = self._ceil_to_multiple(\n                input_size, self.size_factor)\n            pad_w, pad_h = _padded_input_size\n            rsz_w = max(pad_w, pad_h * ratio)\n            rsz_h = max(pad_h, pad_w / ratio)\n\n            actual_input_size = (rsz_w, rsz_h)\n            padded_input_size = self._ceil_to_multiple(actual_input_size,\n                                                       self.size_factor)\n\n        else:\n            raise ValueError(f'Invalid resize mode {self.resize_mode}')\n\n        return actual_input_size, padded_input_size\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`BottomupResize` to perform\n        photometric distortion on images.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n\n        Args:\n            results (dict): Result dict from the data pipeline.\n\n        Returns:\n            dict: Result dict with images distorted.\n        \"\"\"\n\n        img = results['img']\n        img_h, img_w = results['ori_shape']\n        w, h = self.input_size\n\n        input_sizes = [(w, h)]\n        if self.aug_scales:\n            input_sizes += [(int(w * s), int(h * s)) for s in self.aug_scales]\n\n        imgs = []\n        for i, (_w, _h) in enumerate(input_sizes):\n\n            actual_input_size, padded_input_size = self._get_input_size(\n                img_size=(img_w, img_h), input_size=(_w, _h))\n\n            if self.use_udp:\n                center = np.array([(img_w - 1.0) / 2, (img_h - 1.0) / 2],\n                                  dtype=np.float32)\n                scale = np.array([img_w, img_h], dtype=np.float32)\n                warp_mat = get_udp_warp_matrix(\n                    center=center,\n                    scale=scale,\n                    rot=0,\n                    output_size=actual_input_size)\n            else:\n                center = np.array([img_w / 2, img_h / 2], dtype=np.float32)\n                scale = np.array([\n                    img_w * padded_input_size[0] / actual_input_size[0],\n                    img_h * padded_input_size[1] / actual_input_size[1]\n                ],\n                                 dtype=np.float32)\n                warp_mat = get_warp_matrix(\n                    center=center,\n                    scale=scale,\n                    rot=0,\n                    output_size=padded_input_size)\n\n            _img = cv2.warpAffine(\n                img,\n                warp_mat,\n                padded_input_size,\n                flags=cv2.INTER_LINEAR,\n                borderValue=self.pad_val)\n\n            imgs.append(_img)\n\n            # Store the transform information w.r.t. the main input size\n            if i == 0:\n                results['img_shape'] = padded_input_size[::-1]\n                results['input_center'] = center\n                results['input_scale'] = scale\n                results['input_size'] = padded_input_size\n\n        if self.aug_scales:\n            results['img'] = imgs\n            results['aug_scales'] = self.aug_scales\n        else:\n            results['img'] = imgs[0]\n            results['aug_scale'] = None\n\n        return results\n\n\n@TRANSFORMS.register_module()\nclass BottomupRandomCrop(BaseTransform):\n    \"\"\"Random crop the image & bboxes & masks.\n\n    The absolute ``crop_size`` is sampled based on ``crop_type`` and\n    ``image_size``, then the cropped results are generated.\n\n    Required Keys:\n\n        - img\n        - keypoints\n        - bbox (optional)\n        - masks (BitmapMasks | PolygonMasks) (optional)\n\n    Modified Keys:\n\n        - img\n        - img_shape\n        - keypoints\n        - keypoints_visible\n        - num_keypoints\n        - bbox (optional)\n        - bbox_score (optional)\n        - id (optional)\n        - category_id (optional)\n        - raw_ann_info (optional)\n        - iscrowd (optional)\n        - segmentation (optional)\n        - masks (optional)\n\n    Added Keys:\n\n        - warp_mat\n\n    Args:\n        crop_size (tuple): The relative ratio or absolute pixels of\n            (width, height).\n        crop_type (str, optional): One of \"relative_range\", \"relative\",\n            \"absolute\", \"absolute_range\". \"relative\" randomly crops\n            (h * crop_size[0], w * crop_size[1]) part from an input of size\n            (h, w). \"relative_range\" uniformly samples relative crop size from\n            range [crop_size[0], 1] and [crop_size[1], 1] for height and width\n            respectively. \"absolute\" crops from an input with absolute size\n            (crop_size[0], crop_size[1]). \"absolute_range\" uniformly samples\n            crop_h in range [crop_size[0], min(h, crop_size[1])] and crop_w\n            in range [crop_size[0], min(w, crop_size[1])].\n            Defaults to \"absolute\".\n        allow_negative_crop (bool, optional): Whether to allow a crop that does\n            not contain any bbox area. Defaults to False.\n        recompute_bbox (bool, optional): Whether to re-compute the boxes based\n            on cropped instance masks. Defaults to False.\n        bbox_clip_border (bool, optional): Whether clip the objects outside\n            the border of the image. Defaults to True.\n\n    Note:\n        - If the image is smaller than the absolute crop size, return the\n            original image.\n        - If the crop does not contain any gt-bbox region and\n          ``allow_negative_crop`` is set to False, skip this image.\n    \"\"\"\n\n    def __init__(self,\n                 crop_size: tuple,\n                 crop_type: str = 'absolute',\n                 allow_negative_crop: bool = False,\n                 recompute_bbox: bool = False,\n                 bbox_clip_border: bool = True) -> None:\n        if crop_type not in [\n                'relative_range', 'relative', 'absolute', 'absolute_range'\n        ]:\n            raise ValueError(f'Invalid crop_type {crop_type}.')\n        if crop_type in ['absolute', 'absolute_range']:\n            assert crop_size[0] > 0 and crop_size[1] > 0\n            assert isinstance(crop_size[0], int) and isinstance(\n                crop_size[1], int)\n            if crop_type == 'absolute_range':\n                assert crop_size[0] <= crop_size[1]\n        else:\n            assert 0 < crop_size[0] <= 1 and 0 < crop_size[1] <= 1\n        self.crop_size = crop_size\n        self.crop_type = crop_type\n        self.allow_negative_crop = allow_negative_crop\n        self.bbox_clip_border = bbox_clip_border\n        self.recompute_bbox = recompute_bbox\n\n    def _crop_data(self, results: dict, crop_size: Tuple[int, int],\n                   allow_negative_crop: bool) -> Union[dict, None]:\n        \"\"\"Function to randomly crop images, bounding boxes, masks, semantic\n        segmentation maps.\n\n        Args:\n            results (dict): Result dict from loading pipeline.\n            crop_size (Tuple[int, int]): Expected absolute size after\n                cropping, (h, w).\n            allow_negative_crop (bool): Whether to allow a crop that does not\n                contain any bbox area.\n\n        Returns:\n            results (Union[dict, None]): Randomly cropped results, 'img_shape'\n                key in result dict is updated according to crop size. None will\n                be returned when there is no valid bbox after cropping.\n        \"\"\"\n        assert crop_size[0] > 0 and crop_size[1] > 0\n        img = results['img']\n        margin_h = max(img.shape[0] - crop_size[0], 0)\n        margin_w = max(img.shape[1] - crop_size[1], 0)\n        offset_h, offset_w = self._rand_offset((margin_h, margin_w))\n        crop_y1, crop_y2 = offset_h, offset_h + crop_size[0]\n        crop_x1, crop_x2 = offset_w, offset_w + crop_size[1]\n\n        # Record the warp matrix for the RandomCrop\n        warp_mat = np.array([[1, 0, -offset_w], [0, 1, -offset_h], [0, 0, 1]],\n                            dtype=np.float32)\n        if results.get('warp_mat', None) is None:\n            results['warp_mat'] = warp_mat\n        else:\n            results['warp_mat'] = warp_mat @ results['warp_mat']\n\n        # crop the image\n        img = img[crop_y1:crop_y2, crop_x1:crop_x2, ...]\n        img_shape = img.shape\n        results['img'] = img\n        results['img_shape'] = img_shape[:2]\n\n        # crop bboxes accordingly and clip to the image boundary\n        if results.get('bbox', None) is not None:\n            distances = (-offset_w, -offset_h)\n            bboxes = results['bbox']\n            bboxes = bboxes + np.tile(np.asarray(distances), 2)\n\n            if self.bbox_clip_border:\n                bboxes[..., 0::2] = bboxes[..., 0::2].clip(0, img_shape[1])\n                bboxes[..., 1::2] = bboxes[..., 1::2].clip(0, img_shape[0])\n\n            valid_inds = (bboxes[..., 0] < img_shape[1]) & \\\n                (bboxes[..., 1] < img_shape[0]) & \\\n                (bboxes[..., 2] > 0) & \\\n                (bboxes[..., 3] > 0)\n\n            # If the crop does not contain any gt-bbox area and\n            # allow_negative_crop is False, skip this image.\n            if (not valid_inds.any() and not allow_negative_crop):\n                return None\n\n            results['bbox'] = bboxes[valid_inds]\n            meta_keys = [\n                'bbox_score', 'id', 'category_id', 'raw_ann_info', 'iscrowd'\n            ]\n            for key in meta_keys:\n                if results.get(key):\n                    if isinstance(results[key], list):\n                        results[key] = np.asarray(\n                            results[key])[valid_inds].tolist()\n                    else:\n                        results[key] = results[key][valid_inds]\n\n            if results.get('keypoints', None) is not None:\n                keypoints = results['keypoints']\n                distances = np.asarray(distances).reshape(1, 1, 2)\n                keypoints = keypoints + distances\n                if self.bbox_clip_border:\n                    keypoints_outside_x = keypoints[:, :, 0] < 0\n                    keypoints_outside_y = keypoints[:, :, 1] < 0\n                    keypoints_outside_width = keypoints[:, :, 0] > img_shape[1]\n                    keypoints_outside_height = keypoints[:, :,\n                                                         1] > img_shape[0]\n\n                    kpt_outside = np.logical_or.reduce(\n                        (keypoints_outside_x, keypoints_outside_y,\n                         keypoints_outside_width, keypoints_outside_height))\n\n                    results['keypoints_visible'][kpt_outside] *= 0\n                keypoints[:, :, 0] = keypoints[:, :, 0].clip(0, img_shape[1])\n                keypoints[:, :, 1] = keypoints[:, :, 1].clip(0, img_shape[0])\n                results['keypoints'] = keypoints[valid_inds]\n                results['keypoints_visible'] = results['keypoints_visible'][\n                    valid_inds]\n\n            if results.get('segmentation', None) is not None:\n                results['segmentation'] = results['segmentation'][\n                    crop_y1:crop_y2, crop_x1:crop_x2]\n\n            if results.get('masks', None) is not None:\n                results['masks'] = results['masks'][valid_inds.nonzero(\n                )[0]].crop(np.asarray([crop_x1, crop_y1, crop_x2, crop_y2]))\n                if self.recompute_bbox:\n                    results['bbox'] = results['masks'].get_bboxes(\n                        type(results['bbox']))\n\n        return results\n\n    @cache_randomness\n    def _rand_offset(self, margin: Tuple[int, int]) -> Tuple[int, int]:\n        \"\"\"Randomly generate crop offset.\n\n        Args:\n            margin (Tuple[int, int]): The upper bound for the offset generated\n                randomly.\n\n        Returns:\n            Tuple[int, int]: The random offset for the crop.\n        \"\"\"\n        margin_h, margin_w = margin\n        offset_h = np.random.randint(0, margin_h + 1)\n        offset_w = np.random.randint(0, margin_w + 1)\n\n        return offset_h, offset_w\n\n    @cache_randomness\n    def _get_crop_size(self, image_size: Tuple[int, int]) -> Tuple[int, int]:\n        \"\"\"Randomly generates the absolute crop size based on `crop_type` and\n        `image_size`.\n\n        Args:\n            image_size (Tuple[int, int]): (h, w).\n\n        Returns:\n            crop_size (Tuple[int, int]): (crop_h, crop_w) in absolute pixels.\n        \"\"\"\n        h, w = image_size\n        if self.crop_type == 'absolute':\n            return min(self.crop_size[1], h), min(self.crop_size[0], w)\n        elif self.crop_type == 'absolute_range':\n            crop_h = np.random.randint(\n                min(h, self.crop_size[0]),\n                min(h, self.crop_size[1]) + 1)\n            crop_w = np.random.randint(\n                min(w, self.crop_size[0]),\n                min(w, self.crop_size[1]) + 1)\n            return crop_h, crop_w\n        elif self.crop_type == 'relative':\n            crop_w, crop_h = self.crop_size\n            return int(h * crop_h + 0.5), int(w * crop_w + 0.5)\n        else:\n            # 'relative_range'\n            crop_size = np.asarray(self.crop_size, dtype=np.float32)\n            crop_h, crop_w = crop_size + np.random.rand(2) * (1 - crop_size)\n            return int(h * crop_h + 0.5), int(w * crop_w + 0.5)\n\n    def transform(self, results: dict) -> Union[dict, None]:\n        \"\"\"Transform function to randomly crop images, bounding boxes, masks,\n        semantic segmentation maps.\n\n        Args:\n            results (dict): Result dict from loading pipeline.\n\n        Returns:\n            results (Union[dict, None]): Randomly cropped results, 'img_shape'\n                key in result dict is updated according to crop size. None will\n                be returned when there is no valid bbox after cropping.\n        \"\"\"\n        image_size = results['img'].shape[:2]\n        crop_size = self._get_crop_size(image_size)\n        results = self._crop_data(results, crop_size, self.allow_negative_crop)\n        return results\n\n\n@TRANSFORMS.register_module()\nclass BottomupRandomChoiceResize(BaseTransform):\n    \"\"\"Resize images & bbox & mask from a list of multiple scales.\n\n    This transform resizes the input image to some scale. Bboxes and masks are\n    then resized with the same scale factor. Resize scale will be randomly\n    selected from ``scales``.\n\n    How to choose the target scale to resize the image will follow the rules\n    below:\n\n    - if `scale` is a list of tuple, the target scale is sampled from the list\n      uniformally.\n    - if `scale` is a tuple, the target scale will be set to the tuple.\n\n    Required Keys:\n\n    - img\n    - bbox\n    - keypoints\n\n    Modified Keys:\n\n    - img\n    - img_shape\n    - bbox\n    - keypoints\n\n    Added Keys:\n\n    - scale\n    - scale_factor\n    - scale_idx\n\n    Args:\n        scales (Union[list, Tuple]): Images scales for resizing.\n\n        **resize_kwargs: Other keyword arguments for the ``resize_type``.\n    \"\"\"\n\n    def __init__(\n        self,\n        scales: Sequence[Union[int, Tuple]],\n        keep_ratio: bool = False,\n        clip_object_border: bool = True,\n        backend: str = 'cv2',\n        **resize_kwargs,\n    ) -> None:\n        super().__init__()\n        if isinstance(scales, list):\n            self.scales = scales\n        else:\n            self.scales = [scales]\n\n        self.keep_ratio = keep_ratio\n        self.clip_object_border = clip_object_border\n        self.backend = backend\n\n    @cache_randomness\n    def _random_select(self) -> Tuple[int, int]:\n        \"\"\"Randomly select an scale from given candidates.\n\n        Returns:\n            (tuple, int): Returns a tuple ``(scale, scale_dix)``,\n            where ``scale`` is the selected image scale and\n            ``scale_idx`` is the selected index in the given candidates.\n        \"\"\"\n\n        scale_idx = np.random.randint(len(self.scales))\n        scale = self.scales[scale_idx]\n        return scale, scale_idx\n\n    def _resize_img(self, results: dict) -> None:\n        \"\"\"Resize images with ``self.scale``.\"\"\"\n\n        if self.keep_ratio:\n\n            img, scale_factor = imrescale(\n                results['img'],\n                self.scale,\n                interpolation='bilinear',\n                return_scale=True,\n                backend=self.backend)\n            # the w_scale and h_scale has minor difference\n            # a real fix should be done in the mmcv.imrescale in the future\n            new_h, new_w = img.shape[:2]\n            h, w = results['img'].shape[:2]\n            w_scale = new_w / w\n            h_scale = new_h / h\n        else:\n            img, w_scale, h_scale = imresize(\n                results['img'],\n                self.scale,\n                interpolation='bilinear',\n                return_scale=True,\n                backend=self.backend)\n\n        results['img'] = img\n        results['img_shape'] = img.shape[:2]\n        results['scale_factor'] = (w_scale, h_scale)\n        results['input_size'] = img.shape[:2]\n        w, h = results['ori_shape']\n        center = np.array([w / 2, h / 2], dtype=np.float32)\n        scale = np.array([w, h], dtype=np.float32)\n        results['input_center'] = center\n        results['input_scale'] = scale\n\n    def _resize_bboxes(self, results: dict) -> None:\n        \"\"\"Resize bounding boxes with ``self.scale``.\"\"\"\n        if results.get('bbox', None) is not None:\n            bboxes = results['bbox'] * np.tile(\n                np.array(results['scale_factor']), 2)\n            if self.clip_object_border:\n                bboxes[:, 0::2] = np.clip(bboxes[:, 0::2], 0,\n                                          results['img_shape'][1])\n                bboxes[:, 1::2] = np.clip(bboxes[:, 1::2], 0,\n                                          results['img_shape'][0])\n            results['bbox'] = bboxes\n\n    def _resize_keypoints(self, results: dict) -> None:\n        \"\"\"Resize keypoints with ``self.scale``.\"\"\"\n        if results.get('keypoints', None) is not None:\n            keypoints = results['keypoints']\n\n            keypoints[:, :, :2] = keypoints[:, :, :2] * np.array(\n                results['scale_factor'])\n            if self.clip_object_border:\n                keypoints[:, :, 0] = np.clip(keypoints[:, :, 0], 0,\n                                             results['img_shape'][1])\n                keypoints[:, :, 1] = np.clip(keypoints[:, :, 1], 0,\n                                             results['img_shape'][0])\n            results['keypoints'] = keypoints\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"Apply resize transforms on results from a list of scales.\n\n        Args:\n            results (dict): Result dict contains the data to transform.\n\n        Returns:\n            dict: Resized results, 'img', 'bbox',\n            'keypoints', 'scale', 'scale_factor', 'img_shape',\n            and 'keep_ratio' keys are updated in result dict.\n        \"\"\"\n\n        target_scale, scale_idx = self._random_select()\n\n        self.scale = target_scale\n        self._resize_img(results)\n        self._resize_bboxes(results)\n        self._resize_keypoints(results)\n\n        results['scale_idx'] = scale_idx\n        return results\n"
  },
  {
    "path": "mmpose/datasets/transforms/common_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom copy import deepcopy\nfrom typing import Dict, List, Optional, Sequence, Tuple, Union\n\nimport cv2\nimport mmcv\nimport mmengine\nimport numpy as np\nfrom mmcv.image import imflip\nfrom mmcv.transforms import BaseTransform\nfrom mmcv.transforms.utils import avoid_cache_randomness, cache_randomness\nfrom mmengine import is_list_of\nfrom mmengine.dist import get_dist_info\nfrom scipy.stats import truncnorm\n\nfrom mmpose.codecs import *  # noqa: F401, F403\nfrom mmpose.registry import KEYPOINT_CODECS, TRANSFORMS\nfrom mmpose.structures.bbox import bbox_xyxy2cs, flip_bbox\nfrom mmpose.structures.keypoint import flip_keypoints\nfrom mmpose.utils.typing import MultiConfig\n\ntry:\n    import albumentations\nexcept ImportError:\n    albumentations = None\n\nNumber = Union[int, float]\n\n\n@TRANSFORMS.register_module()\nclass GetBBoxCenterScale(BaseTransform):\n    \"\"\"Convert bboxes from [x, y, w, h] to center and scale.\n\n    The center is the coordinates of the bbox center, and the scale is the\n    bbox width and height normalized by a scale factor.\n\n    Required Keys:\n\n        - bbox\n\n    Added Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Args:\n        padding (float): The bbox padding scale that will be multilied to\n            `bbox_scale`. Defaults to 1.25\n    \"\"\"\n\n    def __init__(self, padding: float = 1.25) -> None:\n        super().__init__()\n\n        self.padding = padding\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`GetBBoxCenterScale`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n        if 'bbox_center' in results and 'bbox_scale' in results:\n            rank, _ = get_dist_info()\n            if rank == 0:\n                warnings.warn('Use the existing \"bbox_center\" and \"bbox_scale\"'\n                              '. The padding will still be applied.')\n            results['bbox_scale'] = results['bbox_scale'] * self.padding\n\n        else:\n            bbox = results['bbox']\n            center, scale = bbox_xyxy2cs(bbox, padding=self.padding)\n\n            results['bbox_center'] = center\n            results['bbox_scale'] = scale\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__ + f'(padding={self.padding})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass RandomFlip(BaseTransform):\n    \"\"\"Randomly flip the image, bbox and keypoints.\n\n    Required Keys:\n\n        - img\n        - img_shape\n        - flip_indices\n        - input_size (optional)\n        - bbox (optional)\n        - bbox_center (optional)\n        - keypoints (optional)\n        - keypoints_visible (optional)\n        - img_mask (optional)\n\n    Modified Keys:\n\n        - img\n        - bbox (optional)\n        - bbox_center (optional)\n        - keypoints (optional)\n        - keypoints_visible (optional)\n        - img_mask (optional)\n\n    Added Keys:\n\n        - flip\n        - flip_direction\n\n    Args:\n        prob (float | list[float]): The flipping probability. If a list is\n            given, the argument `direction` should be a list with the same\n            length. And each element in `prob` indicates the flipping\n            probability of the corresponding one in ``direction``. Defaults\n            to 0.5\n        direction (str | list[str]): The flipping direction. Options are\n            ``'horizontal'``, ``'vertical'`` and ``'diagonal'``. If a list is\n            is given, each data sample's flipping direction will be sampled\n            from a distribution determined by the argument ``prob``. Defaults\n            to ``'horizontal'``.\n    \"\"\"\n\n    def __init__(self,\n                 prob: Union[float, List[float]] = 0.5,\n                 direction: Union[str, List[str]] = 'horizontal') -> None:\n        if isinstance(prob, list):\n            assert is_list_of(prob, float)\n            assert 0 <= sum(prob) <= 1\n        elif isinstance(prob, float):\n            assert 0 <= prob <= 1\n        else:\n            raise ValueError(f'probs must be float or list of float, but \\\n                              got `{type(prob)}`.')\n        self.prob = prob\n\n        valid_directions = ['horizontal', 'vertical', 'diagonal']\n        if isinstance(direction, str):\n            assert direction in valid_directions\n        elif isinstance(direction, list):\n            assert is_list_of(direction, str)\n            assert set(direction).issubset(set(valid_directions))\n        else:\n            raise ValueError(f'direction must be either str or list of str, \\\n                               but got `{type(direction)}`.')\n        self.direction = direction\n\n        if isinstance(prob, list):\n            assert len(prob) == len(self.direction)\n\n    @cache_randomness\n    def _choose_direction(self) -> str:\n        \"\"\"Choose the flip direction according to `prob` and `direction`\"\"\"\n        if isinstance(self.direction,\n                      List) and not isinstance(self.direction, str):\n            # None means non-flip\n            direction_list: list = list(self.direction) + [None]\n        elif isinstance(self.direction, str):\n            # None means non-flip\n            direction_list = [self.direction, None]\n\n        if isinstance(self.prob, list):\n            non_prob: float = 1 - sum(self.prob)\n            prob_list = self.prob + [non_prob]\n        elif isinstance(self.prob, float):\n            non_prob = 1. - self.prob\n            # exclude non-flip\n            single_ratio = self.prob / (len(direction_list) - 1)\n            prob_list = [single_ratio] * (len(direction_list) - 1) + [non_prob]\n\n        cur_dir = np.random.choice(direction_list, p=prob_list)\n\n        return cur_dir\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"The transform function of :class:`RandomFlip`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n\n        flip_dir = self._choose_direction()\n\n        if flip_dir is None:\n            results['flip'] = False\n            results['flip_direction'] = None\n        else:\n            results['flip'] = True\n            results['flip_direction'] = flip_dir\n\n            h, w = results.get('input_size', results['img_shape'])\n            # flip image and mask\n            if isinstance(results['img'], list):\n                results['img'] = [\n                    imflip(img, direction=flip_dir) for img in results['img']\n                ]\n            else:\n                results['img'] = imflip(results['img'], direction=flip_dir)\n\n            if 'img_mask' in results:\n                results['img_mask'] = imflip(\n                    results['img_mask'], direction=flip_dir)\n\n            # flip bboxes\n            if results.get('bbox', None) is not None:\n                results['bbox'] = flip_bbox(\n                    results['bbox'],\n                    image_size=(w, h),\n                    bbox_format='xyxy',\n                    direction=flip_dir)\n\n            if results.get('bbox_center', None) is not None:\n                results['bbox_center'] = flip_bbox(\n                    results['bbox_center'],\n                    image_size=(w, h),\n                    bbox_format='center',\n                    direction=flip_dir)\n\n            # flip keypoints\n            if results.get('keypoints', None) is not None:\n                keypoints, keypoints_visible = flip_keypoints(\n                    results['keypoints'],\n                    results.get('keypoints_visible', None),\n                    image_size=(w, h),\n                    flip_indices=results['flip_indices'],\n                    direction=flip_dir)\n\n                results['keypoints'] = keypoints\n                results['keypoints_visible'] = keypoints_visible\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(prob={self.prob}, '\n        repr_str += f'direction={self.direction})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass RandomHalfBody(BaseTransform):\n    \"\"\"Data augmentation with half-body transform that keeps only the upper or\n    lower body at random.\n\n    Required Keys:\n\n        - keypoints\n        - keypoints_visible\n        - upper_body_ids\n        - lower_body_ids\n\n    Modified Keys:\n\n        - bbox\n        - bbox_center\n        - bbox_scale\n\n    Args:\n        min_total_keypoints (int): The minimum required number of total valid\n            keypoints of a person to apply half-body transform. Defaults to 8\n        min_half_keypoints (int): The minimum required number of valid\n            half-body keypoints of a person to apply half-body transform.\n            Defaults to 2\n        padding (float): The bbox padding scale that will be multilied to\n            `bbox_scale`. Defaults to 1.5\n        prob (float): The probability to apply half-body transform when the\n            keypoint number meets the requirement. Defaults to 0.3\n    \"\"\"\n\n    def __init__(self,\n                 min_total_keypoints: int = 9,\n                 min_upper_keypoints: int = 2,\n                 min_lower_keypoints: int = 3,\n                 padding: float = 1.5,\n                 prob: float = 0.3,\n                 upper_prioritized_prob: float = 0.7) -> None:\n        super().__init__()\n        self.min_total_keypoints = min_total_keypoints\n        self.min_upper_keypoints = min_upper_keypoints\n        self.min_lower_keypoints = min_lower_keypoints\n        self.padding = padding\n        self.prob = prob\n        self.upper_prioritized_prob = upper_prioritized_prob\n\n    def _get_half_body_bbox(self, keypoints: np.ndarray,\n                            half_body_ids: List[int]\n                            ) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Get half-body bbox center and scale of a single instance.\n\n        Args:\n            keypoints (np.ndarray): Keypoints in shape (K, D)\n            upper_body_ids (list): The list of half-body keypont indices\n\n        Returns:\n            tuple: A tuple containing half-body bbox center and scale\n            - center: Center (x, y) of the bbox\n            - scale: Scale (w, h) of the bbox\n        \"\"\"\n\n        selected_keypoints = keypoints[half_body_ids]\n        center = selected_keypoints.mean(axis=0)[:2]\n\n        x1, y1 = selected_keypoints.min(axis=0)\n        x2, y2 = selected_keypoints.max(axis=0)\n        w = x2 - x1\n        h = y2 - y1\n        scale = np.array([w, h], dtype=center.dtype) * self.padding\n\n        return center, scale\n\n    @cache_randomness\n    def _random_select_half_body(self, keypoints_visible: np.ndarray,\n                                 upper_body_ids: List[int],\n                                 lower_body_ids: List[int]\n                                 ) -> List[Optional[List[int]]]:\n        \"\"\"Randomly determine whether applying half-body transform and get the\n        half-body keyponit indices of each instances.\n\n        Args:\n            keypoints_visible (np.ndarray, optional): The visibility of\n                keypoints in shape (N, K, 1) or (N, K, 2).\n            upper_body_ids (list): The list of upper body keypoint indices\n            lower_body_ids (list): The list of lower body keypoint indices\n\n        Returns:\n            list[list[int] | None]: The selected half-body keypoint indices\n            of each instance. ``None`` means not applying half-body transform.\n        \"\"\"\n\n        if keypoints_visible.ndim == 3:\n            keypoints_visible = keypoints_visible[..., 0]\n\n        half_body_ids = []\n\n        for visible in keypoints_visible:\n            if visible.sum() < self.min_total_keypoints:\n                indices = None\n            elif np.random.rand() > self.prob:\n                indices = None\n            else:\n                upper_valid_ids = [i for i in upper_body_ids if visible[i] > 0]\n                lower_valid_ids = [i for i in lower_body_ids if visible[i] > 0]\n\n                num_upper = len(upper_valid_ids)\n                num_lower = len(lower_valid_ids)\n\n                prefer_upper = np.random.rand() < self.upper_prioritized_prob\n                if (num_upper < self.min_upper_keypoints\n                        and num_lower < self.min_lower_keypoints):\n                    indices = None\n                elif num_lower < self.min_lower_keypoints:\n                    indices = upper_valid_ids\n                elif num_upper < self.min_upper_keypoints:\n                    indices = lower_valid_ids\n                else:\n                    indices = (\n                        upper_valid_ids if prefer_upper else lower_valid_ids)\n\n            half_body_ids.append(indices)\n\n        return half_body_ids\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`HalfBodyTransform`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n        half_body_ids = self._random_select_half_body(\n            keypoints_visible=results['keypoints_visible'],\n            upper_body_ids=results['upper_body_ids'],\n            lower_body_ids=results['lower_body_ids'])\n\n        bbox_center = []\n        bbox_scale = []\n\n        for i, indices in enumerate(half_body_ids):\n            if indices is None:\n                bbox_center.append(results['bbox_center'][i])\n                bbox_scale.append(results['bbox_scale'][i])\n            else:\n                _center, _scale = self._get_half_body_bbox(\n                    results['keypoints'][i], indices)\n                bbox_center.append(_center)\n                bbox_scale.append(_scale)\n\n        results['bbox_center'] = np.stack(bbox_center)\n        results['bbox_scale'] = np.stack(bbox_scale)\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(min_total_keypoints={self.min_total_keypoints}, '\n        repr_str += f'min_upper_keypoints={self.min_upper_keypoints}, '\n        repr_str += f'min_lower_keypoints={self.min_lower_keypoints}, '\n        repr_str += f'padding={self.padding}, '\n        repr_str += f'prob={self.prob}, '\n        repr_str += f'upper_prioritized_prob={self.upper_prioritized_prob})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass RandomBBoxTransform(BaseTransform):\n    r\"\"\"Rnadomly shift, resize and rotate the bounding boxes.\n\n    Required Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Modified Keys:\n\n        - bbox_center\n        - bbox_scale\n\n    Added Keys:\n        - bbox_rotation\n\n    Args:\n        shift_factor (float): Randomly shift the bbox in range\n            :math:`[-dx, dx]` and :math:`[-dy, dy]` in X and Y directions,\n            where :math:`dx(y) = x(y)_scale \\cdot shift_factor` in pixels.\n            Defaults to 0.16\n        shift_prob (float): Probability of applying random shift. Defaults to\n            0.3\n        scale_factor (Tuple[float, float]): Randomly resize the bbox in range\n            :math:`[scale_factor[0], scale_factor[1]]`. Defaults to (0.5, 1.5)\n        scale_prob (float): Probability of applying random resizing. Defaults\n            to 1.0\n        rotate_factor (float): Randomly rotate the bbox in\n            :math:`[-rotate_factor, rotate_factor]` in degrees. Defaults\n            to 80.0\n        rotate_prob (float): Probability of applying random rotation. Defaults\n            to 0.6\n    \"\"\"\n\n    def __init__(self,\n                 shift_factor: float = 0.16,\n                 shift_prob: float = 0.3,\n                 scale_factor: Tuple[float, float] = (0.5, 1.5),\n                 scale_prob: float = 1.0,\n                 rotate_factor: float = 80.0,\n                 rotate_prob: float = 0.6) -> None:\n        super().__init__()\n\n        self.shift_factor = shift_factor\n        self.shift_prob = shift_prob\n        self.scale_factor = scale_factor\n        self.scale_prob = scale_prob\n        self.rotate_factor = rotate_factor\n        self.rotate_prob = rotate_prob\n\n    @staticmethod\n    def _truncnorm(low: float = -1.,\n                   high: float = 1.,\n                   size: tuple = ()) -> np.ndarray:\n        \"\"\"Sample from a truncated normal distribution.\"\"\"\n        return truncnorm.rvs(low, high, size=size).astype(np.float32)\n\n    @cache_randomness\n    def _get_transform_params(self, num_bboxes: int) -> Tuple:\n        \"\"\"Get random transform parameters.\n\n        Args:\n            num_bboxes (int): The number of bboxes\n\n        Returns:\n            tuple:\n            - offset (np.ndarray): Offset factor of each bbox in shape (n, 2)\n            - scale (np.ndarray): Scaling factor of each bbox in shape (n, 1)\n            - rotate (np.ndarray): Rotation degree of each bbox in shape (n,)\n        \"\"\"\n        random_v = self._truncnorm(size=(num_bboxes, 4))\n        offset_v = random_v[:, :2]\n        scale_v = random_v[:, 2:3]\n        rotate_v = random_v[:, 3]\n\n        # Get shift parameters\n        offset = offset_v * self.shift_factor\n        offset = np.where(\n            np.random.rand(num_bboxes, 1) < self.shift_prob, offset, 0.)\n\n        # Get scaling parameters\n        scale_min, scale_max = self.scale_factor\n        mu = (scale_max + scale_min) * 0.5\n        sigma = (scale_max - scale_min) * 0.5\n        scale = scale_v * sigma + mu\n        scale = np.where(\n            np.random.rand(num_bboxes, 1) < self.scale_prob, scale, 1.)\n\n        # Get rotation parameters\n        rotate = rotate_v * self.rotate_factor\n        rotate = np.where(\n            np.random.rand(num_bboxes) < self.rotate_prob, rotate, 0.)\n\n        return offset, scale, rotate\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`RandomBboxTransform`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n        bbox_scale = results['bbox_scale']\n        num_bboxes = bbox_scale.shape[0]\n\n        offset, scale, rotate = self._get_transform_params(num_bboxes)\n\n        results['bbox_center'] = results['bbox_center'] + offset * bbox_scale\n        results['bbox_scale'] = results['bbox_scale'] * scale\n        results['bbox_rotation'] = rotate\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(shift_prob={self.shift_prob}, '\n        repr_str += f'shift_factor={self.shift_factor}, '\n        repr_str += f'scale_prob={self.scale_prob}, '\n        repr_str += f'scale_factor={self.scale_factor}, '\n        repr_str += f'rotate_prob={self.rotate_prob}, '\n        repr_str += f'rotate_factor={self.rotate_factor})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\n@avoid_cache_randomness\nclass Albumentation(BaseTransform):\n    \"\"\"Albumentation augmentation (pixel-level transforms only).\n\n    Adds custom pixel-level transformations from Albumentations library.\n    Please visit `https://albumentations.ai/docs/`\n    to get more information.\n\n    Note: we only support pixel-level transforms.\n    Please visit `https://github.com/albumentations-team/`\n    `albumentations#pixel-level-transforms`\n    to get more information about pixel-level transforms.\n\n    Required Keys:\n\n    - img\n\n    Modified Keys:\n\n    - img\n\n    Args:\n        transforms (List[dict]): A list of Albumentation transforms.\n            An example of ``transforms`` is as followed:\n            .. code-block:: python\n\n                [\n                    dict(\n                        type='RandomBrightnessContrast',\n                        brightness_limit=[0.1, 0.3],\n                        contrast_limit=[0.1, 0.3],\n                        p=0.2),\n                    dict(type='ChannelShuffle', p=0.1),\n                    dict(\n                        type='OneOf',\n                        transforms=[\n                            dict(type='Blur', blur_limit=3, p=1.0),\n                            dict(type='MedianBlur', blur_limit=3, p=1.0)\n                        ],\n                        p=0.1),\n                ]\n        keymap (dict | None): key mapping from ``input key`` to\n            ``albumentation-style key``.\n            Defaults to None, which will use {'img': 'image'}.\n    \"\"\"\n\n    def __init__(self,\n                 transforms: List[dict],\n                 keymap: Optional[dict] = None) -> None:\n        if albumentations is None:\n            raise RuntimeError('albumentations is not installed')\n\n        self.transforms = transforms\n\n        self.aug = albumentations.Compose(\n            [self.albu_builder(t) for t in self.transforms])\n\n        if not keymap:\n            self.keymap_to_albu = {\n                'img': 'image',\n            }\n        else:\n            self.keymap_to_albu = keymap\n\n    def albu_builder(self, cfg: dict) -> albumentations:\n        \"\"\"Import a module from albumentations.\n\n        It resembles some of :func:`build_from_cfg` logic.\n\n        Args:\n            cfg (dict): Config dict. It should at least contain the key \"type\".\n\n        Returns:\n            albumentations.BasicTransform: The constructed transform object\n        \"\"\"\n\n        assert isinstance(cfg, dict) and 'type' in cfg\n        args = cfg.copy()\n\n        obj_type = args.pop('type')\n        if mmengine.is_str(obj_type):\n            if albumentations is None:\n                raise RuntimeError('albumentations is not installed')\n            rank, _ = get_dist_info()\n            if rank == 0 and not hasattr(\n                    albumentations.augmentations.transforms, obj_type):\n                warnings.warn(\n                    f'{obj_type} is not pixel-level transformations. '\n                    'Please use with caution.')\n            obj_cls = getattr(albumentations, obj_type)\n        elif isinstance(obj_type, type):\n            obj_cls = obj_type\n        else:\n            raise TypeError(f'type must be a str, but got {type(obj_type)}')\n\n        if 'transforms' in args:\n            args['transforms'] = [\n                self.albu_builder(transform)\n                for transform in args['transforms']\n            ]\n\n        return obj_cls(**args)\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"The transform function of :class:`Albumentation` to apply\n        albumentations transforms.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): Result dict from the data pipeline.\n\n        Return:\n            dict: updated result dict.\n        \"\"\"\n        # map result dict to albumentations format\n        results_albu = {}\n        for k, v in self.keymap_to_albu.items():\n            assert k in results, \\\n                f'The `{k}` is required to perform albumentations transforms'\n            results_albu[v] = results[k]\n\n        # Apply albumentations transforms\n        results_albu = self.aug(**results_albu)\n\n        # map the albu results back to the original format\n        for k, v in self.keymap_to_albu.items():\n            results[k] = results_albu[v]\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__ + f'(transforms={self.transforms})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass PhotometricDistortion(BaseTransform):\n    \"\"\"Apply photometric distortion to image sequentially, every transformation\n    is applied with a probability of 0.5. The position of random contrast is in\n    second or second to last.\n\n    1. random brightness\n    2. random contrast (mode 0)\n    3. convert color from BGR to HSV\n    4. random saturation\n    5. random hue\n    6. convert color from HSV to BGR\n    7. random contrast (mode 1)\n    8. randomly swap channels\n\n    Required Keys:\n\n    - img\n\n    Modified Keys:\n\n    - img\n\n    Args:\n        brightness_delta (int): delta of brightness.\n        contrast_range (tuple): range of contrast.\n        saturation_range (tuple): range of saturation.\n        hue_delta (int): delta of hue.\n    \"\"\"\n\n    def __init__(self,\n                 brightness_delta: int = 32,\n                 contrast_range: Sequence[Number] = (0.5, 1.5),\n                 saturation_range: Sequence[Number] = (0.5, 1.5),\n                 hue_delta: int = 18) -> None:\n        self.brightness_delta = brightness_delta\n        self.contrast_lower, self.contrast_upper = contrast_range\n        self.saturation_lower, self.saturation_upper = saturation_range\n        self.hue_delta = hue_delta\n\n    @cache_randomness\n    def _random_flags(self) -> Sequence[Number]:\n        \"\"\"Generate the random flags for subsequent transforms.\n\n        Returns:\n            Sequence[Number]: a sequence of numbers that indicate whether to\n                do the corresponding transforms.\n        \"\"\"\n        # contrast_mode == 0 --> do random contrast first\n        # contrast_mode == 1 --> do random contrast last\n        contrast_mode = np.random.randint(2)\n        # whether to apply brightness distortion\n        brightness_flag = np.random.randint(2)\n        # whether to apply contrast distortion\n        contrast_flag = np.random.randint(2)\n        # the mode to convert color from BGR to HSV\n        hsv_mode = np.random.randint(4)\n        # whether to apply channel swap\n        swap_flag = np.random.randint(2)\n\n        # the beta in `self._convert` to be added to image array\n        # in brightness distortion\n        brightness_beta = np.random.uniform(-self.brightness_delta,\n                                            self.brightness_delta)\n        # the alpha in `self._convert` to be multiplied to image array\n        # in contrast distortion\n        contrast_alpha = np.random.uniform(self.contrast_lower,\n                                           self.contrast_upper)\n        # the alpha in `self._convert` to be multiplied to image array\n        # in saturation distortion to hsv-formatted img\n        saturation_alpha = np.random.uniform(self.saturation_lower,\n                                             self.saturation_upper)\n        # delta of hue to add to image array in hue distortion\n        hue_delta = np.random.randint(-self.hue_delta, self.hue_delta)\n        # the random permutation of channel order\n        swap_channel_order = np.random.permutation(3)\n\n        return (contrast_mode, brightness_flag, contrast_flag, hsv_mode,\n                swap_flag, brightness_beta, contrast_alpha, saturation_alpha,\n                hue_delta, swap_channel_order)\n\n    def _convert(self,\n                 img: np.ndarray,\n                 alpha: float = 1,\n                 beta: float = 0) -> np.ndarray:\n        \"\"\"Multiple with alpha and add beta with clip.\n\n        Args:\n            img (np.ndarray): The image array.\n            alpha (float): The random multiplier.\n            beta (float): The random offset.\n\n        Returns:\n            np.ndarray: The updated image array.\n        \"\"\"\n        img = img.astype(np.float32) * alpha + beta\n        img = np.clip(img, 0, 255)\n        return img.astype(np.uint8)\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"The transform function of :class:`PhotometricDistortion` to perform\n        photometric distortion on images.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n\n        Args:\n            results (dict): Result dict from the data pipeline.\n\n        Returns:\n            dict: Result dict with images distorted.\n        \"\"\"\n\n        assert 'img' in results, '`img` is not found in results'\n        img = results['img']\n\n        (contrast_mode, brightness_flag, contrast_flag, hsv_mode, swap_flag,\n         brightness_beta, contrast_alpha, saturation_alpha, hue_delta,\n         swap_channel_order) = self._random_flags()\n\n        # random brightness distortion\n        if brightness_flag:\n            img = self._convert(img, beta=brightness_beta)\n\n        # contrast_mode == 0 --> do random contrast first\n        # contrast_mode == 1 --> do random contrast last\n        if contrast_mode == 1:\n            if contrast_flag:\n                img = self._convert(img, alpha=contrast_alpha)\n\n        if hsv_mode:\n            # random saturation/hue distortion\n            img = mmcv.bgr2hsv(img)\n            if hsv_mode == 1 or hsv_mode == 3:\n                # apply saturation distortion to hsv-formatted img\n                img[:, :, 1] = self._convert(\n                    img[:, :, 1], alpha=saturation_alpha)\n            if hsv_mode == 2 or hsv_mode == 3:\n                # apply hue distortion to hsv-formatted img\n                img[:, :, 0] = img[:, :, 0].astype(int) + hue_delta\n            img = mmcv.hsv2bgr(img)\n\n        if contrast_mode == 1:\n            if contrast_flag:\n                img = self._convert(img, alpha=contrast_alpha)\n\n        # randomly swap channels\n        if swap_flag:\n            img = img[..., swap_channel_order]\n\n        results['img'] = img\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += (f'(brightness_delta={self.brightness_delta}, '\n                     f'contrast_range=({self.contrast_lower}, '\n                     f'{self.contrast_upper}), '\n                     f'saturation_range=({self.saturation_lower}, '\n                     f'{self.saturation_upper}), '\n                     f'hue_delta={self.hue_delta})')\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass GenerateTarget(BaseTransform):\n    \"\"\"Encode keypoints into Target.\n\n    The generated target is usually the supervision signal of the model\n    learning, e.g. heatmaps or regression labels.\n\n    Required Keys:\n\n        - keypoints\n        - keypoints_visible\n        - dataset_keypoint_weights\n\n    Added Keys:\n\n        - The keys of the encoded items from the codec will be updated into\n            the results, e.g. ``'heatmaps'`` or ``'keypoint_weights'``. See\n            the specific codec for more details.\n\n    Args:\n        encoder (dict | list[dict]): The codec config for keypoint encoding.\n            Both single encoder and multiple encoders (given as a list) are\n            supported\n        multilevel (bool): Determine the method to handle multiple encoders.\n            If ``multilevel==True``, generate multilevel targets from a group\n            of encoders of the same type (e.g. multiple :class:`MSRAHeatmap`\n            encoders with different sigma values); If ``multilevel==False``,\n            generate combined targets from a group of different encoders. This\n            argument will have no effect in case of single encoder. Defaults\n            to ``False``\n        use_dataset_keypoint_weights (bool): Whether use the keypoint weights\n            from the dataset meta information. Defaults to ``False``\n        target_type (str, deprecated): This argument is deprecated and has no\n            effect. Defaults to ``None``\n    \"\"\"\n\n    def __init__(self,\n                 encoder: MultiConfig,\n                 target_type: Optional[str] = None,\n                 multilevel: bool = False,\n                 use_dataset_keypoint_weights: bool = False) -> None:\n        super().__init__()\n\n        if target_type is not None:\n            rank, _ = get_dist_info()\n            if rank == 0:\n                warnings.warn(\n                    'The argument `target_type` is deprecated in'\n                    ' GenerateTarget. The target type and encoded '\n                    'keys will be determined by encoder(s).',\n                    DeprecationWarning)\n\n        self.encoder_cfg = deepcopy(encoder)\n        self.multilevel = multilevel\n        self.use_dataset_keypoint_weights = use_dataset_keypoint_weights\n\n        if isinstance(self.encoder_cfg, list):\n            self.encoder = [\n                KEYPOINT_CODECS.build(cfg) for cfg in self.encoder_cfg\n            ]\n        else:\n            assert not self.multilevel, (\n                'Need multiple encoder configs if ``multilevel==True``')\n            self.encoder = KEYPOINT_CODECS.build(self.encoder_cfg)\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`GenerateTarget`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n        \"\"\"\n\n        if results.get('transformed_keypoints', None) is not None:\n            # use keypoints transformed by TopdownAffine\n            keypoints = results['transformed_keypoints']\n        elif results.get('keypoints', None) is not None:\n            # use original keypoints\n            keypoints = results['keypoints']\n        else:\n            raise ValueError(\n                'GenerateTarget requires \\'transformed_keypoints\\' or'\n                ' \\'keypoints\\' in the results.')\n\n        keypoints_visible = results['keypoints_visible']\n        if keypoints_visible.ndim == 3 and keypoints_visible.shape[2] == 2:\n            keypoints_visible, keypoints_visible_weights = \\\n                keypoints_visible[..., 0], keypoints_visible[..., 1]\n            results['keypoints_visible'] = keypoints_visible\n            results['keypoints_visible_weights'] = keypoints_visible_weights\n\n        # Encoded items from the encoder(s) will be updated into the results.\n        # Please refer to the document of the specific codec for details about\n        # encoded items.\n        if not isinstance(self.encoder, list):\n            # For single encoding, the encoded items will be directly added\n            # into results.\n            auxiliary_encode_kwargs = {\n                key: results.get(key, None)\n                for key in self.encoder.auxiliary_encode_keys\n            }\n            encoded = self.encoder.encode(\n                keypoints=keypoints,\n                keypoints_visible=keypoints_visible,\n                **auxiliary_encode_kwargs)\n\n            if self.encoder.field_mapping_table:\n                encoded[\n                    'field_mapping_table'] = self.encoder.field_mapping_table\n            if self.encoder.instance_mapping_table:\n                encoded['instance_mapping_table'] = \\\n                    self.encoder.instance_mapping_table\n            if self.encoder.label_mapping_table:\n                encoded[\n                    'label_mapping_table'] = self.encoder.label_mapping_table\n\n        else:\n            encoded_list = []\n            _field_mapping_table = dict()\n            _instance_mapping_table = dict()\n            _label_mapping_table = dict()\n            for _encoder in self.encoder:\n                auxiliary_encode_kwargs = {\n                    key: results[key]\n                    for key in _encoder.auxiliary_encode_keys\n                }\n                encoded_list.append(\n                    _encoder.encode(\n                        keypoints=keypoints,\n                        keypoints_visible=keypoints_visible,\n                        **auxiliary_encode_kwargs))\n\n                _field_mapping_table.update(_encoder.field_mapping_table)\n                _instance_mapping_table.update(_encoder.instance_mapping_table)\n                _label_mapping_table.update(_encoder.label_mapping_table)\n\n            if self.multilevel:\n                # For multilevel encoding, the encoded items from each encoder\n                # should have the same keys.\n\n                keys = encoded_list[0].keys()\n                if not all(_encoded.keys() == keys\n                           for _encoded in encoded_list):\n                    raise ValueError(\n                        'Encoded items from all encoders must have the same '\n                        'keys if ``multilevel==True``.')\n\n                encoded = {\n                    k: [_encoded[k] for _encoded in encoded_list]\n                    for k in keys\n                }\n\n            else:\n                # For combined encoding, the encoded items from different\n                # encoders should have no overlapping items, except for\n                # `keypoint_weights`. If multiple `keypoint_weights` are given,\n                # they will be multiplied as the final `keypoint_weights`.\n\n                encoded = dict()\n                keypoint_weights = []\n\n                for _encoded in encoded_list:\n                    for key, value in _encoded.items():\n                        if key == 'keypoint_weights':\n                            keypoint_weights.append(value)\n                        elif key not in encoded:\n                            encoded[key] = value\n                        else:\n                            raise ValueError(\n                                f'Overlapping item \"{key}\" from multiple '\n                                'encoders, which is not supported when '\n                                '``multilevel==False``')\n\n                if keypoint_weights:\n                    encoded['keypoint_weights'] = keypoint_weights\n\n            if _field_mapping_table:\n                encoded['field_mapping_table'] = _field_mapping_table\n            if _instance_mapping_table:\n                encoded['instance_mapping_table'] = _instance_mapping_table\n            if _label_mapping_table:\n                encoded['label_mapping_table'] = _label_mapping_table\n\n        if self.use_dataset_keypoint_weights and 'keypoint_weights' in encoded:\n            if isinstance(encoded['keypoint_weights'], list):\n                for w in encoded['keypoint_weights']:\n                    w = w * results['dataset_keypoint_weights']\n            else:\n                encoded['keypoint_weights'] = encoded[\n                    'keypoint_weights'] * results['dataset_keypoint_weights']\n\n        results.update(encoded)\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += (f'(encoder={str(self.encoder_cfg)}, ')\n        repr_str += ('use_dataset_keypoint_weights='\n                     f'{self.use_dataset_keypoint_weights})')\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass YOLOXHSVRandomAug(BaseTransform):\n    \"\"\"Apply HSV augmentation to image sequentially. It is referenced from\n    https://github.com/Megvii-\n    BaseDetection/YOLOX/blob/main/yolox/data/data_augment.py#L21.\n\n    Required Keys:\n\n    - img\n\n    Modified Keys:\n\n    - img\n\n    Args:\n        hue_delta (int): delta of hue. Defaults to 5.\n        saturation_delta (int): delta of saturation. Defaults to 30.\n        value_delta (int): delat of value. Defaults to 30.\n    \"\"\"\n\n    def __init__(self,\n                 hue_delta: int = 5,\n                 saturation_delta: int = 30,\n                 value_delta: int = 30) -> None:\n        self.hue_delta = hue_delta\n        self.saturation_delta = saturation_delta\n        self.value_delta = value_delta\n\n    @cache_randomness\n    def _get_hsv_gains(self):\n        hsv_gains = np.random.uniform(-1, 1, 3) * [\n            self.hue_delta, self.saturation_delta, self.value_delta\n        ]\n        # random selection of h, s, v\n        hsv_gains *= np.random.randint(0, 2, 3)\n        # prevent overflow\n        hsv_gains = hsv_gains.astype(np.int16)\n        return hsv_gains\n\n    def transform(self, results: dict) -> dict:\n        img = results['img']\n        hsv_gains = self._get_hsv_gains()\n        img_hsv = cv2.cvtColor(img, cv2.COLOR_BGR2HSV).astype(np.int16)\n\n        img_hsv[..., 0] = (img_hsv[..., 0] + hsv_gains[0]) % 180\n        img_hsv[..., 1] = np.clip(img_hsv[..., 1] + hsv_gains[1], 0, 255)\n        img_hsv[..., 2] = np.clip(img_hsv[..., 2] + hsv_gains[2], 0, 255)\n        cv2.cvtColor(img_hsv.astype(img.dtype), cv2.COLOR_HSV2BGR, dst=img)\n\n        results['img'] = img\n        return results\n\n    def __repr__(self):\n        repr_str = self.__class__.__name__\n        repr_str += f'(hue_delta={self.hue_delta}, '\n        repr_str += f'saturation_delta={self.saturation_delta}, '\n        repr_str += f'value_delta={self.value_delta})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass FilterAnnotations(BaseTransform):\n    \"\"\"Eliminate undesirable annotations based on specific conditions.\n\n    This class is designed to sift through annotations by examining multiple\n    factors such as the size of the bounding box, the visibility of keypoints,\n    and the overall area. Users can fine-tune the criteria to filter out\n    instances that have excessively small bounding boxes, insufficient area,\n    or an inadequate number of visible keypoints.\n\n    Required Keys:\n\n    - bbox (np.ndarray) (optional)\n    - area (np.int64) (optional)\n    - keypoints_visible (np.ndarray) (optional)\n\n    Modified Keys:\n\n    - bbox (optional)\n    - bbox_score (optional)\n    - category_id (optional)\n    - keypoints (optional)\n    - keypoints_visible (optional)\n    - area (optional)\n\n    Args:\n        min_gt_bbox_wh (tuple[float]): Minimum width and height of ground\n            truth boxes. Default: (1., 1.)\n        min_gt_area (int): Minimum foreground area of instances.\n            Default: 1\n        min_kpt_vis (int): Minimum number of visible keypoints. Default: 1\n        by_box (bool): Filter instances with bounding boxes not meeting the\n            min_gt_bbox_wh threshold. Default: False\n        by_area (bool): Filter instances with area less than min_gt_area\n            threshold. Default: False\n        by_kpt (bool): Filter instances with keypoints_visible not meeting the\n            min_kpt_vis threshold. Default: True\n        keep_empty (bool): Whether to return None when it\n            becomes an empty bbox after filtering. Defaults to True.\n    \"\"\"\n\n    def __init__(self,\n                 min_gt_bbox_wh: Tuple[int, int] = (1, 1),\n                 min_gt_area: int = 1,\n                 min_kpt_vis: int = 1,\n                 by_box: bool = False,\n                 by_area: bool = False,\n                 by_kpt: bool = True,\n                 keep_empty: bool = True) -> None:\n\n        assert by_box or by_kpt or by_area\n        self.min_gt_bbox_wh = min_gt_bbox_wh\n        self.min_gt_area = min_gt_area\n        self.min_kpt_vis = min_kpt_vis\n        self.by_box = by_box\n        self.by_area = by_area\n        self.by_kpt = by_kpt\n        self.keep_empty = keep_empty\n\n    def transform(self, results: dict) -> Union[dict, None]:\n        \"\"\"Transform function to filter annotations.\n\n        Args:\n            results (dict): Result dict.\n\n        Returns:\n            dict: Updated result dict.\n        \"\"\"\n        assert 'keypoints' in results\n        kpts = results['keypoints']\n        if kpts.shape[0] == 0:\n            return results\n\n        tests = []\n        if self.by_box and 'bbox' in results:\n            bbox = results['bbox']\n            tests.append(\n                ((bbox[..., 2] - bbox[..., 0] > self.min_gt_bbox_wh[0]) &\n                 (bbox[..., 3] - bbox[..., 1] > self.min_gt_bbox_wh[1])))\n        if self.by_area and 'area' in results:\n            area = results['area']\n            tests.append(area >= self.min_gt_area)\n        if self.by_kpt:\n            kpts_vis = results['keypoints_visible']\n            if kpts_vis.ndim == 3:\n                kpts_vis = kpts_vis[..., 0]\n            tests.append(kpts_vis.sum(axis=1) >= self.min_kpt_vis)\n\n        keep = tests[0]\n        for t in tests[1:]:\n            keep = keep & t\n\n        if not keep.any():\n            if self.keep_empty:\n                return None\n\n        keys = ('bbox', 'bbox_score', 'category_id', 'keypoints',\n                'keypoints_visible', 'area')\n        for key in keys:\n            if key in results:\n                results[key] = results[key][keep]\n\n        return results\n\n    def __repr__(self):\n        return (f'{self.__class__.__name__}('\n                f'min_gt_bbox_wh={self.min_gt_bbox_wh}, '\n                f'min_gt_area={self.min_gt_area}, '\n                f'min_kpt_vis={self.min_kpt_vis}, '\n                f'by_box={self.by_box}, '\n                f'by_area={self.by_area}, '\n                f'by_kpt={self.by_kpt}, '\n                f'keep_empty={self.keep_empty})')\n"
  },
  {
    "path": "mmpose/datasets/transforms/converting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple, Union\n\nimport numpy as np\nfrom mmcv.transforms import BaseTransform\n\nfrom mmpose.registry import TRANSFORMS\n\n\n@TRANSFORMS.register_module()\nclass KeypointConverter(BaseTransform):\n    \"\"\"Change the order of keypoints according to the given mapping.\n\n    Required Keys:\n\n        - keypoints\n        - keypoints_visible\n\n    Modified Keys:\n\n        - keypoints\n        - keypoints_visible\n\n    Args:\n        num_keypoints (int): The number of keypoints in target dataset.\n        mapping (list): A list containing mapping indexes. Each element has\n            format (source_index, target_index)\n\n    Example:\n        >>> import numpy as np\n        >>> # case 1: 1-to-1 mapping\n        >>> # (0, 0) means target[0] = source[0]\n        >>> self = KeypointConverter(\n        >>>     num_keypoints=3,\n        >>>     mapping=[\n        >>>         (0, 0), (1, 1), (2, 2), (3, 3)\n        >>>     ])\n        >>> results = dict(\n        >>>     keypoints=np.arange(34).reshape(2, 3, 2),\n        >>>     keypoints_visible=np.arange(34).reshape(2, 3, 2) % 2)\n        >>> results = self(results)\n        >>> assert np.equal(results['keypoints'],\n        >>>                 np.arange(34).reshape(2, 3, 2)).all()\n        >>> assert np.equal(results['keypoints_visible'],\n        >>>                 np.arange(34).reshape(2, 3, 2) % 2).all()\n        >>>\n        >>> # case 2: 2-to-1 mapping\n        >>> # ((1, 2), 0) means target[0] = (source[1] + source[2]) / 2\n        >>> self = KeypointConverter(\n        >>>     num_keypoints=3,\n        >>>     mapping=[\n        >>>         ((1, 2), 0), (1, 1), (2, 2)\n        >>>     ])\n        >>> results = dict(\n        >>>     keypoints=np.arange(34).reshape(2, 3, 2),\n        >>>     keypoints_visible=np.arange(34).reshape(2, 3, 2) % 2)\n        >>> results = self(results)\n    \"\"\"\n\n    def __init__(self, num_keypoints: int,\n                 mapping: Union[List[Tuple[int, int]], List[Tuple[Tuple,\n                                                                  int]]]):\n        self.num_keypoints = num_keypoints\n        self.mapping = mapping\n        if len(mapping):\n            source_index, target_index = zip(*mapping)\n        else:\n            source_index, target_index = [], []\n\n        src1, src2 = [], []\n        interpolation = False\n        for x in source_index:\n            if isinstance(x, (list, tuple)):\n                assert len(x) == 2, 'source_index should be a list/tuple of ' \\\n                                    'length 2'\n                src1.append(x[0])\n                src2.append(x[1])\n                interpolation = True\n            else:\n                src1.append(x)\n                src2.append(x)\n\n        # When paired source_indexes are input,\n        # keep a self.source_index2 for interpolation\n        if interpolation:\n            self.source_index2 = src2\n\n        self.source_index = src1\n        self.target_index = list(target_index)\n        self.interpolation = interpolation\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"Transforms the keypoint results to match the target keypoints.\"\"\"\n        num_instances = results['keypoints'].shape[0]\n\n        if 'keypoints_visible' not in results:\n            results['keypoints_visible'] = np.ones(\n                (num_instances, results['keypoints'].shape[1]))\n\n        if len(results['keypoints_visible'].shape) > 2:\n            results['keypoints_visible'] = results['keypoints_visible'][:, :,\n                                                                        0]\n\n        # Initialize output arrays\n        keypoints = np.zeros((num_instances, self.num_keypoints, 3))\n        keypoints_visible = np.zeros((num_instances, self.num_keypoints))\n        key = 'keypoints_3d' if 'keypoints_3d' in results else 'keypoints'\n        c = results[key].shape[-1]\n\n        flip_indices = results.get('flip_indices', None)\n\n        # Create a mask to weight visibility loss\n        keypoints_visible_weights = keypoints_visible.copy()\n        keypoints_visible_weights[:, self.target_index] = 1.0\n\n        # Interpolate keypoints if pairs of source indexes provided\n        if self.interpolation:\n            keypoints[:, self.target_index, :c] = 0.5 * (\n                results[key][:, self.source_index] +\n                results[key][:, self.source_index2])\n            keypoints_visible[:, self.target_index] = results[\n                'keypoints_visible'][:, self.source_index] * results[\n                    'keypoints_visible'][:, self.source_index2]\n            # Flip keypoints if flip_indices provided\n            if flip_indices is not None:\n                for i, (x1, x2) in enumerate(\n                        zip(self.source_index, self.source_index2)):\n                    idx = flip_indices[x1] if x1 == x2 else i\n                    flip_indices[i] = idx if idx < self.num_keypoints else i\n                flip_indices = flip_indices[:len(self.source_index)]\n        # Otherwise just copy from the source index\n        else:\n            keypoints[:,\n                      self.target_index, :c] = results[key][:,\n                                                            self.source_index]\n            keypoints_visible[:, self.target_index] = results[\n                'keypoints_visible'][:, self.source_index]\n\n        # Update the results dict\n        results['keypoints'] = keypoints[..., :2]\n        results['keypoints_visible'] = np.stack(\n            [keypoints_visible, keypoints_visible_weights], axis=2)\n        if 'keypoints_3d' in results:\n            results['keypoints_3d'] = keypoints\n            results['lifting_target'] = keypoints[results['target_idx']]\n            results['lifting_target_visible'] = keypoints_visible[\n                results['target_idx']]\n        results['flip_indices'] = flip_indices\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(num_keypoints={self.num_keypoints}, '\\\n                    f'mapping={self.mapping})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass SingleHandConverter(BaseTransform):\n    \"\"\"Mapping a single hand keypoints into double hands according to the given\n    mapping and hand type.\n\n    Required Keys:\n\n        - keypoints\n        - keypoints_visible\n        - hand_type\n\n    Modified Keys:\n\n        - keypoints\n        - keypoints_visible\n\n    Args:\n        num_keypoints (int): The number of keypoints in target dataset.\n        left_hand_mapping (list): A list containing mapping indexes. Each\n            element has format (source_index, target_index)\n        right_hand_mapping (list): A list containing mapping indexes. Each\n            element has format (source_index, target_index)\n\n    Example:\n        >>> import numpy as np\n        >>> self = SingleHandConverter(\n        >>>     num_keypoints=42,\n        >>>     left_hand_mapping=[\n        >>>         (0, 0), (1, 1), (2, 2), (3, 3)\n        >>>     ],\n        >>>     right_hand_mapping=[\n        >>>         (0, 21), (1, 22), (2, 23), (3, 24)\n        >>>     ])\n        >>> results = dict(\n        >>>     keypoints=np.arange(84).reshape(2, 21, 2),\n        >>>     keypoints_visible=np.arange(84).reshape(2, 21, 2) % 2,\n        >>>     hand_type=np.array([[0, 1], [1, 0]]))\n        >>> results = self(results)\n    \"\"\"\n\n    def __init__(self, num_keypoints: int,\n                 left_hand_mapping: Union[List[Tuple[int, int]],\n                                          List[Tuple[Tuple, int]]],\n                 right_hand_mapping: Union[List[Tuple[int, int]],\n                                           List[Tuple[Tuple, int]]]):\n        self.num_keypoints = num_keypoints\n        self.left_hand_converter = KeypointConverter(num_keypoints,\n                                                     left_hand_mapping)\n        self.right_hand_converter = KeypointConverter(num_keypoints,\n                                                      right_hand_mapping)\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"Transforms the keypoint results to match the target keypoints.\"\"\"\n        assert 'hand_type' in results, (\n            'hand_type should be provided in results')\n        hand_type = results['hand_type']\n\n        if np.sum(hand_type - [[0, 1]]) <= 1e-6:\n            # left hand\n            results = self.left_hand_converter(results)\n        elif np.sum(hand_type - [[1, 0]]) <= 1e-6:\n            results = self.right_hand_converter(results)\n        else:\n            raise ValueError('hand_type should be left or right')\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(num_keypoints={self.num_keypoints}, '\\\n                    f'left_hand_converter={self.left_hand_converter}, '\\\n                    f'right_hand_converter={self.right_hand_converter})'\n        return repr_str\n"
  },
  {
    "path": "mmpose/datasets/transforms/formatting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Sequence, Union\n\nimport numpy as np\nimport torch\nfrom mmcv.transforms import BaseTransform\nfrom mmengine.structures import InstanceData, PixelData\nfrom mmengine.utils import is_seq_of\n\nfrom mmpose.registry import TRANSFORMS\nfrom mmpose.structures import MultilevelPixelData, PoseDataSample\n\n\ndef image_to_tensor(img: Union[np.ndarray,\n                               Sequence[np.ndarray]]) -> torch.torch.Tensor:\n    \"\"\"Translate image or sequence of images to tensor. Multiple image tensors\n    will be stacked.\n\n    Args:\n        value (np.ndarray | Sequence[np.ndarray]): The original image or\n            image sequence\n\n    Returns:\n        torch.Tensor: The output tensor.\n    \"\"\"\n\n    if isinstance(img, np.ndarray):\n        if len(img.shape) < 3:\n            img = np.expand_dims(img, -1)\n\n        img = np.ascontiguousarray(img)\n        tensor = torch.from_numpy(img).permute(2, 0, 1).contiguous()\n    else:\n        assert is_seq_of(img, np.ndarray)\n        tensor = torch.stack([image_to_tensor(_img) for _img in img])\n\n    return tensor\n\n\ndef keypoints_to_tensor(keypoints: Union[np.ndarray, Sequence[np.ndarray]]\n                        ) -> torch.torch.Tensor:\n    \"\"\"Translate keypoints or sequence of keypoints to tensor. Multiple\n    keypoints tensors will be stacked.\n\n    Args:\n        keypoints (np.ndarray | Sequence[np.ndarray]): The keypoints or\n            keypoints sequence.\n\n    Returns:\n        torch.Tensor: The output tensor.\n    \"\"\"\n    if isinstance(keypoints, np.ndarray):\n        keypoints = np.ascontiguousarray(keypoints)\n        tensor = torch.from_numpy(keypoints).contiguous()\n    else:\n        assert is_seq_of(keypoints, np.ndarray)\n        tensor = torch.stack(\n            [keypoints_to_tensor(_keypoints) for _keypoints in keypoints])\n\n    return tensor\n\n\n@TRANSFORMS.register_module()\nclass PackPoseInputs(BaseTransform):\n    \"\"\"Pack the inputs data for pose estimation.\n\n    The ``img_meta`` item is always populated. The contents of the\n    ``img_meta`` dictionary depends on ``meta_keys``. By default it includes:\n\n        - ``id``: id of the data sample\n\n        - ``img_id``: id of the image\n\n        - ``'category_id'``: the id of the instance category\n\n        - ``img_path``: path to the image file\n\n        - ``crowd_index`` (optional): measure the crowding level of an image,\n            defined in CrowdPose dataset\n\n        - ``ori_shape``: original shape of the image as a tuple (h, w, c)\n\n        - ``img_shape``: shape of the image input to the network as a tuple \\\n            (h, w).  Note that images may be zero padded on the \\\n            bottom/right if the batch tensor is larger than this shape.\n\n        - ``input_size``: the input size to the network\n\n        - ``flip``: a boolean indicating if image flip transform was used\n\n        - ``flip_direction``: the flipping direction\n\n        - ``flip_indices``: the indices of each keypoint's symmetric keypoint\n\n        - ``raw_ann_info`` (optional): raw annotation of the instance(s)\n\n    Args:\n        meta_keys (Sequence[str], optional): Meta keys which will be stored in\n            :obj: `PoseDataSample` as meta info. Defaults to ``('id',\n            'img_id', 'img_path', 'category_id', 'crowd_index, 'ori_shape',\n            'img_shape', 'input_size', 'input_center', 'input_scale', 'flip',\n            'flip_direction', 'flip_indices', 'raw_ann_info')``\n    \"\"\"\n\n    # items in `instance_mapping_table` will be directly packed into\n    # PoseDataSample.gt_instances without converting to Tensor\n    instance_mapping_table = dict(\n        bbox='bboxes',\n        bbox_score='bbox_scores',\n        keypoints='keypoints',\n        keypoints_cam='keypoints_cam',\n        keypoints_visible='keypoints_visible',\n        # In CocoMetric, the area of predicted instances will be calculated\n        # using gt_instances.bbox_scales. To unsure correspondence with\n        # previous version, this key is preserved here.\n        bbox_scale='bbox_scales',\n        # `head_size` is used for computing MpiiPCKAccuracy metric,\n        # namely, PCKh\n        head_size='head_size',\n    )\n\n    # items in `field_mapping_table` will be packed into\n    # PoseDataSample.gt_fields and converted to Tensor. These items will be\n    # used for computing losses\n    field_mapping_table = dict(\n        heatmaps='heatmaps',\n        instance_heatmaps='instance_heatmaps',\n        heatmap_mask='heatmap_mask',\n        heatmap_weights='heatmap_weights',\n        displacements='displacements',\n        displacement_weights='displacement_weights')\n\n    # items in `label_mapping_table` will be packed into\n    # PoseDataSample.gt_instance_labels and converted to Tensor. These items\n    # will be used for computing losses\n    label_mapping_table = dict(\n        keypoint_labels='keypoint_labels',\n        keypoint_weights='keypoint_weights',\n        keypoints_visible_weights='keypoints_visible_weights')\n\n    def __init__(self,\n                 meta_keys=('id', 'img_id', 'img_path', 'category_id',\n                            'crowd_index', 'ori_shape', 'img_shape',\n                            'input_size', 'input_center', 'input_scale',\n                            'flip', 'flip_direction', 'flip_indices',\n                            'raw_ann_info', 'dataset_name'),\n                 pack_transformed=False):\n        self.meta_keys = meta_keys\n        self.pack_transformed = pack_transformed\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"Method to pack the input data.\n\n        Args:\n            results (dict): Result dict from the data pipeline.\n\n        Returns:\n            dict:\n\n            - 'inputs' (obj:`torch.Tensor`): The forward data of models.\n            - 'data_samples' (obj:`PoseDataSample`): The annotation info of the\n                sample.\n        \"\"\"\n        # Pack image(s) for 2d pose estimation\n        if 'img' in results:\n            img = results['img']\n            inputs_tensor = image_to_tensor(img)\n        # Pack keypoints for 3d pose-lifting\n        elif 'lifting_target' in results and 'keypoints' in results:\n            if 'keypoint_labels' in results:\n                keypoints = results['keypoint_labels']\n            else:\n                keypoints = results['keypoints']\n            inputs_tensor = keypoints_to_tensor(keypoints)\n\n        data_sample = PoseDataSample()\n\n        # pack instance data\n        gt_instances = InstanceData()\n        _instance_mapping_table = results.get('instance_mapping_table',\n                                              self.instance_mapping_table)\n        for key, packed_key in _instance_mapping_table.items():\n            if key in results:\n                gt_instances.set_field(results[key], packed_key)\n\n        # pack `transformed_keypoints` for visualizing data transform\n        # and augmentation results\n        if self.pack_transformed and 'transformed_keypoints' in results:\n            gt_instances.set_field(results['transformed_keypoints'],\n                                   'transformed_keypoints')\n\n        data_sample.gt_instances = gt_instances\n\n        # pack instance labels\n        gt_instance_labels = InstanceData()\n        _label_mapping_table = results.get('label_mapping_table',\n                                           self.label_mapping_table)\n        for key, packed_key in _label_mapping_table.items():\n            if key in results:\n                if isinstance(results[key], list):\n                    # A list of labels is usually generated by combined\n                    # multiple encoders (See ``GenerateTarget`` in\n                    # mmpose/datasets/transforms/common_transforms.py)\n                    # In this case, labels in list should have the same\n                    # shape and will be stacked.\n                    _labels = np.stack(results[key])\n                    gt_instance_labels.set_field(_labels, packed_key)\n                else:\n                    gt_instance_labels.set_field(results[key], packed_key)\n        data_sample.gt_instance_labels = gt_instance_labels.to_tensor()\n\n        # pack fields\n        gt_fields = None\n        _field_mapping_table = results.get('field_mapping_table',\n                                           self.field_mapping_table)\n        for key, packed_key in _field_mapping_table.items():\n            if key in results:\n                if isinstance(results[key], list):\n                    if gt_fields is None:\n                        gt_fields = MultilevelPixelData()\n                    else:\n                        assert isinstance(\n                            gt_fields, MultilevelPixelData\n                        ), 'Got mixed single-level and multi-level pixel data.'\n                else:\n                    if gt_fields is None:\n                        gt_fields = PixelData()\n                    else:\n                        assert isinstance(\n                            gt_fields, PixelData\n                        ), 'Got mixed single-level and multi-level pixel data.'\n\n                gt_fields.set_field(results[key], packed_key)\n\n        if gt_fields:\n            data_sample.gt_fields = gt_fields.to_tensor()\n\n        img_meta = {k: results[k] for k in self.meta_keys if k in results}\n        data_sample.set_metainfo(img_meta)\n\n        packed_results = dict()\n        packed_results['inputs'] = inputs_tensor\n        packed_results['data_samples'] = data_sample\n\n        return packed_results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(meta_keys={self.meta_keys}, '\n        repr_str += f'pack_transformed={self.pack_transformed})'\n        return repr_str\n"
  },
  {
    "path": "mmpose/datasets/transforms/hand_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Union\n\nfrom mmpose.codecs import *  # noqa: F401, F403\nfrom mmpose.registry import TRANSFORMS\nfrom .common_transforms import RandomFlip\n\n\n@TRANSFORMS.register_module()\nclass HandRandomFlip(RandomFlip):\n    \"\"\"Data augmentation with random image flip. A child class of\n    `TopDownRandomFlip`.\n\n    Required Keys:\n\n        - img\n        - joints_3d\n        - joints_3d_visible\n        - center\n        - hand_type\n        - rel_root_depth\n        - ann_info\n\n    Modified Keys:\n\n        - img\n        - joints_3d\n        - joints_3d_visible\n        - center\n        - hand_type\n        - rel_root_depth\n\n    Args:\n        prob (float | list[float]): The flipping probability. If a list is\n            given, the argument `direction` should be a list with the same\n            length. And each element in `prob` indicates the flipping\n            probability of the corresponding one in ``direction``. Defaults\n            to 0.5\n    \"\"\"\n\n    def __init__(self, prob: Union[float, List[float]] = 0.5) -> None:\n        super().__init__(prob=prob, direction='horizontal')\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"The transform function of :class:`HandRandomFlip`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n        # base flip augmentation\n        results = super().transform(results)\n\n        # flip hand type and root depth\n        hand_type = results['hand_type']\n        rel_root_depth = results['rel_root_depth']\n        flipped = results['flip']\n        if flipped:\n            hand_type[..., [0, 1]] = hand_type[..., [1, 0]]\n            rel_root_depth = -rel_root_depth\n        results['hand_type'] = hand_type\n        results['rel_root_depth'] = rel_root_depth\n        return results\n"
  },
  {
    "path": "mmpose/datasets/transforms/loading.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional\n\nimport numpy as np\nfrom mmcv.transforms import LoadImageFromFile\n\nfrom mmpose.registry import TRANSFORMS\n\n\n@TRANSFORMS.register_module()\nclass LoadImage(LoadImageFromFile):\n    \"\"\"Load an image from file or from the np.ndarray in ``results['img']``.\n\n    Required Keys:\n\n        - img_path\n        - img (optional)\n\n    Modified Keys:\n\n        - img\n        - img_shape\n        - ori_shape\n        - img_path (optional)\n\n    Args:\n        to_float32 (bool): Whether to convert the loaded image to a float32\n            numpy array. If set to False, the loaded image is an uint8 array.\n            Defaults to False.\n        color_type (str): The flag argument for :func:``mmcv.imfrombytes``.\n            Defaults to 'color'.\n        imdecode_backend (str): The image decoding backend type. The backend\n            argument for :func:``mmcv.imfrombytes``.\n            See :func:``mmcv.imfrombytes`` for details.\n            Defaults to 'cv2'.\n        backend_args (dict, optional): Arguments to instantiate the preifx of\n            uri corresponding backend. Defaults to None.\n        ignore_empty (bool): Whether to allow loading empty image or file path\n            not existent. Defaults to False.\n    \"\"\"\n\n    def transform(self, results: dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`LoadImage`.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n        try:\n            if 'img' not in results:\n                # Load image from file by :meth:`LoadImageFromFile.transform`\n                results = super().transform(results)\n            else:\n                img = results['img']\n                assert isinstance(img, np.ndarray)\n                if self.to_float32:\n                    img = img.astype(np.float32)\n\n                if 'img_path' not in results:\n                    results['img_path'] = None\n                results['img_shape'] = img.shape[:2]\n                results['ori_shape'] = img.shape[:2]\n        except Exception as e:\n            e = type(e)(\n                f'`{str(e)}` occurs when loading `{results[\"img_path\"]}`.'\n                'Please check whether the file exists.')\n            raise e\n\n        return results\n"
  },
  {
    "path": "mmpose/datasets/transforms/mix_img_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nfrom abc import ABCMeta\nfrom collections import defaultdict\nfrom typing import Optional, Sequence, Tuple\n\nimport mmcv\nimport numpy as np\nfrom mmcv.transforms import BaseTransform\nfrom mmengine.dataset.base_dataset import Compose\nfrom numpy import random\n\nfrom mmpose.registry import TRANSFORMS\nfrom mmpose.structures import (bbox_clip_border, flip_bbox, flip_keypoints,\n                               keypoint_clip_border)\n\n\nclass MixImageTransform(BaseTransform, metaclass=ABCMeta):\n    \"\"\"Abstract base class for mixup-style image data augmentation.\n\n    Args:\n        pre_transform (Optional[Sequence[str]]): A sequence of transform\n            to be applied before mixup. Defaults to None.\n        prob (float): Probability of applying the mixup transformation.\n            Defaults to 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 pre_transform: Optional[Sequence[str]] = None,\n                 prob: float = 1.0):\n\n        self.prob = prob\n\n        if pre_transform is None:\n            self.pre_transform = None\n        else:\n            self.pre_transform = Compose(pre_transform)\n\n    def transform(self, results: dict) -> dict:\n        \"\"\"Transform the input data dictionary using mixup-style augmentation.\n\n        Args:\n            results (dict): A dictionary containing input data.\n        \"\"\"\n\n        if random.uniform(0, 1) < self.prob:\n\n            dataset = results.pop('dataset', None)\n\n            results['mixed_data_list'] = self._get_mixed_data_list(dataset)\n            results = self.apply_mix(results)\n\n            if 'mixed_data_list' in results:\n                results.pop('mixed_data_list')\n\n            results['dataset'] = dataset\n\n        return results\n\n    def _get_mixed_data_list(self, dataset):\n        \"\"\"Get a list of mixed data samples from the dataset.\n\n        Args:\n            dataset: The dataset from which to sample the mixed data.\n\n        Returns:\n            List[dict]: A list of dictionaries containing mixed data samples.\n        \"\"\"\n        indexes = [\n            random.randint(0, len(dataset)) for _ in range(self.num_aux_image)\n        ]\n\n        mixed_data_list = [\n            copy.deepcopy(dataset.get_data_info(index)) for index in indexes\n        ]\n\n        if self.pre_transform is not None:\n            for i, data in enumerate(mixed_data_list):\n                data.update({'dataset': dataset})\n                _results = self.pre_transform(data)\n                _results.pop('dataset')\n                mixed_data_list[i] = _results\n\n        return mixed_data_list\n\n\n@TRANSFORMS.register_module()\nclass Mosaic(MixImageTransform):\n    \"\"\"Mosaic augmentation. This transformation takes four input images and\n    combines them into a single output image using the mosaic technique. The\n    resulting image is composed of parts from each of the four sub-images. The\n    mosaic transform steps are as follows:\n\n    1. Choose the mosaic center as the intersection of the four images.\n    2. Select the top-left image according to the index and randomly sample\n        three more images from the custom dataset.\n    3. If an image is larger than the mosaic patch, it will be cropped.\n\n    .. code:: text\n\n                        mosaic transform\n                           center_x\n                +------------------------------+\n                |       pad        |           |\n                |      +-----------+    pad    |\n                |      |           |           |\n                |      |  image1   +-----------+\n                |      |           |           |\n                |      |           |   image2  |\n     center_y   |----+-+-----------+-----------+\n                |    |   cropped   |           |\n                |pad |   image3    |   image4  |\n                |    |             |           |\n                +----|-------------+-----------+\n                     |             |\n                     +-------------+\n\n    Required Keys:\n\n    - img\n    - bbox (optional)\n    - bbox_score (optional)\n    - category_id (optional)\n    - keypoints (optional)\n    - keypoints_visible (optional)\n    - area (optional)\n\n    Modified Keys:\n\n    - img\n    - bbox (optional)\n    - bbox_score (optional)\n    - category_id (optional)\n    - keypoints (optional)\n    - keypoints_visible (optional)\n    - area (optional)\n\n    Args:\n        img_scale (Sequence[int]): Image size after mosaic pipeline of single\n            image. The shape order should be (width, height).\n            Defaults to (640, 640).\n        center_range (Sequence[float]): Center ratio range of mosaic\n            output. Defaults to (0.5, 1.5).\n        pad_val (int): Pad value. Defaults to 114.\n        pre_transform (Optional[Sequence[str]]): A sequence of transform\n            to be applied before mixup. Defaults to None.\n        prob (float): Probability of applying the mixup transformation.\n            Defaults to 1.0.\n    \"\"\"\n\n    num_aux_image = 3\n\n    def __init__(\n        self,\n        img_scale: Tuple[int, int] = (640, 640),\n        center_range: Tuple[float, float] = (0.5, 1.5),\n        pad_val: float = 114.0,\n        pre_transform: Sequence[dict] = None,\n        prob: float = 1.0,\n    ):\n\n        super().__init__(pre_transform=pre_transform, prob=prob)\n\n        self.img_scale = img_scale\n        self.center_range = center_range\n        self.pad_val = pad_val\n\n    def apply_mix(self, results: dict) -> dict:\n        \"\"\"Apply mosaic augmentation to the input data.\"\"\"\n\n        assert 'mixed_data_list' in results\n        mixed_data_list = results.pop('mixed_data_list')\n        assert len(mixed_data_list) == self.num_aux_image\n\n        img, annos = self._create_mosaic_image(results, mixed_data_list)\n        bboxes = annos['bboxes']\n        kpts = annos['keypoints']\n        kpts_vis = annos['keypoints_visible']\n\n        bboxes = bbox_clip_border(bboxes, (2 * self.img_scale[0],\n                                           2 * self.img_scale[1]))\n        kpts, kpts_vis = keypoint_clip_border(kpts, kpts_vis,\n                                              (2 * self.img_scale[0],\n                                               2 * self.img_scale[1]))\n\n        results['img'] = img\n        results['img_shape'] = img.shape\n        results['bbox'] = bboxes\n        results['category_id'] = annos['category_id']\n        results['bbox_score'] = annos['bbox_scores']\n        results['keypoints'] = kpts\n        results['keypoints_visible'] = kpts_vis\n        results['area'] = annos['area']\n\n        return results\n\n    def _create_mosaic_image(self, results, mixed_data_list):\n        \"\"\"Create the mosaic image and corresponding annotations by combining\n        four input images.\"\"\"\n\n        # init mosaic image\n        img_scale_w, img_scale_h = self.img_scale\n        mosaic_img = np.full((int(img_scale_h * 2), int(img_scale_w * 2), 3),\n                             self.pad_val,\n                             dtype=results['img'].dtype)\n\n        # calculate mosaic center\n        center = (int(random.uniform(*self.center_range) * img_scale_w),\n                  int(random.uniform(*self.center_range) * img_scale_h))\n\n        annos = defaultdict(list)\n        locs = ('top_left', 'top_right', 'bottom_left', 'bottom_right')\n        for loc, data in zip(locs, (results, *mixed_data_list)):\n\n            # process image\n            img = data['img']\n            h, w = img.shape[:2]\n            scale_ratio = min(img_scale_h / h, img_scale_w / w)\n            img = mmcv.imresize(img,\n                                (int(w * scale_ratio), int(h * scale_ratio)))\n\n            # paste\n            paste_coord, crop_coord = self._mosaic_combine(\n                loc, center, img.shape[:2][::-1])\n            x1_p, y1_p, x2_p, y2_p = paste_coord\n            x1_c, y1_c, x2_c, y2_c = crop_coord\n\n            # crop and paste image\n            mosaic_img[y1_p:y2_p, x1_p:x2_p] = img[y1_c:y2_c, x1_c:x2_c]\n            padw = x1_p - x1_c\n            padh = y1_p - y1_c\n\n            # merge annotations\n            if 'bbox' in data:\n                bboxes = data['bbox']\n\n                # rescale & translate\n                bboxes *= scale_ratio\n                bboxes[..., ::2] += padw\n                bboxes[..., 1::2] += padh\n\n                annos['bboxes'].append(bboxes)\n                annos['bbox_scores'].append(data['bbox_score'])\n                annos['category_id'].append(data['category_id'])\n\n            if 'keypoints' in data:\n                kpts = data['keypoints']\n\n                # rescale & translate\n                kpts *= scale_ratio\n                kpts[..., 0] += padw\n                kpts[..., 1] += padh\n\n                annos['keypoints'].append(kpts)\n                annos['keypoints_visible'].append(data['keypoints_visible'])\n\n            if 'area' in data:\n                annos['area'].append(data['area'] * scale_ratio**2)\n\n        for key in annos:\n            annos[key] = np.concatenate(annos[key])\n        return mosaic_img, annos\n\n    def _mosaic_combine(\n        self, loc: str, center: Tuple[float, float], img_shape: Tuple[int, int]\n    ) -> Tuple[Tuple[int, int, int, int], Tuple[int, int, int, int]]:\n        \"\"\"Determine the overall coordinates of the mosaic image and the\n        specific coordinates of the cropped sub-image.\"\"\"\n\n        assert loc in ('top_left', 'top_right', 'bottom_left', 'bottom_right')\n\n        x1, y1, x2, y2 = 0, 0, 0, 0\n        cx, cy = center\n        w, h = img_shape\n\n        if loc == 'top_left':\n            x1, y1, x2, y2 = max(cx - w, 0), max(cy - h, 0), cx, cy\n            crop_coord = w - (x2 - x1), h - (y2 - y1), w, h\n        elif loc == 'top_right':\n            x1, y1, x2, y2 = cx, max(cy - h, 0), min(cx + w,\n                                                     self.img_scale[0] * 2), cy\n            crop_coord = 0, h - (y2 - y1), min(w, x2 - x1), h\n        elif loc == 'bottom_left':\n            x1, y1, x2, y2 = max(cx - w,\n                                 0), cy, cx, min(self.img_scale[1] * 2, cy + h)\n            crop_coord = w - (x2 - x1), 0, w, min(y2 - y1, h)\n        else:\n            x1, y1, x2, y2 = cx, cy, min(cx + w, self.img_scale[0] *\n                                         2), min(self.img_scale[1] * 2, cy + h)\n            crop_coord = 0, 0, min(w, x2 - x1), min(y2 - y1, h)\n\n        return (x1, y1, x2, y2), crop_coord\n\n    def __repr__(self) -> str:\n        repr_str = self.__class__.__name__\n        repr_str += f'(img_scale={self.img_scale}, '\n        repr_str += f'center_range={self.center_range}, '\n        repr_str += f'pad_val={self.pad_val}, '\n        repr_str += f'prob={self.prob})'\n        return repr_str\n\n\n@TRANSFORMS.register_module()\nclass YOLOXMixUp(MixImageTransform):\n    \"\"\"MixUp data augmentation for YOLOX. This transform combines two images\n    through mixup to enhance the dataset's diversity.\n\n    Mixup Transform Steps:\n\n        1. A random image is chosen from the dataset and placed in the\n            top-left corner of the target image (after padding and resizing).\n        2. The target of the mixup transform is obtained by taking the\n            weighted average of the mixup image and the original image.\n\n    .. code:: text\n\n                         mixup transform\n                +---------------+--------------+\n                | mixup image   |              |\n                |      +--------|--------+     |\n                |      |        |        |     |\n                +---------------+        |     |\n                |      |                 |     |\n                |      |      image      |     |\n                |      |                 |     |\n                |      |                 |     |\n                |      +-----------------+     |\n                |             pad              |\n                +------------------------------+\n\n    Required Keys:\n\n    - img\n    - bbox (optional)\n    - bbox_score (optional)\n    - category_id (optional)\n    - keypoints (optional)\n    - keypoints_visible (optional)\n    - area (optional)\n\n    Modified Keys:\n\n    - img\n    - bbox (optional)\n    - bbox_score (optional)\n    - category_id (optional)\n    - keypoints (optional)\n    - keypoints_visible (optional)\n    - area (optional)\n\n    Args:\n        img_scale (Sequence[int]): Image output size after mixup pipeline.\n            The shape order should be (width, height). Defaults to (640, 640).\n        ratio_range (Sequence[float]): Scale ratio of mixup image.\n            Defaults to (0.5, 1.5).\n        flip_ratio (float): Horizontal flip ratio of mixup image.\n            Defaults to 0.5.\n        pad_val (int): Pad value. Defaults to 114.\n        pre_transform (Optional[Sequence[str]]): A sequence of transform\n            to be applied before mixup. Defaults to None.\n        prob (float): Probability of applying the mixup transformation.\n            Defaults to 1.0.\n    \"\"\"\n    num_aux_image = 1\n\n    def __init__(self,\n                 img_scale: Tuple[int, int] = (640, 640),\n                 ratio_range: Tuple[float, float] = (0.5, 1.5),\n                 flip_ratio: float = 0.5,\n                 pad_val: float = 114.0,\n                 bbox_clip_border: bool = True,\n                 pre_transform: Sequence[dict] = None,\n                 prob: float = 1.0):\n        assert isinstance(img_scale, tuple)\n        super().__init__(pre_transform=pre_transform, prob=prob)\n        self.img_scale = img_scale\n        self.ratio_range = ratio_range\n        self.flip_ratio = flip_ratio\n        self.pad_val = pad_val\n        self.bbox_clip_border = bbox_clip_border\n\n    def apply_mix(self, results: dict) -> dict:\n        \"\"\"YOLOX MixUp transform function.\"\"\"\n\n        assert 'mixed_data_list' in results\n        mixed_data_list = results.pop('mixed_data_list')\n        assert len(mixed_data_list) == self.num_aux_image\n\n        if mixed_data_list[0]['keypoints'].shape[0] == 0:\n            return results\n\n        img, annos = self._create_mixup_image(results, mixed_data_list)\n        bboxes = annos['bboxes']\n        kpts = annos['keypoints']\n        kpts_vis = annos['keypoints_visible']\n\n        h, w = img.shape[:2]\n        bboxes = bbox_clip_border(bboxes, (w, h))\n        kpts, kpts_vis = keypoint_clip_border(kpts, kpts_vis, (w, h))\n\n        results['img'] = img.astype(np.uint8)\n        results['img_shape'] = img.shape\n        results['bbox'] = bboxes\n        results['category_id'] = annos['category_id']\n        results['bbox_score'] = annos['bbox_scores']\n        results['keypoints'] = kpts\n        results['keypoints_visible'] = kpts_vis\n        results['area'] = annos['area']\n\n        return results\n\n    def _create_mixup_image(self, results, mixed_data_list):\n        \"\"\"Create the mixup image and corresponding annotations by combining\n        two input images.\"\"\"\n\n        aux_results = mixed_data_list[0]\n        aux_img = aux_results['img']\n\n        # init mixup image\n        out_img = np.ones((self.img_scale[1], self.img_scale[0], 3),\n                          dtype=aux_img.dtype) * self.pad_val\n        annos = defaultdict(list)\n\n        # Calculate scale ratio and resize aux_img\n        scale_ratio = min(self.img_scale[1] / aux_img.shape[0],\n                          self.img_scale[0] / aux_img.shape[1])\n        aux_img = mmcv.imresize(aux_img, (int(aux_img.shape[1] * scale_ratio),\n                                          int(aux_img.shape[0] * scale_ratio)))\n\n        # Set the resized aux_img in the top-left of out_img\n        out_img[:aux_img.shape[0], :aux_img.shape[1]] = aux_img\n\n        # random rescale\n        jit_factor = random.uniform(*self.ratio_range)\n        scale_ratio *= jit_factor\n        out_img = mmcv.imresize(out_img, (int(out_img.shape[1] * jit_factor),\n                                          int(out_img.shape[0] * jit_factor)))\n\n        # random flip\n        is_filp = random.uniform(0, 1) > self.flip_ratio\n        if is_filp:\n            out_img = out_img[:, ::-1, :]\n\n        # random crop\n        ori_img = results['img']\n        aux_h, aux_w = out_img.shape[:2]\n        h, w = ori_img.shape[:2]\n        padded_img = np.ones((max(aux_h, h), max(aux_w, w), 3)) * self.pad_val\n        padded_img = padded_img.astype(np.uint8)\n        padded_img[:aux_h, :aux_w] = out_img\n\n        dy = random.randint(0, max(0, padded_img.shape[0] - h) + 1)\n        dx = random.randint(0, max(0, padded_img.shape[1] - w) + 1)\n        padded_cropped_img = padded_img[dy:dy + h, dx:dx + w]\n\n        # mix up\n        mixup_img = 0.5 * ori_img + 0.5 * padded_cropped_img\n\n        # merge annotations\n        # bboxes\n        bboxes = aux_results['bbox'].copy()\n        bboxes *= scale_ratio\n        bboxes = bbox_clip_border(bboxes, (aux_w, aux_h))\n        if is_filp:\n            bboxes = flip_bbox(bboxes, [aux_w, aux_h], 'xyxy')\n        bboxes[..., ::2] -= dx\n        bboxes[..., 1::2] -= dy\n        annos['bboxes'] = [results['bbox'], bboxes]\n        annos['bbox_scores'] = [\n            results['bbox_score'], aux_results['bbox_score']\n        ]\n        annos['category_id'] = [\n            results['category_id'], aux_results['category_id']\n        ]\n\n        # keypoints\n        kpts = aux_results['keypoints'] * scale_ratio\n        kpts, kpts_vis = keypoint_clip_border(kpts,\n                                              aux_results['keypoints_visible'],\n                                              (aux_w, aux_h))\n        if is_filp:\n            kpts, kpts_vis = flip_keypoints(kpts, kpts_vis, (aux_w, aux_h),\n                                            aux_results['flip_indices'])\n        kpts[..., 0] -= dx\n        kpts[..., 1] -= dy\n        annos['keypoints'] = [results['keypoints'], kpts]\n        annos['keypoints_visible'] = [results['keypoints_visible'], kpts_vis]\n        annos['area'] = [results['area'], aux_results['area'] * scale_ratio**2]\n\n        for key in annos:\n            annos[key] = np.concatenate(annos[key])\n\n        return mixup_img, annos\n\n    def __repr__(self) -> str:\n        repr_str = self.__class__.__name__\n        repr_str += f'(img_scale={self.img_scale}, '\n        repr_str += f'ratio_range={self.ratio_range}, '\n        repr_str += f'flip_ratio={self.flip_ratio}, '\n        repr_str += f'pad_val={self.pad_val})'\n        return repr_str\n"
  },
  {
    "path": "mmpose/datasets/transforms/pose3d_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\nfrom typing import Dict\n\nimport numpy as np\nfrom mmcv.transforms import BaseTransform\n\nfrom mmpose.registry import TRANSFORMS\nfrom mmpose.structures.keypoint import flip_keypoints_custom_center\n\n\n@TRANSFORMS.register_module()\nclass RandomFlipAroundRoot(BaseTransform):\n    \"\"\"Data augmentation with random horizontal joint flip around a root joint.\n\n    Args:\n        keypoints_flip_cfg (dict): Configurations of the\n            ``flip_keypoints_custom_center`` function for ``keypoints``. Please\n            refer to the docstring of the ``flip_keypoints_custom_center``\n            function for more details.\n        target_flip_cfg (dict): Configurations of the\n            ``flip_keypoints_custom_center`` function for ``lifting_target``.\n            Please refer to the docstring of the\n            ``flip_keypoints_custom_center`` function for more details.\n        flip_prob (float): Probability of flip. Default: 0.5.\n        flip_camera (bool): Whether to flip horizontal distortion coefficients.\n            Default: ``False``.\n        flip_label (bool): Whether to flip labels instead of data.\n            Default: ``False``.\n\n    Required keys:\n        - keypoints or keypoint_labels\n        - lifting_target or lifting_target_label\n        - keypoints_visible or keypoint_labels_visible (optional)\n        - lifting_target_visible (optional)\n        - flip_indices (optional)\n\n    Modified keys:\n        - keypoints or keypoint_labels (optional)\n        - keypoints_visible or keypoint_labels_visible (optional)\n        - lifting_target or lifting_target_label (optional)\n        - lifting_target_visible (optional)\n        - camera_param (optional)\n    \"\"\"\n\n    def __init__(self,\n                 keypoints_flip_cfg: dict,\n                 target_flip_cfg: dict,\n                 flip_prob: float = 0.5,\n                 flip_camera: bool = False,\n                 flip_label: bool = False):\n        self.keypoints_flip_cfg = keypoints_flip_cfg\n        self.target_flip_cfg = target_flip_cfg\n        self.flip_prob = flip_prob\n        self.flip_camera = flip_camera\n        self.flip_label = flip_label\n\n    def transform(self, results: Dict) -> dict:\n        \"\"\"The transform function of :class:`RandomFlipAroundRoot`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n\n        if np.random.rand() <= self.flip_prob:\n            if self.flip_label:\n                assert 'keypoint_labels' in results\n                assert 'lifting_target_label' in results\n                keypoints_key = 'keypoint_labels'\n                keypoints_visible_key = 'keypoint_labels_visible'\n                target_key = 'lifting_target_label'\n            else:\n                assert 'keypoints' in results\n                assert 'lifting_target' in results\n                keypoints_key = 'keypoints'\n                keypoints_visible_key = 'keypoints_visible'\n                target_key = 'lifting_target'\n\n            keypoints = results[keypoints_key]\n            if keypoints_visible_key in results:\n                keypoints_visible = results[keypoints_visible_key]\n            else:\n                keypoints_visible = np.ones(\n                    keypoints.shape[:-1], dtype=np.float32)\n\n            lifting_target = results[target_key]\n            if 'lifting_target_visible' in results:\n                lifting_target_visible = results['lifting_target_visible']\n            else:\n                lifting_target_visible = np.ones(\n                    lifting_target.shape[:-1], dtype=np.float32)\n\n            if 'flip_indices' not in results:\n                flip_indices = list(range(self.num_keypoints))\n            else:\n                flip_indices = results['flip_indices']\n\n            # flip joint coordinates\n            _camera_param = deepcopy(results['camera_param'])\n\n            keypoints, keypoints_visible = flip_keypoints_custom_center(\n                keypoints,\n                keypoints_visible,\n                flip_indices,\n                center_mode=self.keypoints_flip_cfg.get(\n                    'center_mode', 'static'),\n                center_x=self.keypoints_flip_cfg.get('center_x', 0.5),\n                center_index=self.keypoints_flip_cfg.get('center_index', 0))\n            lifting_target, lifting_target_visible = flip_keypoints_custom_center(  # noqa\n                lifting_target,\n                lifting_target_visible,\n                flip_indices,\n                center_mode=self.target_flip_cfg.get('center_mode', 'static'),\n                center_x=self.target_flip_cfg.get('center_x', 0.5),\n                center_index=self.target_flip_cfg.get('center_index', 0))\n\n            results[keypoints_key] = keypoints\n            results[keypoints_visible_key] = keypoints_visible\n            results[target_key] = lifting_target\n            results['lifting_target_visible'] = lifting_target_visible\n\n            # flip horizontal distortion coefficients\n            if self.flip_camera:\n                assert 'camera_param' in results, \\\n                    'Camera parameters are missing.'\n\n                assert 'c' in _camera_param\n                _camera_param['c'][0] *= -1\n\n                if 'p' in _camera_param:\n                    _camera_param['p'][0] *= -1\n\n                results['camera_param'].update(_camera_param)\n\n        return results\n"
  },
  {
    "path": "mmpose/datasets/transforms/topdown_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, Optional, Tuple\n\nimport cv2\nimport numpy as np\nfrom mmcv.transforms import BaseTransform\nfrom mmengine import is_seq_of\n\nfrom mmpose.registry import TRANSFORMS\nfrom mmpose.structures.bbox import get_udp_warp_matrix, get_warp_matrix\n\n\n@TRANSFORMS.register_module()\nclass TopdownAffine(BaseTransform):\n    \"\"\"Get the bbox image as the model input by affine transform.\n\n    Required Keys:\n\n        - img\n        - bbox_center\n        - bbox_scale\n        - bbox_rotation (optional)\n        - keypoints (optional)\n\n    Modified Keys:\n\n        - img\n        - bbox_scale\n\n    Added Keys:\n\n        - input_size\n        - transformed_keypoints\n\n    Args:\n        input_size (Tuple[int, int]): The input image size of the model in\n            [w, h]. The bbox region will be cropped and resize to `input_size`\n        use_udp (bool): Whether use unbiased data processing. See\n            `UDP (CVPR 2020)`_ for details. Defaults to ``False``\n\n    .. _`UDP (CVPR 2020)`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n\n    def __init__(self,\n                 input_size: Tuple[int, int],\n                 use_udp: bool = False) -> None:\n        super().__init__()\n\n        assert is_seq_of(input_size, int) and len(input_size) == 2, (\n            f'Invalid input_size {input_size}')\n\n        self.input_size = input_size\n        self.use_udp = use_udp\n\n    @staticmethod\n    def _fix_aspect_ratio(bbox_scale: np.ndarray, aspect_ratio: float):\n        \"\"\"Reshape the bbox to a fixed aspect ratio.\n\n        Args:\n            bbox_scale (np.ndarray): The bbox scales (w, h) in shape (n, 2)\n            aspect_ratio (float): The ratio of ``w/h``\n\n        Returns:\n            np.darray: The reshaped bbox scales in (n, 2)\n        \"\"\"\n\n        w, h = np.hsplit(bbox_scale, [1])\n        bbox_scale = np.where(w > h * aspect_ratio,\n                              np.hstack([w, w / aspect_ratio]),\n                              np.hstack([h * aspect_ratio, h]))\n        return bbox_scale\n\n    def transform(self, results: Dict) -> Optional[dict]:\n        \"\"\"The transform function of :class:`TopdownAffine`.\n\n        See ``transform()`` method of :class:`BaseTransform` for details.\n\n        Args:\n            results (dict): The result dict\n\n        Returns:\n            dict: The result dict.\n        \"\"\"\n\n        w, h = self.input_size\n        warp_size = (int(w), int(h))\n\n        # reshape bbox to fixed aspect ratio\n        results['bbox_scale'] = self._fix_aspect_ratio(\n            results['bbox_scale'], aspect_ratio=w / h)\n\n        # TODO: support multi-instance\n        assert results['bbox_center'].shape[0] == 1, (\n            'Top-down heatmap only supports single instance. Got invalid '\n            f'shape of bbox_center {results[\"bbox_center\"].shape}.')\n\n        center = results['bbox_center'][0]\n        scale = results['bbox_scale'][0]\n        if 'bbox_rotation' in results:\n            rot = results['bbox_rotation'][0]\n        else:\n            rot = 0.\n\n        if self.use_udp:\n            warp_mat = get_udp_warp_matrix(\n                center, scale, rot, output_size=(w, h))\n        else:\n            warp_mat = get_warp_matrix(center, scale, rot, output_size=(w, h))\n\n        if isinstance(results['img'], list):\n            results['img'] = [\n                cv2.warpAffine(\n                    img, warp_mat, warp_size, flags=cv2.INTER_LINEAR)\n                for img in results['img']\n            ]\n        else:\n            results['img'] = cv2.warpAffine(\n                results['img'], warp_mat, warp_size, flags=cv2.INTER_LINEAR)\n\n        if results.get('keypoints', None) is not None:\n            if results.get('transformed_keypoints', None) is not None:\n                transformed_keypoints = results['transformed_keypoints'].copy()\n            else:\n                transformed_keypoints = results['keypoints'].copy()\n            # Only transform (x, y) coordinates\n            transformed_keypoints[..., :2] = cv2.transform(\n                results['keypoints'][..., :2], warp_mat)\n            results['transformed_keypoints'] = transformed_keypoints\n        else:\n            results['transformed_keypoints'] = np.zeros([])\n            results['keypoints_visible'] = np.ones((1, 1, 1))\n\n        results['input_size'] = (w, h)\n        results['input_center'] = center\n        results['input_scale'] = scale\n\n        return results\n\n    def __repr__(self) -> str:\n        \"\"\"print the basic information of the transform.\n\n        Returns:\n            str: Formatted string.\n        \"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(input_size={self.input_size}, '\n        repr_str += f'use_udp={self.use_udp})'\n        return repr_str\n"
  },
  {
    "path": "mmpose/engine/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .hooks import *  # noqa: F401, F403\nfrom .optim_wrappers import *  # noqa: F401, F403\nfrom .schedulers import *  # noqa: F401, F403\n"
  },
  {
    "path": "mmpose/engine/hooks/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .badcase_hook import BadCaseAnalysisHook\nfrom .ema_hook import ExpMomentumEMA\nfrom .mode_switch_hooks import RTMOModeSwitchHook, YOLOXPoseModeSwitchHook\nfrom .sync_norm_hook import SyncNormHook\nfrom .visualization_hook import PoseVisualizationHook\n\n__all__ = [\n    'PoseVisualizationHook', 'ExpMomentumEMA', 'BadCaseAnalysisHook',\n    'YOLOXPoseModeSwitchHook', 'SyncNormHook', 'RTMOModeSwitchHook'\n]\n"
  },
  {
    "path": "mmpose/engine/hooks/badcase_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport logging\nimport os\nimport warnings\nfrom typing import Dict, Optional, Sequence\n\nimport mmcv\nimport mmengine\nimport mmengine.fileio as fileio\nimport torch\nfrom mmengine.config import ConfigDict\nfrom mmengine.hooks import Hook\nfrom mmengine.logging import print_log\nfrom mmengine.runner import Runner\nfrom mmengine.visualization import Visualizer\n\nfrom mmpose.registry import HOOKS, METRICS, MODELS\nfrom mmpose.structures import PoseDataSample, merge_data_samples\n\n\n@HOOKS.register_module()\nclass BadCaseAnalysisHook(Hook):\n    \"\"\"Bad Case Analyze Hook. Used to visualize validation and testing process\n    prediction results.\n\n    In the testing phase:\n\n    1. If ``show`` is True, it means that only the prediction results are\n        visualized without storing data, so ``vis_backends`` needs to\n        be excluded.\n    2. If ``out_dir`` is specified, it means that the prediction results\n        need to be saved to ``out_dir``. In order to avoid vis_backends\n        also storing data, so ``vis_backends`` needs to be excluded.\n    3. ``vis_backends`` takes effect if the user does not specify ``show``\n        and `out_dir``. You can set ``vis_backends`` to WandbVisBackend or\n        TensorboardVisBackend to store the prediction result in Wandb or\n        Tensorboard.\n\n    Args:\n        enable (bool): whether to draw prediction results. If it is False,\n            it means that no drawing will be done. Defaults to False.\n        show (bool): Whether to display the drawn image. Default to False.\n        wait_time (float): The interval of show (s). Defaults to 0.\n        interval (int): The interval of visualization. Defaults to 50.\n        kpt_thr (float): The threshold to visualize the keypoints.\n            Defaults to 0.3.\n        out_dir (str, optional): directory where painted images\n            will be saved in testing process.\n        backend_args (dict, optional): Arguments to instantiate the preifx of\n            uri corresponding backend. Defaults to None.\n        metric_type (str): the mretic type to decide a badcase,\n            loss or accuracy.\n        metric (ConfigDict): The config of metric.\n        metric_key (str): key of needed metric value in the return dict\n            from class 'metric'.\n        badcase_thr (float): min loss or max accuracy for a badcase.\n    \"\"\"\n\n    def __init__(\n        self,\n        enable: bool = False,\n        show: bool = False,\n        wait_time: float = 0.,\n        interval: int = 50,\n        kpt_thr: float = 0.3,\n        out_dir: Optional[str] = None,\n        backend_args: Optional[dict] = None,\n        metric_type: str = 'loss',\n        metric: ConfigDict = ConfigDict(type='KeypointMSELoss'),\n        metric_key: str = 'PCK',\n        badcase_thr: float = 5,\n    ):\n        self._visualizer: Visualizer = Visualizer.get_current_instance()\n        self.interval = interval\n        self.kpt_thr = kpt_thr\n        self.show = show\n        if self.show:\n            # No need to think about vis backends.\n            self._visualizer._vis_backends = {}\n            warnings.warn('The show is True, it means that only '\n                          'the prediction results are visualized '\n                          'without storing data, so vis_backends '\n                          'needs to be excluded.')\n\n        self.wait_time = wait_time\n        self.enable = enable\n        self.out_dir = out_dir\n        self._test_index = 0\n        self.backend_args = backend_args\n\n        self.metric_type = metric_type\n        if metric_type not in ['loss', 'accuracy']:\n            raise KeyError(\n                f'The badcase metric type {metric_type} is not supported by '\n                f\"{self.__class__.__name__}. Should be one of 'loss', \"\n                f\"'accuracy', but got {metric_type}.\")\n        self.metric = MODELS.build(metric) if metric_type == 'loss'\\\n            else METRICS.build(metric)\n        self.metric_name = metric.type if metric_type == 'loss'\\\n            else metric_key\n        self.metric_key = metric_key\n        self.badcase_thr = badcase_thr\n        self.results = []\n\n    def check_badcase(self, data_batch, data_sample):\n        \"\"\"Check whether the sample is a badcase.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        Return:\n            is_badcase (bool): whether the sample is a badcase or not\n            metric_value (float)\n        \"\"\"\n        if self.metric_type == 'loss':\n            gts = data_sample.gt_instances.keypoints\n            preds = data_sample.pred_instances.keypoints\n            weights = data_sample.gt_instances.keypoints_visible\n            with torch.no_grad():\n                metric_value = self.metric(\n                    torch.from_numpy(preds), torch.from_numpy(gts),\n                    torch.from_numpy(weights)).item()\n            is_badcase = metric_value >= self.badcase_thr\n        else:\n            self.metric.process([data_batch], [data_sample.to_dict()])\n            metric_value = self.metric.evaluate(1)[self.metric_key]\n            is_badcase = metric_value <= self.badcase_thr\n        return is_badcase, metric_value\n\n    def after_test_iter(self, runner: Runner, batch_idx: int, data_batch: dict,\n                        outputs: Sequence[PoseDataSample]) -> None:\n        \"\"\"Run after every testing iterations.\n\n        Args:\n            runner (:obj:`Runner`): The runner of the testing process.\n            batch_idx (int): The index of the current batch in the test loop.\n            data_batch (dict): Data from dataloader.\n            outputs (Sequence[:obj:`PoseDataSample`]): Outputs from model.\n        \"\"\"\n        if not self.enable:\n            return\n\n        if self.out_dir is not None:\n            self.out_dir = os.path.join(runner.work_dir, runner.timestamp,\n                                        self.out_dir)\n            mmengine.mkdir_or_exist(self.out_dir)\n\n        self._visualizer.set_dataset_meta(runner.test_evaluator.dataset_meta)\n\n        for data_sample in outputs:\n            self._test_index += 1\n\n            img_path = data_sample.get('img_path')\n            img_bytes = fileio.get(img_path, backend_args=self.backend_args)\n            img = mmcv.imfrombytes(img_bytes, channel_order='rgb')\n            data_sample = merge_data_samples([data_sample])\n\n            is_badcase, metric_value = self.check_badcase(\n                data_batch, data_sample)\n\n            if is_badcase:\n                img_name, postfix = os.path.basename(img_path).rsplit('.', 1)\n                bboxes = data_sample.gt_instances.bboxes.astype(int).tolist()\n                bbox_info = 'bbox' + str(bboxes)\n                metric_postfix = self.metric_name + str(round(metric_value, 2))\n\n                self.results.append({\n                    'img': img_name,\n                    'bbox': bboxes,\n                    self.metric_name: metric_value\n                })\n\n                badcase_name = f'{img_name}_{bbox_info}_{metric_postfix}'\n\n                out_file = None\n                if self.out_dir is not None:\n                    out_file = f'{badcase_name}.{postfix}'\n                    out_file = os.path.join(self.out_dir, out_file)\n\n                # draw gt keypoints in blue color\n                self._visualizer.kpt_color = 'blue'\n                self._visualizer.link_color = 'blue'\n                img_gt_drawn = self._visualizer.add_datasample(\n                    badcase_name if self.show else 'test_img',\n                    img,\n                    data_sample=data_sample,\n                    show=False,\n                    draw_pred=False,\n                    draw_gt=True,\n                    draw_bbox=False,\n                    draw_heatmap=False,\n                    wait_time=self.wait_time,\n                    kpt_thr=self.kpt_thr,\n                    out_file=None,\n                    step=self._test_index)\n                # draw pred keypoints in red color\n                self._visualizer.kpt_color = 'red'\n                self._visualizer.link_color = 'red'\n                self._visualizer.add_datasample(\n                    badcase_name if self.show else 'test_img',\n                    img_gt_drawn,\n                    data_sample=data_sample,\n                    show=self.show,\n                    draw_pred=True,\n                    draw_gt=False,\n                    draw_bbox=True,\n                    draw_heatmap=False,\n                    wait_time=self.wait_time,\n                    kpt_thr=self.kpt_thr,\n                    out_file=out_file,\n                    step=self._test_index)\n\n    def after_test_epoch(self,\n                         runner,\n                         metrics: Optional[Dict[str, float]] = None) -> None:\n        \"\"\"All subclasses should override this method, if they need any\n        operations after each test epoch.\n\n        Args:\n            runner (Runner): The runner of the testing process.\n            metrics (Dict[str, float], optional): Evaluation results of all\n                metrics on test dataset. The keys are the names of the\n                metrics, and the values are corresponding results.\n        \"\"\"\n        if not self.enable or not self.results:\n            return\n\n        mmengine.mkdir_or_exist(self.out_dir)\n        out_file = os.path.join(self.out_dir, 'results.json')\n        with open(out_file, 'w') as f:\n            json.dump(self.results, f)\n\n        print_log(\n            f'the bad cases are saved under {self.out_dir}',\n            logger='current',\n            level=logging.INFO)\n"
  },
  {
    "path": "mmpose/engine/hooks/ema_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nfrom mmengine.model import ExponentialMovingAverage\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass ExpMomentumEMA(ExponentialMovingAverage):\n    \"\"\"Exponential moving average (EMA) with exponential momentum strategy,\n    which is used in YOLOX.\n\n    Ported from ` the implementation of MMDetection\n    <https://github.com/open-mmlab/mmdetection/blob/3.x/mmdet/models/layers/ema.py>`_.\n\n    Args:\n        model (nn.Module): The model to be averaged.\n        momentum (float): The momentum used for updating ema parameter.\n            Ema's parameter are updated with the formula:\n           `averaged_param = (1-momentum) * averaged_param + momentum *\n           source_param`. Defaults to 0.0002.\n        gamma (int): Use a larger momentum early in training and gradually\n            annealing to a smaller value to update the ema model smoothly. The\n            momentum is calculated as\n            `(1 - momentum) * exp(-(1 + steps) / gamma) + momentum`.\n            Defaults to 2000.\n        interval (int): Interval between two updates. Defaults to 1.\n        device (torch.device, optional): If provided, the averaged model will\n            be stored on the :attr:`device`. Defaults to None.\n        update_buffers (bool): if True, it will compute running averages for\n            both the parameters and the buffers of the model. Defaults to\n            False.\n    \"\"\"\n\n    def __init__(self,\n                 model: nn.Module,\n                 momentum: float = 0.0002,\n                 gamma: int = 2000,\n                 interval=1,\n                 device: Optional[torch.device] = None,\n                 update_buffers: bool = False) -> None:\n        super().__init__(\n            model=model,\n            momentum=momentum,\n            interval=interval,\n            device=device,\n            update_buffers=update_buffers)\n        assert gamma > 0, f'gamma must be greater than 0, but got {gamma}'\n        self.gamma = gamma\n\n    def avg_func(self, averaged_param: Tensor, source_param: Tensor,\n                 steps: int) -> None:\n        \"\"\"Compute the moving average of the parameters using the exponential\n        momentum strategy.\n\n        Args:\n            averaged_param (Tensor): The averaged parameters.\n            source_param (Tensor): The source parameters.\n            steps (int): The number of times the parameters have been\n                updated.\n        \"\"\"\n        momentum = (1 - self.momentum) * math.exp(\n            -float(1 + steps) / self.gamma) + self.momentum\n        averaged_param.mul_(1 - momentum).add_(source_param, alpha=momentum)\n"
  },
  {
    "path": "mmpose/engine/hooks/mode_switch_hooks.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nfrom typing import Dict, Sequence\n\nfrom mmengine.hooks import Hook\nfrom mmengine.model import is_model_wrapper\nfrom mmengine.runner import Runner\n\nfrom mmpose.registry import HOOKS\nfrom mmpose.utils.hooks import rgetattr, rsetattr\n\n\n@HOOKS.register_module()\nclass YOLOXPoseModeSwitchHook(Hook):\n    \"\"\"Switch the mode of YOLOX-Pose during training.\n\n    This hook:\n    1) Turns off mosaic and mixup data augmentation.\n    2) Uses instance mask to assist positive anchor selection.\n    3) Uses auxiliary L1 loss in the head.\n\n    Args:\n        num_last_epochs (int): The number of last epochs at the end of\n            training to close the data augmentation and switch to L1 loss.\n            Defaults to 20.\n        new_train_dataset (dict): New training dataset configuration that\n            will be used in place of the original training dataset. Defaults\n            to None.\n        new_train_pipeline (Sequence[dict]): New data augmentation pipeline\n            configuration that will be used in place of the original pipeline\n            during training. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 num_last_epochs: int = 20,\n                 new_train_dataset: dict = None,\n                 new_train_pipeline: Sequence[dict] = None):\n        self.num_last_epochs = num_last_epochs\n        self.new_train_dataset = new_train_dataset\n        self.new_train_pipeline = new_train_pipeline\n\n    def _modify_dataloader(self, runner: Runner):\n        \"\"\"Modify dataloader with new dataset and pipeline configurations.\"\"\"\n        runner.logger.info(f'New Pipeline: {self.new_train_pipeline}')\n\n        train_dataloader_cfg = copy.deepcopy(runner.cfg.train_dataloader)\n        if self.new_train_dataset:\n            train_dataloader_cfg.dataset = self.new_train_dataset\n        if self.new_train_pipeline:\n            train_dataloader_cfg.dataset.pipeline = self.new_train_pipeline\n\n        new_train_dataloader = Runner.build_dataloader(train_dataloader_cfg)\n        runner.train_loop.dataloader = new_train_dataloader\n        runner.logger.info('Recreated the dataloader!')\n\n    def before_train_epoch(self, runner: Runner):\n        \"\"\"Close mosaic and mixup augmentation, switch to use L1 loss.\"\"\"\n        epoch = runner.epoch\n        model = runner.model\n        if is_model_wrapper(model):\n            model = model.module\n\n        if epoch + 1 == runner.max_epochs - self.num_last_epochs:\n            self._modify_dataloader(runner)\n            runner.logger.info('Added additional reg loss now!')\n            model.head.use_aux_loss = True\n\n\n@HOOKS.register_module()\nclass RTMOModeSwitchHook(Hook):\n    \"\"\"A hook to switch the mode of RTMO during training.\n\n    This hook allows for dynamic adjustments of model attributes at specified\n    training epochs. It is designed to modify configurations such as turning\n    off specific augmentations or changing loss functions at different stages\n    of the training process.\n\n    Args:\n        epoch_attributes (Dict[str, Dict]): A dictionary where keys are epoch\n        numbers and values are attribute modification dictionaries. Each\n        dictionary specifies the attribute to modify and its new value.\n\n    Example:\n        epoch_attributes = {\n            5: [{\"attr1.subattr\": new_value1}, {\"attr2.subattr\": new_value2}],\n            10: [{\"attr3.subattr\": new_value3}]\n        }\n    \"\"\"\n\n    def __init__(self, epoch_attributes: Dict[int, Dict]):\n        self.epoch_attributes = epoch_attributes\n\n    def before_train_epoch(self, runner: Runner):\n        \"\"\"Method called before each training epoch.\n\n        It checks if the current epoch is in the `epoch_attributes` mapping and\n        applies the corresponding attribute changes to the model.\n        \"\"\"\n        epoch = runner.epoch\n        model = runner.model\n        if is_model_wrapper(model):\n            model = model.module\n\n        if epoch in self.epoch_attributes:\n            for key, value in self.epoch_attributes[epoch].items():\n                rsetattr(model.head, key, value)\n                runner.logger.info(\n                    f'Change model.head.{key} to {rgetattr(model.head, key)}')\n"
  },
  {
    "path": "mmpose/engine/hooks/sync_norm_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import OrderedDict\n\nfrom mmengine.dist import all_reduce_dict, get_dist_info\nfrom mmengine.hooks import Hook\nfrom torch import nn\n\nfrom mmpose.registry import HOOKS\n\n\ndef get_norm_states(module: nn.Module) -> OrderedDict:\n    \"\"\"Get the state_dict of batch norms in the module.\"\"\"\n    async_norm_states = OrderedDict()\n    for name, child in module.named_modules():\n        if isinstance(child, nn.modules.batchnorm._NormBase):\n            for k, v in child.state_dict().items():\n                async_norm_states['.'.join([name, k])] = v\n    return async_norm_states\n\n\n@HOOKS.register_module()\nclass SyncNormHook(Hook):\n    \"\"\"Synchronize Norm states before validation.\"\"\"\n\n    def before_val_epoch(self, runner):\n        \"\"\"Synchronize normalization statistics.\"\"\"\n        module = runner.model\n        rank, world_size = get_dist_info()\n\n        if world_size == 1:\n            return\n\n        norm_states = get_norm_states(module)\n        if len(norm_states) == 0:\n            return\n\n        try:\n            norm_states = all_reduce_dict(norm_states, op='mean')\n            module.load_state_dict(norm_states, strict=True)\n        except Exception as e:\n            runner.logger.warn(f'SyncNormHook failed: {str(e)}')\n"
  },
  {
    "path": "mmpose/engine/hooks/visualization_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport warnings\nfrom typing import Optional, Sequence\n\nimport mmcv\nimport mmengine\nimport mmengine.fileio as fileio\nfrom mmengine.hooks import Hook\nfrom mmengine.runner import Runner\nfrom mmengine.visualization import Visualizer\n\nfrom mmpose.registry import HOOKS\nfrom mmpose.structures import PoseDataSample, merge_data_samples\n\n\n@HOOKS.register_module()\nclass PoseVisualizationHook(Hook):\n    \"\"\"Pose Estimation Visualization Hook. Used to visualize validation and\n    testing process prediction results.\n\n    In the testing phase:\n\n    1. If ``show`` is True, it means that only the prediction results are\n        visualized without storing data, so ``vis_backends`` needs to\n        be excluded.\n    2. If ``out_dir`` is specified, it means that the prediction results\n        need to be saved to ``out_dir``. In order to avoid vis_backends\n        also storing data, so ``vis_backends`` needs to be excluded.\n    3. ``vis_backends`` takes effect if the user does not specify ``show``\n        and `out_dir``. You can set ``vis_backends`` to WandbVisBackend or\n        TensorboardVisBackend to store the prediction result in Wandb or\n        Tensorboard.\n\n    Args:\n        enable (bool): whether to draw prediction results. If it is False,\n            it means that no drawing will be done. Defaults to False.\n        interval (int): The interval of visualization. Defaults to 50.\n        score_thr (float): The threshold to visualize the bboxes\n            and masks. Defaults to 0.3.\n        show (bool): Whether to display the drawn image. Default to False.\n        wait_time (float): The interval of show (s). Defaults to 0.\n        out_dir (str, optional): directory where painted images\n            will be saved in testing process.\n        backend_args (dict, optional): Arguments to instantiate the preifx of\n            uri corresponding backend. Defaults to None.\n    \"\"\"\n\n    def __init__(\n        self,\n        enable: bool = False,\n        interval: int = 50,\n        kpt_thr: float = 0.3,\n        show: bool = False,\n        wait_time: float = 0.,\n        out_dir: Optional[str] = None,\n        backend_args: Optional[dict] = None,\n    ):\n        self._visualizer: Visualizer = Visualizer.get_current_instance()\n        self.interval = interval\n        self.kpt_thr = kpt_thr\n        self.show = show\n        if self.show:\n            # No need to think about vis backends.\n            self._visualizer._vis_backends = {}\n            warnings.warn('The show is True, it means that only '\n                          'the prediction results are visualized '\n                          'without storing data, so vis_backends '\n                          'needs to be excluded.')\n\n        self.wait_time = wait_time\n        self.enable = enable\n        self.out_dir = out_dir\n        self._test_index = 0\n        self.backend_args = backend_args\n\n    def after_val_iter(self, runner: Runner, batch_idx: int, data_batch: dict,\n                       outputs: Sequence[PoseDataSample]) -> None:\n        \"\"\"Run after every ``self.interval`` validation iterations.\n\n        Args:\n            runner (:obj:`Runner`): The runner of the validation process.\n            batch_idx (int): The index of the current batch in the val loop.\n            data_batch (dict): Data from dataloader.\n            outputs (Sequence[:obj:`PoseDataSample`]): Outputs from model.\n        \"\"\"\n        if self.enable is False:\n            return\n\n        self._visualizer.set_dataset_meta(runner.val_evaluator.dataset_meta)\n\n        # There is no guarantee that the same batch of images\n        # is visualized for each evaluation.\n        total_curr_iter = runner.iter + batch_idx\n\n        # Visualize only the first data\n        img_path = data_batch['data_samples'][0].get('img_path')\n        img_bytes = fileio.get(img_path, backend_args=self.backend_args)\n        img = mmcv.imfrombytes(img_bytes, channel_order='rgb')\n        data_sample = outputs[0]\n\n        # revert the heatmap on the original image\n        data_sample = merge_data_samples([data_sample])\n\n        if total_curr_iter % self.interval == 0:\n            self._visualizer.add_datasample(\n                os.path.basename(img_path) if self.show else 'val_img',\n                img,\n                data_sample=data_sample,\n                draw_gt=False,\n                draw_bbox=True,\n                draw_heatmap=True,\n                show=self.show,\n                wait_time=self.wait_time,\n                kpt_thr=self.kpt_thr,\n                step=total_curr_iter)\n\n    def after_test_iter(self, runner: Runner, batch_idx: int, data_batch: dict,\n                        outputs: Sequence[PoseDataSample]) -> None:\n        \"\"\"Run after every testing iterations.\n\n        Args:\n            runner (:obj:`Runner`): The runner of the testing process.\n            batch_idx (int): The index of the current batch in the test loop.\n            data_batch (dict): Data from dataloader.\n            outputs (Sequence[:obj:`PoseDataSample`]): Outputs from model.\n        \"\"\"\n        if self.enable is False:\n            return\n\n        if self.out_dir is not None:\n            self.out_dir = os.path.join(runner.work_dir, runner.timestamp,\n                                        self.out_dir)\n            mmengine.mkdir_or_exist(self.out_dir)\n\n        self._visualizer.set_dataset_meta(runner.test_evaluator.dataset_meta)\n\n        for data_sample in outputs:\n            self._test_index += 1\n\n            img_path = data_sample.get('img_path')\n            img_bytes = fileio.get(img_path, backend_args=self.backend_args)\n            img = mmcv.imfrombytes(img_bytes, channel_order='rgb')\n            data_sample = merge_data_samples([data_sample])\n\n            out_file = None\n            if self.out_dir is not None:\n                out_file_name, postfix = os.path.basename(img_path).rsplit(\n                    '.', 1)\n                index = len([\n                    fname for fname in os.listdir(self.out_dir)\n                    if fname.startswith(out_file_name)\n                ])\n                out_file = f'{out_file_name}_{index}.{postfix}'\n                out_file = os.path.join(self.out_dir, out_file)\n\n            self._visualizer.add_datasample(\n                os.path.basename(img_path) if self.show else 'test_img',\n                img,\n                data_sample=data_sample,\n                show=self.show,\n                draw_gt=False,\n                draw_bbox=True,\n                draw_heatmap=True,\n                wait_time=self.wait_time,\n                kpt_thr=self.kpt_thr,\n                out_file=out_file,\n                step=self._test_index)\n"
  },
  {
    "path": "mmpose/engine/optim_wrappers/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .force_default_constructor import ForceDefaultOptimWrapperConstructor\nfrom .layer_decay_optim_wrapper import LayerDecayOptimWrapperConstructor\n\n__all__ = [\n    'LayerDecayOptimWrapperConstructor', 'ForceDefaultOptimWrapperConstructor'\n]\n"
  },
  {
    "path": "mmpose/engine/optim_wrappers/force_default_constructor.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nfrom typing import List, Optional, Union\n\nimport torch\nimport torch.nn as nn\nfrom mmengine.logging import print_log\nfrom mmengine.optim import DefaultOptimWrapperConstructor\nfrom mmengine.utils.dl_utils import mmcv_full_available\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm, _InstanceNorm\nfrom torch.nn import GroupNorm, LayerNorm\n\nfrom mmpose.registry import OPTIM_WRAPPER_CONSTRUCTORS\n\n\n@OPTIM_WRAPPER_CONSTRUCTORS.register_module()\nclass ForceDefaultOptimWrapperConstructor(DefaultOptimWrapperConstructor):\n    \"\"\"Default constructor with forced optimizer settings.\n\n    This constructor extends the default constructor to add an option for\n    forcing default optimizer settings. This is useful for ensuring that\n    certain parameters or layers strictly adhere to pre-defined default\n    settings, regardless of any custom settings specified.\n\n    By default, each parameter share the same optimizer settings, and we\n    provide an argument ``paramwise_cfg`` to specify parameter-wise settings.\n    It is a dict and may contain various fields like 'custom_keys',\n    'bias_lr_mult', etc., as well as the additional field\n    `force_default_settings` which allows for enforcing default settings on\n    optimizer parameters.\n\n    - ``custom_keys`` (dict): Specified parameters-wise settings by keys. If\n      one of the keys in ``custom_keys`` is a substring of the name of one\n      parameter, then the setting of the parameter will be specified by\n      ``custom_keys[key]`` and other setting like ``bias_lr_mult`` etc. will\n      be ignored. It should be noted that the aforementioned ``key`` is the\n      longest key that is a substring of the name of the parameter. If there\n      are multiple matched keys with the same length, then the key with lower\n      alphabet order will be chosen.\n      ``custom_keys[key]`` should be a dict and may contain fields ``lr_mult``\n      and ``decay_mult``. See Example 2 below.\n    - ``bias_lr_mult`` (float): It will be multiplied to the learning\n      rate for all bias parameters (except for those in normalization\n      layers and offset layers of DCN).\n    - ``bias_decay_mult`` (float): It will be multiplied to the weight\n      decay for all bias parameters (except for those in\n      normalization layers, depthwise conv layers, offset layers of DCN).\n    - ``norm_decay_mult`` (float): It will be multiplied to the weight\n      decay for all weight and bias parameters of normalization\n      layers.\n    - ``flat_decay_mult`` (float): It will be multiplied to the weight\n      decay for all one-dimensional parameters\n    - ``dwconv_decay_mult`` (float): It will be multiplied to the weight\n      decay for all weight and bias parameters of depthwise conv\n      layers.\n    - ``dcn_offset_lr_mult`` (float): It will be multiplied to the learning\n      rate for parameters of offset layer in the deformable convs\n      of a model.\n    - ``bypass_duplicate`` (bool): If true, the duplicate parameters\n      would not be added into optimizer. Defaults to False.\n    - ``force_default_settings`` (bool): If true, this will override any\n      custom settings defined by ``custom_keys`` and enforce the use of\n      default settings for optimizer parameters like ``bias_lr_mult``.\n      This is particularly useful when you want to ensure that certain layers\n      or parameters adhere strictly to the pre-defined default settings.\n\n    Note:\n\n        1. If the option ``dcn_offset_lr_mult`` is used, the constructor will\n        override the effect of ``bias_lr_mult`` in the bias of offset layer.\n        So be careful when using both ``bias_lr_mult`` and\n        ``dcn_offset_lr_mult``. If you wish to apply both of them to the offset\n        layer in deformable convs, set ``dcn_offset_lr_mult`` to the original\n        ``dcn_offset_lr_mult`` * ``bias_lr_mult``.\n\n        2. If the option ``dcn_offset_lr_mult`` is used, the constructor will\n        apply it to all the DCN layers in the model. So be careful when the\n        model contains multiple DCN layers in places other than backbone.\n\n        3. When the option ``force_default_settings`` is true, it will override\n        any custom settings provided in ``custom_keys``. This ensures that the\n        default settings for the optimizer parameters are used.\n\n    Args:\n        optim_wrapper_cfg (dict): The config dict of the optimizer wrapper.\n\n            Required fields of ``optim_wrapper_cfg`` are\n\n            - ``type``: class name of the OptimizerWrapper\n            - ``optimizer``: The configuration of optimizer.\n\n            Optional fields of ``optim_wrapper_cfg`` are\n\n            - any arguments of the corresponding optimizer wrapper type,\n              e.g., accumulative_counts, clip_grad, etc.\n\n            Required fields of ``optimizer`` are\n\n            - `type`: class name of the optimizer.\n\n            Optional fields of ``optimizer`` are\n\n            - any arguments of the corresponding optimizer type, e.g.,\n              lr, weight_decay, momentum, etc.\n\n        paramwise_cfg (dict, optional): Parameter-wise options.\n\n    Example 1:\n        >>> model = torch.nn.modules.Conv1d(1, 1, 1)\n        >>> optim_wrapper_cfg = dict(\n        >>>     dict(type='OptimWrapper', optimizer=dict(type='SGD', lr=0.01,\n        >>>         momentum=0.9, weight_decay=0.0001))\n        >>> paramwise_cfg = dict(norm_decay_mult=0.)\n        >>> optim_wrapper_builder = DefaultOptimWrapperConstructor(\n        >>>     optim_wrapper_cfg, paramwise_cfg)\n        >>> optim_wrapper = optim_wrapper_builder(model)\n\n    Example 2:\n        >>> # assume model have attribute model.backbone and model.cls_head\n        >>> optim_wrapper_cfg = dict(type='OptimWrapper', optimizer=dict(\n        >>>     type='SGD', lr=0.01, weight_decay=0.95))\n        >>> paramwise_cfg = dict(custom_keys={\n        >>>     'backbone': dict(lr_mult=0.1, decay_mult=0.9)})\n        >>> optim_wrapper_builder = DefaultOptimWrapperConstructor(\n        >>>     optim_wrapper_cfg, paramwise_cfg)\n        >>> optim_wrapper = optim_wrapper_builder(model)\n        >>> # Then the `lr` and `weight_decay` for model.backbone is\n        >>> # (0.01 * 0.1, 0.95 * 0.9). `lr` and `weight_decay` for\n        >>> # model.cls_head is (0.01, 0.95).\n    \"\"\"\n\n    def add_params(self,\n                   params: List[dict],\n                   module: nn.Module,\n                   prefix: str = '',\n                   is_dcn_module: Optional[Union[int, float]] = None) -> None:\n        \"\"\"Add all parameters of module to the params list.\n\n        The parameters of the given module will be added to the list of param\n        groups, with specific rules defined by paramwise_cfg.\n\n        Args:\n            params (list[dict]): A list of param groups, it will be modified\n                in place.\n            module (nn.Module): The module to be added.\n            prefix (str): The prefix of the module\n            is_dcn_module (int|float|None): If the current module is a\n                submodule of DCN, `is_dcn_module` will be passed to\n                control conv_offset layer's learning rate. Defaults to None.\n        \"\"\"\n        # get param-wise options\n        custom_keys = self.paramwise_cfg.get('custom_keys', {})\n        # first sort with alphabet order and then sort with reversed len of str\n        sorted_keys = sorted(sorted(custom_keys.keys()), key=len, reverse=True)\n\n        bias_lr_mult = self.paramwise_cfg.get('bias_lr_mult', None)\n        bias_decay_mult = self.paramwise_cfg.get('bias_decay_mult', None)\n        norm_decay_mult = self.paramwise_cfg.get('norm_decay_mult', None)\n        dwconv_decay_mult = self.paramwise_cfg.get('dwconv_decay_mult', None)\n        flat_decay_mult = self.paramwise_cfg.get('flat_decay_mult', None)\n        bypass_duplicate = self.paramwise_cfg.get('bypass_duplicate', False)\n        dcn_offset_lr_mult = self.paramwise_cfg.get('dcn_offset_lr_mult', None)\n        force_default_settings = self.paramwise_cfg.get(\n            'force_default_settings', False)\n\n        # special rules for norm layers and depth-wise conv layers\n        is_norm = isinstance(module,\n                             (_BatchNorm, _InstanceNorm, GroupNorm, LayerNorm))\n        is_dwconv = (\n            isinstance(module, torch.nn.Conv2d)\n            and module.in_channels == module.groups)\n\n        for name, param in module.named_parameters(recurse=False):\n            param_group = {'params': [param]}\n            if bypass_duplicate and self._is_in(param_group, params):\n                print_log(\n                    f'{prefix} is duplicate. It is skipped since '\n                    f'bypass_duplicate={bypass_duplicate}',\n                    logger='current',\n                    level=logging.WARNING)\n                continue\n            if not param.requires_grad:\n                params.append(param_group)\n                continue\n\n            # if the parameter match one of the custom keys, ignore other rules\n            is_custom = False\n            for key in sorted_keys:\n                if key in f'{prefix}.{name}':\n                    is_custom = True\n                    lr_mult = custom_keys[key].get('lr_mult', 1.)\n                    param_group['lr'] = self.base_lr * lr_mult\n                    if self.base_wd is not None:\n                        decay_mult = custom_keys[key].get('decay_mult', 1.)\n                        param_group['weight_decay'] = self.base_wd * decay_mult\n                    # add custom settings to param_group\n                    for k, v in custom_keys[key].items():\n                        param_group[k] = v\n                    break\n\n            if not is_custom or force_default_settings:\n                # bias_lr_mult affects all bias parameters\n                # except for norm.bias dcn.conv_offset.bias\n                if name == 'bias' and not (\n                        is_norm or is_dcn_module) and bias_lr_mult is not None:\n                    param_group['lr'] = self.base_lr * bias_lr_mult\n\n                if (prefix.find('conv_offset') != -1 and is_dcn_module\n                        and dcn_offset_lr_mult is not None\n                        and isinstance(module, torch.nn.Conv2d)):\n                    # deal with both dcn_offset's bias & weight\n                    param_group['lr'] = self.base_lr * dcn_offset_lr_mult\n\n                # apply weight decay policies\n                if self.base_wd is not None:\n                    # norm decay\n                    if is_norm and norm_decay_mult is not None:\n                        param_group[\n                            'weight_decay'] = self.base_wd * norm_decay_mult\n                    # bias lr and decay\n                    elif (name == 'bias' and not is_dcn_module\n                          and bias_decay_mult is not None):\n                        param_group[\n                            'weight_decay'] = self.base_wd * bias_decay_mult\n                    # depth-wise conv\n                    elif is_dwconv and dwconv_decay_mult is not None:\n                        param_group[\n                            'weight_decay'] = self.base_wd * dwconv_decay_mult\n                    # flatten parameters except dcn offset\n                    elif (param.ndim == 1 and not is_dcn_module\n                          and flat_decay_mult is not None):\n                        param_group[\n                            'weight_decay'] = self.base_wd * flat_decay_mult\n            params.append(param_group)\n            for key, value in param_group.items():\n                if key == 'params':\n                    continue\n                full_name = f'{prefix}.{name}' if prefix else name\n                print_log(\n                    f'paramwise_options -- {full_name}:{key}={value}',\n                    logger='current')\n\n        if mmcv_full_available():\n            from mmcv.ops import DeformConv2d, ModulatedDeformConv2d\n            is_dcn_module = isinstance(module,\n                                       (DeformConv2d, ModulatedDeformConv2d))\n        else:\n            is_dcn_module = False\n        for child_name, child_mod in module.named_children():\n            child_prefix = f'{prefix}.{child_name}' if prefix else child_name\n            self.add_params(\n                params,\n                child_mod,\n                prefix=child_prefix,\n                is_dcn_module=is_dcn_module)\n"
  },
  {
    "path": "mmpose/engine/optim_wrappers/layer_decay_optim_wrapper.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.dist.utils import get_dist_info\nfrom mmengine.optim import DefaultOptimWrapperConstructor\nfrom mmengine.registry import OPTIM_WRAPPER_CONSTRUCTORS\n\n\ndef get_num_layer_for_vit(var_name, num_max_layer):\n    if var_name in ('backbone.cls_token', 'backbone.mask_token',\n                    'backbone.pos_embed'):\n        return 0\n    elif var_name.startswith('backbone.patch_embed'):\n        return 0\n    elif var_name.startswith('backbone.layers'):\n        layer_id = int(var_name.split('.')[2])\n        return layer_id + 1\n    else:\n        return num_max_layer - 1\n\n\n@OPTIM_WRAPPER_CONSTRUCTORS.register_module(force=True)\nclass LayerDecayOptimWrapperConstructor(DefaultOptimWrapperConstructor):\n\n    def __init__(self, optim_wrapper_cfg, paramwise_cfg=None):\n        super().__init__(optim_wrapper_cfg, paramwise_cfg=None)\n        self.layer_decay_rate = paramwise_cfg.get('layer_decay_rate', 0.5)\n\n        super().__init__(optim_wrapper_cfg, paramwise_cfg)\n\n    def add_params(self, params, module, prefix='', lr=None):\n        parameter_groups = {}\n        print(self.paramwise_cfg)\n        num_layers = self.paramwise_cfg.get('num_layers') + 2\n        layer_decay_rate = self.paramwise_cfg.get('layer_decay_rate')\n        weight_decay = self.base_wd\n\n        for name, param in module.named_parameters():\n            if not param.requires_grad:\n                continue  # frozen weights\n            if (len(param.shape) == 1 or name.endswith('.bias')\n                    or 'pos_embed' in name):\n                group_name = 'no_decay'\n                this_weight_decay = 0.\n            else:\n                group_name = 'decay'\n                this_weight_decay = weight_decay\n            layer_id = get_num_layer_for_vit(name, num_layers)\n            group_name = 'layer_%d_%s' % (layer_id, group_name)\n\n            if group_name not in parameter_groups:\n                scale = layer_decay_rate**(num_layers - layer_id - 1)\n\n                parameter_groups[group_name] = {\n                    'weight_decay': this_weight_decay,\n                    'params': [],\n                    'param_names': [],\n                    'lr_scale': scale,\n                    'group_name': group_name,\n                    'lr': scale * self.base_lr,\n                }\n\n            parameter_groups[group_name]['params'].append(param)\n            parameter_groups[group_name]['param_names'].append(name)\n        rank, _ = get_dist_info()\n        if rank == 0:\n            to_display = {}\n            for key in parameter_groups:\n                to_display[key] = {\n                    'param_names': parameter_groups[key]['param_names'],\n                    'lr_scale': parameter_groups[key]['lr_scale'],\n                    'lr': parameter_groups[key]['lr'],\n                    'weight_decay': parameter_groups[key]['weight_decay'],\n                }\n        params.extend(parameter_groups.values())\n"
  },
  {
    "path": "mmpose/engine/schedulers/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .constant_lr import ConstantLR\nfrom .quadratic_warmup import (QuadraticWarmupLR, QuadraticWarmupMomentum,\n                               QuadraticWarmupParamScheduler)\n\n__all__ = [\n    'QuadraticWarmupParamScheduler', 'QuadraticWarmupMomentum',\n    'QuadraticWarmupLR', 'ConstantLR'\n]\n"
  },
  {
    "path": "mmpose/engine/schedulers/constant_lr.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.optim.scheduler import \\\n    ConstantParamScheduler as MMENGINE_ConstantParamScheduler\nfrom mmengine.optim.scheduler.lr_scheduler import LRSchedulerMixin\n\nfrom mmpose.registry import PARAM_SCHEDULERS\n\nINF = int(1e9)\n\n\nclass ConstantParamScheduler(MMENGINE_ConstantParamScheduler):\n    \"\"\"Decays the parameter value of each parameter group by a small constant\n    factor until the number of epoch reaches a pre-defined milestone: ``end``.\n    Notice that such decay can happen simultaneously with other changes to the\n    parameter value from outside this scheduler. The factor range restriction\n    is removed.\n\n    Args:\n        optimizer (Optimizer or BaseOptimWrapper): optimizer or Wrapped\n            optimizer.\n        param_name (str): Name of the parameter to be adjusted, such as\n            ``lr``, ``momentum``.\n        factor (float): The number we multiply parameter value until the\n            milestone. Defaults to 1./3.\n        begin (int): Step at which to start updating the parameters.\n            Defaults to 0.\n        end (int): Step at which to stop updating the parameters.\n            Defaults to INF.\n        last_step (int): The index of last step. Used for resume without\n            state dict. Defaults to -1.\n        by_epoch (bool): Whether the scheduled parameters are updated by\n            epochs. Defaults to True.\n        verbose (bool): Whether to print the value for each update.\n            Defaults to False.\n    \"\"\"\n\n    def __init__(self,\n                 optimizer,\n                 param_name: str,\n                 factor: float = 1.0 / 3,\n                 begin: int = 0,\n                 end: int = INF,\n                 last_step: int = -1,\n                 by_epoch: bool = True,\n                 verbose: bool = False):\n\n        self.factor = factor\n        self.total_iters = end - begin - 1\n        super(MMENGINE_ConstantParamScheduler, self).__init__(\n            optimizer,\n            param_name=param_name,\n            begin=begin,\n            end=end,\n            last_step=last_step,\n            by_epoch=by_epoch,\n            verbose=verbose)\n\n\n@PARAM_SCHEDULERS.register_module()\nclass ConstantLR(LRSchedulerMixin, ConstantParamScheduler):\n    \"\"\"Decays the learning rate value of each parameter group by a small\n    constant factor until the number of epoch reaches a pre-defined milestone:\n    ``end``. Notice that such decay can happen simultaneously with other\n    changes to the learning rate value from outside this scheduler.\n\n    Args:\n        optimizer (Optimizer or OptimWrapper): Wrapped optimizer.\n        factor (float): The number we multiply learning rate until the\n            milestone. Defaults to 1./3.\n        begin (int): Step at which to start updating the learning rate.\n            Defaults to 0.\n        end (int): Step at which to stop updating the learning rate.\n            Defaults to INF.\n        last_step (int): The index of last step. Used for resume without state\n            dict. Defaults to -1.\n        by_epoch (bool): Whether the scheduled learning rate is updated by\n            epochs. Defaults to True.\n        verbose (bool): Whether to print the learning rate for each update.\n            Defaults to False.\n    \"\"\"\n"
  },
  {
    "path": "mmpose/engine/schedulers/quadratic_warmup.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.optim.scheduler.lr_scheduler import LRSchedulerMixin\nfrom mmengine.optim.scheduler.momentum_scheduler import MomentumSchedulerMixin\nfrom mmengine.optim.scheduler.param_scheduler import INF, _ParamScheduler\nfrom torch.optim import Optimizer\n\nfrom mmpose.registry import PARAM_SCHEDULERS\n\n\n@PARAM_SCHEDULERS.register_module()\nclass QuadraticWarmupParamScheduler(_ParamScheduler):\n    r\"\"\"Warm up the parameter value of each parameter group by quadratic\n    formula:\n\n    .. math::\n\n        X_{t} = X_{t-1} + \\frac{2t+1}{{(end-begin)}^{2}} \\times X_{base}\n\n    Args:\n        optimizer (Optimizer): Wrapped optimizer.\n        param_name (str): Name of the parameter to be adjusted, such as\n            ``lr``, ``momentum``.\n        begin (int): Step at which to start updating the parameters.\n            Defaults to 0.\n        end (int): Step at which to stop updating the parameters.\n            Defaults to INF.\n        last_step (int): The index of last step. Used for resume without\n            state dict. Defaults to -1.\n        by_epoch (bool): Whether the scheduled parameters are updated by\n            epochs. Defaults to True.\n        verbose (bool): Whether to print the value for each update.\n            Defaults to False.\n    \"\"\"\n\n    def __init__(self,\n                 optimizer: Optimizer,\n                 param_name: str,\n                 begin: int = 0,\n                 end: int = INF,\n                 last_step: int = -1,\n                 by_epoch: bool = True,\n                 verbose: bool = False):\n        if end >= INF:\n            raise ValueError('``end`` must be less than infinity,'\n                             'Please set ``end`` parameter of '\n                             '``QuadraticWarmupScheduler`` as the '\n                             'number of warmup end.')\n        self.total_iters = end - begin\n        super().__init__(\n            optimizer=optimizer,\n            param_name=param_name,\n            begin=begin,\n            end=end,\n            last_step=last_step,\n            by_epoch=by_epoch,\n            verbose=verbose)\n\n    @classmethod\n    def build_iter_from_epoch(cls,\n                              *args,\n                              begin=0,\n                              end=INF,\n                              by_epoch=True,\n                              epoch_length=None,\n                              **kwargs):\n        \"\"\"Build an iter-based instance of this scheduler from an epoch-based\n        config.\"\"\"\n        assert by_epoch, 'Only epoch-based kwargs whose `by_epoch=True` can ' \\\n                         'be converted to iter-based.'\n        assert epoch_length is not None and epoch_length > 0, \\\n            f'`epoch_length` must be a positive integer, ' \\\n            f'but got {epoch_length}.'\n        by_epoch = False\n        begin = begin * epoch_length\n        if end != INF:\n            end = end * epoch_length\n        return cls(*args, begin=begin, end=end, by_epoch=by_epoch, **kwargs)\n\n    def _get_value(self):\n        \"\"\"Compute value using chainable form of the scheduler.\"\"\"\n        if self.last_step == 0:\n            return [\n                base_value * (2 * self.last_step + 1) / self.total_iters**2\n                for base_value in self.base_values\n            ]\n\n        return [\n            group[self.param_name] + base_value *\n            (2 * self.last_step + 1) / self.total_iters**2\n            for base_value, group in zip(self.base_values,\n                                         self.optimizer.param_groups)\n        ]\n\n\n@PARAM_SCHEDULERS.register_module()\nclass QuadraticWarmupLR(LRSchedulerMixin, QuadraticWarmupParamScheduler):\n    \"\"\"Warm up the learning rate of each parameter group by quadratic formula.\n\n    Args:\n        optimizer (Optimizer): Wrapped optimizer.\n        begin (int): Step at which to start updating the parameters.\n            Defaults to 0.\n        end (int): Step at which to stop updating the parameters.\n            Defaults to INF.\n        last_step (int): The index of last step. Used for resume without\n            state dict. Defaults to -1.\n        by_epoch (bool): Whether the scheduled parameters are updated by\n            epochs. Defaults to True.\n        verbose (bool): Whether to print the value for each update.\n            Defaults to False.\n    \"\"\"\n\n\n@PARAM_SCHEDULERS.register_module()\nclass QuadraticWarmupMomentum(MomentumSchedulerMixin,\n                              QuadraticWarmupParamScheduler):\n    \"\"\"Warm up the momentum value of each parameter group by quadratic formula.\n\n    Args:\n        optimizer (Optimizer): Wrapped optimizer.\n        begin (int): Step at which to start updating the parameters.\n            Defaults to 0.\n        end (int): Step at which to stop updating the parameters.\n            Defaults to INF.\n        last_step (int): The index of last step. Used for resume without\n            state dict. Defaults to -1.\n        by_epoch (bool): Whether the scheduled parameters are updated by\n            epochs. Defaults to True.\n        verbose (bool): Whether to print the value for each update.\n            Defaults to False.\n    \"\"\"\n"
  },
  {
    "path": "mmpose/evaluation/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .evaluators import *  # noqa: F401,F403\nfrom .functional import *  # noqa: F401,F403\nfrom .metrics import *  # noqa: F401,F403\n"
  },
  {
    "path": "mmpose/evaluation/evaluators/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .mutli_dataset_evaluator import MultiDatasetEvaluator\n\n__all__ = ['MultiDatasetEvaluator']\n"
  },
  {
    "path": "mmpose/evaluation/evaluators/mutli_dataset_evaluator.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import defaultdict\nfrom typing import Any, Optional, Sequence, Union\n\nfrom mmengine.evaluator.evaluator import Evaluator\nfrom mmengine.evaluator.metric import BaseMetric\nfrom mmengine.structures import BaseDataElement\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.registry import DATASETS, EVALUATORS\n\n\n@EVALUATORS.register_module()\nclass MultiDatasetEvaluator(Evaluator):\n    \"\"\"Wrapper class to compose multiple :class:`BaseMetric` instances.\n\n    Args:\n        metrics (dict or BaseMetric or Sequence): The configs of metrics.\n        datasets (Sequence[str]): The configs of datasets.\n    \"\"\"\n\n    def __init__(\n        self,\n        metrics: Union[dict, BaseMetric, Sequence],\n        datasets: Sequence[dict],\n    ):\n\n        assert len(metrics) == len(datasets), 'the argument ' \\\n            'datasets should have same length as metrics'\n\n        super().__init__(metrics)\n\n        # Initialize metrics for each dataset\n        metrics_dict = dict()\n        for dataset, metric in zip(datasets, self.metrics):\n            metainfo_file = DATASETS.module_dict[dataset['type']].METAINFO\n            dataset_meta = parse_pose_metainfo(metainfo_file)\n            metric.dataset_meta = dataset_meta\n            metrics_dict[dataset_meta['dataset_name']] = metric\n        self.metrics_dict = metrics_dict\n\n    @property\n    def dataset_meta(self) -> Optional[dict]:\n        \"\"\"Optional[dict]: Meta info of the dataset.\"\"\"\n        return self._dataset_meta\n\n    @dataset_meta.setter\n    def dataset_meta(self, dataset_meta: dict) -> None:\n        \"\"\"Set the dataset meta info to the evaluator and it's metrics.\"\"\"\n        self._dataset_meta = dataset_meta\n\n    def process(self,\n                data_samples: Sequence[BaseDataElement],\n                data_batch: Optional[Any] = None):\n        \"\"\"Convert ``BaseDataSample`` to dict and invoke process method of each\n        metric.\n\n        Args:\n            data_samples (Sequence[BaseDataElement]): predictions of the model,\n                and the ground truth of the validation set.\n            data_batch (Any, optional): A batch of data from the dataloader.\n        \"\"\"\n        _data_samples = defaultdict(list)\n        _data_batch = dict(\n            inputs=defaultdict(list),\n            data_samples=defaultdict(list),\n        )\n\n        for inputs, data_ds, data_sample in zip(data_batch['inputs'],\n                                                data_batch['data_samples'],\n                                                data_samples):\n            if isinstance(data_sample, BaseDataElement):\n                data_sample = data_sample.to_dict()\n            assert isinstance(data_sample, dict)\n            dataset_name = data_sample.get('dataset_name',\n                                           self.dataset_meta['dataset_name'])\n            _data_samples[dataset_name].append(data_sample)\n            _data_batch['inputs'][dataset_name].append(inputs)\n            _data_batch['data_samples'][dataset_name].append(data_ds)\n\n        for dataset_name, metric in self.metrics_dict.items():\n            if dataset_name in _data_samples:\n                data_batch = dict(\n                    inputs=_data_batch['inputs'][dataset_name],\n                    data_samples=_data_batch['data_samples'][dataset_name])\n                metric.process(data_batch, _data_samples[dataset_name])\n            else:\n                continue\n"
  },
  {
    "path": "mmpose/evaluation/functional/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .keypoint_eval import (keypoint_auc, keypoint_epe, keypoint_mpjpe,\n                            keypoint_nme, keypoint_pck_accuracy,\n                            multilabel_classification_accuracy,\n                            pose_pck_accuracy, simcc_pck_accuracy)\nfrom .nms import nearby_joints_nms, nms, nms_torch, oks_nms, soft_oks_nms\nfrom .transforms import transform_ann, transform_pred, transform_sigmas\n\n__all__ = [\n    'keypoint_pck_accuracy', 'keypoint_auc', 'keypoint_nme', 'keypoint_epe',\n    'pose_pck_accuracy', 'multilabel_classification_accuracy',\n    'simcc_pck_accuracy', 'nms', 'oks_nms', 'soft_oks_nms', 'keypoint_mpjpe',\n    'nms_torch', 'transform_ann', 'transform_sigmas', 'transform_pred',\n    'nearby_joints_nms'\n]\n"
  },
  {
    "path": "mmpose/evaluation/functional/keypoint_eval.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.codecs.utils import get_heatmap_maximum, get_simcc_maximum\nfrom .mesh_eval import compute_similarity_transform\n\n\ndef _calc_distances(preds: np.ndarray, gts: np.ndarray, mask: np.ndarray,\n                    norm_factor: np.ndarray) -> np.ndarray:\n    \"\"\"Calculate the normalized distances between preds and target.\n\n    Note:\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D (normally, D=2 or D=3)\n\n    Args:\n        preds (np.ndarray[N, K, D]): Predicted keypoint location.\n        gts (np.ndarray[N, K, D]): Groundtruth keypoint location.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n        norm_factor (np.ndarray[N, D]): Normalization factor.\n            Typical value is heatmap_size.\n\n    Returns:\n        np.ndarray[K, N]: The normalized distances. \\\n            If target keypoints are missing, the distance is -1.\n    \"\"\"\n    N, K, _ = preds.shape\n    # set mask=0 when norm_factor==0\n    _mask = mask.copy()\n    _mask[np.where((norm_factor == 0).sum(1))[0], :] = False\n\n    distances = np.full((N, K), -1, dtype=np.float32)\n    # handle invalid values\n    norm_factor[np.where(norm_factor <= 0)] = 1e6\n    distances[_mask] = np.linalg.norm(\n        ((preds - gts) / norm_factor[:, None, :])[_mask], axis=-1)\n    return distances.T\n\n\ndef _distance_acc(distances: np.ndarray, thr: float = 0.5) -> float:\n    \"\"\"Return the percentage below the distance threshold, while ignoring\n    distances values with -1.\n\n    Note:\n        - instance number: N\n\n    Args:\n        distances (np.ndarray[N, ]): The normalized distances.\n        thr (float): Threshold of the distances.\n\n    Returns:\n        float: Percentage of distances below the threshold. \\\n            If all target keypoints are missing, return -1.\n    \"\"\"\n    distance_valid = distances != -1\n    num_distance_valid = distance_valid.sum()\n    if num_distance_valid > 0:\n        return (distances[distance_valid] < thr).sum() / num_distance_valid\n    return -1\n\n\ndef keypoint_pck_accuracy(pred: np.ndarray, gt: np.ndarray, mask: np.ndarray,\n                          thr: np.ndarray, norm_factor: np.ndarray) -> tuple:\n    \"\"\"Calculate the pose accuracy of PCK for each individual keypoint and the\n    averaged accuracy across all keypoints for coordinates.\n\n    Note:\n        PCK metric measures accuracy of the localization of the body joints.\n        The distances between predicted positions and the ground-truth ones\n        are typically normalized by the bounding box size.\n        The threshold (thr) of the normalized distance is commonly set\n        as 0.05, 0.1 or 0.2 etc.\n\n        - instance number: N\n        - keypoint number: K\n\n    Args:\n        pred (np.ndarray[N, K, 2]): Predicted keypoint location.\n        gt (np.ndarray[N, K, 2]): Groundtruth keypoint location.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n        thr (float): Threshold of PCK calculation.\n        norm_factor (np.ndarray[N, 2]): Normalization factor for H&W.\n\n    Returns:\n        tuple: A tuple containing keypoint accuracy.\n\n        - acc (np.ndarray[K]): Accuracy of each keypoint.\n        - avg_acc (float): Averaged accuracy across all keypoints.\n        - cnt (int): Number of valid keypoints.\n    \"\"\"\n    distances = _calc_distances(pred, gt, mask, norm_factor)\n    acc = np.array([_distance_acc(d, thr) for d in distances])\n    valid_acc = acc[acc >= 0]\n    cnt = len(valid_acc)\n    avg_acc = valid_acc.mean() if cnt > 0 else 0.0\n    return acc, avg_acc, cnt\n\n\ndef keypoint_auc(pred: np.ndarray,\n                 gt: np.ndarray,\n                 mask: np.ndarray,\n                 norm_factor: np.ndarray,\n                 num_thrs: int = 20) -> float:\n    \"\"\"Calculate the Area under curve (AUC) of keypoint PCK accuracy.\n\n    Note:\n        - instance number: N\n        - keypoint number: K\n\n    Args:\n        pred (np.ndarray[N, K, 2]): Predicted keypoint location.\n        gt (np.ndarray[N, K, 2]): Groundtruth keypoint location.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n        norm_factor (float): Normalization factor.\n        num_thrs (int): number of thresholds to calculate auc.\n\n    Returns:\n        float: Area under curve (AUC) of keypoint PCK accuracy.\n    \"\"\"\n    nor = np.tile(np.array([[norm_factor, norm_factor]]), (pred.shape[0], 1))\n    thrs = [1.0 * i / num_thrs for i in range(num_thrs)]\n    avg_accs = []\n    for thr in thrs:\n        _, avg_acc, _ = keypoint_pck_accuracy(pred, gt, mask, thr, nor)\n        avg_accs.append(avg_acc)\n\n    auc = 0\n    for i in range(num_thrs):\n        auc += 1.0 / num_thrs * avg_accs[i]\n    return auc\n\n\ndef keypoint_nme(pred: np.ndarray, gt: np.ndarray, mask: np.ndarray,\n                 normalize_factor: np.ndarray) -> float:\n    \"\"\"Calculate the normalized mean error (NME).\n\n    Note:\n        - instance number: N\n        - keypoint number: K\n\n    Args:\n        pred (np.ndarray[N, K, 2]): Predicted keypoint location.\n        gt (np.ndarray[N, K, 2]): Groundtruth keypoint location.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n        normalize_factor (np.ndarray[N, 2]): Normalization factor.\n\n    Returns:\n        float: normalized mean error\n    \"\"\"\n    distances = _calc_distances(pred, gt, mask, normalize_factor)\n    distance_valid = distances[distances != -1]\n    return distance_valid.sum() / max(1, len(distance_valid))\n\n\ndef keypoint_epe(pred: np.ndarray, gt: np.ndarray, mask: np.ndarray) -> float:\n    \"\"\"Calculate the end-point error.\n\n    Note:\n        - instance number: N\n        - keypoint number: K\n\n    Args:\n        pred (np.ndarray[N, K, 2]): Predicted keypoint location.\n        gt (np.ndarray[N, K, 2]): Groundtruth keypoint location.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n\n    Returns:\n        float: Average end-point error.\n    \"\"\"\n\n    distances = _calc_distances(\n        pred, gt, mask,\n        np.ones((pred.shape[0], pred.shape[2]), dtype=np.float32))\n    distance_valid = distances[distances != -1]\n    return distance_valid.sum() / max(1, len(distance_valid))\n\n\ndef pose_pck_accuracy(output: np.ndarray,\n                      target: np.ndarray,\n                      mask: np.ndarray,\n                      thr: float = 0.05,\n                      normalize: Optional[np.ndarray] = None) -> tuple:\n    \"\"\"Calculate the pose accuracy of PCK for each individual keypoint and the\n    averaged accuracy across all keypoints from heatmaps.\n\n    Note:\n        PCK metric measures accuracy of the localization of the body joints.\n        The distances between predicted positions and the ground-truth ones\n        are typically normalized by the bounding box size.\n        The threshold (thr) of the normalized distance is commonly set\n        as 0.05, 0.1 or 0.2 etc.\n\n        - batch_size: N\n        - num_keypoints: K\n        - heatmap height: H\n        - heatmap width: W\n\n    Args:\n        output (np.ndarray[N, K, H, W]): Model output heatmaps.\n        target (np.ndarray[N, K, H, W]): Groundtruth heatmaps.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n        thr (float): Threshold of PCK calculation. Default 0.05.\n        normalize (np.ndarray[N, 2]): Normalization factor for H&W.\n\n    Returns:\n        tuple: A tuple containing keypoint accuracy.\n\n        - np.ndarray[K]: Accuracy of each keypoint.\n        - float: Averaged accuracy across all keypoints.\n        - int: Number of valid keypoints.\n    \"\"\"\n    N, K, H, W = output.shape\n    if K == 0:\n        return None, 0, 0\n    if normalize is None:\n        normalize = np.tile(np.array([[H, W]]), (N, 1))\n\n    pred, _ = get_heatmap_maximum(output)\n    gt, _ = get_heatmap_maximum(target)\n    return keypoint_pck_accuracy(pred, gt, mask, thr, normalize)\n\n\ndef simcc_pck_accuracy(output: Tuple[np.ndarray, np.ndarray],\n                       target: Tuple[np.ndarray, np.ndarray],\n                       simcc_split_ratio: float,\n                       mask: np.ndarray,\n                       thr: float = 0.05,\n                       normalize: Optional[np.ndarray] = None) -> tuple:\n    \"\"\"Calculate the pose accuracy of PCK for each individual keypoint and the\n    averaged accuracy across all keypoints from SimCC.\n\n    Note:\n        PCK metric measures accuracy of the localization of the body joints.\n        The distances between predicted positions and the ground-truth ones\n        are typically normalized by the bounding box size.\n        The threshold (thr) of the normalized distance is commonly set\n        as 0.05, 0.1 or 0.2 etc.\n\n        - instance number: N\n        - keypoint number: K\n\n    Args:\n        output (Tuple[np.ndarray, np.ndarray]): Model predicted SimCC.\n        target (Tuple[np.ndarray, np.ndarray]): Groundtruth SimCC.\n        mask (np.ndarray[N, K]): Visibility of the target. False for invisible\n            joints, and True for visible. Invisible joints will be ignored for\n            accuracy calculation.\n        thr (float): Threshold of PCK calculation. Default 0.05.\n        normalize (np.ndarray[N, 2]): Normalization factor for H&W.\n\n    Returns:\n        tuple: A tuple containing keypoint accuracy.\n\n        - np.ndarray[K]: Accuracy of each keypoint.\n        - float: Averaged accuracy across all keypoints.\n        - int: Number of valid keypoints.\n    \"\"\"\n    pred_x, pred_y = output\n    gt_x, gt_y = target\n\n    N, _, Wx = pred_x.shape\n    _, _, Wy = pred_y.shape\n    W, H = int(Wx / simcc_split_ratio), int(Wy / simcc_split_ratio)\n\n    if normalize is None:\n        normalize = np.tile(np.array([[H, W]]), (N, 1))\n\n    pred_coords, _ = get_simcc_maximum(pred_x, pred_y)\n    pred_coords /= simcc_split_ratio\n    gt_coords, _ = get_simcc_maximum(gt_x, gt_y)\n    gt_coords /= simcc_split_ratio\n\n    return keypoint_pck_accuracy(pred_coords, gt_coords, mask, thr, normalize)\n\n\ndef multilabel_classification_accuracy(pred: np.ndarray,\n                                       gt: np.ndarray,\n                                       mask: np.ndarray,\n                                       thr: float = 0.5) -> float:\n    \"\"\"Get multi-label classification accuracy.\n\n    Note:\n        - batch size: N\n        - label number: L\n\n    Args:\n        pred (np.ndarray[N, L, 2]): model predicted labels.\n        gt (np.ndarray[N, L, 2]): ground-truth labels.\n        mask (np.ndarray[N, 1] or np.ndarray[N, L] ): reliability of\n            ground-truth labels.\n        thr (float): Threshold for calculating accuracy.\n\n    Returns:\n        float: multi-label classification accuracy.\n    \"\"\"\n    # we only compute accuracy on the samples with ground-truth of all labels.\n    valid = (mask > 0).min(axis=1) if mask.ndim == 2 else (mask > 0)\n    pred, gt = pred[valid], gt[valid]\n\n    if pred.shape[0] == 0:\n        acc = 0.0  # when no sample is with gt labels, set acc to 0.\n    else:\n        # The classification of a sample is regarded as correct\n        # only if it's correct for all labels.\n        acc = (((pred - thr) * (gt - thr)) > 0).all(axis=1).mean()\n    return acc\n\n\ndef keypoint_mpjpe(pred: np.ndarray,\n                   gt: np.ndarray,\n                   mask: np.ndarray,\n                   alignment: str = 'none'):\n    \"\"\"Calculate the mean per-joint position error (MPJPE) and the error after\n    rigid alignment with the ground truth (P-MPJPE).\n\n    Note:\n        - batch_size: N\n        - num_keypoints: K\n        - keypoint_dims: C\n\n    Args:\n        pred (np.ndarray): Predicted keypoint location with shape [N, K, C].\n        gt (np.ndarray): Groundtruth keypoint location with shape [N, K, C].\n        mask (np.ndarray): Visibility of the target with shape [N, K].\n            False for invisible joints, and True for visible.\n            Invisible joints will be ignored for accuracy calculation.\n        alignment (str, optional): method to align the prediction with the\n            groundtruth. Supported options are:\n\n                - ``'none'``: no alignment will be applied\n                - ``'scale'``: align in the least-square sense in scale\n                - ``'procrustes'``: align in the least-square sense in\n                    scale, rotation and translation.\n\n    Returns:\n        tuple: A tuple containing joint position errors\n\n        - (float | np.ndarray): mean per-joint position error (mpjpe).\n        - (float | np.ndarray): mpjpe after rigid alignment with the\n            ground truth (p-mpjpe).\n    \"\"\"\n    assert mask.any()\n\n    if alignment == 'none':\n        pass\n    elif alignment == 'procrustes':\n        pred = np.stack([\n            compute_similarity_transform(pred_i, gt_i)\n            for pred_i, gt_i in zip(pred, gt)\n        ])\n    elif alignment == 'scale':\n        pred_dot_pred = np.einsum('nkc,nkc->n', pred, pred)\n        pred_dot_gt = np.einsum('nkc,nkc->n', pred, gt)\n        scale_factor = pred_dot_gt / pred_dot_pred\n        pred = pred * scale_factor[:, None, None]\n    else:\n        raise ValueError(f'Invalid value for alignment: {alignment}')\n    error = np.linalg.norm(pred - gt, ord=2, axis=-1)[mask].mean()\n\n    return error\n"
  },
  {
    "path": "mmpose/evaluation/functional/mesh_eval.py",
    "content": "# ------------------------------------------------------------------------------\n# Adapted from https://github.com/akanazawa/hmr\n# Original licence: Copyright (c) 2018 akanazawa, under the MIT License.\n# ------------------------------------------------------------------------------\n\nimport numpy as np\n\n\ndef compute_similarity_transform(source_points, target_points):\n    \"\"\"Computes a similarity transform (sR, t) that takes a set of 3D points\n    source_points (N x 3) closest to a set of 3D points target_points, where R\n    is an 3x3 rotation matrix, t 3x1 translation, s scale. And return the\n    transformed 3D points source_points_hat (N x 3). i.e. solves the orthogonal\n    Procrutes problem.\n\n    Note:\n        Points number: N\n\n    Args:\n        source_points (np.ndarray): Source point set with shape [N, 3].\n        target_points (np.ndarray): Target point set with shape [N, 3].\n\n    Returns:\n        np.ndarray: Transformed source point set with shape [N, 3].\n    \"\"\"\n\n    assert target_points.shape[0] == source_points.shape[0]\n    assert target_points.shape[1] == 3 and source_points.shape[1] == 3\n\n    source_points = source_points.T\n    target_points = target_points.T\n\n    # 1. Remove mean.\n    mu1 = source_points.mean(axis=1, keepdims=True)\n    mu2 = target_points.mean(axis=1, keepdims=True)\n    X1 = source_points - mu1\n    X2 = target_points - mu2\n\n    # 2. Compute variance of X1 used for scale.\n    var1 = np.sum(X1**2)\n\n    # 3. The outer product of X1 and X2.\n    K = X1.dot(X2.T)\n\n    # 4. Solution that Maximizes trace(R'K) is R=U*V', where U, V are\n    # singular vectors of K.\n    U, _, Vh = np.linalg.svd(K)\n    V = Vh.T\n    # Construct Z that fixes the orientation of R to get det(R)=1.\n    Z = np.eye(U.shape[0])\n    Z[-1, -1] *= np.sign(np.linalg.det(U.dot(V.T)))\n    # Construct R.\n    R = V.dot(Z.dot(U.T))\n\n    # 5. Recover scale.\n    scale = np.trace(R.dot(K)) / var1\n\n    # 6. Recover translation.\n    t = mu2 - scale * (R.dot(mu1))\n\n    # 7. Transform the source points:\n    source_points_hat = scale * R.dot(source_points) + t\n\n    source_points_hat = source_points_hat.T\n\n    return source_points_hat\n"
  },
  {
    "path": "mmpose/evaluation/functional/nms.py",
    "content": "# ------------------------------------------------------------------------------\n# Adapted from https://github.com/leoxiaobin/deep-high-resolution-net.pytorch\n# and https://github.com/HRNet/DEKR\n# Original licence: Copyright (c) Microsoft, under the MIT License.\n# ------------------------------------------------------------------------------\n\nfrom typing import List, Optional\n\nimport numpy as np\nimport torch\nfrom torch import Tensor\n\nfrom mmpose.structures.bbox import bbox_overlaps\n\n\ndef nms(dets: np.ndarray, thr: float) -> List[int]:\n    \"\"\"Greedily select boxes with high confidence and overlap <= thr.\n\n    Args:\n        dets (np.ndarray): [[x1, y1, x2, y2, score]].\n        thr (float): Retain overlap < thr.\n\n    Returns:\n        list: Indexes to keep.\n    \"\"\"\n    if len(dets) == 0:\n        return []\n\n    x1 = dets[:, 0]\n    y1 = dets[:, 1]\n    x2 = dets[:, 2]\n    y2 = dets[:, 3]\n    scores = dets[:, 4]\n\n    areas = (x2 - x1 + 1) * (y2 - y1 + 1)\n    order = scores.argsort()[::-1]\n\n    keep = []\n    while len(order) > 0:\n        i = order[0]\n        keep.append(i)\n        xx1 = np.maximum(x1[i], x1[order[1:]])\n        yy1 = np.maximum(y1[i], y1[order[1:]])\n        xx2 = np.minimum(x2[i], x2[order[1:]])\n        yy2 = np.minimum(y2[i], y2[order[1:]])\n\n        w = np.maximum(0.0, xx2 - xx1 + 1)\n        h = np.maximum(0.0, yy2 - yy1 + 1)\n        inter = w * h\n        ovr = inter / (areas[i] + areas[order[1:]] - inter)\n\n        inds = np.where(ovr <= thr)[0]\n        order = order[inds + 1]\n\n    return keep\n\n\ndef oks_iou(g: np.ndarray,\n            d: np.ndarray,\n            a_g: float,\n            a_d: np.ndarray,\n            sigmas: Optional[np.ndarray] = None,\n            vis_thr: Optional[float] = None) -> np.ndarray:\n    \"\"\"Calculate oks ious.\n\n    Note:\n\n        - number of keypoints: K\n        - number of instances: N\n\n    Args:\n        g (np.ndarray): The instance to calculate OKS IOU with other\n            instances. Containing the keypoints coordinates. Shape: (K*3, )\n        d (np.ndarray): The rest instances. Containing the keypoints\n            coordinates. Shape: (N, K*3)\n        a_g (float): Area of the ground truth object.\n        a_d (np.ndarray): Area of the detected object. Shape: (N, )\n        sigmas (np.ndarray, optional): Keypoint labelling uncertainty.\n            Please refer to `COCO keypoint evaluation\n            <https://cocodataset.org/#keypoints-eval>`__ for more details.\n            If not given, use the sigmas on COCO dataset.\n            If specified, shape: (K, ). Defaults to ``None``\n        vis_thr(float, optional): Threshold of the keypoint visibility.\n            If specified, will calculate OKS based on those keypoints whose\n            visibility higher than vis_thr. If not given, calculate the OKS\n            based on all keypoints. Defaults to ``None``\n\n    Returns:\n        np.ndarray: The oks ious.\n    \"\"\"\n    if sigmas is None:\n        sigmas = np.array([\n            .26, .25, .25, .35, .35, .79, .79, .72, .72, .62, .62, 1.07, 1.07,\n            .87, .87, .89, .89\n        ]) / 10.0\n    vars = (sigmas * 2)**2\n    xg = g[0::3]\n    yg = g[1::3]\n    vg = g[2::3]\n    ious = np.zeros(len(d), dtype=np.float32)\n    for n_d in range(0, len(d)):\n        xd = d[n_d, 0::3]\n        yd = d[n_d, 1::3]\n        vd = d[n_d, 2::3]\n        dx = xd - xg\n        dy = yd - yg\n        e = (dx**2 + dy**2) / vars / ((a_g + a_d[n_d]) / 2 + np.spacing(1)) / 2\n        if vis_thr is not None:\n            ind = list((vg > vis_thr) & (vd > vis_thr))\n            e = e[ind]\n        ious[n_d] = np.sum(np.exp(-e)) / len(e) if len(e) != 0 else 0.0\n    return ious\n\n\ndef oks_nms(kpts_db: List[dict],\n            thr: float,\n            sigmas: Optional[np.ndarray] = None,\n            vis_thr: Optional[float] = None,\n            score_per_joint: bool = False):\n    \"\"\"OKS NMS implementations.\n\n    Args:\n        kpts_db (List[dict]): The keypoints results of the same image.\n        thr (float): The threshold of NMS. Will retain oks overlap < thr.\n        sigmas (np.ndarray, optional): Keypoint labelling uncertainty.\n            Please refer to `COCO keypoint evaluation\n            <https://cocodataset.org/#keypoints-eval>`__ for more details.\n            If not given, use the sigmas on COCO dataset. Defaults to ``None``\n        vis_thr(float, optional): Threshold of the keypoint visibility.\n            If specified, will calculate OKS based on those keypoints whose\n            visibility higher than vis_thr. If not given, calculate the OKS\n            based on all keypoints. Defaults to ``None``\n        score_per_joint(bool): Whether the input scores (in kpts_db) are\n            per-joint scores. Defaults to ``False``\n\n    Returns:\n        np.ndarray: indexes to keep.\n    \"\"\"\n    if len(kpts_db) == 0:\n        return []\n\n    if score_per_joint:\n        scores = np.array([k['score'].mean() for k in kpts_db])\n    else:\n        scores = np.array([k['score'] for k in kpts_db])\n\n    kpts = np.array([k['keypoints'].flatten() for k in kpts_db])\n    areas = np.array([k['area'] for k in kpts_db])\n\n    order = scores.argsort()[::-1]\n\n    keep = []\n    while len(order) > 0:\n        i = order[0]\n        keep.append(i)\n\n        oks_ovr = oks_iou(kpts[i], kpts[order[1:]], areas[i], areas[order[1:]],\n                          sigmas, vis_thr)\n\n        inds = np.where(oks_ovr <= thr)[0]\n        order = order[inds + 1]\n\n    keep = np.array(keep)\n\n    return keep\n\n\ndef _rescore(overlap: np.ndarray,\n             scores: np.ndarray,\n             thr: float,\n             type: str = 'gaussian'):\n    \"\"\"Rescoring mechanism gaussian or linear.\n\n    Args:\n        overlap (np.ndarray): The calculated oks ious.\n        scores (np.ndarray): target scores.\n        thr (float): retain oks overlap < thr.\n        type (str): The rescoring type. Could be 'gaussian' or 'linear'.\n            Defaults to ``'gaussian'``\n\n    Returns:\n        np.ndarray: indexes to keep\n    \"\"\"\n    assert len(overlap) == len(scores)\n    assert type in ['gaussian', 'linear']\n\n    if type == 'linear':\n        inds = np.where(overlap >= thr)[0]\n        scores[inds] = scores[inds] * (1 - overlap[inds])\n    else:\n        scores = scores * np.exp(-overlap**2 / thr)\n\n    return scores\n\n\ndef soft_oks_nms(kpts_db: List[dict],\n                 thr: float,\n                 max_dets: int = 20,\n                 sigmas: Optional[np.ndarray] = None,\n                 vis_thr: Optional[float] = None,\n                 score_per_joint: bool = False):\n    \"\"\"Soft OKS NMS implementations.\n\n    Args:\n        kpts_db (List[dict]): The keypoints results of the same image.\n        thr (float): The threshold of NMS. Will retain oks overlap < thr.\n        max_dets (int): Maximum number of detections to keep. Defaults to 20\n        sigmas (np.ndarray, optional): Keypoint labelling uncertainty.\n            Please refer to `COCO keypoint evaluation\n            <https://cocodataset.org/#keypoints-eval>`__ for more details.\n            If not given, use the sigmas on COCO dataset. Defaults to ``None``\n        vis_thr(float, optional): Threshold of the keypoint visibility.\n            If specified, will calculate OKS based on those keypoints whose\n            visibility higher than vis_thr. If not given, calculate the OKS\n            based on all keypoints. Defaults to ``None``\n        score_per_joint(bool): Whether the input scores (in kpts_db) are\n            per-joint scores. Defaults to ``False``\n\n    Returns:\n        np.ndarray: indexes to keep.\n    \"\"\"\n    if len(kpts_db) == 0:\n        return []\n\n    if score_per_joint:\n        scores = np.array([k['score'].mean() for k in kpts_db])\n    else:\n        scores = np.array([k['score'] for k in kpts_db])\n\n    kpts = np.array([k['keypoints'].flatten() for k in kpts_db])\n    areas = np.array([k['area'] for k in kpts_db])\n\n    order = scores.argsort()[::-1]\n    scores = scores[order]\n\n    keep = np.zeros(max_dets, dtype=np.intp)\n    keep_cnt = 0\n    while len(order) > 0 and keep_cnt < max_dets:\n        i = order[0]\n\n        oks_ovr = oks_iou(kpts[i], kpts[order[1:]], areas[i], areas[order[1:]],\n                          sigmas, vis_thr)\n\n        order = order[1:]\n        scores = _rescore(oks_ovr, scores[1:], thr)\n\n        tmp = scores.argsort()[::-1]\n        order = order[tmp]\n        scores = scores[tmp]\n\n        keep[keep_cnt] = i\n        keep_cnt += 1\n\n    keep = keep[:keep_cnt]\n\n    return keep\n\n\ndef nearby_joints_nms(\n    kpts_db: List[dict],\n    dist_thr: float = 0.05,\n    num_nearby_joints_thr: Optional[int] = None,\n    score_per_joint: bool = False,\n    max_dets: int = 30,\n):\n    \"\"\"Nearby joints NMS implementations. Instances with non-maximum scores\n    will be suppressed if they have too much closed joints with other\n    instances. This function is modified from project\n    `DEKR<https://github.com/HRNet/DEKR/blob/main/lib/core/nms.py>`.\n\n    Args:\n        kpts_db (list[dict]): keypoints and scores.\n        dist_thr (float): threshold for judging whether two joints are close.\n            Defaults to 0.05.\n        num_nearby_joints_thr (int): threshold for judging whether two\n            instances are close.\n        max_dets (int): max number of detections to keep. Defaults to 30.\n        score_per_joint (bool): the input scores (in kpts_db) are per joint\n            scores.\n\n    Returns:\n        np.ndarray: indexes to keep.\n    \"\"\"\n\n    assert dist_thr > 0, '`dist_thr` must be greater than 0.'\n    if len(kpts_db) == 0:\n        return []\n\n    if score_per_joint:\n        scores = np.array([k['score'].mean() for k in kpts_db])\n    else:\n        scores = np.array([k['score'] for k in kpts_db])\n\n    kpts = np.array([k['keypoints'] for k in kpts_db])\n\n    num_people, num_joints, _ = kpts.shape\n    if num_nearby_joints_thr is None:\n        num_nearby_joints_thr = num_joints // 2\n    assert num_nearby_joints_thr < num_joints, '`num_nearby_joints_thr` must '\\\n        'be less than the number of joints.'\n\n    # compute distance threshold\n    pose_area = kpts.max(axis=1) - kpts.min(axis=1)\n    pose_area = np.sqrt(np.power(pose_area, 2).sum(axis=1))\n    pose_area = pose_area.reshape(num_people, 1, 1)\n    pose_area = np.tile(pose_area, (num_people, num_joints))\n    close_dist_thr = pose_area * dist_thr\n\n    # count nearby joints between instances\n    instance_dist = kpts[:, None] - kpts\n    instance_dist = np.sqrt(np.power(instance_dist, 2).sum(axis=3))\n    close_instance_num = (instance_dist < close_dist_thr).sum(2)\n    close_instance = close_instance_num > num_nearby_joints_thr\n\n    # apply nms\n    ignored_pose_inds, keep_pose_inds = set(), list()\n    indexes = np.argsort(scores)[::-1]\n    for i in indexes:\n        if i in ignored_pose_inds:\n            continue\n        keep_inds = close_instance[i].nonzero()[0]\n        keep_ind = keep_inds[np.argmax(scores[keep_inds])]\n        if keep_ind not in ignored_pose_inds:\n            keep_pose_inds.append(keep_ind)\n            ignored_pose_inds = ignored_pose_inds.union(set(keep_inds))\n\n    # limit the number of output instances\n    if max_dets > 0 and len(keep_pose_inds) > max_dets:\n        sub_inds = np.argsort(scores[keep_pose_inds])[-1:-max_dets - 1:-1]\n        keep_pose_inds = [keep_pose_inds[i] for i in sub_inds]\n\n    return keep_pose_inds\n\n\ndef nms_torch(bboxes: Tensor,\n              scores: Tensor,\n              threshold: float = 0.65,\n              iou_calculator=bbox_overlaps,\n              return_group: bool = False):\n    \"\"\"Perform Non-Maximum Suppression (NMS) on a set of bounding boxes using\n    their corresponding scores.\n\n    Args:\n\n        bboxes (Tensor): list of bounding boxes (each containing 4 elements\n            for x1, y1, x2, y2).\n        scores (Tensor): scores associated with each bounding box.\n        threshold (float): IoU threshold to determine overlap.\n        iou_calculator (function): method to calculate IoU.\n        return_group (bool): if True, returns groups of overlapping bounding\n            boxes, otherwise returns the main bounding boxes.\n    \"\"\"\n\n    _, indices = scores.sort(descending=True)\n    groups = []\n    while len(indices):\n        idx, indices = indices[0], indices[1:]\n        bbox = bboxes[idx]\n        ious = iou_calculator(bbox, bboxes[indices])\n        close_indices = torch.where(ious > threshold)[1]\n        keep_indices = torch.ones_like(indices, dtype=torch.bool)\n        keep_indices[close_indices] = 0\n        groups.append(torch.cat((idx[None], indices[close_indices])))\n        indices = indices[keep_indices]\n\n    if return_group:\n        return groups\n    else:\n        return torch.cat([g[:1] for g in groups])\n"
  },
  {
    "path": "mmpose/evaluation/functional/transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple, Union\n\nimport numpy as np\n\n\ndef transform_sigmas(sigmas: Union[List, np.ndarray], num_keypoints: int,\n                     mapping: Union[List[Tuple[int, int]], List[Tuple[Tuple,\n                                                                      int]]]):\n    \"\"\"Transforms the sigmas based on the mapping.\"\"\"\n    if len(mapping):\n        source_index, target_index = map(list, zip(*mapping))\n    else:\n        source_index, target_index = [], []\n\n    list_input = False\n    if isinstance(sigmas, list):\n        sigmas = np.array(sigmas)\n        list_input = True\n\n    new_sigmas = np.ones(num_keypoints, dtype=sigmas.dtype)\n    new_sigmas[target_index] = sigmas[source_index]\n\n    if list_input:\n        new_sigmas = new_sigmas.tolist()\n\n    return new_sigmas\n\n\ndef transform_ann(ann_info: Union[dict, list], num_keypoints: int,\n                  mapping: Union[List[Tuple[int, int]], List[Tuple[Tuple,\n                                                                   int]]]):\n    \"\"\"Transforms COCO-format annotations based on the mapping.\"\"\"\n    if len(mapping):\n        source_index, target_index = map(list, zip(*mapping))\n    else:\n        source_index, target_index = [], []\n\n    list_input = True\n    if not isinstance(ann_info, list):\n        ann_info = [ann_info]\n        list_input = False\n\n    for each in ann_info:\n        if 'keypoints' in each:\n            keypoints = np.array(each['keypoints'])\n\n            C = 3  # COCO-format: x, y, score\n            keypoints = keypoints.reshape(-1, C)\n            new_keypoints = np.zeros((num_keypoints, C), dtype=keypoints.dtype)\n            new_keypoints[target_index] = keypoints[source_index]\n            each['keypoints'] = new_keypoints.reshape(-1).tolist()\n\n        if 'num_keypoints' in each:\n            each['num_keypoints'] = num_keypoints\n\n    if not list_input:\n        ann_info = ann_info[0]\n\n    return ann_info\n\n\ndef transform_pred(pred_info: Union[dict, list], num_keypoints: int,\n                   mapping: Union[List[Tuple[int, int]], List[Tuple[Tuple,\n                                                                    int]]]):\n    \"\"\"Transforms predictions based on the mapping.\"\"\"\n    if len(mapping):\n        source_index, target_index = map(list, zip(*mapping))\n    else:\n        source_index, target_index = [], []\n\n    list_input = True\n    if not isinstance(pred_info, list):\n        pred_info = [pred_info]\n        list_input = False\n\n    for each in pred_info:\n        if 'keypoints' in each:\n            keypoints = np.array(each['keypoints'])\n\n            N, _, C = keypoints.shape\n            new_keypoints = np.zeros((N, num_keypoints, C),\n                                     dtype=keypoints.dtype)\n            new_keypoints[:, target_index] = keypoints[:, source_index]\n            each['keypoints'] = new_keypoints\n\n            keypoint_scores = np.array(each['keypoint_scores'])\n            new_scores = np.zeros((N, num_keypoints),\n                                  dtype=keypoint_scores.dtype)\n            new_scores[:, target_index] = keypoint_scores[:, source_index]\n            each['keypoint_scores'] = new_scores\n\n        if 'num_keypoints' in each:\n            each['num_keypoints'] = num_keypoints\n\n    if not list_input:\n        pred_info = pred_info[0]\n\n    return pred_info\n"
  },
  {
    "path": "mmpose/evaluation/metrics/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .coco_metric import CocoMetric\nfrom .coco_wholebody_metric import CocoWholeBodyMetric\nfrom .hand_metric import InterHandMetric\nfrom .keypoint_2d_metrics import (AUC, EPE, NME, JhmdbPCKAccuracy,\n                                  MpiiPCKAccuracy, PCKAccuracy)\nfrom .keypoint_3d_metrics import MPJPE\nfrom .keypoint_partition_metric import KeypointPartitionMetric\nfrom .posetrack18_metric import PoseTrack18Metric\nfrom .simple_keypoint_3d_metrics import SimpleMPJPE\n\n__all__ = [\n    'CocoMetric', 'PCKAccuracy', 'MpiiPCKAccuracy', 'JhmdbPCKAccuracy', 'AUC',\n    'EPE', 'NME', 'PoseTrack18Metric', 'CocoWholeBodyMetric',\n    'KeypointPartitionMetric', 'MPJPE', 'InterHandMetric', 'SimpleMPJPE'\n]\n"
  },
  {
    "path": "mmpose/evaluation/metrics/coco_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport datetime\nimport os.path as osp\nimport tempfile\nfrom collections import OrderedDict, defaultdict\nfrom typing import Dict, Optional, Sequence\n\nimport numpy as np\nfrom mmengine.evaluator import BaseMetric\nfrom mmengine.fileio import dump, get_local_path, load\nfrom mmengine.logging import MessageHub, MMLogger, print_log\nfrom xtcocotools.coco import COCO\nfrom xtcocotools.cocoeval import COCOeval\n\nfrom mmpose.registry import METRICS\nfrom mmpose.structures.bbox import bbox_xyxy2xywh\nfrom ..functional import (oks_nms, soft_oks_nms, transform_ann, transform_pred,\n                          transform_sigmas)\n\n\n@METRICS.register_module()\nclass CocoMetric(BaseMetric):\n    \"\"\"COCO pose estimation task evaluation metric.\n\n    Evaluate AR, AP, and mAP for keypoint detection tasks. Support COCO\n    dataset and other datasets in COCO format. Please refer to\n    `COCO keypoint evaluation <https://cocodataset.org/#keypoints-eval>`__\n    for more details.\n\n    Args:\n        ann_file (str, optional): Path to the coco format annotation file.\n            If not specified, ground truth annotations from the dataset will\n            be converted to coco format. Defaults to None\n        use_area (bool): Whether to use ``'area'`` message in the annotations.\n            If the ground truth annotations (e.g. CrowdPose, AIC) do not have\n            the field ``'area'``, please set ``use_area=False``.\n            Defaults to ``True``\n        iou_type (str): The same parameter as `iouType` in\n            :class:`xtcocotools.COCOeval`, which can be ``'keypoints'``, or\n            ``'keypoints_crowd'`` (used in CrowdPose dataset).\n            Defaults to ``'keypoints'``\n        score_mode (str): The mode to score the prediction results which\n            should be one of the following options:\n\n                - ``'bbox'``: Take the score of bbox as the score of the\n                    prediction results.\n                - ``'bbox_keypoint'``: Use keypoint score to rescore the\n                    prediction results.\n                - ``'bbox_rle'``: Use rle_score to rescore the\n                    prediction results.\n\n            Defaults to ``'bbox_keypoint'`\n        keypoint_score_thr (float): The threshold of keypoint score. The\n            keypoints with score lower than it will not be included to\n            rescore the prediction results. Valid only when ``score_mode`` is\n            ``bbox_keypoint``. Defaults to ``0.2``\n        nms_mode (str): The mode to perform Non-Maximum Suppression (NMS),\n            which should be one of the following options:\n\n                - ``'oks_nms'``: Use Object Keypoint Similarity (OKS) to\n                    perform NMS.\n                - ``'soft_oks_nms'``: Use Object Keypoint Similarity (OKS)\n                    to perform soft NMS.\n                - ``'none'``: Do not perform NMS. Typically for bottomup mode\n                    output.\n\n            Defaults to ``'oks_nms'`\n        nms_thr (float): The Object Keypoint Similarity (OKS) threshold\n            used in NMS when ``nms_mode`` is ``'oks_nms'`` or\n            ``'soft_oks_nms'``. Will retain the prediction results with OKS\n            lower than ``nms_thr``. Defaults to ``0.9``\n        format_only (bool): Whether only format the output results without\n            doing quantitative evaluation. This is designed for the need of\n            test submission when the ground truth annotations are absent. If\n            set to ``True``, ``outfile_prefix`` should specify the path to\n            store the output results. Defaults to ``False``\n        pred_converter (dict, optional): Config dictionary for the prediction\n            converter. The dictionary has the same parameters as\n            'KeypointConverter'. Defaults to None.\n        gt_converter (dict, optional): Config dictionary for the ground truth\n            converter. The dictionary has the same parameters as\n            'KeypointConverter'. Defaults to None.\n        outfile_prefix (str | None): The prefix of json files. It includes\n            the file path and the prefix of filename, e.g., ``'a/b/prefix'``.\n            If not specified, a temp file will be created. Defaults to ``None``\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Defaults to ``'cpu'``\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Defaults to ``None``\n    \"\"\"\n    default_prefix: Optional[str] = 'coco'\n\n    def __init__(self,\n                 ann_file: Optional[str] = None,\n                 use_area: bool = True,\n                 iou_type: str = 'keypoints',\n                 score_mode: str = 'bbox_keypoint',\n                 keypoint_score_thr: float = 0.2,\n                 nms_mode: str = 'oks_nms',\n                 nms_thr: float = 0.9,\n                 format_only: bool = False,\n                 pred_converter: Dict = None,\n                 gt_converter: Dict = None,\n                 outfile_prefix: Optional[str] = None,\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        self.ann_file = ann_file\n        # initialize coco helper with the annotation json file\n        # if ann_file is not specified, initialize with the converted dataset\n        if ann_file is not None:\n            with get_local_path(ann_file) as local_path:\n                self.coco = COCO(local_path)\n        else:\n            self.coco = None\n\n        self.use_area = use_area\n        self.iou_type = iou_type\n\n        allowed_score_modes = ['bbox', 'bbox_keypoint', 'bbox_rle', 'keypoint']\n        if score_mode not in allowed_score_modes:\n            raise ValueError(\n                \"`score_mode` should be one of 'bbox', 'bbox_keypoint', \"\n                f\"'bbox_rle', but got {score_mode}\")\n        self.score_mode = score_mode\n        self.keypoint_score_thr = keypoint_score_thr\n\n        allowed_nms_modes = ['oks_nms', 'soft_oks_nms', 'none']\n        if nms_mode not in allowed_nms_modes:\n            raise ValueError(\n                \"`nms_mode` should be one of 'oks_nms', 'soft_oks_nms', \"\n                f\"'none', but got {nms_mode}\")\n        self.nms_mode = nms_mode\n        self.nms_thr = nms_thr\n\n        if format_only:\n            assert outfile_prefix is not None, '`outfile_prefix` can not be '\\\n                'None when `format_only` is True, otherwise the result file '\\\n                'will be saved to a temp directory which will be cleaned up '\\\n                'in the end.'\n        elif ann_file is not None:\n            # do evaluation only if the ground truth annotations exist\n            assert 'annotations' in load(ann_file), \\\n                'Ground truth annotations are required for evaluation '\\\n                'when `format_only` is False.'\n\n        self.format_only = format_only\n        self.outfile_prefix = outfile_prefix\n        self.pred_converter = pred_converter\n        self.gt_converter = gt_converter\n\n    @property\n    def dataset_meta(self) -> Optional[dict]:\n        \"\"\"Optional[dict]: Meta info of the dataset.\"\"\"\n        return self._dataset_meta\n\n    @dataset_meta.setter\n    def dataset_meta(self, dataset_meta: dict) -> None:\n        \"\"\"Set the dataset meta info to the metric.\"\"\"\n        if self.gt_converter is not None:\n            dataset_meta['sigmas'] = transform_sigmas(\n                dataset_meta['sigmas'], self.gt_converter['num_keypoints'],\n                self.gt_converter['mapping'])\n            dataset_meta['num_keypoints'] = len(dataset_meta['sigmas'])\n        self._dataset_meta = dataset_meta\n\n        if self.coco is None:\n            message = MessageHub.get_current_instance()\n            ann_file = message.get_info(\n                f\"{dataset_meta['dataset_name']}_ann_file\", None)\n            if ann_file is not None:\n                with get_local_path(ann_file) as local_path:\n                    self.coco = COCO(local_path)\n                print_log(\n                    f'CocoMetric for dataset '\n                    f\"{dataset_meta['dataset_name']} has successfully \"\n                    f'loaded the annotation file from {ann_file}', 'current')\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model, each of which has the following keys:\n\n                - 'id': The id of the sample\n                - 'img_id': The image_id of the sample\n                - 'pred_instances': The prediction results of instance(s)\n        \"\"\"\n        for data_sample in data_samples:\n            if 'pred_instances' not in data_sample:\n                raise ValueError(\n                    '`pred_instances` are required to process the '\n                    f'predictions results in {self.__class__.__name__}. ')\n\n            # keypoints.shape: [N, K, 2],\n            # N: number of instances, K: number of keypoints\n            # for topdown-style output, N is usually 1, while for\n            # bottomup-style output, N is the number of instances in the image\n            keypoints = data_sample['pred_instances']['keypoints']\n            # [N, K], the scores for all keypoints of all instances\n            keypoint_scores = data_sample['pred_instances']['keypoint_scores']\n            assert keypoint_scores.shape == keypoints.shape[:2]\n\n            # parse prediction results\n            pred = dict()\n            pred['id'] = data_sample['id']\n            pred['img_id'] = data_sample['img_id']\n\n            pred['keypoints'] = keypoints\n            pred['keypoint_scores'] = keypoint_scores\n            pred['category_id'] = data_sample.get('category_id', 1)\n            if 'bboxes' in data_sample['pred_instances']:\n                pred['bbox'] = bbox_xyxy2xywh(\n                    data_sample['pred_instances']['bboxes'])\n\n            if 'bbox_scores' in data_sample['pred_instances']:\n                # some one-stage models will predict bboxes and scores\n                # together with keypoints\n                bbox_scores = data_sample['pred_instances']['bbox_scores']\n            elif ('bbox_scores' not in data_sample['gt_instances']\n                  or len(data_sample['gt_instances']['bbox_scores']) !=\n                  len(keypoints)):\n                # bottom-up models might output different number of\n                # instances from annotation\n                bbox_scores = np.ones(len(keypoints))\n            else:\n                # top-down models use detected bboxes, the scores of which\n                # are contained in the gt_instances\n                bbox_scores = data_sample['gt_instances']['bbox_scores']\n            pred['bbox_scores'] = bbox_scores\n\n            # get area information\n            if 'bbox_scales' in data_sample['gt_instances']:\n                pred['areas'] = np.prod(\n                    data_sample['gt_instances']['bbox_scales'], axis=1)\n\n            # parse gt\n            gt = dict()\n            if self.coco is None:\n                gt['width'] = data_sample['ori_shape'][1]\n                gt['height'] = data_sample['ori_shape'][0]\n                gt['img_id'] = data_sample['img_id']\n                if self.iou_type == 'keypoints_crowd':\n                    assert 'crowd_index' in data_sample, \\\n                        '`crowd_index` is required when `self.iou_type` is ' \\\n                        '`keypoints_crowd`'\n                    gt['crowd_index'] = data_sample['crowd_index']\n                assert 'raw_ann_info' in data_sample, \\\n                    'The row ground truth annotations are required for ' \\\n                    'evaluation when `ann_file` is not provided'\n                anns = data_sample['raw_ann_info']\n                gt['raw_ann_info'] = anns if isinstance(anns, list) else [anns]\n\n            # add converted result to the results list\n            self.results.append((pred, gt))\n\n    def gt_to_coco_json(self, gt_dicts: Sequence[dict],\n                        outfile_prefix: str) -> str:\n        \"\"\"Convert ground truth to coco format json file.\n\n        Args:\n            gt_dicts (Sequence[dict]): Ground truth of the dataset. Each dict\n                contains the ground truth information about the data sample.\n                Required keys of the each `gt_dict` in `gt_dicts`:\n                    - `img_id`: image id of the data sample\n                    - `width`: original image width\n                    - `height`: original image height\n                    - `raw_ann_info`: the raw annotation information\n                Optional keys:\n                    - `crowd_index`: measure the crowding level of an image,\n                        defined in CrowdPose dataset\n                It is worth mentioning that, in order to compute `CocoMetric`,\n                there are some required keys in the `raw_ann_info`:\n                    - `id`: the id to distinguish different annotations\n                    - `image_id`: the image id of this annotation\n                    - `category_id`: the category of the instance.\n                    - `bbox`: the object bounding box\n                    - `keypoints`: the keypoints cooridinates along with their\n                        visibilities. Note that it need to be aligned\n                        with the official COCO format, e.g., a list with length\n                        N * 3, in which N is the number of keypoints. And each\n                        triplet represent the [x, y, visible] of the keypoint.\n                    - `iscrowd`: indicating whether the annotation is a crowd.\n                        It is useful when matching the detection results to\n                        the ground truth.\n                There are some optional keys as well:\n                    - `area`: it is necessary when `self.use_area` is `True`\n                    - `num_keypoints`: it is necessary when `self.iou_type`\n                        is set as `keypoints_crowd`.\n            outfile_prefix (str): The filename prefix of the json files. If the\n                prefix is \"somepath/xxx\", the json file will be named\n                \"somepath/xxx.gt.json\".\n        Returns:\n            str: The filename of the json file.\n        \"\"\"\n        image_infos = []\n        annotations = []\n        img_ids = []\n        ann_ids = []\n\n        for gt_dict in gt_dicts:\n            # filter duplicate image_info\n            if gt_dict['img_id'] not in img_ids:\n                image_info = dict(\n                    id=gt_dict['img_id'],\n                    width=gt_dict['width'],\n                    height=gt_dict['height'],\n                )\n                if self.iou_type == 'keypoints_crowd':\n                    image_info['crowdIndex'] = gt_dict['crowd_index']\n\n                image_infos.append(image_info)\n                img_ids.append(gt_dict['img_id'])\n\n            # filter duplicate annotations\n            for ann in gt_dict['raw_ann_info']:\n                if ann is None:\n                    # during evaluation on bottom-up datasets, some images\n                    # do not have instance annotation\n                    continue\n\n                annotation = dict(\n                    id=ann['id'],\n                    image_id=ann['image_id'],\n                    category_id=ann['category_id'],\n                    bbox=ann['bbox'],\n                    keypoints=ann['keypoints'],\n                    iscrowd=ann['iscrowd'],\n                )\n                if self.use_area:\n                    assert 'area' in ann, \\\n                        '`area` is required when `self.use_area` is `True`'\n                    annotation['area'] = ann['area']\n\n                if self.iou_type == 'keypoints_crowd':\n                    assert 'num_keypoints' in ann, \\\n                        '`num_keypoints` is required when `self.iou_type` ' \\\n                        'is `keypoints_crowd`'\n                    annotation['num_keypoints'] = ann['num_keypoints']\n\n                annotations.append(annotation)\n                ann_ids.append(ann['id'])\n\n        info = dict(\n            date_created=str(datetime.datetime.now()),\n            description='Coco json file converted by mmpose CocoMetric.')\n        coco_json = dict(\n            info=info,\n            images=image_infos,\n            categories=self.dataset_meta['CLASSES'],\n            licenses=None,\n            annotations=annotations,\n        )\n        converted_json_path = f'{outfile_prefix}.gt.json'\n        dump(coco_json, converted_json_path, sort_keys=True, indent=4)\n        return converted_json_path\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # split prediction and gt list\n        preds, gts = zip(*results)\n\n        tmp_dir = None\n        if self.outfile_prefix is None:\n            tmp_dir = tempfile.TemporaryDirectory()\n            outfile_prefix = osp.join(tmp_dir.name, 'results')\n        else:\n            outfile_prefix = self.outfile_prefix\n\n        if self.coco is None:\n            # use converted gt json file to initialize coco helper\n            logger.info('Converting ground truth to coco format...')\n            coco_json_path = self.gt_to_coco_json(\n                gt_dicts=gts, outfile_prefix=outfile_prefix)\n            self.coco = COCO(coco_json_path)\n        if self.gt_converter is not None:\n            for id_, ann in self.coco.anns.items():\n                self.coco.anns[id_] = transform_ann(\n                    ann, self.gt_converter['num_keypoints'],\n                    self.gt_converter['mapping'])\n\n        kpts = defaultdict(list)\n\n        # group the preds by img_id\n        for pred in preds:\n            img_id = pred['img_id']\n\n            if self.pred_converter is not None:\n                pred = transform_pred(pred,\n                                      self.pred_converter['num_keypoints'],\n                                      self.pred_converter['mapping'])\n\n            for idx, keypoints in enumerate(pred['keypoints']):\n\n                instance = {\n                    'id': pred['id'],\n                    'img_id': pred['img_id'],\n                    'category_id': pred['category_id'],\n                    'keypoints': keypoints,\n                    'keypoint_scores': pred['keypoint_scores'][idx],\n                    'bbox_score': pred['bbox_scores'][idx],\n                }\n                if 'bbox' in pred:\n                    instance['bbox'] = pred['bbox'][idx]\n\n                if 'areas' in pred:\n                    instance['area'] = pred['areas'][idx]\n                else:\n                    # use keypoint to calculate bbox and get area\n                    area = (\n                        np.max(keypoints[:, 0]) - np.min(keypoints[:, 0])) * (\n                            np.max(keypoints[:, 1]) - np.min(keypoints[:, 1]))\n                    instance['area'] = area\n\n                kpts[img_id].append(instance)\n\n        # sort keypoint results according to id and remove duplicate ones\n        kpts = self._sort_and_unique_bboxes(kpts, key='id')\n\n        # score the prediction results according to `score_mode`\n        # and perform NMS according to `nms_mode`\n        valid_kpts = defaultdict(list)\n        if self.pred_converter is not None:\n            num_keypoints = self.pred_converter['num_keypoints']\n        else:\n            num_keypoints = self.dataset_meta['num_keypoints']\n        for img_id, instances in kpts.items():\n            for instance in instances:\n                # concatenate the keypoint coordinates and scores\n                instance['keypoints'] = np.concatenate([\n                    instance['keypoints'], instance['keypoint_scores'][:, None]\n                ],\n                                                       axis=-1)\n                if self.score_mode == 'bbox':\n                    instance['score'] = instance['bbox_score']\n                elif self.score_mode == 'keypoint':\n                    instance['score'] = np.mean(instance['keypoint_scores'])\n                else:\n                    bbox_score = instance['bbox_score']\n                    if self.score_mode == 'bbox_rle':\n                        keypoint_scores = instance['keypoint_scores']\n                        instance['score'] = float(bbox_score +\n                                                  np.mean(keypoint_scores) +\n                                                  np.max(keypoint_scores))\n\n                    else:  # self.score_mode == 'bbox_keypoint':\n                        mean_kpt_score = 0\n                        valid_num = 0\n                        for kpt_idx in range(num_keypoints):\n                            kpt_score = instance['keypoint_scores'][kpt_idx]\n                            if kpt_score > self.keypoint_score_thr:\n                                mean_kpt_score += kpt_score\n                                valid_num += 1\n                        if valid_num != 0:\n                            mean_kpt_score /= valid_num\n                        instance['score'] = bbox_score * mean_kpt_score\n            # perform nms\n            if self.nms_mode == 'none':\n                valid_kpts[img_id] = instances\n            else:\n                nms = oks_nms if self.nms_mode == 'oks_nms' else soft_oks_nms\n                keep = nms(\n                    instances,\n                    self.nms_thr,\n                    sigmas=self.dataset_meta['sigmas'])\n                valid_kpts[img_id] = [instances[_keep] for _keep in keep]\n\n        # convert results to coco style and dump into a json file\n        self.results2json(valid_kpts, outfile_prefix=outfile_prefix)\n\n        # only format the results without doing quantitative evaluation\n        if self.format_only:\n            logger.info('results are saved in '\n                        f'{osp.dirname(outfile_prefix)}')\n            return {}\n\n        # evaluation results\n        eval_results = OrderedDict()\n        logger.info(f'Evaluating {self.__class__.__name__}...')\n        info_str = self._do_python_keypoint_eval(outfile_prefix)\n        name_value = OrderedDict(info_str)\n        eval_results.update(name_value)\n\n        if tmp_dir is not None:\n            tmp_dir.cleanup()\n        return eval_results\n\n    def results2json(self, keypoints: Dict[int, list],\n                     outfile_prefix: str) -> str:\n        \"\"\"Dump the keypoint detection results to a COCO style json file.\n\n        Args:\n            keypoints (Dict[int, list]): Keypoint detection results\n                of the dataset.\n            outfile_prefix (str): The filename prefix of the json files. If the\n                prefix is \"somepath/xxx\", the json files will be named\n                \"somepath/xxx.keypoints.json\",\n\n        Returns:\n            str: The json file name of keypoint results.\n        \"\"\"\n        # the results with category_id\n        cat_results = []\n\n        for _, img_kpts in keypoints.items():\n            _keypoints = np.array(\n                [img_kpt['keypoints'] for img_kpt in img_kpts])\n            num_keypoints = self.dataset_meta['num_keypoints']\n            # collect all the person keypoints in current image\n            _keypoints = _keypoints.reshape(-1, num_keypoints * 3)\n\n            result = []\n            for img_kpt, keypoint in zip(img_kpts, _keypoints):\n                res = {\n                    'image_id': img_kpt['img_id'],\n                    'category_id': img_kpt['category_id'],\n                    'keypoints': keypoint.tolist(),\n                    'score': float(img_kpt['score']),\n                }\n                if 'bbox' in img_kpt:\n                    res['bbox'] = img_kpt['bbox'].tolist()\n                result.append(res)\n\n            cat_results.extend(result)\n\n        res_file = f'{outfile_prefix}.keypoints.json'\n        dump(cat_results, res_file, sort_keys=True, indent=4)\n\n    def _do_python_keypoint_eval(self, outfile_prefix: str) -> list:\n        \"\"\"Do keypoint evaluation using COCOAPI.\n\n        Args:\n            outfile_prefix (str): The filename prefix of the json files. If the\n                prefix is \"somepath/xxx\", the json files will be named\n                \"somepath/xxx.keypoints.json\",\n\n        Returns:\n            list: a list of tuples. Each tuple contains the evaluation stats\n            name and corresponding stats value.\n        \"\"\"\n        res_file = f'{outfile_prefix}.keypoints.json'\n        coco_det = self.coco.loadRes(res_file)\n        sigmas = self.dataset_meta['sigmas']\n        coco_eval = COCOeval(self.coco, coco_det, self.iou_type, sigmas,\n                             self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        if self.iou_type == 'keypoints_crowd':\n            stats_names = [\n                'AP', 'AP .5', 'AP .75', 'AR', 'AR .5', 'AR .75', 'AP(E)',\n                'AP(M)', 'AP(H)'\n            ]\n        else:\n            stats_names = [\n                'AP', 'AP .5', 'AP .75', 'AP (M)', 'AP (L)', 'AR', 'AR .5',\n                'AR .75', 'AR (M)', 'AR (L)'\n            ]\n\n        info_str = list(zip(stats_names, coco_eval.stats))\n\n        return info_str\n\n    def _sort_and_unique_bboxes(self,\n                                kpts: Dict[int, list],\n                                key: str = 'id') -> Dict[int, list]:\n        \"\"\"Sort keypoint detection results in each image and remove the\n        duplicate ones. Usually performed in multi-batch testing.\n\n        Args:\n            kpts (Dict[int, list]): keypoint prediction results. The keys are\n                '`img_id`' and the values are list that may contain\n                keypoints of multiple persons. Each element in the list is a\n                dict containing the ``'key'`` field.\n                See the argument ``key`` for details.\n            key (str): The key name in each person prediction results. The\n                corresponding value will be used for sorting the results.\n                Default: ``'id'``.\n\n        Returns:\n            Dict[int, list]: The sorted keypoint detection results.\n        \"\"\"\n        for img_id, persons in kpts.items():\n            # deal with bottomup-style output\n            if isinstance(kpts[img_id][0][key], Sequence):\n                return kpts\n            num = len(persons)\n            kpts[img_id] = sorted(kpts[img_id], key=lambda x: x[key])\n            for i in range(num - 1, 0, -1):\n                if kpts[img_id][i][key] == kpts[img_id][i - 1][key]:\n                    del kpts[img_id][i]\n\n        return kpts\n"
  },
  {
    "path": "mmpose/evaluation/metrics/coco_wholebody_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport datetime\nfrom typing import Dict, Optional, Sequence\n\nimport numpy as np\nfrom mmengine.fileio import dump\nfrom xtcocotools.cocoeval import COCOeval\n\nfrom mmpose.registry import METRICS\nfrom .coco_metric import CocoMetric\n\n\n@METRICS.register_module()\nclass CocoWholeBodyMetric(CocoMetric):\n    \"\"\"COCO-WholeBody evaluation metric.\n\n    Evaluate AR, AP, and mAP for COCO-WholeBody keypoint detection tasks.\n    Support COCO-WholeBody dataset. Please refer to\n    `COCO keypoint evaluation <https://cocodataset.org/#keypoints-eval>`__\n    for more details.\n\n    Args:\n        ann_file (str, optional): Path to the coco format annotation file.\n            If not specified, ground truth annotations from the dataset will\n            be converted to coco format. Defaults to None\n        use_area (bool): Whether to use ``'area'`` message in the annotations.\n            If the ground truth annotations (e.g. CrowdPose, AIC) do not have\n            the field ``'area'``, please set ``use_area=False``.\n            Defaults to ``True``\n        iou_type (str): The same parameter as `iouType` in\n            :class:`xtcocotools.COCOeval`, which can be ``'keypoints'``, or\n            ``'keypoints_crowd'`` (used in CrowdPose dataset).\n            Defaults to ``'keypoints'``\n        score_mode (str): The mode to score the prediction results which\n            should be one of the following options:\n\n                - ``'bbox'``: Take the score of bbox as the score of the\n                    prediction results.\n                - ``'bbox_keypoint'``: Use keypoint score to rescore the\n                    prediction results.\n                - ``'bbox_rle'``: Use rle_score to rescore the\n                    prediction results.\n\n            Defaults to ``'bbox_keypoint'`\n        keypoint_score_thr (float): The threshold of keypoint score. The\n            keypoints with score lower than it will not be included to\n            rescore the prediction results. Valid only when ``score_mode`` is\n            ``bbox_keypoint``. Defaults to ``0.2``\n        nms_mode (str): The mode to perform Non-Maximum Suppression (NMS),\n            which should be one of the following options:\n\n                - ``'oks_nms'``: Use Object Keypoint Similarity (OKS) to\n                    perform NMS.\n                - ``'soft_oks_nms'``: Use Object Keypoint Similarity (OKS)\n                    to perform soft NMS.\n                - ``'none'``: Do not perform NMS. Typically for bottomup mode\n                    output.\n\n            Defaults to ``'oks_nms'`\n        nms_thr (float): The Object Keypoint Similarity (OKS) threshold\n            used in NMS when ``nms_mode`` is ``'oks_nms'`` or\n            ``'soft_oks_nms'``. Will retain the prediction results with OKS\n            lower than ``nms_thr``. Defaults to ``0.9``\n        format_only (bool): Whether only format the output results without\n            doing quantitative evaluation. This is designed for the need of\n            test submission when the ground truth annotations are absent. If\n            set to ``True``, ``outfile_prefix`` should specify the path to\n            store the output results. Defaults to ``False``\n        outfile_prefix (str | None): The prefix of json files. It includes\n            the file path and the prefix of filename, e.g., ``'a/b/prefix'``.\n            If not specified, a temp file will be created. Defaults to ``None``\n        **kwargs: Keyword parameters passed to :class:`mmeval.BaseMetric`\n    \"\"\"\n    default_prefix: Optional[str] = 'coco-wholebody'\n    body_num = 17\n    foot_num = 6\n    face_num = 68\n    left_hand_num = 21\n    right_hand_num = 21\n\n    def gt_to_coco_json(self, gt_dicts: Sequence[dict],\n                        outfile_prefix: str) -> str:\n        \"\"\"Convert ground truth to coco format json file.\n\n        Args:\n            gt_dicts (Sequence[dict]): Ground truth of the dataset. Each dict\n                contains the ground truth information about the data sample.\n                Required keys of the each `gt_dict` in `gt_dicts`:\n                    - `img_id`: image id of the data sample\n                    - `width`: original image width\n                    - `height`: original image height\n                    - `raw_ann_info`: the raw annotation information\n                Optional keys:\n                    - `crowd_index`: measure the crowding level of an image,\n                        defined in CrowdPose dataset\n                It is worth mentioning that, in order to compute `CocoMetric`,\n                there are some required keys in the `raw_ann_info`:\n                    - `id`: the id to distinguish different annotations\n                    - `image_id`: the image id of this annotation\n                    - `category_id`: the category of the instance.\n                    - `bbox`: the object bounding box\n                    - `keypoints`: the keypoints cooridinates along with their\n                        visibilities. Note that it need to be aligned\n                        with the official COCO format, e.g., a list with length\n                        N * 3, in which N is the number of keypoints. And each\n                        triplet represent the [x, y, visible] of the keypoint.\n                    - 'keypoints'\n                    - `iscrowd`: indicating whether the annotation is a crowd.\n                        It is useful when matching the detection results to\n                        the ground truth.\n                There are some optional keys as well:\n                    - `area`: it is necessary when `self.use_area` is `True`\n                    - `num_keypoints`: it is necessary when `self.iou_type`\n                        is set as `keypoints_crowd`.\n            outfile_prefix (str): The filename prefix of the json files. If the\n                prefix is \"somepath/xxx\", the json file will be named\n                \"somepath/xxx.gt.json\".\n        Returns:\n            str: The filename of the json file.\n        \"\"\"\n        image_infos = []\n        annotations = []\n        img_ids = []\n        ann_ids = []\n\n        for gt_dict in gt_dicts:\n            # filter duplicate image_info\n            if gt_dict['img_id'] not in img_ids:\n                image_info = dict(\n                    id=gt_dict['img_id'],\n                    width=gt_dict['width'],\n                    height=gt_dict['height'],\n                )\n                if self.iou_type == 'keypoints_crowd':\n                    image_info['crowdIndex'] = gt_dict['crowd_index']\n\n                image_infos.append(image_info)\n                img_ids.append(gt_dict['img_id'])\n\n            # filter duplicate annotations\n            for ann in gt_dict['raw_ann_info']:\n                annotation = dict(\n                    id=ann['id'],\n                    image_id=ann['image_id'],\n                    category_id=ann['category_id'],\n                    bbox=ann['bbox'],\n                    keypoints=ann['keypoints'],\n                    foot_kpts=ann['foot_kpts'],\n                    face_kpts=ann['face_kpts'],\n                    lefthand_kpts=ann['lefthand_kpts'],\n                    righthand_kpts=ann['righthand_kpts'],\n                    iscrowd=ann['iscrowd'],\n                )\n                if self.use_area:\n                    assert 'area' in ann, \\\n                        '`area` is required when `self.use_area` is `True`'\n                    annotation['area'] = ann['area']\n\n                annotations.append(annotation)\n                ann_ids.append(ann['id'])\n\n        info = dict(\n            date_created=str(datetime.datetime.now()),\n            description='Coco json file converted by mmpose CocoMetric.')\n        coco_json: dict = dict(\n            info=info,\n            images=image_infos,\n            categories=self.dataset_meta['CLASSES'],\n            licenses=None,\n            annotations=annotations,\n        )\n        converted_json_path = f'{outfile_prefix}.gt.json'\n        dump(coco_json, converted_json_path, sort_keys=True, indent=4)\n        return converted_json_path\n\n    def results2json(self, keypoints: Dict[int, list],\n                     outfile_prefix: str) -> str:\n        \"\"\"Dump the keypoint detection results to a COCO style json file.\n\n        Args:\n            keypoints (Dict[int, list]): Keypoint detection results\n                of the dataset.\n            outfile_prefix (str): The filename prefix of the json files. If the\n                prefix is \"somepath/xxx\", the json files will be named\n                \"somepath/xxx.keypoints.json\",\n\n        Returns:\n            str: The json file name of keypoint results.\n        \"\"\"\n        # the results with category_id\n        cat_id = 1\n        cat_results = []\n\n        cuts = np.cumsum([\n            0, self.body_num, self.foot_num, self.face_num, self.left_hand_num,\n            self.right_hand_num\n        ]) * 3\n\n        for _, img_kpts in keypoints.items():\n            _keypoints = np.array(\n                [img_kpt['keypoints'] for img_kpt in img_kpts])\n            num_keypoints = self.dataset_meta['num_keypoints']\n            # collect all the person keypoints in current image\n            _keypoints = _keypoints.reshape(-1, num_keypoints * 3)\n\n            result = [{\n                'image_id': img_kpt['img_id'],\n                'category_id': cat_id,\n                'keypoints': _keypoint[cuts[0]:cuts[1]].tolist(),\n                'foot_kpts': _keypoint[cuts[1]:cuts[2]].tolist(),\n                'face_kpts': _keypoint[cuts[2]:cuts[3]].tolist(),\n                'lefthand_kpts': _keypoint[cuts[3]:cuts[4]].tolist(),\n                'righthand_kpts': _keypoint[cuts[4]:cuts[5]].tolist(),\n                'score': float(img_kpt['score']),\n            } for img_kpt, _keypoint in zip(img_kpts, _keypoints)]\n\n            cat_results.extend(result)\n\n        res_file = f'{outfile_prefix}.keypoints.json'\n        dump(cat_results, res_file, sort_keys=True, indent=4)\n\n    def _do_python_keypoint_eval(self, outfile_prefix: str) -> list:\n        \"\"\"Do keypoint evaluation using COCOAPI.\n\n        Args:\n            outfile_prefix (str): The filename prefix of the json files. If the\n                prefix is \"somepath/xxx\", the json files will be named\n                \"somepath/xxx.keypoints.json\",\n\n        Returns:\n            list: a list of tuples. Each tuple contains the evaluation stats\n            name and corresponding stats value.\n        \"\"\"\n        res_file = f'{outfile_prefix}.keypoints.json'\n        coco_det = self.coco.loadRes(res_file)\n        sigmas = self.dataset_meta['sigmas']\n\n        cuts = np.cumsum([\n            0, self.body_num, self.foot_num, self.face_num, self.left_hand_num,\n            self.right_hand_num\n        ])\n\n        coco_eval = COCOeval(\n            self.coco,\n            coco_det,\n            'keypoints_body',\n            sigmas[cuts[0]:cuts[1]],\n            use_area=self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        coco_eval = COCOeval(\n            self.coco,\n            coco_det,\n            'keypoints_foot',\n            sigmas[cuts[1]:cuts[2]],\n            use_area=self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        coco_eval = COCOeval(\n            self.coco,\n            coco_det,\n            'keypoints_face',\n            sigmas[cuts[2]:cuts[3]],\n            use_area=self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        coco_eval = COCOeval(\n            self.coco,\n            coco_det,\n            'keypoints_lefthand',\n            sigmas[cuts[3]:cuts[4]],\n            use_area=self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        coco_eval = COCOeval(\n            self.coco,\n            coco_det,\n            'keypoints_righthand',\n            sigmas[cuts[4]:cuts[5]],\n            use_area=self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        coco_eval = COCOeval(\n            self.coco,\n            coco_det,\n            'keypoints_wholebody',\n            sigmas,\n            use_area=self.use_area)\n        coco_eval.params.useSegm = None\n        coco_eval.evaluate()\n        coco_eval.accumulate()\n        coco_eval.summarize()\n\n        stats_names = [\n            'AP', 'AP .5', 'AP .75', 'AP (M)', 'AP (L)', 'AR', 'AR .5',\n            'AR .75', 'AR (M)', 'AR (L)'\n        ]\n\n        info_str = list(zip(stats_names, coco_eval.stats))\n\n        return info_str\n"
  },
  {
    "path": "mmpose/evaluation/metrics/hand_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, List, Optional, Sequence\n\nimport numpy as np\nfrom mmengine.evaluator import BaseMetric\nfrom mmengine.logging import MMLogger\n\nfrom mmpose.codecs.utils import pixel_to_camera\nfrom mmpose.registry import METRICS\nfrom ..functional import keypoint_epe\n\n\n@METRICS.register_module()\nclass InterHandMetric(BaseMetric):\n\n    METRICS = {'MPJPE', 'MRRPE', 'HandednessAcc'}\n\n    def __init__(self,\n                 modes: List[str] = ['MPJPE', 'MRRPE', 'HandednessAcc'],\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        for mode in modes:\n            if mode not in self.METRICS:\n                raise ValueError(\"`mode` should be 'MPJPE', 'MRRPE', or \"\n                                 f\"'HandednessAcc', but got '{mode}'.\")\n\n        self.modes = modes\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [1, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            _, K, _ = pred_coords.shape\n            pred_coords_cam = pred_coords.copy()\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [1, K, D]\n            gt_coords = gt['keypoints_cam']\n\n            keypoints_cam = gt_coords.copy()\n            # ground truth keypoints_visible, [1, K, 1]\n            mask = gt['keypoints_visible'].astype(bool).reshape(1, -1)\n\n            pred_hand_type = data_sample['pred_instances']['hand_type']\n            gt_hand_type = data_sample['hand_type']\n            if pred_hand_type is None and 'HandednessAcc' in self.modes:\n                raise KeyError('metric HandednessAcc is not supported')\n\n            pred_root_depth = data_sample['pred_instances']['rel_root_depth']\n            if pred_root_depth is None and 'MRRPE' in self.modes:\n                raise KeyError('metric MRRPE is not supported')\n\n            abs_depth = data_sample['abs_depth']\n            focal = data_sample['focal']\n            principal_pt = data_sample['principal_pt']\n\n            result = {}\n\n            if 'MPJPE' in self.modes:\n                keypoints_cam[..., :21, :] -= keypoints_cam[..., 20, :]\n                keypoints_cam[..., 21:, :] -= keypoints_cam[..., 41, :]\n\n                pred_coords_cam[..., :21, 2] += abs_depth[0]\n                pred_coords_cam[..., 21:, 2] += abs_depth[1]\n                pred_coords_cam = pixel_to_camera(pred_coords_cam, focal[0],\n                                                  focal[1], principal_pt[0],\n                                                  principal_pt[1])\n\n                pred_coords_cam[..., :21, :] -= pred_coords_cam[..., 20, :]\n                pred_coords_cam[..., 21:, :] -= pred_coords_cam[..., 41, :]\n\n                if gt_hand_type.all():\n                    single_mask = np.zeros((1, K), dtype=bool)\n                    interacting_mask = mask\n                else:\n                    single_mask = mask\n                    interacting_mask = np.zeros((1, K), dtype=bool)\n\n                result['pred_coords'] = pred_coords_cam\n                result['gt_coords'] = keypoints_cam\n                result['mask'] = mask\n                result['single_mask'] = single_mask\n                result['interacting_mask'] = interacting_mask\n\n            if 'HandednessAcc' in self.modes:\n                hand_type_mask = data_sample['hand_type_valid'] > 0\n                result['pred_hand_type'] = pred_hand_type\n                result['gt_hand_type'] = gt_hand_type\n                result['hand_type_mask'] = hand_type_mask\n\n            if 'MRRPE' in self.modes:\n                keypoints_visible = gt['keypoints_visible']\n                if gt_hand_type.all() and keypoints_visible[\n                        ..., 20] and keypoints_visible[..., 41]:\n                    rel_root_mask = np.array([True])\n\n                    pred_left_root_coords = np.array(\n                        pred_coords[..., 41, :], dtype=np.float32)\n                    pred_left_root_coords[...,\n                                          2] += abs_depth[0] + pred_root_depth\n                    pred_left_root_coords = pixel_to_camera(\n                        pred_left_root_coords, focal[0], focal[1],\n                        principal_pt[0], principal_pt[1])\n\n                    pred_right_root_coords = np.array(\n                        pred_coords[..., 20, :], dtype=np.float32)\n                    pred_right_root_coords[..., 2] += abs_depth[0]\n                    pred_right_root_coords = pixel_to_camera(\n                        pred_right_root_coords, focal[0], focal[1],\n                        principal_pt[0], principal_pt[1])\n                    pred_rel_root_coords = pred_left_root_coords - \\\n                        pred_right_root_coords\n                    pred_rel_root_coords = np.expand_dims(\n                        pred_rel_root_coords, axis=0)\n                    gt_rel_root_coords = gt_coords[...,\n                                                   41, :] - gt_coords[...,\n                                                                      20, :]\n                    gt_rel_root_coords = np.expand_dims(\n                        gt_rel_root_coords, axis=0)\n                else:\n                    rel_root_mask = np.array([False])\n                    pred_rel_root_coords = np.array([[0, 0, 0]])\n                    pred_rel_root_coords = pred_rel_root_coords.reshape(\n                        1, 1, 3)\n                    gt_rel_root_coords = np.array([[0, 0, 0]]).reshape(1, 1, 3)\n\n                result['pred_rel_root_coords'] = pred_rel_root_coords\n                result['gt_rel_root_coords'] = gt_rel_root_coords\n                result['rel_root_mask'] = rel_root_mask\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        metrics = dict()\n\n        logger.info(f'Evaluating {self.__class__.__name__}...')\n\n        if 'MPJPE' in self.modes:\n            # pred_coords: [N, K, D]\n            pred_coords = np.concatenate(\n                [result['pred_coords'] for result in results])\n            # gt_coords: [N, K, D]\n            gt_coords = np.concatenate(\n                [result['gt_coords'] for result in results])\n            # mask: [N, K]\n            mask = np.concatenate([result['mask'] for result in results])\n            single_mask = np.concatenate(\n                [result['single_mask'] for result in results])\n            interacting_mask = np.concatenate(\n                [result['interacting_mask'] for result in results])\n\n            metrics['MPJPE_all'] = keypoint_epe(pred_coords, gt_coords, mask)\n            metrics['MPJPE_single'] = keypoint_epe(pred_coords, gt_coords,\n                                                   single_mask)\n            metrics['MPJPE_interacting'] = keypoint_epe(\n                pred_coords, gt_coords, interacting_mask)\n\n        if 'HandednessAcc' in self.modes:\n            pred_hand_type = np.concatenate(\n                [result['pred_hand_type'] for result in results])\n            gt_hand_type = np.concatenate(\n                [result['gt_hand_type'] for result in results])\n            hand_type_mask = np.concatenate(\n                [result['hand_type_mask'] for result in results])\n            acc = (pred_hand_type == gt_hand_type).all(axis=-1)\n            metrics['HandednessAcc'] = np.mean(acc[hand_type_mask])\n\n        if 'MRRPE' in self.modes:\n            pred_rel_root_coords = np.concatenate(\n                [result['pred_rel_root_coords'] for result in results])\n            gt_rel_root_coords = np.concatenate(\n                [result['gt_rel_root_coords'] for result in results])\n            rel_root_mask = np.array(\n                [result['rel_root_mask'] for result in results])\n            metrics['MRRPE'] = keypoint_epe(pred_rel_root_coords,\n                                            gt_rel_root_coords, rel_root_mask)\n        return metrics\n"
  },
  {
    "path": "mmpose/evaluation/metrics/keypoint_2d_metrics.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import Dict, Optional, Sequence, Union\n\nimport numpy as np\nfrom mmengine.evaluator import BaseMetric\nfrom mmengine.logging import MMLogger\n\nfrom mmpose.registry import METRICS\nfrom ..functional import (keypoint_auc, keypoint_epe, keypoint_nme,\n                          keypoint_pck_accuracy)\n\n\n@METRICS.register_module()\nclass PCKAccuracy(BaseMetric):\n    \"\"\"PCK accuracy evaluation metric.\n    Calculate the pose accuracy of Percentage of Correct Keypoints (PCK) for\n    each individual keypoint and the averaged accuracy across all keypoints.\n    PCK metric measures accuracy of the localization of the body joints.\n    The distances between predicted positions and the ground-truth ones\n    are typically normalized by the person bounding box size.\n    The threshold (thr) of the normalized distance is commonly set\n    as 0.05, 0.1 or 0.2 etc.\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n    Args:\n        thr(float): Threshold of PCK calculation. Default: 0.05.\n        norm_item (str | Sequence[str]): The item used for normalization.\n            Valid items include 'bbox', 'head', 'torso', which correspond\n            to 'PCK', 'PCKh' and 'tPCK' respectively. Default: ``'bbox'``.\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n\n    Examples:\n\n        >>> from mmpose.evaluation.metrics import PCKAccuracy\n        >>> import numpy as np\n        >>> from mmengine.structures import InstanceData\n        >>> num_keypoints = 15\n        >>> keypoints = np.random.random((1, num_keypoints, 2)) * 10\n        >>> gt_instances = InstanceData()\n        >>> gt_instances.keypoints = keypoints\n        >>> gt_instances.keypoints_visible = np.ones(\n        ...     (1, num_keypoints, 1)).astype(bool)\n        >>> gt_instances.bboxes = np.random.random((1, 4)) * 20\n        >>> pred_instances = InstanceData()\n        >>> pred_instances.keypoints = keypoints\n        >>> data_sample = {\n        ...     'gt_instances': gt_instances.to_dict(),\n        ...     'pred_instances': pred_instances.to_dict(),\n        ... }\n        >>> data_samples = [data_sample]\n        >>> data_batch = [{'inputs': None}]\n        >>> pck_metric = PCKAccuracy(thr=0.5, norm_item='bbox')\n        ...: UserWarning: The prefix is not set in metric class PCKAccuracy.\n        >>> pck_metric.process(data_batch, data_samples)\n        >>> pck_metric.evaluate(1)\n        10/26 15:37:57 - mmengine - INFO - Evaluating PCKAccuracy (normalized by ``\"bbox_size\"``)...  # noqa\n        {'PCK': 1.0}\n\n    \"\"\"\n\n    def __init__(self,\n                 thr: float = 0.05,\n                 norm_item: Union[str, Sequence[str]] = 'bbox',\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        self.thr = thr\n        self.norm_item = norm_item if isinstance(norm_item,\n                                                 (tuple,\n                                                  list)) else [norm_item]\n        allow_normalized_items = ['bbox', 'head', 'torso']\n        for item in self.norm_item:\n            if item not in allow_normalized_items:\n                raise KeyError(\n                    f'The normalized item {item} is not supported by '\n                    f\"{self.__class__.__name__}. Should be one of 'bbox', \"\n                    f\"'head', 'torso', but got {item}.\")\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions.\n\n        The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [1, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [1, K, D]\n            gt_coords = gt['keypoints']\n            # ground truth keypoints_visible, [1, K, 1]\n            mask = gt['keypoints_visible'].astype(bool)\n            if mask.ndim == 3:\n                mask = mask[:, :, 0]\n            mask = mask.reshape(1, -1)\n\n            result = {\n                'pred_coords': pred_coords,\n                'gt_coords': gt_coords,\n                'mask': mask,\n            }\n\n            if 'bbox' in self.norm_item:\n                assert 'bboxes' in gt, 'The ground truth data info do not ' \\\n                    'have the expected normalized_item ``\"bbox\"``.'\n                # ground truth bboxes, [1, 4]\n                bbox_size_ = np.max(gt['bboxes'][0][2:] - gt['bboxes'][0][:2])\n                bbox_size = np.array([bbox_size_, bbox_size_]).reshape(-1, 2)\n                result['bbox_size'] = bbox_size\n\n            if 'head' in self.norm_item:\n                assert 'head_size' in gt, 'The ground truth data info do ' \\\n                    'not have the expected normalized_item ``\"head_size\"``.'\n                # ground truth bboxes\n                head_size_ = gt['head_size']\n                head_size = np.array([head_size_, head_size_]).reshape(-1, 2)\n                result['head_size'] = head_size\n\n            if 'torso' in self.norm_item:\n                # used in JhmdbDataset\n                torso_size_ = np.linalg.norm(gt_coords[0][4] - gt_coords[0][5])\n                if torso_size_ < 1:\n                    torso_size_ = np.linalg.norm(pred_coords[0][4] -\n                                                 pred_coords[0][5])\n                    warnings.warn('Ground truth torso size < 1. '\n                                  'Use torso size from predicted '\n                                  'keypoint results instead.')\n                torso_size = np.array([torso_size_,\n                                       torso_size_]).reshape(-1, 2)\n                result['torso_size'] = torso_size\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n            The returned result dict may have the following keys:\n                - 'PCK': The pck accuracy normalized by `bbox_size`.\n                - 'PCKh': The pck accuracy normalized by `head_size`.\n                - 'tPCK': The pck accuracy normalized by `torso_size`.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        metrics = dict()\n        if 'bbox' in self.norm_item:\n            norm_size_bbox = np.concatenate(\n                [result['bbox_size'] for result in results])\n\n            logger.info(f'Evaluating {self.__class__.__name__} '\n                        f'(normalized by ``\"bbox_size\"``)...')\n\n            _, pck, _ = keypoint_pck_accuracy(pred_coords, gt_coords, mask,\n                                              self.thr, norm_size_bbox)\n            metrics['PCK'] = pck\n\n        if 'head' in self.norm_item:\n            norm_size_head = np.concatenate(\n                [result['head_size'] for result in results])\n\n            logger.info(f'Evaluating {self.__class__.__name__} '\n                        f'(normalized by ``\"head_size\"``)...')\n\n            _, pckh, _ = keypoint_pck_accuracy(pred_coords, gt_coords, mask,\n                                               self.thr, norm_size_head)\n            metrics['PCKh'] = pckh\n\n        if 'torso' in self.norm_item:\n            norm_size_torso = np.concatenate(\n                [result['torso_size'] for result in results])\n\n            logger.info(f'Evaluating {self.__class__.__name__} '\n                        f'(normalized by ``\"torso_size\"``)...')\n\n            _, tpck, _ = keypoint_pck_accuracy(pred_coords, gt_coords, mask,\n                                               self.thr, norm_size_torso)\n            metrics['tPCK'] = tpck\n\n        return metrics\n\n\n@METRICS.register_module()\nclass MpiiPCKAccuracy(PCKAccuracy):\n    \"\"\"PCKh accuracy evaluation metric for MPII dataset.\n\n    Calculate the pose accuracy of Percentage of Correct Keypoints (PCK) for\n    each individual keypoint and the averaged accuracy across all keypoints.\n    PCK metric measures accuracy of the localization of the body joints.\n    The distances between predicted positions and the ground-truth ones\n    are typically normalized by the person bounding box size.\n    The threshold (thr) of the normalized distance is commonly set\n    as 0.05, 0.1 or 0.2 etc.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        thr(float): Threshold of PCK calculation. Default: 0.05.\n        norm_item (str | Sequence[str]): The item used for normalization.\n            Valid items include 'bbox', 'head', 'torso', which correspond\n            to 'PCK', 'PCKh' and 'tPCK' respectively. Default: ``'head'``.\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n\n    Examples:\n\n        >>> from mmpose.evaluation.metrics import MpiiPCKAccuracy\n        >>> import numpy as np\n        >>> from mmengine.structures import InstanceData\n        >>> num_keypoints = 16\n        >>> keypoints = np.random.random((1, num_keypoints, 2)) * 10\n        >>> gt_instances = InstanceData()\n        >>> gt_instances.keypoints = keypoints + 1.0\n        >>> gt_instances.keypoints_visible = np.ones(\n        ...     (1, num_keypoints, 1)).astype(bool)\n        >>> gt_instances.head_size = np.random.random((1, 1)) * 10\n        >>> pred_instances = InstanceData()\n        >>> pred_instances.keypoints = keypoints\n        >>> data_sample = {\n        ...     'gt_instances': gt_instances.to_dict(),\n        ...     'pred_instances': pred_instances.to_dict(),\n        ... }\n        >>> data_samples = [data_sample]\n        >>> data_batch = [{'inputs': None}]\n        >>> mpii_pck_metric = MpiiPCKAccuracy(thr=0.3, norm_item='head')\n        ... UserWarning: The prefix is not set in metric class MpiiPCKAccuracy.\n        >>> mpii_pck_metric.process(data_batch, data_samples)\n        >>> mpii_pck_metric.evaluate(1)\n        10/26 17:43:39 - mmengine - INFO - Evaluating MpiiPCKAccuracy (normalized by ``\"head_size\"``)...  # noqa\n        {'Head PCK': 100.0, 'Shoulder PCK': 100.0, 'Elbow PCK': 100.0,\n        Wrist PCK': 100.0, 'Hip PCK': 100.0, 'Knee PCK': 100.0,\n        'Ankle PCK': 100.0, 'PCK': 100.0, 'PCK@0.1': 100.0}\n    \"\"\"\n\n    def __init__(self,\n                 thr: float = 0.5,\n                 norm_item: Union[str, Sequence[str]] = 'head',\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(\n            thr=thr,\n            norm_item=norm_item,\n            collect_device=collect_device,\n            prefix=prefix)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n            If `'head'` in `self.norm_item`, the returned results are the pck\n            accuracy normalized by `head_size`, which have the following keys:\n                - 'Head PCK': The PCK of head\n                - 'Shoulder PCK': The PCK of shoulder\n                - 'Elbow PCK': The PCK of elbow\n                - 'Wrist PCK': The PCK of wrist\n                - 'Hip PCK': The PCK of hip\n                - 'Knee PCK': The PCK of knee\n                - 'Ankle PCK': The PCK of ankle\n                - 'PCK': The mean PCK over all keypoints\n                - 'PCK@0.1': The mean PCK at threshold 0.1\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        # MPII uses matlab format, gt index is 1-based,\n        # convert 0-based index to 1-based index\n        pred_coords = pred_coords + 1.0\n\n        metrics = {}\n        if 'head' in self.norm_item:\n            norm_size_head = np.concatenate(\n                [result['head_size'] for result in results])\n\n            logger.info(f'Evaluating {self.__class__.__name__} '\n                        f'(normalized by ``\"head_size\"``)...')\n\n            pck_p, _, _ = keypoint_pck_accuracy(pred_coords, gt_coords, mask,\n                                                self.thr, norm_size_head)\n\n            jnt_count = np.sum(mask, axis=0)\n            PCKh = 100. * pck_p\n\n            rng = np.arange(0, 0.5 + 0.01, 0.01)\n            pckAll = np.zeros((len(rng), 16), dtype=np.float32)\n\n            for r, threshold in enumerate(rng):\n                _pck, _, _ = keypoint_pck_accuracy(pred_coords, gt_coords,\n                                                   mask, threshold,\n                                                   norm_size_head)\n                pckAll[r, :] = 100. * _pck\n\n            PCKh = np.ma.array(PCKh, mask=False)\n            PCKh.mask[6:8] = True\n\n            jnt_count = np.ma.array(jnt_count, mask=False)\n            jnt_count.mask[6:8] = True\n            jnt_ratio = jnt_count / np.sum(jnt_count).astype(np.float64)\n\n            # dataset_joints_idx:\n            #   head 9\n            #   lsho 13  rsho 12\n            #   lelb 14  relb 11\n            #   lwri 15  rwri 10\n            #   lhip 3   rhip 2\n            #   lkne 4   rkne 1\n            #   lank 5   rank 0\n            stats = {\n                'Head PCK': PCKh[9],\n                'Shoulder PCK': 0.5 * (PCKh[13] + PCKh[12]),\n                'Elbow PCK': 0.5 * (PCKh[14] + PCKh[11]),\n                'Wrist PCK': 0.5 * (PCKh[15] + PCKh[10]),\n                'Hip PCK': 0.5 * (PCKh[3] + PCKh[2]),\n                'Knee PCK': 0.5 * (PCKh[4] + PCKh[1]),\n                'Ankle PCK': 0.5 * (PCKh[5] + PCKh[0]),\n                'PCK': np.sum(PCKh * jnt_ratio),\n                'PCK@0.1': np.sum(pckAll[10, :] * jnt_ratio)\n            }\n\n            for stats_name, stat in stats.items():\n                metrics[stats_name] = stat\n\n        return metrics\n\n\n@METRICS.register_module()\nclass JhmdbPCKAccuracy(PCKAccuracy):\n    \"\"\"PCK accuracy evaluation metric for Jhmdb dataset.\n\n    Calculate the pose accuracy of Percentage of Correct Keypoints (PCK) for\n    each individual keypoint and the averaged accuracy across all keypoints.\n    PCK metric measures accuracy of the localization of the body joints.\n    The distances between predicted positions and the ground-truth ones\n    are typically normalized by the person bounding box size.\n    The threshold (thr) of the normalized distance is commonly set\n    as 0.05, 0.1 or 0.2 etc.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        thr(float): Threshold of PCK calculation. Default: 0.05.\n        norm_item (str | Sequence[str]): The item used for normalization.\n            Valid items include 'bbox', 'head', 'torso', which correspond\n            to 'PCK', 'PCKh' and 'tPCK' respectively. Default: ``'bbox'``.\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n\n    Examples:\n\n        >>> from mmpose.evaluation.metrics import JhmdbPCKAccuracy\n        >>> import numpy as np\n        >>> from mmengine.structures import InstanceData\n        >>> num_keypoints = 15\n        >>> keypoints = np.random.random((1, num_keypoints, 2)) * 10\n        >>> gt_instances = InstanceData()\n        >>> gt_instances.keypoints = keypoints\n        >>> gt_instances.keypoints_visible = np.ones(\n        ...     (1, num_keypoints, 1)).astype(bool)\n        >>> gt_instances.bboxes = np.random.random((1, 4)) * 20\n        >>> gt_instances.head_size = np.random.random((1, 1)) * 10\n        >>> pred_instances = InstanceData()\n        >>> pred_instances.keypoints = keypoints\n        >>> data_sample = {\n        ...     'gt_instances': gt_instances.to_dict(),\n        ...     'pred_instances': pred_instances.to_dict(),\n        ... }\n        >>> data_samples = [data_sample]\n        >>> data_batch = [{'inputs': None}]\n        >>> jhmdb_pck_metric = JhmdbPCKAccuracy(thr=0.2, norm_item=['bbox', 'torso'])\n        ... UserWarning: The prefix is not set in metric class JhmdbPCKAccuracy.\n        >>> jhmdb_pck_metric.process(data_batch, data_samples)\n        >>> jhmdb_pck_metric.evaluate(1)\n        10/26 17:48:09 - mmengine - INFO - Evaluating JhmdbPCKAccuracy (normalized by ``\"bbox_size\"``)...  # noqa\n        10/26 17:48:09 - mmengine - INFO - Evaluating JhmdbPCKAccuracy (normalized by ``\"torso_size\"``)...  # noqa\n        {'Head PCK': 1.0, 'Sho PCK': 1.0, 'Elb PCK': 1.0, 'Wri PCK': 1.0,\n        'Hip PCK': 1.0, 'Knee PCK': 1.0, 'Ank PCK': 1.0, 'PCK': 1.0,\n        'Head tPCK': 1.0, 'Sho tPCK': 1.0, 'Elb tPCK': 1.0, 'Wri tPCK': 1.0,\n        'Hip tPCK': 1.0, 'Knee tPCK': 1.0, 'Ank tPCK': 1.0, 'tPCK': 1.0}\n    \"\"\"\n\n    def __init__(self,\n                 thr: float = 0.05,\n                 norm_item: Union[str, Sequence[str]] = 'bbox',\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(\n            thr=thr,\n            norm_item=norm_item,\n            collect_device=collect_device,\n            prefix=prefix)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n            If `'bbox'` in `self.norm_item`, the returned results are the pck\n            accuracy normalized by `bbox_size`, which have the following keys:\n                - 'Head PCK': The PCK of head\n                - 'Sho PCK': The PCK of shoulder\n                - 'Elb PCK': The PCK of elbow\n                - 'Wri PCK': The PCK of wrist\n                - 'Hip PCK': The PCK of hip\n                - 'Knee PCK': The PCK of knee\n                - 'Ank PCK': The PCK of ankle\n                - 'PCK': The mean PCK over all keypoints\n            If `'torso'` in `self.norm_item`, the returned results are the pck\n            accuracy normalized by `torso_size`, which have the following keys:\n                - 'Head tPCK': The PCK of head\n                - 'Sho tPCK': The PCK of shoulder\n                - 'Elb tPCK': The PCK of elbow\n                - 'Wri tPCK': The PCK of wrist\n                - 'Hip tPCK': The PCK of hip\n                - 'Knee tPCK': The PCK of knee\n                - 'Ank tPCK': The PCK of ankle\n                - 'tPCK': The mean PCK over all keypoints\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        metrics = dict()\n        if 'bbox' in self.norm_item:\n            norm_size_bbox = np.concatenate(\n                [result['bbox_size'] for result in results])\n\n            logger.info(f'Evaluating {self.__class__.__name__} '\n                        f'(normalized by ``\"bbox_size\"``)...')\n\n            pck_p, pck, _ = keypoint_pck_accuracy(pred_coords, gt_coords, mask,\n                                                  self.thr, norm_size_bbox)\n            stats = {\n                'Head PCK': pck_p[2],\n                'Sho PCK': 0.5 * pck_p[3] + 0.5 * pck_p[4],\n                'Elb PCK': 0.5 * pck_p[7] + 0.5 * pck_p[8],\n                'Wri PCK': 0.5 * pck_p[11] + 0.5 * pck_p[12],\n                'Hip PCK': 0.5 * pck_p[5] + 0.5 * pck_p[6],\n                'Knee PCK': 0.5 * pck_p[9] + 0.5 * pck_p[10],\n                'Ank PCK': 0.5 * pck_p[13] + 0.5 * pck_p[14],\n                'PCK': pck\n            }\n\n            for stats_name, stat in stats.items():\n                metrics[stats_name] = stat\n\n        if 'torso' in self.norm_item:\n            norm_size_torso = np.concatenate(\n                [result['torso_size'] for result in results])\n\n            logger.info(f'Evaluating {self.__class__.__name__} '\n                        f'(normalized by ``\"torso_size\"``)...')\n\n            pck_p, pck, _ = keypoint_pck_accuracy(pred_coords, gt_coords, mask,\n                                                  self.thr, norm_size_torso)\n\n            stats = {\n                'Head tPCK': pck_p[2],\n                'Sho tPCK': 0.5 * pck_p[3] + 0.5 * pck_p[4],\n                'Elb tPCK': 0.5 * pck_p[7] + 0.5 * pck_p[8],\n                'Wri tPCK': 0.5 * pck_p[11] + 0.5 * pck_p[12],\n                'Hip tPCK': 0.5 * pck_p[5] + 0.5 * pck_p[6],\n                'Knee tPCK': 0.5 * pck_p[9] + 0.5 * pck_p[10],\n                'Ank tPCK': 0.5 * pck_p[13] + 0.5 * pck_p[14],\n                'tPCK': pck\n            }\n\n            for stats_name, stat in stats.items():\n                metrics[stats_name] = stat\n\n        return metrics\n\n\n@METRICS.register_module()\nclass AUC(BaseMetric):\n    \"\"\"AUC evaluation metric.\n\n    Calculate the Area Under Curve (AUC) of keypoint PCK accuracy.\n\n    By altering the threshold percentage in the calculation of PCK accuracy,\n    AUC can be generated to further evaluate the pose estimation algorithms.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        norm_factor (float): AUC normalization factor, Default: 30 (pixels).\n        num_thrs (int): number of thresholds to calculate auc. Default: 20.\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n    \"\"\"\n\n    def __init__(self,\n                 norm_factor: float = 30,\n                 num_thrs: int = 20,\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        self.norm_factor = norm_factor\n        self.num_thrs = num_thrs\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_sample (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [1, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [1, K, D]\n            gt_coords = gt['keypoints']\n            # ground truth keypoints_visible, [1, K, 1]\n            mask = gt['keypoints_visible'].astype(bool)\n            if mask.ndim == 3:\n                mask = mask[:, :, 0]\n            mask = mask.reshape(1, -1)\n\n            result = {\n                'pred_coords': pred_coords,\n                'gt_coords': gt_coords,\n                'mask': mask,\n            }\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        logger.info(f'Evaluating {self.__class__.__name__}...')\n\n        auc = keypoint_auc(pred_coords, gt_coords, mask, self.norm_factor,\n                           self.num_thrs)\n\n        metrics = dict()\n        metrics['AUC'] = auc\n\n        return metrics\n\n\n@METRICS.register_module()\nclass EPE(BaseMetric):\n    \"\"\"EPE evaluation metric.\n\n    Calculate the end-point error (EPE) of keypoints.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n    \"\"\"\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [1, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [1, K, D]\n            gt_coords = gt['keypoints']\n            # ground truth keypoints_visible, [1, K, 1]\n            mask = gt['keypoints_visible'].astype(bool)\n            if mask.ndim == 3:\n                mask = mask[:, :, 0]\n            mask = mask.reshape(1, -1)\n\n            result = {\n                'pred_coords': pred_coords,\n                'gt_coords': gt_coords,\n                'mask': mask,\n            }\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        logger.info(f'Evaluating {self.__class__.__name__}...')\n\n        epe = keypoint_epe(pred_coords, gt_coords, mask)\n\n        metrics = dict()\n        metrics['EPE'] = epe\n\n        return metrics\n\n\n@METRICS.register_module()\nclass NME(BaseMetric):\n    \"\"\"NME evaluation metric.\n\n    Calculate the normalized mean error (NME) of keypoints.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        norm_mode (str): The normalization mode. There are two valid modes:\n            `'use_norm_item'` and `'keypoint_distance'`.\n            When set as `'use_norm_item'`, should specify the argument\n            `norm_item`, which represents the item in the datainfo that\n            will be used as the normalization factor.\n            When set as `'keypoint_distance'`, should specify the argument\n            `keypoint_indices` that are used to calculate the keypoint\n            distance as the normalization factor.\n        norm_item (str, optional): The item used as the normalization factor.\n            For example, `'bbox_size'` in `'AFLWDataset'`. Only valid when\n            ``norm_mode`` is ``use_norm_item``.\n            Default: ``None``.\n        keypoint_indices (Sequence[int], optional): The keypoint indices used\n            to calculate the keypoint distance as the normalization factor.\n            Only valid when ``norm_mode`` is ``keypoint_distance``.\n            If set as None, will use the default ``keypoint_indices`` in\n            `DEFAULT_KEYPOINT_INDICES` for specific datasets, else use the\n            given ``keypoint_indices`` of the dataset. Default: ``None``.\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n    \"\"\"\n\n    DEFAULT_KEYPOINT_INDICES = {\n        # horse10: corresponding to `nose` and `eye` keypoints\n        'horse10': [0, 1],\n        # 300w: corresponding to `right-most` and `left-most` eye keypoints\n        '300w': [36, 45],\n        # coco_wholebody_face corresponding to `right-most` and `left-most`\n        # eye keypoints\n        'coco_wholebody_face': [36, 45],\n        # cofw: corresponding to `right-most` and `left-most` eye keypoints\n        'cofw': [8, 9],\n        # wflw: corresponding to `right-most` and `left-most` eye keypoints\n        'wflw': [60, 72],\n        # lapa: corresponding to `right-most` and `left-most` eye keypoints\n        'lapa': [66, 79],\n    }\n\n    def __init__(self,\n                 norm_mode: str,\n                 norm_item: Optional[str] = None,\n                 keypoint_indices: Optional[Sequence[int]] = None,\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        allowed_norm_modes = ['use_norm_item', 'keypoint_distance']\n        if norm_mode not in allowed_norm_modes:\n            raise KeyError(\"`norm_mode` should be 'use_norm_item' or \"\n                           f\"'keypoint_distance', but got {norm_mode}.\")\n\n        self.norm_mode = norm_mode\n        if self.norm_mode == 'use_norm_item':\n            if not norm_item:\n                raise KeyError('`norm_mode` is set to `\"use_norm_item\"`, '\n                               'please specify the `norm_item` in the '\n                               'datainfo used as the normalization factor.')\n        self.norm_item = norm_item\n        self.keypoint_indices = keypoint_indices\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [1, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [1, K, D]\n            gt_coords = gt['keypoints']\n            # ground truth keypoints_visible, [1, K, 1]\n            mask = gt['keypoints_visible'].astype(bool)\n            if mask.ndim == 3:\n                mask = mask[:, :, 0]\n            mask = mask.reshape(1, -1)\n\n            result = {\n                'pred_coords': pred_coords,\n                'gt_coords': gt_coords,\n                'mask': mask,\n            }\n\n            if self.norm_item:\n                if self.norm_item == 'bbox_size':\n                    assert 'bboxes' in gt, 'The ground truth data info do ' \\\n                        'not have the item ``bboxes`` for expected ' \\\n                        'normalized_item ``\"bbox_size\"``.'\n                    # ground truth bboxes, [1, 4]\n                    bbox_size = np.max(gt['bboxes'][0][2:] -\n                                       gt['bboxes'][0][:2])\n                    result['bbox_size'] = np.array([bbox_size]).reshape(-1, 1)\n                else:\n                    assert self.norm_item in gt, f'The ground truth data ' \\\n                        f'info do not have the expected normalized factor ' \\\n                        f'\"{self.norm_item}\"'\n                    # ground truth norm_item\n                    result[self.norm_item] = np.array(\n                        gt[self.norm_item]).reshape([-1, 1])\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        logger.info(f'Evaluating {self.__class__.__name__}...')\n        metrics = dict()\n\n        if self.norm_mode == 'use_norm_item':\n            normalize_factor_ = np.concatenate(\n                [result[self.norm_item] for result in results])\n            # normalize_factor: [N, 2]\n            normalize_factor = np.tile(normalize_factor_, [1, 2])\n            nme = keypoint_nme(pred_coords, gt_coords, mask, normalize_factor)\n            metrics['NME'] = nme\n\n        else:\n            if self.keypoint_indices is None:\n                # use default keypoint_indices in some datasets\n                dataset_name = self.dataset_meta['dataset_name']\n                if dataset_name not in self.DEFAULT_KEYPOINT_INDICES:\n                    raise KeyError(\n                        '`norm_mode` is set to `keypoint_distance`, and the '\n                        'keypoint_indices is set to None, can not find the '\n                        'keypoint_indices in `DEFAULT_KEYPOINT_INDICES`, '\n                        'please specify `keypoint_indices` appropriately.')\n                self.keypoint_indices = self.DEFAULT_KEYPOINT_INDICES[\n                    dataset_name]\n            else:\n                assert len(self.keypoint_indices) == 2, 'The keypoint '\\\n                    'indices used for normalization should be a pair.'\n                keypoint_id2name = self.dataset_meta['keypoint_id2name']\n                dataset_name = self.dataset_meta['dataset_name']\n                for idx in self.keypoint_indices:\n                    assert idx in keypoint_id2name, f'The {dataset_name} '\\\n                        f'dataset does not contain the required '\\\n                        f'{idx}-th keypoint.'\n            # normalize_factor: [N, 2]\n            normalize_factor = self._get_normalize_factor(gt_coords=gt_coords)\n            nme = keypoint_nme(pred_coords, gt_coords, mask, normalize_factor)\n            metrics['NME'] = nme\n\n        return metrics\n\n    def _get_normalize_factor(self, gt_coords: np.ndarray) -> np.ndarray:\n        \"\"\"Get the normalize factor. generally inter-ocular distance measured\n        as the Euclidean distance between the outer corners of the eyes is\n        used.\n\n        Args:\n            gt_coords (np.ndarray[N, K, 2]): Groundtruth keypoint coordinates.\n\n        Returns:\n            np.ndarray[N, 2]: normalized factor\n        \"\"\"\n        idx1, idx2 = self.keypoint_indices\n\n        interocular = np.linalg.norm(\n            gt_coords[:, idx1, :] - gt_coords[:, idx2, :],\n            axis=1,\n            keepdims=True)\n\n        return np.tile(interocular, [1, 2])\n"
  },
  {
    "path": "mmpose/evaluation/metrics/keypoint_3d_metrics.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import defaultdict\nfrom os import path as osp\nfrom typing import Dict, List, Optional, Sequence\n\nimport numpy as np\nfrom mmengine.evaluator import BaseMetric\nfrom mmengine.logging import MMLogger\n\nfrom mmpose.registry import METRICS\nfrom ..functional import keypoint_mpjpe\n\n\n@METRICS.register_module()\nclass MPJPE(BaseMetric):\n    \"\"\"MPJPE evaluation metric.\n\n    Calculate the mean per-joint position error (MPJPE) of keypoints.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        mode (str): Method to align the prediction with the\n            ground truth. Supported options are:\n\n                - ``'mpjpe'``: no alignment will be applied\n                - ``'p-mpjpe'``: align in the least-square sense in scale\n                - ``'n-mpjpe'``: align in the least-square sense in\n                    scale, rotation, and translation.\n\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n        skip_list (list, optional): The list of subject and action combinations\n            to be skipped. Default: [].\n    \"\"\"\n\n    ALIGNMENT = {'mpjpe': 'none', 'p-mpjpe': 'procrustes', 'n-mpjpe': 'scale'}\n\n    def __init__(self,\n                 mode: str = 'mpjpe',\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None,\n                 skip_list: List[str] = []) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        allowed_modes = self.ALIGNMENT.keys()\n        if mode not in allowed_modes:\n            raise KeyError(\"`mode` should be 'mpjpe', 'p-mpjpe', or \"\n                           f\"'n-mpjpe', but got '{mode}'.\")\n\n        self.mode = mode\n        self.skip_list = skip_list\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [T, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            if pred_coords.ndim == 4:\n                pred_coords = np.squeeze(pred_coords, axis=0)\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [T, K, D]\n            gt_coords = gt['lifting_target']\n            # ground truth keypoints_visible, [T, K, 1]\n            mask = gt['lifting_target_visible'].astype(bool).reshape(\n                gt_coords.shape[0], -1)\n            # instance action\n            img_path = data_sample['target_img_path'][0]\n            _, rest = osp.basename(img_path).split('_', 1)\n            action, _ = rest.split('.', 1)\n            actions = np.array([action] * gt_coords.shape[0])\n\n            subj_act = osp.basename(img_path).split('.')[0]\n            if subj_act in self.skip_list:\n                continue\n\n            result = {\n                'pred_coords': pred_coords,\n                'gt_coords': gt_coords,\n                'mask': mask,\n                'actions': actions\n            }\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are the corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n        # action_category_indices: Dict[List[int]]\n        action_category_indices = defaultdict(list)\n        actions = np.concatenate([result['actions'] for result in results])\n        for idx, action in enumerate(actions):\n            action_category = action.split('_')[0]\n            action_category_indices[action_category].append(idx)\n\n        error_name = self.mode.upper()\n\n        logger.info(f'Evaluating {self.mode.upper()}...')\n        metrics = dict()\n\n        metrics[error_name] = keypoint_mpjpe(pred_coords, gt_coords, mask,\n                                             self.ALIGNMENT[self.mode])\n\n        for action_category, indices in action_category_indices.items():\n            metrics[f'{error_name}_{action_category}'] = keypoint_mpjpe(\n                pred_coords[indices], gt_coords[indices], mask[indices],\n                self.ALIGNMENT[self.mode])\n\n        return metrics\n"
  },
  {
    "path": "mmpose/evaluation/metrics/keypoint_partition_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom collections import OrderedDict\nfrom copy import deepcopy\nfrom typing import Sequence\n\nimport numpy as np\nfrom mmengine.evaluator import BaseMetric\n\nfrom mmpose.registry import METRICS\n\n\n@METRICS.register_module()\nclass KeypointPartitionMetric(BaseMetric):\n    \"\"\"Wrapper metric for evaluating pose metric on user-defined body parts.\n\n    Sometimes one may be interested in the performance of a pose model on\n    certain body parts rather than on all the keypoints. For example,\n    ``CocoWholeBodyMetric`` evaluates coco metric on body, foot, face,\n    lefthand and righthand. However, ``CocoWholeBodyMetric`` cannot be\n    applied to arbitrary custom datasets. This wrapper metric solves this\n    problem.\n\n    Supported metrics:\n        ``CocoMetric``  Note 1: all keypoint ground truth should be stored in\n            `keypoints` not other data fields. Note 2: `ann_file` is not\n            supported, it will be ignored. Note 3: `score_mode` other than\n            'bbox' may produce results different from the\n            ``CocoWholebodyMetric``. Note 4: `nms_mode` other than 'none' may\n            produce results different from the ``CocoWholebodyMetric``.\n        ``PCKAccuracy`` Note 1: data fields required by ``PCKAccuracy`` should\n         be provided, such as bbox, head_size, etc. Note 2: In terms of\n        'torso', since it is specifically designed for ``JhmdbDataset``, it is\n         not recommended to use it for other datasets.\n        ``AUC`` supported without limitations.\n        ``EPE`` supported without limitations.\n        ``NME`` only `norm_mode` = 'use_norm_item' is supported,\n        'keypoint_distance' is incompatible with ``KeypointPartitionMetric``.\n\n    Incompatible metrics:\n        The following metrics are dataset specific metrics:\n            ``CocoWholeBodyMetric``\n            ``MpiiPCKAccuracy``\n            ``JhmdbPCKAccuracy``\n            ``PoseTrack18Metric``\n        Keypoint partitioning is included in these metrics.\n\n    Args:\n        metric (dict): arguments to instantiate a metric, please refer to the\n            arguments required by the metric of your choice.\n        partitions (dict): definition of body partitions. For example, if we\n            have 10 keypoints in total, the first 7 keypoints belong to body\n            and the last 3 keypoints belong to foot, this field can be like\n            this:\n                dict(\n                    body=[0, 1, 2, 3, 4, 5, 6],\n                    foot=[7, 8, 9],\n                    all=[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]\n                )\n            where the numbers are the indices of keypoints and they can be\n            discontinuous.\n    \"\"\"\n\n    def __init__(\n        self,\n        metric: dict,\n        partitions: dict,\n    ) -> None:\n        super().__init__()\n        # check metric type\n        supported_metric_types = [\n            'CocoMetric', 'PCKAccuracy', 'AUC', 'EPE', 'NME'\n        ]\n        if metric['type'] not in supported_metric_types:\n            raise ValueError(\n                'Metrics supported by KeypointPartitionMetric are CocoMetric, '\n                'PCKAccuracy, AUC, EPE and NME, '\n                f\"but got {metric['type']}\")\n\n        # check CocoMetric arguments\n        if metric['type'] == 'CocoMetric':\n            if 'ann_file' in metric:\n                warnings.warn(\n                    'KeypointPartitionMetric does not support the ann_file '\n                    'argument of CocoMetric, this argument will be ignored.')\n                metric['ann_file'] = None\n            score_mode = metric.get('score_mode', 'bbox_keypoint')\n            if score_mode != 'bbox':\n                warnings.warn(\n                    'When using KeypointPartitionMetric with CocoMetric, '\n                    \"if score_mode is not 'bbox', pose scores will be \"\n                    \"calculated part by part rather than by 'wholebody'. \"\n                    'Therefore, this may produce results different from the '\n                    'CocoWholebodyMetric.')\n            nms_mode = metric.get('nms_mode', 'oks_nms')\n            if nms_mode != 'none':\n                warnings.warn(\n                    'When using KeypointPartitionMetric with CocoMetric, '\n                    'oks_nms and soft_oks_nms will be calculated part by part '\n                    \"rather than by 'wholebody'. Therefore, this may produce \"\n                    'results different from the CocoWholebodyMetric.')\n\n        # check PCKAccuracy arguments\n        if metric['type'] == 'PCKAccuracy':\n            norm_item = metric.get('norm_item', 'bbox')\n            if norm_item == 'torso' or 'torso' in norm_item:\n                warnings.warn(\n                    'norm_item torso is used in JhmdbDataset, it may not be '\n                    'compatible with other datasets, use at your own risk.')\n\n        # check NME arguments\n        if metric['type'] == 'NME':\n            assert 'norm_mode' in metric, \\\n                'Missing norm_mode required by the NME metric.'\n            if metric['norm_mode'] != 'use_norm_item':\n                raise ValueError(\n                    \"NME norm_mode 'keypoint_distance' is incompatible with \"\n                    'KeypointPartitionMetric.')\n\n        # check partitions\n        assert len(partitions) > 0, 'There should be at least one partition.'\n        for partition_name, partition in partitions.items():\n            assert isinstance(partition, Sequence), \\\n                'Each partition should be a sequence.'\n            assert len(partition) > 0, \\\n                'Each partition should have at least one element.'\n        self.partitions = partitions\n\n        # instantiate metrics for each partition\n        self.metrics = {}\n        for partition_name in partitions.keys():\n            _metric = deepcopy(metric)\n            if 'outfile_prefix' in _metric:\n                _metric['outfile_prefix'] = _metric[\n                    'outfile_prefix'] + '.' + partition_name\n            self.metrics[partition_name] = METRICS.build(_metric)\n\n    @BaseMetric.dataset_meta.setter\n    def dataset_meta(self, dataset_meta: dict) -> None:\n        \"\"\"Set the dataset meta info to the metric.\"\"\"\n        self._dataset_meta = dataset_meta\n        # sigmas required by coco metric have to be split as well\n        for partition_name, keypoint_ids in self.partitions.items():\n            _dataset_meta = deepcopy(dataset_meta)\n            _dataset_meta['num_keypoints'] = len(keypoint_ids)\n            _dataset_meta['sigmas'] = _dataset_meta['sigmas'][keypoint_ids]\n            self.metrics[partition_name].dataset_meta = _dataset_meta\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Split data samples by partitions, then call metric.process part by\n        part.\"\"\"\n        parted_data_samples = {\n            partition_name: []\n            for partition_name in self.partitions.keys()\n        }\n        for data_sample in data_samples:\n            for partition_name, keypoint_ids in self.partitions.items():\n                _data_sample = deepcopy(data_sample)\n                if 'keypoint_scores' in _data_sample['pred_instances']:\n                    _data_sample['pred_instances'][\n                        'keypoint_scores'] = _data_sample['pred_instances'][\n                            'keypoint_scores'][:, keypoint_ids]\n                _data_sample['pred_instances']['keypoints'] = _data_sample[\n                    'pred_instances']['keypoints'][:, keypoint_ids]\n                _data_sample['gt_instances']['keypoints'] = _data_sample[\n                    'gt_instances']['keypoints'][:, keypoint_ids]\n                _data_sample['gt_instances'][\n                    'keypoints_visible'] = _data_sample['gt_instances'][\n                        'keypoints_visible'][:, keypoint_ids]\n\n                # for coco metric\n                if 'raw_ann_info' in _data_sample:\n                    raw_ann_info = _data_sample['raw_ann_info']\n                    anns = raw_ann_info if isinstance(\n                        raw_ann_info, list) else [raw_ann_info]\n                    for ann in anns:\n                        if 'keypoints' in ann:\n                            keypoints = np.array(ann['keypoints']).reshape(\n                                -1, 3)\n                            keypoints = keypoints[keypoint_ids]\n                            num_keypoints = np.sum(keypoints[:, 2] > 0)\n                            ann['keypoints'] = keypoints.flatten().tolist()\n                            ann['num_keypoints'] = num_keypoints\n\n                parted_data_samples[partition_name].append(_data_sample)\n\n        for partition_name, metric in self.metrics.items():\n            metric.process(data_batch, parted_data_samples[partition_name])\n\n    def compute_metrics(self, results: list) -> dict:\n        pass\n\n    def evaluate(self, size: int) -> dict:\n        \"\"\"Run evaluation for each partition.\"\"\"\n        eval_results = OrderedDict()\n        for partition_name, metric in self.metrics.items():\n            _eval_results = metric.evaluate(size)\n            for key in list(_eval_results.keys()):\n                new_key = partition_name + '/' + key\n                _eval_results[new_key] = _eval_results.pop(key)\n            eval_results.update(_eval_results)\n        return eval_results\n"
  },
  {
    "path": "mmpose/evaluation/metrics/posetrack18_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nfrom typing import Dict, List, Optional\n\nimport numpy as np\nfrom mmengine.fileio import dump, load\nfrom mmengine.logging import MMLogger\n\nfrom mmpose.registry import METRICS\nfrom .coco_metric import CocoMetric\n\ntry:\n    from poseval import eval_helpers\n    from poseval.evaluateAP import evaluateAP\n    has_poseval = True\nexcept (ImportError, ModuleNotFoundError):\n    has_poseval = False\n\n\n@METRICS.register_module()\nclass PoseTrack18Metric(CocoMetric):\n    \"\"\"PoseTrack18 evaluation metric.\n\n    Evaluate AP, and mAP for keypoint detection tasks.\n    Support PoseTrack18 (video) dataset. Please refer to\n    `<https://github.com/leonid-pishchulin/poseval>`__\n    for more details.\n\n    Args:\n        ann_file (str, optional): Path to the coco format annotation file.\n            If not specified, ground truth annotations from the dataset will\n            be converted to coco format. Defaults to None\n        score_mode (str): The mode to score the prediction results which\n            should be one of the following options:\n\n                - ``'bbox'``: Take the score of bbox as the score of the\n                    prediction results.\n                - ``'bbox_keypoint'``: Use keypoint score to rescore the\n                    prediction results.\n\n            Defaults to ``'bbox_keypoint'`\n        keypoint_score_thr (float): The threshold of keypoint score. The\n            keypoints with score lower than it will not be included to\n            rescore the prediction results. Valid only when ``score_mode`` is\n            ``bbox_keypoint``. Defaults to ``0.2``\n        nms_mode (str): The mode to perform Non-Maximum Suppression (NMS),\n            which should be one of the following options:\n\n                - ``'oks_nms'``: Use Object Keypoint Similarity (OKS) to\n                    perform NMS.\n                - ``'soft_oks_nms'``: Use Object Keypoint Similarity (OKS)\n                    to perform soft NMS.\n                - ``'none'``: Do not perform NMS. Typically for bottomup mode\n                    output.\n\n            Defaults to ``'oks_nms'`\n        nms_thr (float): The Object Keypoint Similarity (OKS) threshold\n            used in NMS when ``nms_mode`` is ``'oks_nms'`` or\n            ``'soft_oks_nms'``. Will retain the prediction results with OKS\n            lower than ``nms_thr``. Defaults to ``0.9``\n        format_only (bool): Whether only format the output results without\n            doing quantitative evaluation. This is designed for the need of\n            test submission when the ground truth annotations are absent. If\n            set to ``True``, ``outfile_prefix`` should specify the path to\n            store the output results. Defaults to ``False``\n        outfile_prefix (str | None): The prefix of json files. It includes\n            the file path and the prefix of filename, e.g., ``'a/b/prefix'``.\n            If not specified, a temp file will be created. Defaults to ``None``\n        **kwargs: Keyword parameters passed to :class:`mmeval.BaseMetric`\n    \"\"\"\n    default_prefix: Optional[str] = 'posetrack18'\n\n    def __init__(self,\n                 ann_file: Optional[str] = None,\n                 score_mode: str = 'bbox_keypoint',\n                 keypoint_score_thr: float = 0.2,\n                 nms_mode: str = 'oks_nms',\n                 nms_thr: float = 0.9,\n                 format_only: bool = False,\n                 outfile_prefix: Optional[str] = None,\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None) -> None:\n        # raise an error to avoid long time running without getting results\n        if not has_poseval:\n            raise ImportError('Please install ``poseval`` package for '\n                              'evaluation on PoseTrack dataset '\n                              '(see `requirements/optional.txt`)')\n        super().__init__(\n            ann_file=ann_file,\n            score_mode=score_mode,\n            keypoint_score_thr=keypoint_score_thr,\n            nms_mode=nms_mode,\n            nms_thr=nms_thr,\n            format_only=format_only,\n            outfile_prefix=outfile_prefix,\n            collect_device=collect_device,\n            prefix=prefix)\n\n    def results2json(self, keypoints: Dict[int, list],\n                     outfile_prefix: str) -> str:\n        \"\"\"Dump the keypoint detection results into a json file.\n\n        Args:\n            keypoints (Dict[int, list]): Keypoint detection results\n                of the dataset.\n            outfile_prefix (str): The filename prefix of the json files.\n                If the prefix is \"somepath/xxx\", the json files will be named\n                \"somepath/xxx.keypoints.json\".\n\n        Returns:\n            str: The json file name of keypoint results.\n        \"\"\"\n        categories = []\n\n        cat = {}\n        cat['supercategory'] = 'person'\n        cat['id'] = 1\n        cat['name'] = 'person'\n        cat['keypoints'] = [\n            'nose', 'head_bottom', 'head_top', 'left_ear', 'right_ear',\n            'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow',\n            'left_wrist', 'right_wrist', 'left_hip', 'right_hip', 'left_knee',\n            'right_knee', 'left_ankle', 'right_ankle'\n        ]\n        cat['skeleton'] = [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13],\n                           [6, 12], [7, 13], [6, 7], [6, 8], [7, 9], [8, 10],\n                           [9, 11], [2, 3], [1, 2], [1, 3], [2, 4], [3, 5],\n                           [4, 6], [5, 7]]\n        categories.append(cat)\n\n        # path of directory for official gt files\n        gt_folder = osp.join(\n            osp.dirname(self.ann_file),\n            osp.splitext(self.ann_file.split('_')[-1])[0])\n        # the json file for each video sequence\n        json_files = [\n            pos for pos in os.listdir(gt_folder) if pos.endswith('.json')\n        ]\n\n        for json_file in json_files:\n            gt = load(osp.join(gt_folder, json_file))\n            annotations = []\n            images = []\n\n            for image in gt['images']:\n                img = {}\n                img['id'] = image['id']\n                img['file_name'] = image['file_name']\n                images.append(img)\n\n                img_kpts = keypoints[img['id']]\n\n                for track_id, img_kpt in enumerate(img_kpts):\n                    ann = {}\n                    ann['image_id'] = img_kpt['img_id']\n                    ann['keypoints'] = np.array(\n                        img_kpt['keypoints']).reshape(-1).tolist()\n                    ann['scores'] = np.array(ann['keypoints']).reshape(\n                        [-1, 3])[:, 2].tolist()\n                    ann['score'] = float(img_kpt['score'])\n                    ann['track_id'] = track_id\n                    annotations.append(ann)\n\n            pred_file = osp.join(osp.dirname(outfile_prefix), json_file)\n            info = {}\n            info['images'] = images\n            info['categories'] = categories\n            info['annotations'] = annotations\n\n            dump(info, pred_file, sort_keys=True, indent=4)\n\n    def _do_python_keypoint_eval(self, outfile_prefix: str) -> List[tuple]:\n        \"\"\"Do keypoint evaluation using `poseval` package.\n\n        Args:\n            outfile_prefix (str): The filename prefix of the json files.\n                If the prefix is \"somepath/xxx\", the json files will be named\n                \"somepath/xxx.keypoints.json\".\n\n        Returns:\n            list: a list of tuples. Each tuple contains the evaluation stats\n            name and corresponding stats value.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # path of directory for official gt files\n        # 'xxx/posetrack18_train.json' -> 'xxx/train/'\n        gt_folder = osp.join(\n            osp.dirname(self.ann_file),\n            osp.splitext(self.ann_file.split('_')[-1])[0])\n        pred_folder = osp.dirname(outfile_prefix)\n\n        argv = ['', gt_folder + '/', pred_folder + '/']\n\n        logger.info('Loading data')\n        gtFramesAll, prFramesAll = eval_helpers.load_data_dir(argv)\n\n        logger.info(f'# gt frames  : {len(gtFramesAll)}')\n        logger.info(f'# pred frames: {len(prFramesAll)}')\n\n        # evaluate per-frame multi-person pose estimation (AP)\n        # compute AP\n        logger.info('Evaluation of per-frame multi-person pose estimation')\n        apAll, _, _ = evaluateAP(gtFramesAll, prFramesAll, None, False, False)\n\n        # print AP\n        logger.info('Average Precision (AP) metric:')\n        eval_helpers.printTable(apAll)\n\n        stats = eval_helpers.getCum(apAll)\n\n        stats_names = [\n            'Head AP', 'Shou AP', 'Elb AP', 'Wri AP', 'Hip AP', 'Knee AP',\n            'Ankl AP', 'AP'\n        ]\n\n        info_str = list(zip(stats_names, stats))\n\n        return info_str\n"
  },
  {
    "path": "mmpose/evaluation/metrics/simple_keypoint_3d_metrics.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, List, Optional, Sequence\n\nimport numpy as np\nfrom mmengine.evaluator import BaseMetric\nfrom mmengine.logging import MMLogger\n\nfrom mmpose.registry import METRICS\nfrom ..functional import keypoint_mpjpe\n\n\n@METRICS.register_module()\nclass SimpleMPJPE(BaseMetric):\n    \"\"\"MPJPE evaluation metric.\n\n    Calculate the mean per-joint position error (MPJPE) of keypoints.\n\n    Note:\n        - length of dataset: N\n        - num_keypoints: K\n        - number of keypoint dimensions: D (typically D = 2)\n\n    Args:\n        mode (str): Method to align the prediction with the\n            ground truth. Supported options are:\n\n                - ``'mpjpe'``: no alignment will be applied\n                - ``'p-mpjpe'``: align in the least-square sense in scale\n                - ``'n-mpjpe'``: align in the least-square sense in\n                    scale, rotation, and translation.\n\n        collect_device (str): Device name used for collecting results from\n            different ranks during distributed training. Must be ``'cpu'`` or\n            ``'gpu'``. Default: ``'cpu'``.\n        prefix (str, optional): The prefix that will be added in the metric\n            names to disambiguate homonymous metrics of different evaluators.\n            If prefix is not provided in the argument, ``self.default_prefix``\n            will be used instead. Default: ``None``.\n        skip_list (list, optional): The list of subject and action combinations\n            to be skipped. Default: [].\n    \"\"\"\n\n    ALIGNMENT = {'mpjpe': 'none', 'p-mpjpe': 'procrustes', 'n-mpjpe': 'scale'}\n\n    def __init__(self,\n                 mode: str = 'mpjpe',\n                 collect_device: str = 'cpu',\n                 prefix: Optional[str] = None,\n                 skip_list: List[str] = []) -> None:\n        super().__init__(collect_device=collect_device, prefix=prefix)\n        allowed_modes = self.ALIGNMENT.keys()\n        if mode not in allowed_modes:\n            raise KeyError(\"`mode` should be 'mpjpe', 'p-mpjpe', or \"\n                           f\"'n-mpjpe', but got '{mode}'.\")\n\n        self.mode = mode\n        self.skip_list = skip_list\n\n    def process(self, data_batch: Sequence[dict],\n                data_samples: Sequence[dict]) -> None:\n        \"\"\"Process one batch of data samples and predictions. The processed\n        results should be stored in ``self.results``, which will be used to\n        compute the metrics when all batches have been processed.\n\n        Args:\n            data_batch (Sequence[dict]): A batch of data\n                from the dataloader.\n            data_samples (Sequence[dict]): A batch of outputs from\n                the model.\n        \"\"\"\n        for data_sample in data_samples:\n            # predicted keypoints coordinates, [T, K, D]\n            pred_coords = data_sample['pred_instances']['keypoints']\n            if pred_coords.ndim == 4:\n                pred_coords = np.squeeze(pred_coords, axis=0)\n            # ground truth data_info\n            gt = data_sample['gt_instances']\n            # ground truth keypoints coordinates, [T, K, D]\n            gt_coords = gt['lifting_target']\n            # ground truth keypoints_visible, [T, K, 1]\n            mask = gt['lifting_target_visible'].astype(bool).reshape(\n                gt_coords.shape[0], -1)\n\n            result = {\n                'pred_coords': pred_coords,\n                'gt_coords': gt_coords,\n                'mask': mask,\n            }\n\n            self.results.append(result)\n\n    def compute_metrics(self, results: list) -> Dict[str, float]:\n        \"\"\"Compute the metrics from processed results.\n\n        Args:\n            results (list): The processed results of each batch.\n\n        Returns:\n            Dict[str, float]: The computed metrics. The keys are the names of\n            the metrics, and the values are the corresponding results.\n        \"\"\"\n        logger: MMLogger = MMLogger.get_current_instance()\n\n        # pred_coords: [N, K, D]\n        pred_coords = np.concatenate(\n            [result['pred_coords'] for result in results])\n        # gt_coords: [N, K, D]\n        gt_coords = np.concatenate([result['gt_coords'] for result in results])\n        # mask: [N, K]\n        mask = np.concatenate([result['mask'] for result in results])\n\n        error_name = self.mode.upper()\n\n        logger.info(f'Evaluating {self.mode.upper()}...')\n        return {\n            error_name:\n            keypoint_mpjpe(pred_coords, gt_coords, mask,\n                           self.ALIGNMENT[self.mode])\n        }\n"
  },
  {
    "path": "mmpose/models/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .backbones import *  # noqa\nfrom .builder import (BACKBONES, HEADS, LOSSES, NECKS, build_backbone,\n                      build_head, build_loss, build_neck, build_pose_estimator,\n                      build_posenet)\nfrom .data_preprocessors import *  # noqa\nfrom .distillers import *  # noqa\nfrom .heads import *  # noqa\nfrom .losses import *  # noqa\nfrom .necks import *  # noqa\nfrom .pose_estimators import *  # noqa\n\n__all__ = [\n    'BACKBONES',\n    'HEADS',\n    'NECKS',\n    'LOSSES',\n    'build_backbone',\n    'build_head',\n    'build_loss',\n    'build_posenet',\n    'build_neck',\n    'build_pose_estimator',\n]\n"
  },
  {
    "path": "mmpose/models/backbones/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .alexnet import AlexNet\nfrom .cpm import CPM\nfrom .csp_darknet import CSPDarknet\nfrom .cspnext import CSPNeXt\nfrom .dstformer import DSTFormer\nfrom .hourglass import HourglassNet\nfrom .hourglass_ae import HourglassAENet\nfrom .hrformer import HRFormer\nfrom .hrnet import HRNet\nfrom .litehrnet import LiteHRNet\nfrom .mobilenet_v2 import MobileNetV2\nfrom .mobilenet_v3 import MobileNetV3\nfrom .mspn import MSPN\nfrom .pvt import PyramidVisionTransformer, PyramidVisionTransformerV2\nfrom .regnet import RegNet\nfrom .resnest import ResNeSt\nfrom .resnet import ResNet, ResNetV1d\nfrom .resnext import ResNeXt\nfrom .rsn import RSN\nfrom .scnet import SCNet\nfrom .seresnet import SEResNet\nfrom .seresnext import SEResNeXt\nfrom .shufflenet_v1 import ShuffleNetV1\nfrom .shufflenet_v2 import ShuffleNetV2\nfrom .swin import SwinTransformer\nfrom .tcn import TCN\nfrom .v2v_net import V2VNet\nfrom .vgg import VGG\nfrom .vipnas_mbv3 import ViPNAS_MobileNetV3\nfrom .vipnas_resnet import ViPNAS_ResNet\n\n__all__ = [\n    'AlexNet', 'HourglassNet', 'HourglassAENet', 'HRNet', 'MobileNetV2',\n    'MobileNetV3', 'RegNet', 'ResNet', 'ResNetV1d', 'ResNeXt', 'SCNet',\n    'SEResNet', 'SEResNeXt', 'ShuffleNetV1', 'ShuffleNetV2', 'CPM', 'RSN',\n    'MSPN', 'ResNeSt', 'VGG', 'TCN', 'ViPNAS_ResNet', 'ViPNAS_MobileNetV3',\n    'LiteHRNet', 'V2VNet', 'HRFormer', 'PyramidVisionTransformer',\n    'PyramidVisionTransformerV2', 'SwinTransformer', 'DSTFormer', 'CSPDarknet',\n    'CSPNeXt'\n]\n"
  },
  {
    "path": "mmpose/models/backbones/alexnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.nn as nn\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\n@MODELS.register_module()\nclass AlexNet(BaseBackbone):\n    \"\"\"`AlexNet <https://en.wikipedia.org/wiki/AlexNet>`__ backbone.\n\n    The input for AlexNet is a 224x224 RGB image.\n\n    Args:\n        num_classes (int): number of classes for classification.\n            The default value is -1, which uses the backbone as\n            a feature extractor without the top classifier.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self, num_classes=-1, init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        self.num_classes = num_classes\n        self.features = nn.Sequential(\n            nn.Conv2d(3, 64, kernel_size=11, stride=4, padding=2),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=3, stride=2),\n            nn.Conv2d(64, 192, kernel_size=5, padding=2),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=3, stride=2),\n            nn.Conv2d(192, 384, kernel_size=3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(384, 256, kernel_size=3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.Conv2d(256, 256, kernel_size=3, padding=1),\n            nn.ReLU(inplace=True),\n            nn.MaxPool2d(kernel_size=3, stride=2),\n        )\n        if self.num_classes > 0:\n            self.classifier = nn.Sequential(\n                nn.Dropout(),\n                nn.Linear(256 * 6 * 6, 4096),\n                nn.ReLU(inplace=True),\n                nn.Dropout(),\n                nn.Linear(4096, 4096),\n                nn.ReLU(inplace=True),\n                nn.Linear(4096, num_classes),\n            )\n\n    def forward(self, x):\n\n        x = self.features(x)\n        if self.num_classes > 0:\n            x = x.view(x.size(0), 256 * 6 * 6)\n            x = self.classifier(x)\n\n        return (x, )\n"
  },
  {
    "path": "mmpose/models/backbones/base_backbone.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta, abstractmethod\n\nfrom mmengine.model import BaseModule\n\n\nclass BaseBackbone(BaseModule, metaclass=ABCMeta):\n    \"\"\"Base backbone.\n\n    This class defines the basic functions of a backbone. Any backbone that\n    inherits this class should at least define its own `forward` function.\n    \"\"\"\n\n    @abstractmethod\n    def forward(self, x):\n        \"\"\"Forward function.\n\n        Args:\n            x (Tensor | tuple[Tensor]): x could be a torch.Tensor or a tuple of\n                torch.Tensor, containing input data for forward computation.\n        \"\"\"\n\n    def train(self, mode=True):\n        \"\"\"Set module status before forward computation.\n\n        Args:\n            mode (bool): Whether it is train_mode or test_mode\n        \"\"\"\n        super(BaseBackbone, self).train(mode)\n"
  },
  {
    "path": "mmpose/models/backbones/cpm.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass CpmBlock(BaseModule):\n    \"\"\"CpmBlock for Convolutional Pose Machine.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        channels (list): Output channels of each conv module.\n        kernels (list): Kernel sizes of each conv module.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 channels=(128, 128, 128),\n                 kernels=(11, 11, 11),\n                 norm_cfg=None,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n\n        assert len(channels) == len(kernels)\n        layers = []\n        for i in range(len(channels)):\n            if i == 0:\n                input_channels = in_channels\n            else:\n                input_channels = channels[i - 1]\n            layers.append(\n                ConvModule(\n                    input_channels,\n                    channels[i],\n                    kernels[i],\n                    padding=(kernels[i] - 1) // 2,\n                    norm_cfg=norm_cfg))\n        self.model = nn.Sequential(*layers)\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        out = self.model(x)\n        return out\n\n\n@MODELS.register_module()\nclass CPM(BaseBackbone):\n    \"\"\"CPM backbone.\n\n    Convolutional Pose Machines.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1602.00134>`__ .\n\n    Args:\n        in_channels (int): The input channels of the CPM.\n        out_channels (int): The output channels of the CPM.\n        feat_channels (int): Feature channel of each CPM stage.\n        middle_channels (int): Feature channel of conv after the middle stage.\n        num_stages (int): Number of stages.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import CPM\n        >>> import torch\n        >>> self = CPM(3, 17)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 368, 368)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_output in level_outputs:\n        ...     print(tuple(level_output.shape))\n        (1, 17, 46, 46)\n        (1, 17, 46, 46)\n        (1, 17, 46, 46)\n        (1, 17, 46, 46)\n        (1, 17, 46, 46)\n        (1, 17, 46, 46)\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels,\n        out_channels,\n        feat_channels=128,\n        middle_channels=32,\n        num_stages=6,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        init_cfg=[\n            dict(type='Normal', std=0.001, layer=['Conv2d']),\n            dict(type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm'])\n        ],\n    ):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n\n        assert in_channels == 3\n\n        self.num_stages = num_stages\n        assert self.num_stages >= 1\n\n        self.stem = nn.Sequential(\n            ConvModule(in_channels, 128, 9, padding=4, norm_cfg=norm_cfg),\n            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),\n            ConvModule(128, 128, 9, padding=4, norm_cfg=norm_cfg),\n            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),\n            ConvModule(128, 128, 9, padding=4, norm_cfg=norm_cfg),\n            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),\n            ConvModule(128, 32, 5, padding=2, norm_cfg=norm_cfg),\n            ConvModule(32, 512, 9, padding=4, norm_cfg=norm_cfg),\n            ConvModule(512, 512, 1, padding=0, norm_cfg=norm_cfg),\n            ConvModule(512, out_channels, 1, padding=0, act_cfg=None))\n\n        self.middle = nn.Sequential(\n            ConvModule(in_channels, 128, 9, padding=4, norm_cfg=norm_cfg),\n            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),\n            ConvModule(128, 128, 9, padding=4, norm_cfg=norm_cfg),\n            nn.MaxPool2d(kernel_size=3, stride=2, padding=1),\n            ConvModule(128, 128, 9, padding=4, norm_cfg=norm_cfg),\n            nn.MaxPool2d(kernel_size=3, stride=2, padding=1))\n\n        self.cpm_stages = nn.ModuleList([\n            CpmBlock(\n                middle_channels + out_channels,\n                channels=[feat_channels, feat_channels, feat_channels],\n                kernels=[11, 11, 11],\n                norm_cfg=norm_cfg) for _ in range(num_stages - 1)\n        ])\n\n        self.middle_conv = nn.ModuleList([\n            nn.Sequential(\n                ConvModule(\n                    128, middle_channels, 5, padding=2, norm_cfg=norm_cfg))\n            for _ in range(num_stages - 1)\n        ])\n\n        self.out_convs = nn.ModuleList([\n            nn.Sequential(\n                ConvModule(\n                    feat_channels,\n                    feat_channels,\n                    1,\n                    padding=0,\n                    norm_cfg=norm_cfg),\n                ConvModule(feat_channels, out_channels, 1, act_cfg=None))\n            for _ in range(num_stages - 1)\n        ])\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        stage1_out = self.stem(x)\n        middle_out = self.middle(x)\n        out_feats = []\n\n        out_feats.append(stage1_out)\n\n        for ind in range(self.num_stages - 1):\n            single_stage = self.cpm_stages[ind]\n            out_conv = self.out_convs[ind]\n\n            inp_feat = torch.cat(\n                [out_feats[-1], self.middle_conv[ind](middle_out)], 1)\n            cpm_feat = single_stage(inp_feat)\n            out_feat = out_conv(cpm_feat)\n            out_feats.append(out_feat)\n\n        return out_feats\n"
  },
  {
    "path": "mmpose/models/backbones/csp_darknet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, DepthwiseSeparableConvModule\nfrom mmengine.model import BaseModule\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom ..utils import CSPLayer\n\n\nclass Focus(nn.Module):\n    \"\"\"Focus width and height information into channel space.\n\n    Args:\n        in_channels (int): The input channels of this Module.\n        out_channels (int): The output channels of this Module.\n        kernel_size (int): The kernel size of the convolution. Default: 1\n        stride (int): The stride of the convolution. Default: 1\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN', momentum=0.03, eps=0.001).\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='Swish').\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size=1,\n                 stride=1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n                 act_cfg=dict(type='Swish')):\n        super().__init__()\n        self.conv = ConvModule(\n            in_channels * 4,\n            out_channels,\n            kernel_size,\n            stride,\n            padding=(kernel_size - 1) // 2,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n\n    def forward(self, x):\n        # shape of x (b,c,w,h) -> y(b,4c,w/2,h/2)\n        patch_top_left = x[..., ::2, ::2]\n        patch_top_right = x[..., ::2, 1::2]\n        patch_bot_left = x[..., 1::2, ::2]\n        patch_bot_right = x[..., 1::2, 1::2]\n        x = torch.cat(\n            (\n                patch_top_left,\n                patch_bot_left,\n                patch_top_right,\n                patch_bot_right,\n            ),\n            dim=1,\n        )\n        return self.conv(x)\n\n\nclass SPPBottleneck(BaseModule):\n    \"\"\"Spatial pyramid pooling layer used in YOLOv3-SPP.\n\n    Args:\n        in_channels (int): The input channels of this Module.\n        out_channels (int): The output channels of this Module.\n        kernel_sizes (tuple[int]): Sequential of kernel sizes of pooling\n            layers. Default: (5, 9, 13).\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='Swish').\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_sizes=(5, 9, 13),\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n                 act_cfg=dict(type='Swish'),\n                 init_cfg=None):\n        super().__init__(init_cfg)\n        mid_channels = in_channels // 2\n        self.conv1 = ConvModule(\n            in_channels,\n            mid_channels,\n            1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.poolings = nn.ModuleList([\n            nn.MaxPool2d(kernel_size=ks, stride=1, padding=ks // 2)\n            for ks in kernel_sizes\n        ])\n        conv2_channels = mid_channels * (len(kernel_sizes) + 1)\n        self.conv2 = ConvModule(\n            conv2_channels,\n            out_channels,\n            1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        with torch.cuda.amp.autocast(enabled=False):\n            x = torch.cat(\n                [x] + [pooling(x) for pooling in self.poolings], dim=1)\n        x = self.conv2(x)\n        return x\n\n\n@MODELS.register_module()\nclass CSPDarknet(BaseModule):\n    \"\"\"CSP-Darknet backbone used in YOLOv5 and YOLOX.\n\n    Args:\n        arch (str): Architecture of CSP-Darknet, from {P5, P6}.\n            Default: P5.\n        deepen_factor (float): Depth multiplier, multiply number of\n            blocks in CSP layer by this amount. Default: 1.0.\n        widen_factor (float): Width multiplier, multiply number of\n            channels in each layer by this amount. Default: 1.0.\n        out_indices (Sequence[int]): Output from which stages.\n            Default: (2, 3, 4).\n        frozen_stages (int): Stages to be frozen (stop grad and set eval\n            mode). -1 means not freezing any parameters. Default: -1.\n        use_depthwise (bool): Whether to use depthwise separable convolution.\n            Default: False.\n        arch_ovewrite(list): Overwrite default arch settings. Default: None.\n        spp_kernal_sizes: (tuple[int]): Sequential of kernel sizes of SPP\n            layers. Default: (5, 9, 13).\n        conv_cfg (dict): Config dict for convolution layer. Default: None.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n            Default: dict(type='BN', requires_grad=True).\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='LeakyReLU', negative_slope=0.1).\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    Example:\n        >>> from mmpose.models import CSPDarknet\n        >>> import torch\n        >>> self = CSPDarknet(depth=53)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 416, 416)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        ...\n        (1, 256, 52, 52)\n        (1, 512, 26, 26)\n        (1, 1024, 13, 13)\n    \"\"\"\n    # From left to right:\n    # in_channels, out_channels, num_blocks, add_identity, use_spp\n    arch_settings = {\n        'P5': [[64, 128, 3, True, False], [128, 256, 9, True, False],\n               [256, 512, 9, True, False], [512, 1024, 3, False, True]],\n        'P6': [[64, 128, 3, True, False], [128, 256, 9, True, False],\n               [256, 512, 9, True, False], [512, 768, 3, True, False],\n               [768, 1024, 3, False, True]]\n    }\n\n    def __init__(self,\n                 arch='P5',\n                 deepen_factor=1.0,\n                 widen_factor=1.0,\n                 out_indices=(2, 3, 4),\n                 frozen_stages=-1,\n                 use_depthwise=False,\n                 arch_ovewrite=None,\n                 spp_kernal_sizes=(5, 9, 13),\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n                 act_cfg=dict(type='Swish'),\n                 norm_eval=False,\n                 init_cfg=dict(\n                     type='Kaiming',\n                     layer='Conv2d',\n                     a=math.sqrt(5),\n                     distribution='uniform',\n                     mode='fan_in',\n                     nonlinearity='leaky_relu')):\n        super().__init__(init_cfg)\n        arch_setting = self.arch_settings[arch]\n        if arch_ovewrite:\n            arch_setting = arch_ovewrite\n        assert set(out_indices).issubset(\n            i for i in range(len(arch_setting) + 1))\n        if frozen_stages not in range(-1, len(arch_setting) + 1):\n            raise ValueError('frozen_stages must be in range(-1, '\n                             'len(arch_setting) + 1). But received '\n                             f'{frozen_stages}')\n\n        self.out_indices = out_indices\n        self.frozen_stages = frozen_stages\n        self.use_depthwise = use_depthwise\n        self.norm_eval = norm_eval\n        conv = DepthwiseSeparableConvModule if use_depthwise else ConvModule\n\n        self.stem = Focus(\n            3,\n            int(arch_setting[0][0] * widen_factor),\n            kernel_size=3,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.layers = ['stem']\n\n        for i, (in_channels, out_channels, num_blocks, add_identity,\n                use_spp) in enumerate(arch_setting):\n            in_channels = int(in_channels * widen_factor)\n            out_channels = int(out_channels * widen_factor)\n            num_blocks = max(round(num_blocks * deepen_factor), 1)\n            stage = []\n            conv_layer = conv(\n                in_channels,\n                out_channels,\n                3,\n                stride=2,\n                padding=1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n            stage.append(conv_layer)\n            if use_spp:\n                spp = SPPBottleneck(\n                    out_channels,\n                    out_channels,\n                    kernel_sizes=spp_kernal_sizes,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg)\n                stage.append(spp)\n            csp_layer = CSPLayer(\n                out_channels,\n                out_channels,\n                num_blocks=num_blocks,\n                add_identity=add_identity,\n                use_depthwise=use_depthwise,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n            stage.append(csp_layer)\n            self.add_module(f'stage{i + 1}', nn.Sequential(*stage))\n            self.layers.append(f'stage{i + 1}')\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            for i in range(self.frozen_stages + 1):\n                m = getattr(self, self.layers[i])\n                m.eval()\n                for param in m.parameters():\n                    param.requires_grad = False\n\n    def train(self, mode=True):\n        super(CSPDarknet, self).train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n\n    def forward(self, x):\n        outs = []\n        for i, layer_name in enumerate(self.layers):\n            layer = getattr(self, layer_name)\n            x = layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/backbones/cspnext.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Optional, Sequence, Tuple\n\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, DepthwiseSeparableConvModule\nfrom mmengine.model import BaseModule\nfrom torch import Tensor\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import ConfigType\nfrom ..utils import CSPLayer\nfrom .csp_darknet import SPPBottleneck\n\n\n@MODELS.register_module()\nclass CSPNeXt(BaseModule):\n    \"\"\"CSPNeXt backbone used in RTMDet.\n\n    Args:\n        arch (str): Architecture of CSPNeXt, from {P5, P6}.\n            Defaults to P5.\n        expand_ratio (float): Ratio to adjust the number of channels of the\n            hidden layer. Defaults to 0.5.\n        deepen_factor (float): Depth multiplier, multiply number of\n            blocks in CSP layer by this amount. Defaults to 1.0.\n        widen_factor (float): Width multiplier, multiply number of\n            channels in each layer by this amount. Defaults to 1.0.\n        out_indices (Sequence[int]): Output from which stages.\n            Defaults to (2, 3, 4).\n        frozen_stages (int): Stages to be frozen (stop grad and set eval\n            mode). -1 means not freezing any parameters. Defaults to -1.\n        use_depthwise (bool): Whether to use depthwise separable convolution.\n            Defaults to False.\n        arch_ovewrite (list): Overwrite default arch settings.\n            Defaults to None.\n        spp_kernel_sizes: (tuple[int]): Sequential of kernel sizes of SPP\n            layers. Defaults to (5, 9, 13).\n        channel_attention (bool): Whether to add channel attention in each\n            stage. Defaults to True.\n        conv_cfg (:obj:`ConfigDict` or dict, optional): Config dict for\n            convolution layer. Defaults to None.\n        norm_cfg (:obj:`ConfigDict` or dict): Dictionary to construct and\n            config norm layer. Defaults to dict(type='BN', requires_grad=True).\n        act_cfg (:obj:`ConfigDict` or dict): Config dict for activation layer.\n            Defaults to dict(type='SiLU').\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only.\n        init_cfg (:obj:`ConfigDict` or dict or list[dict] or\n            list[:obj:`ConfigDict`]): Initialization config dict.\n    \"\"\"\n    # From left to right:\n    # in_channels, out_channels, num_blocks, add_identity, use_spp\n    arch_settings = {\n        'P5': [[64, 128, 3, True, False], [128, 256, 6, True, False],\n               [256, 512, 6, True, False], [512, 1024, 3, False, True]],\n        'P6': [[64, 128, 3, True, False], [128, 256, 6, True, False],\n               [256, 512, 6, True, False], [512, 768, 3, True, False],\n               [768, 1024, 3, False, True]]\n    }\n\n    def __init__(\n        self,\n        arch: str = 'P5',\n        deepen_factor: float = 1.0,\n        widen_factor: float = 1.0,\n        out_indices: Sequence[int] = (2, 3, 4),\n        frozen_stages: int = -1,\n        use_depthwise: bool = False,\n        expand_ratio: float = 0.5,\n        arch_ovewrite: dict = None,\n        spp_kernel_sizes: Sequence[int] = (5, 9, 13),\n        channel_attention: bool = True,\n        conv_cfg: Optional[ConfigType] = None,\n        norm_cfg: ConfigType = dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg: ConfigType = dict(type='SiLU'),\n        norm_eval: bool = False,\n        init_cfg: Optional[ConfigType] = dict(\n            type='Kaiming',\n            layer='Conv2d',\n            a=math.sqrt(5),\n            distribution='uniform',\n            mode='fan_in',\n            nonlinearity='leaky_relu')\n    ) -> None:\n        super().__init__(init_cfg=init_cfg)\n        arch_setting = self.arch_settings[arch]\n        if arch_ovewrite:\n            arch_setting = arch_ovewrite\n        assert set(out_indices).issubset(\n            i for i in range(len(arch_setting) + 1))\n        if frozen_stages not in range(-1, len(arch_setting) + 1):\n            raise ValueError('frozen_stages must be in range(-1, '\n                             'len(arch_setting) + 1). But received '\n                             f'{frozen_stages}')\n\n        self.out_indices = out_indices\n        self.frozen_stages = frozen_stages\n        self.use_depthwise = use_depthwise\n        self.norm_eval = norm_eval\n        conv = DepthwiseSeparableConvModule if use_depthwise else ConvModule\n        self.stem = nn.Sequential(\n            ConvModule(\n                3,\n                int(arch_setting[0][0] * widen_factor // 2),\n                3,\n                padding=1,\n                stride=2,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg),\n            ConvModule(\n                int(arch_setting[0][0] * widen_factor // 2),\n                int(arch_setting[0][0] * widen_factor // 2),\n                3,\n                padding=1,\n                stride=1,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg),\n            ConvModule(\n                int(arch_setting[0][0] * widen_factor // 2),\n                int(arch_setting[0][0] * widen_factor),\n                3,\n                padding=1,\n                stride=1,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg))\n        self.layers = ['stem']\n\n        for i, (in_channels, out_channels, num_blocks, add_identity,\n                use_spp) in enumerate(arch_setting):\n            in_channels = int(in_channels * widen_factor)\n            out_channels = int(out_channels * widen_factor)\n            num_blocks = max(round(num_blocks * deepen_factor), 1)\n            stage = []\n            conv_layer = conv(\n                in_channels,\n                out_channels,\n                3,\n                stride=2,\n                padding=1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n            stage.append(conv_layer)\n            if use_spp:\n                spp = SPPBottleneck(\n                    out_channels,\n                    out_channels,\n                    kernel_sizes=spp_kernel_sizes,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg)\n                stage.append(spp)\n            csp_layer = CSPLayer(\n                out_channels,\n                out_channels,\n                num_blocks=num_blocks,\n                add_identity=add_identity,\n                use_depthwise=use_depthwise,\n                use_cspnext_block=True,\n                expand_ratio=expand_ratio,\n                channel_attention=channel_attention,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n            stage.append(csp_layer)\n            self.add_module(f'stage{i + 1}', nn.Sequential(*stage))\n            self.layers.append(f'stage{i + 1}')\n\n    def _freeze_stages(self) -> None:\n        if self.frozen_stages >= 0:\n            for i in range(self.frozen_stages + 1):\n                m = getattr(self, self.layers[i])\n                m.eval()\n                for param in m.parameters():\n                    param.requires_grad = False\n\n    def train(self, mode=True) -> None:\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n\n    def forward(self, x: Tuple[Tensor, ...]) -> Tuple[Tensor, ...]:\n        outs = []\n        for i, layer_name in enumerate(self.layers):\n            layer = getattr(self, layer_name)\n            x = layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/backbones/dstformer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn.bricks import DropPath\nfrom mmengine.model import BaseModule, constant_init\nfrom mmengine.model.weight_init import trunc_normal_\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass Attention(BaseModule):\n\n    def __init__(self,\n                 dim,\n                 num_heads=8,\n                 qkv_bias=False,\n                 qk_scale=None,\n                 attn_drop=0.,\n                 proj_drop=0.,\n                 mode='spatial'):\n        super().__init__()\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        self.scale = qk_scale or head_dim**-0.5\n\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(dim, dim)\n        self.mode = mode\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n        self.attn_count_s = None\n        self.attn_count_t = None\n\n    def forward(self, x, seq_len=1):\n        B, N, C = x.shape\n\n        if self.mode == 'temporal':\n            qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C //\n                                      self.num_heads).permute(2, 0, 3, 1, 4)\n            q, k, v = qkv[0], qkv[1], qkv[\n                2]  # make torchscript happy (cannot use tensor as tuple)\n            x = self.forward_temporal(q, k, v, seq_len=seq_len)\n        elif self.mode == 'spatial':\n            qkv = self.qkv(x).reshape(B, N, 3, self.num_heads, C //\n                                      self.num_heads).permute(2, 0, 3, 1, 4)\n            q, k, v = qkv[0], qkv[1], qkv[\n                2]  # make torchscript happy (cannot use tensor as tuple)\n            x = self.forward_spatial(q, k, v)\n        else:\n            raise NotImplementedError(self.mode)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n    def forward_spatial(self, q, k, v):\n        B, _, N, C = q.shape\n        attn = (q @ k.transpose(-2, -1)) * self.scale\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = attn @ v\n        x = x.transpose(1, 2).reshape(B, N, C * self.num_heads)\n        return x\n\n    def forward_temporal(self, q, k, v, seq_len=8):\n        B, _, N, C = q.shape\n        qt = q.reshape(-1, seq_len, self.num_heads, N,\n                       C).permute(0, 2, 3, 1, 4)  # (B, H, N, T, C)\n        kt = k.reshape(-1, seq_len, self.num_heads, N,\n                       C).permute(0, 2, 3, 1, 4)  # (B, H, N, T, C)\n        vt = v.reshape(-1, seq_len, self.num_heads, N,\n                       C).permute(0, 2, 3, 1, 4)  # (B, H, N, T, C)\n\n        attn = (qt @ kt.transpose(-2, -1)) * self.scale\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = attn @ vt  # (B, H, N, T, C)\n        x = x.permute(0, 3, 2, 1, 4).reshape(B, N, C * self.num_heads)\n        return x\n\n\nclass AttentionBlock(BaseModule):\n\n    def __init__(self,\n                 dim,\n                 num_heads,\n                 mlp_ratio=4.,\n                 mlp_out_ratio=1.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 st_mode='st'):\n        super().__init__()\n\n        self.st_mode = st_mode\n        self.norm1_s = nn.LayerNorm(dim, eps=1e-06)\n        self.norm1_t = nn.LayerNorm(dim, eps=1e-06)\n\n        self.attn_s = Attention(\n            dim,\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop=attn_drop,\n            proj_drop=drop,\n            mode='spatial')\n        self.attn_t = Attention(\n            dim,\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop=attn_drop,\n            proj_drop=drop,\n            mode='temporal')\n\n        self.drop_path = DropPath(\n            drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2_s = nn.LayerNorm(dim, eps=1e-06)\n        self.norm2_t = nn.LayerNorm(dim, eps=1e-06)\n\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        mlp_out_dim = int(dim * mlp_out_ratio)\n        self.mlp_s = nn.Sequential(\n            nn.Linear(dim, mlp_hidden_dim), nn.GELU(),\n            nn.Linear(mlp_hidden_dim, mlp_out_dim), nn.Dropout(drop))\n        self.mlp_t = nn.Sequential(\n            nn.Linear(dim, mlp_hidden_dim), nn.GELU(),\n            nn.Linear(mlp_hidden_dim, mlp_out_dim), nn.Dropout(drop))\n\n    def forward(self, x, seq_len=1):\n        if self.st_mode == 'st':\n            x = x + self.drop_path(self.attn_s(self.norm1_s(x), seq_len))\n            x = x + self.drop_path(self.mlp_s(self.norm2_s(x)))\n            x = x + self.drop_path(self.attn_t(self.norm1_t(x), seq_len))\n            x = x + self.drop_path(self.mlp_t(self.norm2_t(x)))\n        elif self.st_mode == 'ts':\n            x = x + self.drop_path(self.attn_t(self.norm1_t(x), seq_len))\n            x = x + self.drop_path(self.mlp_t(self.norm2_t(x)))\n            x = x + self.drop_path(self.attn_s(self.norm1_s(x), seq_len))\n            x = x + self.drop_path(self.mlp_s(self.norm2_s(x)))\n        else:\n            raise NotImplementedError(self.st_mode)\n        return x\n\n\n@MODELS.register_module()\nclass DSTFormer(BaseBackbone):\n    \"\"\"Dual-stream Spatio-temporal Transformer Module.\n\n    Args:\n        in_channels (int): Number of input channels.\n        feat_size: Number of feature channels. Default: 256.\n        depth: The network depth. Default: 5.\n        num_heads: Number of heads in multi-Head self-attention blocks.\n            Default: 8.\n        mlp_ratio (int, optional): The expansion ratio of FFN. Default: 4.\n        num_keypoints: num_keypoints (int): Number of keypoints. Default: 17.\n        seq_len: The sequence length. Default: 243.\n        qkv_bias (bool, optional): If True, add a learnable bias to q, k, v.\n            Default: True.\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        drop_rate (float, optional): Dropout ratio of input. Default: 0.\n        attn_drop_rate (float, optional): Dropout ratio of attention weight.\n            Default: 0.\n        drop_path_rate (float, optional): Stochastic depth rate. Default: 0.\n        att_fuse: Whether to fuse the results of attention blocks.\n            Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n\n    Example:\n        >>> from mmpose.models import DSTFormer\n        >>> import torch\n        >>> self = DSTFormer(in_channels=3)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 2, 17, 3)\n        >>> level_outputs = self.forward(inputs)\n        >>> print(tuple(level_outputs.shape))\n        (1, 2, 17, 512)\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 feat_size=256,\n                 depth=5,\n                 num_heads=8,\n                 mlp_ratio=4,\n                 num_keypoints=17,\n                 seq_len=243,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.,\n                 att_fuse=True,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n\n        self.in_channels = in_channels\n        self.feat_size = feat_size\n\n        self.joints_embed = nn.Linear(in_channels, feat_size)\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        dpr = [x.item() for x in torch.linspace(0, drop_path_rate, depth)\n               ]  # stochastic depth decay rule\n\n        self.blocks_st = nn.ModuleList([\n            AttentionBlock(\n                dim=feat_size,\n                num_heads=num_heads,\n                mlp_ratio=mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop=drop_rate,\n                attn_drop=attn_drop_rate,\n                drop_path=dpr[i],\n                st_mode='st') for i in range(depth)\n        ])\n        self.blocks_ts = nn.ModuleList([\n            AttentionBlock(\n                dim=feat_size,\n                num_heads=num_heads,\n                mlp_ratio=mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop=drop_rate,\n                attn_drop=attn_drop_rate,\n                drop_path=dpr[i],\n                st_mode='ts') for i in range(depth)\n        ])\n\n        self.norm = nn.LayerNorm(feat_size, eps=1e-06)\n\n        self.temp_embed = nn.Parameter(torch.zeros(1, seq_len, 1, feat_size))\n        self.spat_embed = nn.Parameter(\n            torch.zeros(1, num_keypoints, feat_size))\n\n        trunc_normal_(self.temp_embed, std=.02)\n        trunc_normal_(self.spat_embed, std=.02)\n\n        self.att_fuse = att_fuse\n        if self.att_fuse:\n            self.attn_regress = nn.ModuleList(\n                [nn.Linear(feat_size * 2, 2) for i in range(depth)])\n            for i in range(depth):\n                self.attn_regress[i].weight.data.fill_(0)\n                self.attn_regress[i].bias.data.fill_(0.5)\n\n    def forward(self, x):\n        if len(x.shape) == 3:\n            x = x[None, :]\n        assert len(x.shape) == 4\n\n        B, F, K, C = x.shape\n        x = x.reshape(-1, K, C)\n        BF = x.shape[0]\n        x = self.joints_embed(x)  # (BF, K, feat_size)\n        x = x + self.spat_embed\n        _, K, C = x.shape\n        x = x.reshape(-1, F, K, C) + self.temp_embed[:, :F, :, :]\n        x = x.reshape(BF, K, C)  # (BF, K, feat_size)\n        x = self.pos_drop(x)\n\n        for idx, (blk_st,\n                  blk_ts) in enumerate(zip(self.blocks_st, self.blocks_ts)):\n            x_st = blk_st(x, F)\n            x_ts = blk_ts(x, F)\n            if self.att_fuse:\n                att = self.attn_regress[idx]\n                alpha = torch.cat([x_st, x_ts], dim=-1)\n                BF, K = alpha.shape[:2]\n                alpha = att(alpha)\n                alpha = alpha.softmax(dim=-1)\n                x = x_st * alpha[:, :, 0:1] + x_ts * alpha[:, :, 1:2]\n            else:\n                x = (x_st + x_ts) * 0.5\n        x = self.norm(x)  # (BF, K, feat_size)\n        x = x.reshape(B, F, K, -1)\n        return x\n\n    def init_weights(self):\n        \"\"\"Initialize the weights in backbone.\"\"\"\n        super(DSTFormer, self).init_weights()\n\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            return\n\n        for m in self.modules():\n            if isinstance(m, nn.Linear):\n                trunc_normal_(m.weight, std=.02)\n                if isinstance(m, nn.Linear) and m.bias is not None:\n                    constant_init(m.bias, 0)\n            elif isinstance(m, nn.LayerNorm):\n                constant_init(m.bias, 0)\n                constant_init(m.weight, 1.0)\n"
  },
  {
    "path": "mmpose/models/backbones/hourglass.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .resnet import BasicBlock, ResLayer\n\n\nclass HourglassModule(BaseModule):\n    \"\"\"Hourglass Module for HourglassNet backbone.\n\n    Generate module recursively and use BasicBlock as the base unit.\n\n    Args:\n        depth (int): Depth of current HourglassModule.\n        stage_channels (list[int]): Feature channels of sub-modules in current\n            and follow-up HourglassModule.\n        stage_blocks (list[int]): Number of sub-modules stacked in current and\n            follow-up HourglassModule.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 depth,\n                 stage_channels,\n                 stage_blocks,\n                 norm_cfg=dict(type='BN', requires_grad=True),\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n\n        self.depth = depth\n\n        cur_block = stage_blocks[0]\n        next_block = stage_blocks[1]\n\n        cur_channel = stage_channels[0]\n        next_channel = stage_channels[1]\n\n        self.up1 = ResLayer(\n            BasicBlock, cur_block, cur_channel, cur_channel, norm_cfg=norm_cfg)\n\n        self.low1 = ResLayer(\n            BasicBlock,\n            cur_block,\n            cur_channel,\n            next_channel,\n            stride=2,\n            norm_cfg=norm_cfg)\n\n        if self.depth > 1:\n            self.low2 = HourglassModule(depth - 1, stage_channels[1:],\n                                        stage_blocks[1:])\n        else:\n            self.low2 = ResLayer(\n                BasicBlock,\n                next_block,\n                next_channel,\n                next_channel,\n                norm_cfg=norm_cfg)\n\n        self.low3 = ResLayer(\n            BasicBlock,\n            cur_block,\n            next_channel,\n            cur_channel,\n            norm_cfg=norm_cfg,\n            downsample_first=False)\n\n        self.up2 = nn.Upsample(scale_factor=2)\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        up1 = self.up1(x)\n        low1 = self.low1(x)\n        low2 = self.low2(low1)\n        low3 = self.low3(low2)\n        up2 = self.up2(low3)\n        return up1 + up2\n\n\n@MODELS.register_module()\nclass HourglassNet(BaseBackbone):\n    \"\"\"HourglassNet backbone.\n\n    Stacked Hourglass Networks for Human Pose Estimation.\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1603.06937>`__ .\n\n    Args:\n        downsample_times (int): Downsample times in a HourglassModule.\n        num_stacks (int): Number of HourglassModule modules stacked,\n            1 for Hourglass-52, 2 for Hourglass-104.\n        stage_channels (list[int]): Feature channel of each sub-module in a\n            HourglassModule.\n        stage_blocks (list[int]): Number of sub-modules stacked in a\n            HourglassModule.\n        feat_channel (int): Feature channel of conv after a HourglassModule.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import HourglassNet\n        >>> import torch\n        >>> self = HourglassNet()\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 511, 511)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_output in level_outputs:\n        ...     print(tuple(level_output.shape))\n        (1, 256, 128, 128)\n        (1, 256, 128, 128)\n    \"\"\"\n\n    def __init__(\n        self,\n        downsample_times=5,\n        num_stacks=2,\n        stage_channels=(256, 256, 384, 384, 384, 512),\n        stage_blocks=(2, 2, 2, 2, 2, 4),\n        feat_channel=256,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        init_cfg=[\n            dict(type='Normal', std=0.001, layer=['Conv2d']),\n            dict(type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm'])\n        ],\n    ):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n\n        self.num_stacks = num_stacks\n        assert self.num_stacks >= 1\n        assert len(stage_channels) == len(stage_blocks)\n        assert len(stage_channels) > downsample_times\n\n        cur_channel = stage_channels[0]\n\n        self.stem = nn.Sequential(\n            ConvModule(3, 128, 7, padding=3, stride=2, norm_cfg=norm_cfg),\n            ResLayer(BasicBlock, 1, 128, 256, stride=2, norm_cfg=norm_cfg))\n\n        self.hourglass_modules = nn.ModuleList([\n            HourglassModule(downsample_times, stage_channels, stage_blocks)\n            for _ in range(num_stacks)\n        ])\n\n        self.inters = ResLayer(\n            BasicBlock,\n            num_stacks - 1,\n            cur_channel,\n            cur_channel,\n            norm_cfg=norm_cfg)\n\n        self.conv1x1s = nn.ModuleList([\n            ConvModule(\n                cur_channel, cur_channel, 1, norm_cfg=norm_cfg, act_cfg=None)\n            for _ in range(num_stacks - 1)\n        ])\n\n        self.out_convs = nn.ModuleList([\n            ConvModule(\n                cur_channel, feat_channel, 3, padding=1, norm_cfg=norm_cfg)\n            for _ in range(num_stacks)\n        ])\n\n        self.remap_convs = nn.ModuleList([\n            ConvModule(\n                feat_channel, cur_channel, 1, norm_cfg=norm_cfg, act_cfg=None)\n            for _ in range(num_stacks - 1)\n        ])\n\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        inter_feat = self.stem(x)\n        out_feats = []\n\n        for ind in range(self.num_stacks):\n            single_hourglass = self.hourglass_modules[ind]\n            out_conv = self.out_convs[ind]\n\n            hourglass_feat = single_hourglass(inter_feat)\n            out_feat = out_conv(hourglass_feat)\n            out_feats.append(out_feat)\n\n            if ind < self.num_stacks - 1:\n                inter_feat = self.conv1x1s[ind](\n                    inter_feat) + self.remap_convs[ind](\n                        out_feat)\n                inter_feat = self.inters[ind](self.relu(inter_feat))\n\n        return out_feats\n"
  },
  {
    "path": "mmpose/models/backbones/hourglass_ae.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, MaxPool2d\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass HourglassAEModule(BaseModule):\n    \"\"\"Modified Hourglass Module for HourglassNet_AE backbone.\n\n    Generate module recursively and use BasicBlock as the base unit.\n\n    Args:\n        depth (int): Depth of current HourglassModule.\n        stage_channels (list[int]): Feature channels of sub-modules in current\n            and follow-up HourglassModule.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 depth,\n                 stage_channels,\n                 norm_cfg=dict(type='BN', requires_grad=True),\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n\n        self.depth = depth\n\n        cur_channel = stage_channels[0]\n        next_channel = stage_channels[1]\n\n        self.up1 = ConvModule(\n            cur_channel, cur_channel, 3, padding=1, norm_cfg=norm_cfg)\n\n        self.pool1 = MaxPool2d(2, 2)\n\n        self.low1 = ConvModule(\n            cur_channel, next_channel, 3, padding=1, norm_cfg=norm_cfg)\n\n        if self.depth > 1:\n            self.low2 = HourglassAEModule(depth - 1, stage_channels[1:])\n        else:\n            self.low2 = ConvModule(\n                next_channel, next_channel, 3, padding=1, norm_cfg=norm_cfg)\n\n        self.low3 = ConvModule(\n            next_channel, cur_channel, 3, padding=1, norm_cfg=norm_cfg)\n\n        self.up2 = nn.UpsamplingNearest2d(scale_factor=2)\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        up1 = self.up1(x)\n        pool1 = self.pool1(x)\n        low1 = self.low1(pool1)\n        low2 = self.low2(low1)\n        low3 = self.low3(low2)\n        up2 = self.up2(low3)\n        return up1 + up2\n\n\n@MODELS.register_module()\nclass HourglassAENet(BaseBackbone):\n    \"\"\"Hourglass-AE Network proposed by Newell et al.\n\n    Associative Embedding: End-to-End Learning for Joint\n    Detection and Grouping.\n\n    More details can be found in the `paper\n    <https://arxiv.org/abs/1611.05424>`__ .\n\n    Args:\n        downsample_times (int): Downsample times in a HourglassModule.\n        num_stacks (int): Number of HourglassModule modules stacked,\n            1 for Hourglass-52, 2 for Hourglass-104.\n        stage_channels (list[int]): Feature channel of each sub-module in a\n            HourglassModule.\n        stage_blocks (list[int]): Number of sub-modules stacked in a\n            HourglassModule.\n        feat_channels (int): Feature channel of conv after a HourglassModule.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import HourglassAENet\n        >>> import torch\n        >>> self = HourglassAENet()\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 512, 512)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_output in level_outputs:\n        ...     print(tuple(level_output.shape))\n        (1, 34, 128, 128)\n    \"\"\"\n\n    def __init__(\n        self,\n        downsample_times=4,\n        num_stacks=1,\n        out_channels=34,\n        stage_channels=(256, 384, 512, 640, 768),\n        feat_channels=256,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        init_cfg=[\n            dict(type='Normal', std=0.001, layer=['Conv2d']),\n            dict(type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm'])\n        ],\n    ):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n\n        self.num_stacks = num_stacks\n        assert self.num_stacks >= 1\n        assert len(stage_channels) > downsample_times\n\n        cur_channels = stage_channels[0]\n\n        self.stem = nn.Sequential(\n            ConvModule(3, 64, 7, padding=3, stride=2, norm_cfg=norm_cfg),\n            ConvModule(64, 128, 3, padding=1, norm_cfg=norm_cfg),\n            MaxPool2d(2, 2),\n            ConvModule(128, 128, 3, padding=1, norm_cfg=norm_cfg),\n            ConvModule(128, feat_channels, 3, padding=1, norm_cfg=norm_cfg),\n        )\n\n        self.hourglass_modules = nn.ModuleList([\n            nn.Sequential(\n                HourglassAEModule(\n                    downsample_times, stage_channels, norm_cfg=norm_cfg),\n                ConvModule(\n                    feat_channels,\n                    feat_channels,\n                    3,\n                    padding=1,\n                    norm_cfg=norm_cfg),\n                ConvModule(\n                    feat_channels,\n                    feat_channels,\n                    3,\n                    padding=1,\n                    norm_cfg=norm_cfg)) for _ in range(num_stacks)\n        ])\n\n        self.out_convs = nn.ModuleList([\n            ConvModule(\n                cur_channels,\n                out_channels,\n                1,\n                padding=0,\n                norm_cfg=None,\n                act_cfg=None) for _ in range(num_stacks)\n        ])\n\n        self.remap_out_convs = nn.ModuleList([\n            ConvModule(\n                out_channels,\n                feat_channels,\n                1,\n                norm_cfg=norm_cfg,\n                act_cfg=None) for _ in range(num_stacks - 1)\n        ])\n\n        self.remap_feature_convs = nn.ModuleList([\n            ConvModule(\n                feat_channels,\n                feat_channels,\n                1,\n                norm_cfg=norm_cfg,\n                act_cfg=None) for _ in range(num_stacks - 1)\n        ])\n\n        self.relu = nn.ReLU(inplace=True)\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        inter_feat = self.stem(x)\n        out_feats = []\n\n        for ind in range(self.num_stacks):\n            single_hourglass = self.hourglass_modules[ind]\n            out_conv = self.out_convs[ind]\n\n            hourglass_feat = single_hourglass(inter_feat)\n            out_feat = out_conv(hourglass_feat)\n            out_feats.append(out_feat)\n\n            if ind < self.num_stacks - 1:\n                inter_feat = inter_feat + self.remap_out_convs[ind](\n                    out_feat) + self.remap_feature_convs[ind](\n                        hourglass_feat)\n\n        return out_feats\n"
  },
  {
    "path": "mmpose/models/backbones/hrformer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nimport math\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import build_activation_layer, build_conv_layer, build_norm_layer\nfrom mmcv.cnn.bricks.transformer import build_dropout\nfrom mmengine.model import BaseModule, trunc_normal_init\nfrom torch.nn.functional import pad\n\nfrom mmpose.registry import MODELS\nfrom .hrnet import Bottleneck, HRModule, HRNet\n\n\ndef nlc_to_nchw(x, hw_shape):\n    \"\"\"Convert [N, L, C] shape tensor to [N, C, H, W] shape tensor.\n\n    Args:\n        x (Tensor): The input tensor of shape [N, L, C] before conversion.\n        hw_shape (Sequence[int]): The height and width of output feature map.\n\n    Returns:\n        Tensor: The output tensor of shape [N, C, H, W] after conversion.\n    \"\"\"\n    H, W = hw_shape\n    assert len(x.shape) == 3\n    B, L, C = x.shape\n    assert L == H * W, 'The seq_len doesn\\'t match H, W'\n    return x.transpose(1, 2).reshape(B, C, H, W)\n\n\ndef nchw_to_nlc(x):\n    \"\"\"Flatten [N, C, H, W] shape tensor to [N, L, C] shape tensor.\n\n    Args:\n        x (Tensor): The input tensor of shape [N, C, H, W] before conversion.\n\n    Returns:\n        Tensor: The output tensor of shape [N, L, C] after conversion.\n    \"\"\"\n    assert len(x.shape) == 4\n    return x.flatten(2).transpose(1, 2).contiguous()\n\n\ndef build_drop_path(drop_path_rate):\n    \"\"\"Build drop path layer.\"\"\"\n    return build_dropout(dict(type='DropPath', drop_prob=drop_path_rate))\n\n\nclass WindowMSA(BaseModule):\n    \"\"\"Window based multi-head self-attention (W-MSA) module with relative\n    position bias.\n\n    Args:\n        embed_dims (int): Number of input channels.\n        num_heads (int): Number of attention heads.\n        window_size (tuple[int]): The height and width of the window.\n        qkv_bias (bool, optional):  If True, add a learnable bias to q, k, v.\n            Default: True.\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        attn_drop_rate (float, optional): Dropout ratio of attention weight.\n            Default: 0.0\n        proj_drop_rate (float, optional): Dropout ratio of output. Default: 0.\n        with_rpe (bool, optional): If True, use relative position bias.\n            Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 window_size,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 attn_drop_rate=0.,\n                 proj_drop_rate=0.,\n                 with_rpe=True,\n                 init_cfg=None):\n\n        super().__init__(init_cfg=init_cfg)\n        self.embed_dims = embed_dims\n        self.window_size = window_size  # Wh, Ww\n        self.num_heads = num_heads\n        head_embed_dims = embed_dims // num_heads\n        self.scale = qk_scale or head_embed_dims**-0.5\n\n        self.with_rpe = with_rpe\n        if self.with_rpe:\n            # define a parameter table of relative position bias\n            self.relative_position_bias_table = nn.Parameter(\n                torch.zeros(\n                    (2 * window_size[0] - 1) * (2 * window_size[1] - 1),\n                    num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n\n            Wh, Ww = self.window_size\n            rel_index_coords = self.double_step_seq(2 * Ww - 1, Wh, 1, Ww)\n            rel_position_index = rel_index_coords + rel_index_coords.T\n            rel_position_index = rel_position_index.flip(1).contiguous()\n            self.register_buffer('relative_position_index', rel_position_index)\n\n        self.qkv = nn.Linear(embed_dims, embed_dims * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop_rate)\n        self.proj = nn.Linear(embed_dims, embed_dims)\n        self.proj_drop = nn.Dropout(proj_drop_rate)\n\n        self.softmax = nn.Softmax(dim=-1)\n\n    def init_weights(self):\n        trunc_normal_init(self.relative_position_bias_table, std=0.02)\n\n    def forward(self, x, mask=None):\n        \"\"\"\n        Args:\n\n            x (tensor): input features with shape of (B*num_windows, N, C)\n            mask (tensor | None, Optional): mask with shape of (num_windows,\n                Wh*Ww, Wh*Ww), value should be between (-inf, 0].\n        \"\"\"\n        B, N, C = x.shape\n        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads,\n                                  C // self.num_heads).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[2]\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        if self.with_rpe:\n            relative_position_bias = self.relative_position_bias_table[\n                self.relative_position_index.view(-1)].view(\n                    self.window_size[0] * self.window_size[1],\n                    self.window_size[0] * self.window_size[1],\n                    -1)  # Wh*Ww,Wh*Ww,nH\n            relative_position_bias = relative_position_bias.permute(\n                2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n            attn = attn + relative_position_bias.unsqueeze(0)\n\n        if mask is not None:\n            nW = mask.shape[0]\n            attn = attn.view(B // nW, nW, self.num_heads, N,\n                             N) + mask.unsqueeze(1).unsqueeze(0)\n            attn = attn.view(-1, self.num_heads, N, N)\n        attn = self.softmax(attn)\n\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n    @staticmethod\n    def double_step_seq(step1, len1, step2, len2):\n        seq1 = torch.arange(0, step1 * len1, step1)\n        seq2 = torch.arange(0, step2 * len2, step2)\n        return (seq1[:, None] + seq2[None, :]).reshape(1, -1)\n\n\nclass LocalWindowSelfAttention(BaseModule):\n    r\"\"\" Local-window Self Attention (LSA) module with relative position bias.\n\n    This module is the short-range self-attention module in the\n    Interlaced Sparse Self-Attention <https://arxiv.org/abs/1907.12273>`_.\n\n    Args:\n        embed_dims (int): Number of input channels.\n        num_heads (int): Number of attention heads.\n        window_size (tuple[int] | int): The height and width of the window.\n        qkv_bias (bool, optional):  If True, add a learnable bias to q, k, v.\n            Default: True.\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        attn_drop_rate (float, optional): Dropout ratio of attention weight.\n            Default: 0.0\n        proj_drop_rate (float, optional): Dropout ratio of output. Default: 0.\n        with_rpe (bool, optional): If True, use relative position bias.\n            Default: True.\n        with_pad_mask (bool, optional): If True, mask out the padded tokens in\n            the attention process. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 window_size,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 attn_drop_rate=0.,\n                 proj_drop_rate=0.,\n                 with_rpe=True,\n                 with_pad_mask=False,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        if isinstance(window_size, int):\n            window_size = (window_size, window_size)\n        self.window_size = window_size\n        self.with_pad_mask = with_pad_mask\n        self.attn = WindowMSA(\n            embed_dims=embed_dims,\n            num_heads=num_heads,\n            window_size=window_size,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop_rate=attn_drop_rate,\n            proj_drop_rate=proj_drop_rate,\n            with_rpe=with_rpe,\n            init_cfg=init_cfg)\n\n    def forward(self, x, H, W, **kwargs):\n        \"\"\"Forward function.\"\"\"\n        B, N, C = x.shape\n        x = x.view(B, H, W, C)\n        Wh, Ww = self.window_size\n\n        # center-pad the feature on H and W axes\n        pad_h = math.ceil(H / Wh) * Wh - H\n        pad_w = math.ceil(W / Ww) * Ww - W\n        x = pad(x, (0, 0, pad_w // 2, pad_w - pad_w // 2, pad_h // 2,\n                    pad_h - pad_h // 2))\n\n        # permute\n        x = x.view(B, math.ceil(H / Wh), Wh, math.ceil(W / Ww), Ww, C)\n        x = x.permute(0, 1, 3, 2, 4, 5)\n        x = x.reshape(-1, Wh * Ww, C)  # (B*num_window, Wh*Ww, C)\n\n        # attention\n        if self.with_pad_mask and pad_h > 0 and pad_w > 0:\n            pad_mask = x.new_zeros(1, H, W, 1)\n            pad_mask = pad(\n                pad_mask, [\n                    0, 0, pad_w // 2, pad_w - pad_w // 2, pad_h // 2,\n                    pad_h - pad_h // 2\n                ],\n                value=-float('inf'))\n            pad_mask = pad_mask.view(1, math.ceil(H / Wh), Wh,\n                                     math.ceil(W / Ww), Ww, 1)\n            pad_mask = pad_mask.permute(1, 3, 0, 2, 4, 5)\n            pad_mask = pad_mask.reshape(-1, Wh * Ww)\n            pad_mask = pad_mask[:, None, :].expand([-1, Wh * Ww, -1])\n            out = self.attn(x, pad_mask, **kwargs)\n        else:\n            out = self.attn(x, **kwargs)\n\n        # reverse permutation\n        out = out.reshape(B, math.ceil(H / Wh), math.ceil(W / Ww), Wh, Ww, C)\n        out = out.permute(0, 1, 3, 2, 4, 5)\n        out = out.reshape(B, H + pad_h, W + pad_w, C)\n\n        # de-pad\n        out = out[:, pad_h // 2:H + pad_h // 2, pad_w // 2:W + pad_w // 2]\n        return out.reshape(B, N, C)\n\n\nclass CrossFFN(BaseModule):\n    r\"\"\"FFN with Depthwise Conv of HRFormer.\n\n    Args:\n        in_features (int): The feature dimension.\n        hidden_features (int, optional): The hidden dimension of FFNs.\n            Defaults: The same as in_features.\n        act_cfg (dict, optional): Config of activation layer.\n            Default: dict(type='GELU').\n        dw_act_cfg (dict, optional): Config of activation layer appended\n            right after DW Conv. Default: dict(type='GELU').\n        norm_cfg (dict, optional): Config of norm layer.\n            Default: dict(type='SyncBN').\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 in_features,\n                 hidden_features=None,\n                 out_features=None,\n                 act_cfg=dict(type='GELU'),\n                 dw_act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='SyncBN'),\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Conv2d(in_features, hidden_features, kernel_size=1)\n        self.act1 = build_activation_layer(act_cfg)\n        self.norm1 = build_norm_layer(norm_cfg, hidden_features)[1]\n        self.dw3x3 = nn.Conv2d(\n            hidden_features,\n            hidden_features,\n            kernel_size=3,\n            stride=1,\n            groups=hidden_features,\n            padding=1)\n        self.act2 = build_activation_layer(dw_act_cfg)\n        self.norm2 = build_norm_layer(norm_cfg, hidden_features)[1]\n        self.fc2 = nn.Conv2d(hidden_features, out_features, kernel_size=1)\n        self.act3 = build_activation_layer(act_cfg)\n        self.norm3 = build_norm_layer(norm_cfg, out_features)[1]\n\n    def forward(self, x, H, W):\n        \"\"\"Forward function.\"\"\"\n        x = nlc_to_nchw(x, (H, W))\n        x = self.act1(self.norm1(self.fc1(x)))\n        x = self.act2(self.norm2(self.dw3x3(x)))\n        x = self.act3(self.norm3(self.fc2(x)))\n        x = nchw_to_nlc(x)\n        return x\n\n\nclass HRFormerBlock(BaseModule):\n    \"\"\"High-Resolution Block for HRFormer.\n\n    Args:\n        in_features (int): The input dimension.\n        out_features (int): The output dimension.\n        num_heads (int): The number of head within each LSA.\n        window_size (int, optional): The window size for the LSA.\n            Default: 7\n        mlp_ratio (int, optional): The expansion ration of FFN.\n            Default: 4\n        act_cfg (dict, optional): Config of activation layer.\n            Default: dict(type='GELU').\n        norm_cfg (dict, optional): Config of norm layer.\n            Default: dict(type='SyncBN').\n        transformer_norm_cfg (dict, optional): Config of transformer norm\n            layer. Default: dict(type='LN', eps=1e-6).\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    expansion = 1\n\n    def __init__(self,\n                 in_features,\n                 out_features,\n                 num_heads,\n                 window_size=7,\n                 mlp_ratio=4.0,\n                 drop_path=0.0,\n                 act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='SyncBN'),\n                 transformer_norm_cfg=dict(type='LN', eps=1e-6),\n                 init_cfg=None,\n                 **kwargs):\n        super(HRFormerBlock, self).__init__(init_cfg=init_cfg)\n        self.num_heads = num_heads\n        self.window_size = window_size\n        self.mlp_ratio = mlp_ratio\n\n        self.norm1 = build_norm_layer(transformer_norm_cfg, in_features)[1]\n        self.attn = LocalWindowSelfAttention(\n            in_features,\n            num_heads=num_heads,\n            window_size=window_size,\n            init_cfg=None,\n            **kwargs)\n\n        self.norm2 = build_norm_layer(transformer_norm_cfg, out_features)[1]\n        self.ffn = CrossFFN(\n            in_features=in_features,\n            hidden_features=int(in_features * mlp_ratio),\n            out_features=out_features,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg,\n            dw_act_cfg=act_cfg,\n            init_cfg=None)\n\n        self.drop_path = build_drop_path(\n            drop_path) if drop_path > 0.0 else nn.Identity()\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        B, C, H, W = x.size()\n        # Attention\n        x = x.view(B, C, -1).permute(0, 2, 1)\n        x = x + self.drop_path(self.attn(self.norm1(x), H, W))\n        # FFN\n        x = x + self.drop_path(self.ffn(self.norm2(x), H, W))\n        x = x.permute(0, 2, 1).view(B, C, H, W)\n        return x\n\n    def extra_repr(self):\n        \"\"\"(Optional) Set the extra information about this module.\"\"\"\n        return 'num_heads={}, window_size={}, mlp_ratio={}'.format(\n            self.num_heads, self.window_size, self.mlp_ratio)\n\n\nclass HRFomerModule(HRModule):\n    \"\"\"High-Resolution Module for HRFormer.\n\n    Args:\n        num_branches (int): The number of branches in the HRFormerModule.\n        block (nn.Module): The building block of HRFormer.\n            The block should be the HRFormerBlock.\n        num_blocks (tuple): The number of blocks in each branch.\n            The length must be equal to num_branches.\n        num_inchannels (tuple): The number of input channels in each branch.\n            The length must be equal to num_branches.\n        num_channels (tuple): The number of channels in each branch.\n            The length must be equal to num_branches.\n        num_heads (tuple): The number of heads within the LSAs.\n        num_window_sizes (tuple): The window size for the LSAs.\n        num_mlp_ratios (tuple): The expansion ratio for the FFNs.\n        drop_path (int, optional): The drop path rate of HRFomer.\n            Default: 0.0\n        multiscale_output (bool, optional): Whether to output multi-level\n            features produced by multiple branches. If False, only the first\n            level feature will be output. Default: True.\n        conv_cfg (dict, optional): Config of the conv layers.\n            Default: None.\n        norm_cfg (dict, optional): Config of the norm layers appended\n            right after conv. Default: dict(type='SyncBN', requires_grad=True)\n        transformer_norm_cfg (dict, optional): Config of the norm layers.\n            Default: dict(type='LN', eps=1e-6)\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False\n        upsample_cfg(dict, optional): The config of upsample layers in fuse\n            layers. Default: dict(mode='bilinear', align_corners=False)\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 num_branches,\n                 block,\n                 num_blocks,\n                 num_inchannels,\n                 num_channels,\n                 num_heads,\n                 num_window_sizes,\n                 num_mlp_ratios,\n                 multiscale_output=True,\n                 drop_paths=0.0,\n                 with_rpe=True,\n                 with_pad_mask=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='SyncBN', requires_grad=True),\n                 transformer_norm_cfg=dict(type='LN', eps=1e-6),\n                 with_cp=False,\n                 upsample_cfg=dict(mode='bilinear', align_corners=False),\n                 **kwargs):\n\n        self.transformer_norm_cfg = transformer_norm_cfg\n        self.drop_paths = drop_paths\n        self.num_heads = num_heads\n        self.num_window_sizes = num_window_sizes\n        self.num_mlp_ratios = num_mlp_ratios\n        self.with_rpe = with_rpe\n        self.with_pad_mask = with_pad_mask\n\n        super().__init__(num_branches, block, num_blocks, num_inchannels,\n                         num_channels, multiscale_output, with_cp, conv_cfg,\n                         norm_cfg, upsample_cfg, **kwargs)\n\n    def _make_one_branch(self,\n                         branch_index,\n                         block,\n                         num_blocks,\n                         num_channels,\n                         stride=1):\n        \"\"\"Build one branch.\"\"\"\n        # HRFormerBlock does not support down sample layer yet.\n        assert stride == 1 and self.in_channels[branch_index] == num_channels[\n            branch_index]\n        layers = []\n        layers.append(\n            block(\n                self.in_channels[branch_index],\n                num_channels[branch_index],\n                num_heads=self.num_heads[branch_index],\n                window_size=self.num_window_sizes[branch_index],\n                mlp_ratio=self.num_mlp_ratios[branch_index],\n                drop_path=self.drop_paths[0],\n                norm_cfg=self.norm_cfg,\n                transformer_norm_cfg=self.transformer_norm_cfg,\n                init_cfg=None,\n                with_rpe=self.with_rpe,\n                with_pad_mask=self.with_pad_mask))\n\n        self.in_channels[\n            branch_index] = self.in_channels[branch_index] * block.expansion\n        for i in range(1, num_blocks[branch_index]):\n            layers.append(\n                block(\n                    self.in_channels[branch_index],\n                    num_channels[branch_index],\n                    num_heads=self.num_heads[branch_index],\n                    window_size=self.num_window_sizes[branch_index],\n                    mlp_ratio=self.num_mlp_ratios[branch_index],\n                    drop_path=self.drop_paths[i],\n                    norm_cfg=self.norm_cfg,\n                    transformer_norm_cfg=self.transformer_norm_cfg,\n                    init_cfg=None,\n                    with_rpe=self.with_rpe,\n                    with_pad_mask=self.with_pad_mask))\n        return nn.Sequential(*layers)\n\n    def _make_fuse_layers(self):\n        \"\"\"Build fuse layers.\"\"\"\n        if self.num_branches == 1:\n            return None\n        num_branches = self.num_branches\n        num_inchannels = self.in_channels\n        fuse_layers = []\n        for i in range(num_branches if self.multiscale_output else 1):\n            fuse_layer = []\n            for j in range(num_branches):\n                if j > i:\n                    fuse_layer.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                num_inchannels[j],\n                                num_inchannels[i],\n                                kernel_size=1,\n                                stride=1,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg,\n                                             num_inchannels[i])[1],\n                            nn.Upsample(\n                                scale_factor=2**(j - i),\n                                mode=self.upsample_cfg['mode'],\n                                align_corners=self.\n                                upsample_cfg['align_corners'])))\n                elif j == i:\n                    fuse_layer.append(None)\n                else:\n                    conv3x3s = []\n                    for k in range(i - j):\n                        if k == i - j - 1:\n                            num_outchannels_conv3x3 = num_inchannels[i]\n                            with_out_act = False\n                        else:\n                            num_outchannels_conv3x3 = num_inchannels[j]\n                            with_out_act = True\n                        sub_modules = [\n                            build_conv_layer(\n                                self.conv_cfg,\n                                num_inchannels[j],\n                                num_inchannels[j],\n                                kernel_size=3,\n                                stride=2,\n                                padding=1,\n                                groups=num_inchannels[j],\n                                bias=False,\n                            ),\n                            build_norm_layer(self.norm_cfg,\n                                             num_inchannels[j])[1],\n                            build_conv_layer(\n                                self.conv_cfg,\n                                num_inchannels[j],\n                                num_outchannels_conv3x3,\n                                kernel_size=1,\n                                stride=1,\n                                bias=False,\n                            ),\n                            build_norm_layer(self.norm_cfg,\n                                             num_outchannels_conv3x3)[1]\n                        ]\n                        if with_out_act:\n                            sub_modules.append(nn.ReLU(False))\n                        conv3x3s.append(nn.Sequential(*sub_modules))\n                    fuse_layer.append(nn.Sequential(*conv3x3s))\n            fuse_layers.append(nn.ModuleList(fuse_layer))\n\n        return nn.ModuleList(fuse_layers)\n\n    def get_num_inchannels(self):\n        \"\"\"Return the number of input channels.\"\"\"\n        return self.in_channels\n\n\n@MODELS.register_module()\nclass HRFormer(HRNet):\n    \"\"\"HRFormer backbone.\n\n    This backbone is the implementation of `HRFormer: High-Resolution\n    Transformer for Dense Prediction <https://arxiv.org/abs/2110.09408>`_.\n\n    Args:\n        extra (dict): Detailed configuration for each stage of HRNet.\n            There must be 4 stages, the configuration for each stage must have\n            5 keys:\n\n                - num_modules (int): The number of HRModule in this stage.\n                - num_branches (int): The number of branches in the HRModule.\n                - block (str): The type of block.\n                - num_blocks (tuple): The number of blocks in each branch.\n                    The length must be equal to num_branches.\n                - num_channels (tuple): The number of channels in each branch.\n                    The length must be equal to num_branches.\n        in_channels (int): Number of input image channels. Normally 3.\n        conv_cfg (dict): Dictionary to construct and config conv layer.\n            Default: None.\n        norm_cfg (dict): Config of norm layer.\n            Use `SyncBN` by default.\n        transformer_norm_cfg (dict): Config of transformer norm layer.\n            Use `LN` by default.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import HRFormer\n        >>> import torch\n        >>> extra = dict(\n        >>>     stage1=dict(\n        >>>         num_modules=1,\n        >>>         num_branches=1,\n        >>>         block='BOTTLENECK',\n        >>>         num_blocks=(2, ),\n        >>>         num_channels=(64, )),\n        >>>     stage2=dict(\n        >>>         num_modules=1,\n        >>>         num_branches=2,\n        >>>         block='HRFORMER',\n        >>>         window_sizes=(7, 7),\n        >>>         num_heads=(1, 2),\n        >>>         mlp_ratios=(4, 4),\n        >>>         num_blocks=(2, 2),\n        >>>         num_channels=(32, 64)),\n        >>>     stage3=dict(\n        >>>         num_modules=4,\n        >>>         num_branches=3,\n        >>>         block='HRFORMER',\n        >>>         window_sizes=(7, 7, 7),\n        >>>         num_heads=(1, 2, 4),\n        >>>         mlp_ratios=(4, 4, 4),\n        >>>         num_blocks=(2, 2, 2),\n        >>>         num_channels=(32, 64, 128)),\n        >>>     stage4=dict(\n        >>>         num_modules=2,\n        >>>         num_branches=4,\n        >>>         block='HRFORMER',\n        >>>         window_sizes=(7, 7, 7, 7),\n        >>>         num_heads=(1, 2, 4, 8),\n        >>>         mlp_ratios=(4, 4, 4, 4),\n        >>>         num_blocks=(2, 2, 2, 2),\n        >>>         num_channels=(32, 64, 128, 256)))\n        >>> self = HRFormer(extra, in_channels=1)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 1, 32, 32)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 32, 8, 8)\n        (1, 64, 4, 4)\n        (1, 128, 2, 2)\n        (1, 256, 1, 1)\n    \"\"\"\n\n    blocks_dict = {'BOTTLENECK': Bottleneck, 'HRFORMERBLOCK': HRFormerBlock}\n\n    def __init__(\n        self,\n        extra,\n        in_channels=3,\n        conv_cfg=None,\n        norm_cfg=dict(type='BN', requires_grad=True),\n        transformer_norm_cfg=dict(type='LN', eps=1e-6),\n        norm_eval=False,\n        with_cp=False,\n        zero_init_residual=False,\n        frozen_stages=-1,\n        init_cfg=[\n            dict(type='Normal', std=0.001, layer=['Conv2d']),\n            dict(type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm'])\n        ],\n    ):\n\n        # stochastic depth\n        depths = [\n            extra[stage]['num_blocks'][0] * extra[stage]['num_modules']\n            for stage in ['stage2', 'stage3', 'stage4']\n        ]\n        depth_s2, depth_s3, _ = depths\n        drop_path_rate = extra['drop_path_rate']\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))\n        ]\n        extra['stage2']['drop_path_rates'] = dpr[0:depth_s2]\n        extra['stage3']['drop_path_rates'] = dpr[depth_s2:depth_s2 + depth_s3]\n        extra['stage4']['drop_path_rates'] = dpr[depth_s2 + depth_s3:]\n\n        # HRFormer use bilinear upsample as default\n        upsample_cfg = extra.get('upsample', {\n            'mode': 'bilinear',\n            'align_corners': False\n        })\n        extra['upsample'] = upsample_cfg\n        self.transformer_norm_cfg = transformer_norm_cfg\n        self.with_rpe = extra.get('with_rpe', True)\n        self.with_pad_mask = extra.get('with_pad_mask', False)\n\n        super().__init__(extra, in_channels, conv_cfg, norm_cfg, norm_eval,\n                         with_cp, zero_init_residual, frozen_stages, init_cfg)\n\n    def _make_stage(self,\n                    layer_config,\n                    num_inchannels,\n                    multiscale_output=True):\n        \"\"\"Make each stage.\"\"\"\n        num_modules = layer_config['num_modules']\n        num_branches = layer_config['num_branches']\n        num_blocks = layer_config['num_blocks']\n        num_channels = layer_config['num_channels']\n        block = self.blocks_dict[layer_config['block']]\n        num_heads = layer_config['num_heads']\n        num_window_sizes = layer_config['window_sizes']\n        num_mlp_ratios = layer_config['mlp_ratios']\n        drop_path_rates = layer_config['drop_path_rates']\n\n        modules = []\n        for i in range(num_modules):\n            # multiscale_output is only used at the last module\n            if not multiscale_output and i == num_modules - 1:\n                reset_multiscale_output = False\n            else:\n                reset_multiscale_output = True\n\n            modules.append(\n                HRFomerModule(\n                    num_branches,\n                    block,\n                    num_blocks,\n                    num_inchannels,\n                    num_channels,\n                    num_heads,\n                    num_window_sizes,\n                    num_mlp_ratios,\n                    reset_multiscale_output,\n                    drop_paths=drop_path_rates[num_blocks[0] *\n                                               i:num_blocks[0] * (i + 1)],\n                    with_rpe=self.with_rpe,\n                    with_pad_mask=self.with_pad_mask,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    transformer_norm_cfg=self.transformer_norm_cfg,\n                    with_cp=self.with_cp,\n                    upsample_cfg=self.upsample_cfg))\n            num_inchannels = modules[-1].get_num_inchannels()\n\n        return nn.Sequential(*modules), num_inchannels\n"
  },
  {
    "path": "mmpose/models/backbones/hrnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\nfrom mmengine.model import BaseModule, constant_init\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .resnet import BasicBlock, Bottleneck, get_expansion\n\n\nclass HRModule(BaseModule):\n    \"\"\"High-Resolution Module for HRNet.\n\n    In this module, every branch has 4 BasicBlocks/Bottlenecks. Fusion/Exchange\n    is in this module.\n    \"\"\"\n\n    def __init__(self,\n                 num_branches,\n                 blocks,\n                 num_blocks,\n                 in_channels,\n                 num_channels,\n                 multiscale_output=False,\n                 with_cp=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 upsample_cfg=dict(mode='nearest', align_corners=None),\n                 init_cfg=None):\n\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self._check_branches(num_branches, num_blocks, in_channels,\n                             num_channels)\n\n        self.in_channels = in_channels\n        self.num_branches = num_branches\n\n        self.multiscale_output = multiscale_output\n        self.norm_cfg = norm_cfg\n        self.conv_cfg = conv_cfg\n        self.upsample_cfg = upsample_cfg\n        self.with_cp = with_cp\n        self.branches = self._make_branches(num_branches, blocks, num_blocks,\n                                            num_channels)\n        self.fuse_layers = self._make_fuse_layers()\n        self.relu = nn.ReLU(inplace=True)\n\n    @staticmethod\n    def _check_branches(num_branches, num_blocks, in_channels, num_channels):\n        \"\"\"Check input to avoid ValueError.\"\"\"\n        if num_branches != len(num_blocks):\n            error_msg = f'NUM_BRANCHES({num_branches}) ' \\\n                f'!= NUM_BLOCKS({len(num_blocks)})'\n            raise ValueError(error_msg)\n\n        if num_branches != len(num_channels):\n            error_msg = f'NUM_BRANCHES({num_branches}) ' \\\n                f'!= NUM_CHANNELS({len(num_channels)})'\n            raise ValueError(error_msg)\n\n        if num_branches != len(in_channels):\n            error_msg = f'NUM_BRANCHES({num_branches}) ' \\\n                f'!= NUM_INCHANNELS({len(in_channels)})'\n            raise ValueError(error_msg)\n\n    def _make_one_branch(self,\n                         branch_index,\n                         block,\n                         num_blocks,\n                         num_channels,\n                         stride=1):\n        \"\"\"Make one branch.\"\"\"\n        downsample = None\n        if stride != 1 or \\\n                self.in_channels[branch_index] != \\\n                num_channels[branch_index] * get_expansion(block):\n            downsample = nn.Sequential(\n                build_conv_layer(\n                    self.conv_cfg,\n                    self.in_channels[branch_index],\n                    num_channels[branch_index] * get_expansion(block),\n                    kernel_size=1,\n                    stride=stride,\n                    bias=False),\n                build_norm_layer(\n                    self.norm_cfg,\n                    num_channels[branch_index] * get_expansion(block))[1])\n\n        layers = []\n        layers.append(\n            block(\n                self.in_channels[branch_index],\n                num_channels[branch_index] * get_expansion(block),\n                stride=stride,\n                downsample=downsample,\n                with_cp=self.with_cp,\n                norm_cfg=self.norm_cfg,\n                conv_cfg=self.conv_cfg))\n        self.in_channels[branch_index] = \\\n            num_channels[branch_index] * get_expansion(block)\n        for _ in range(1, num_blocks[branch_index]):\n            layers.append(\n                block(\n                    self.in_channels[branch_index],\n                    num_channels[branch_index] * get_expansion(block),\n                    with_cp=self.with_cp,\n                    norm_cfg=self.norm_cfg,\n                    conv_cfg=self.conv_cfg))\n\n        return nn.Sequential(*layers)\n\n    def _make_branches(self, num_branches, block, num_blocks, num_channels):\n        \"\"\"Make branches.\"\"\"\n        branches = []\n\n        for i in range(num_branches):\n            branches.append(\n                self._make_one_branch(i, block, num_blocks, num_channels))\n\n        return nn.ModuleList(branches)\n\n    def _make_fuse_layers(self):\n        \"\"\"Make fuse layer.\"\"\"\n        if self.num_branches == 1:\n            return None\n\n        num_branches = self.num_branches\n        in_channels = self.in_channels\n        fuse_layers = []\n        num_out_branches = num_branches if self.multiscale_output else 1\n\n        for i in range(num_out_branches):\n            fuse_layer = []\n            for j in range(num_branches):\n                if j > i:\n                    fuse_layer.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                in_channels[j],\n                                in_channels[i],\n                                kernel_size=1,\n                                stride=1,\n                                padding=0,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg, in_channels[i])[1],\n                            nn.Upsample(\n                                scale_factor=2**(j - i),\n                                mode=self.upsample_cfg['mode'],\n                                align_corners=self.\n                                upsample_cfg['align_corners'])))\n                elif j == i:\n                    fuse_layer.append(None)\n                else:\n                    conv_downsamples = []\n                    for k in range(i - j):\n                        if k == i - j - 1:\n                            conv_downsamples.append(\n                                nn.Sequential(\n                                    build_conv_layer(\n                                        self.conv_cfg,\n                                        in_channels[j],\n                                        in_channels[i],\n                                        kernel_size=3,\n                                        stride=2,\n                                        padding=1,\n                                        bias=False),\n                                    build_norm_layer(self.norm_cfg,\n                                                     in_channels[i])[1]))\n                        else:\n                            conv_downsamples.append(\n                                nn.Sequential(\n                                    build_conv_layer(\n                                        self.conv_cfg,\n                                        in_channels[j],\n                                        in_channels[j],\n                                        kernel_size=3,\n                                        stride=2,\n                                        padding=1,\n                                        bias=False),\n                                    build_norm_layer(self.norm_cfg,\n                                                     in_channels[j])[1],\n                                    nn.ReLU(inplace=True)))\n                    fuse_layer.append(nn.Sequential(*conv_downsamples))\n            fuse_layers.append(nn.ModuleList(fuse_layer))\n\n        return nn.ModuleList(fuse_layers)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        if self.num_branches == 1:\n            return [self.branches[0](x[0])]\n\n        for i in range(self.num_branches):\n            x[i] = self.branches[i](x[i])\n\n        x_fuse = []\n        for i in range(len(self.fuse_layers)):\n            y = 0\n            for j in range(self.num_branches):\n                if i == j:\n                    y += x[j]\n                else:\n                    y += self.fuse_layers[i][j](x[j])\n            x_fuse.append(self.relu(y))\n        return x_fuse\n\n\n@MODELS.register_module()\nclass HRNet(BaseBackbone):\n    \"\"\"HRNet backbone.\n\n    `High-Resolution Representations for Labeling Pixels and Regions\n    <https://arxiv.org/abs/1904.04514>`__\n\n    Args:\n        extra (dict): detailed configuration for each stage of HRNet.\n        in_channels (int): Number of input image channels. Default: 3.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n        norm_cfg (dict): dictionary to construct and config norm layer.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        zero_init_residual (bool): whether to use zero init for last norm layer\n            in resblocks to let them behave as identity.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import HRNet\n        >>> import torch\n        >>> extra = dict(\n        >>>     stage1=dict(\n        >>>         num_modules=1,\n        >>>         num_branches=1,\n        >>>         block='BOTTLENECK',\n        >>>         num_blocks=(4, ),\n        >>>         num_channels=(64, )),\n        >>>     stage2=dict(\n        >>>         num_modules=1,\n        >>>         num_branches=2,\n        >>>         block='BASIC',\n        >>>         num_blocks=(4, 4),\n        >>>         num_channels=(32, 64)),\n        >>>     stage3=dict(\n        >>>         num_modules=4,\n        >>>         num_branches=3,\n        >>>         block='BASIC',\n        >>>         num_blocks=(4, 4, 4),\n        >>>         num_channels=(32, 64, 128)),\n        >>>     stage4=dict(\n        >>>         num_modules=3,\n        >>>         num_branches=4,\n        >>>         block='BASIC',\n        >>>         num_blocks=(4, 4, 4, 4),\n        >>>         num_channels=(32, 64, 128, 256)))\n        >>> self = HRNet(extra, in_channels=1)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 1, 32, 32)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 32, 8, 8)\n    \"\"\"\n\n    blocks_dict = {'BASIC': BasicBlock, 'BOTTLENECK': Bottleneck}\n\n    def __init__(\n        self,\n        extra,\n        in_channels=3,\n        conv_cfg=None,\n        norm_cfg=dict(type='BN'),\n        norm_eval=False,\n        with_cp=False,\n        zero_init_residual=False,\n        frozen_stages=-1,\n        init_cfg=[\n            dict(type='Normal', std=0.001, layer=['Conv2d']),\n            dict(type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm'])\n        ],\n    ):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.extra = extra\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.init_cfg = init_cfg\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n        self.zero_init_residual = zero_init_residual\n        self.frozen_stages = frozen_stages\n\n        # stem net\n        self.norm1_name, norm1 = build_norm_layer(self.norm_cfg, 64, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(self.norm_cfg, 64, postfix=2)\n\n        self.conv1 = build_conv_layer(\n            self.conv_cfg,\n            in_channels,\n            64,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            bias=False)\n\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = build_conv_layer(\n            self.conv_cfg,\n            64,\n            64,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            bias=False)\n\n        self.add_module(self.norm2_name, norm2)\n        self.relu = nn.ReLU(inplace=True)\n\n        self.upsample_cfg = self.extra.get('upsample', {\n            'mode': 'nearest',\n            'align_corners': None\n        })\n\n        # stage 1\n        self.stage1_cfg = self.extra['stage1']\n        num_channels = self.stage1_cfg['num_channels'][0]\n        block_type = self.stage1_cfg['block']\n        num_blocks = self.stage1_cfg['num_blocks'][0]\n\n        block = self.blocks_dict[block_type]\n        stage1_out_channels = num_channels * get_expansion(block)\n        self.layer1 = self._make_layer(block, 64, stage1_out_channels,\n                                       num_blocks)\n\n        # stage 2\n        self.stage2_cfg = self.extra['stage2']\n        num_channels = self.stage2_cfg['num_channels']\n        block_type = self.stage2_cfg['block']\n\n        block = self.blocks_dict[block_type]\n        num_channels = [\n            channel * get_expansion(block) for channel in num_channels\n        ]\n        self.transition1 = self._make_transition_layer([stage1_out_channels],\n                                                       num_channels)\n        self.stage2, pre_stage_channels = self._make_stage(\n            self.stage2_cfg, num_channels)\n\n        # stage 3\n        self.stage3_cfg = self.extra['stage3']\n        num_channels = self.stage3_cfg['num_channels']\n        block_type = self.stage3_cfg['block']\n\n        block = self.blocks_dict[block_type]\n        num_channels = [\n            channel * get_expansion(block) for channel in num_channels\n        ]\n        self.transition2 = self._make_transition_layer(pre_stage_channels,\n                                                       num_channels)\n        self.stage3, pre_stage_channels = self._make_stage(\n            self.stage3_cfg, num_channels)\n\n        # stage 4\n        self.stage4_cfg = self.extra['stage4']\n        num_channels = self.stage4_cfg['num_channels']\n        block_type = self.stage4_cfg['block']\n\n        block = self.blocks_dict[block_type]\n        num_channels = [\n            channel * get_expansion(block) for channel in num_channels\n        ]\n        self.transition3 = self._make_transition_layer(pre_stage_channels,\n                                                       num_channels)\n\n        self.stage4, pre_stage_channels = self._make_stage(\n            self.stage4_cfg,\n            num_channels,\n            multiscale_output=self.stage4_cfg.get('multiscale_output', False))\n\n        self._freeze_stages()\n\n    @property\n    def norm1(self):\n        \"\"\"nn.Module: the normalization layer named \"norm1\" \"\"\"\n        return getattr(self, self.norm1_name)\n\n    @property\n    def norm2(self):\n        \"\"\"nn.Module: the normalization layer named \"norm2\" \"\"\"\n        return getattr(self, self.norm2_name)\n\n    def _make_transition_layer(self, num_channels_pre_layer,\n                               num_channels_cur_layer):\n        \"\"\"Make transition layer.\"\"\"\n        num_branches_cur = len(num_channels_cur_layer)\n        num_branches_pre = len(num_channels_pre_layer)\n\n        transition_layers = []\n        for i in range(num_branches_cur):\n            if i < num_branches_pre:\n                if num_channels_cur_layer[i] != num_channels_pre_layer[i]:\n                    transition_layers.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                num_channels_pre_layer[i],\n                                num_channels_cur_layer[i],\n                                kernel_size=3,\n                                stride=1,\n                                padding=1,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg,\n                                             num_channels_cur_layer[i])[1],\n                            nn.ReLU(inplace=True)))\n                else:\n                    transition_layers.append(None)\n            else:\n                conv_downsamples = []\n                for j in range(i + 1 - num_branches_pre):\n                    in_channels = num_channels_pre_layer[-1]\n                    out_channels = num_channels_cur_layer[i] \\\n                        if j == i - num_branches_pre else in_channels\n                    conv_downsamples.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                in_channels,\n                                out_channels,\n                                kernel_size=3,\n                                stride=2,\n                                padding=1,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg, out_channels)[1],\n                            nn.ReLU(inplace=True)))\n                transition_layers.append(nn.Sequential(*conv_downsamples))\n\n        return nn.ModuleList(transition_layers)\n\n    def _make_layer(self, block, in_channels, out_channels, blocks, stride=1):\n        \"\"\"Make layer.\"\"\"\n        downsample = None\n        if stride != 1 or in_channels != out_channels:\n            downsample = nn.Sequential(\n                build_conv_layer(\n                    self.conv_cfg,\n                    in_channels,\n                    out_channels,\n                    kernel_size=1,\n                    stride=stride,\n                    bias=False),\n                build_norm_layer(self.norm_cfg, out_channels)[1])\n\n        layers = []\n        layers.append(\n            block(\n                in_channels,\n                out_channels,\n                stride=stride,\n                downsample=downsample,\n                with_cp=self.with_cp,\n                norm_cfg=self.norm_cfg,\n                conv_cfg=self.conv_cfg))\n        for _ in range(1, blocks):\n            layers.append(\n                block(\n                    out_channels,\n                    out_channels,\n                    with_cp=self.with_cp,\n                    norm_cfg=self.norm_cfg,\n                    conv_cfg=self.conv_cfg))\n\n        return nn.Sequential(*layers)\n\n    def _make_stage(self, layer_config, in_channels, multiscale_output=True):\n        \"\"\"Make stage.\"\"\"\n        num_modules = layer_config['num_modules']\n        num_branches = layer_config['num_branches']\n        num_blocks = layer_config['num_blocks']\n        num_channels = layer_config['num_channels']\n        block = self.blocks_dict[layer_config['block']]\n\n        hr_modules = []\n        for i in range(num_modules):\n            # multi_scale_output is only used for the last module\n            if not multiscale_output and i == num_modules - 1:\n                reset_multiscale_output = False\n            else:\n                reset_multiscale_output = True\n\n            hr_modules.append(\n                HRModule(\n                    num_branches,\n                    block,\n                    num_blocks,\n                    in_channels,\n                    num_channels,\n                    reset_multiscale_output,\n                    with_cp=self.with_cp,\n                    norm_cfg=self.norm_cfg,\n                    conv_cfg=self.conv_cfg,\n                    upsample_cfg=self.upsample_cfg))\n\n            in_channels = hr_modules[-1].in_channels\n\n        return nn.Sequential(*hr_modules), in_channels\n\n    def _freeze_stages(self):\n        \"\"\"Freeze parameters.\"\"\"\n        if self.frozen_stages >= 0:\n            self.norm1.eval()\n            self.norm2.eval()\n\n            for m in [self.conv1, self.norm1, self.conv2, self.norm2]:\n                for param in m.parameters():\n                    param.requires_grad = False\n\n        for i in range(1, self.frozen_stages + 1):\n            if i == 1:\n                m = getattr(self, 'layer1')\n            else:\n                m = getattr(self, f'stage{i}')\n\n            m.eval()\n            for param in m.parameters():\n                param.requires_grad = False\n\n            if i < 4:\n                m = getattr(self, f'transition{i}')\n                m.eval()\n                for param in m.parameters():\n                    param.requires_grad = False\n\n    def init_weights(self):\n        \"\"\"Initialize the weights in backbone.\"\"\"\n        super(HRNet, self).init_weights()\n\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            # Suppress zero_init_residual if use pretrained model.\n            return\n\n        if self.zero_init_residual:\n            for m in self.modules():\n                if isinstance(m, Bottleneck):\n                    constant_init(m.norm3, 0)\n                elif isinstance(m, BasicBlock):\n                    constant_init(m.norm2, 0)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        x = self.conv1(x)\n        x = self.norm1(x)\n        x = self.relu(x)\n        x = self.conv2(x)\n        x = self.norm2(x)\n        x = self.relu(x)\n        x = self.layer1(x)\n\n        x_list = []\n        for i in range(self.stage2_cfg['num_branches']):\n            if self.transition1[i] is not None:\n                x_list.append(self.transition1[i](x))\n            else:\n                x_list.append(x)\n        y_list = self.stage2(x_list)\n\n        x_list = []\n        for i in range(self.stage3_cfg['num_branches']):\n            if self.transition2[i] is not None:\n                x_list.append(self.transition2[i](y_list[-1]))\n            else:\n                x_list.append(y_list[i])\n        y_list = self.stage3(x_list)\n\n        x_list = []\n        for i in range(self.stage4_cfg['num_branches']):\n            if self.transition3[i] is not None:\n                x_list.append(self.transition3[i](y_list[-1]))\n            else:\n                x_list.append(y_list[i])\n        y_list = self.stage4(x_list)\n\n        return tuple(y_list)\n\n    def train(self, mode=True):\n        \"\"\"Convert the model into training mode.\"\"\"\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/litehrnet.py",
    "content": "# ------------------------------------------------------------------------------\n# Adapted from https://github.com/HRNet/Lite-HRNet\n# Original licence: Apache License 2.0.\n# ------------------------------------------------------------------------------\n\nimport mmengine\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import (ConvModule, DepthwiseSeparableConvModule,\n                      build_conv_layer, build_norm_layer)\nfrom mmengine.model import BaseModule\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .utils import channel_shuffle\n\n\nclass SpatialWeighting(BaseModule):\n    \"\"\"Spatial weighting module.\n\n    Args:\n        channels (int): The channels of the module.\n        ratio (int): channel reduction ratio.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: None.\n        act_cfg (dict): Config dict for activation layer.\n            Default: (dict(type='ReLU'), dict(type='Sigmoid')).\n            The last ConvModule uses Sigmoid by default.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 channels,\n                 ratio=16,\n                 conv_cfg=None,\n                 norm_cfg=None,\n                 act_cfg=(dict(type='ReLU'), dict(type='Sigmoid')),\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        if isinstance(act_cfg, dict):\n            act_cfg = (act_cfg, act_cfg)\n        assert len(act_cfg) == 2\n        assert mmengine.is_tuple_of(act_cfg, dict)\n        self.global_avgpool = nn.AdaptiveAvgPool2d(1)\n        self.conv1 = ConvModule(\n            in_channels=channels,\n            out_channels=int(channels / ratio),\n            kernel_size=1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg[0])\n        self.conv2 = ConvModule(\n            in_channels=int(channels / ratio),\n            out_channels=channels,\n            kernel_size=1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg[1])\n\n    def forward(self, x):\n        out = self.global_avgpool(x)\n        out = self.conv1(out)\n        out = self.conv2(out)\n        return x * out\n\n\nclass CrossResolutionWeighting(BaseModule):\n    \"\"\"Cross-resolution channel weighting module.\n\n    Args:\n        channels (int): The channels of the module.\n        ratio (int): channel reduction ratio.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: None.\n        act_cfg (dict): Config dict for activation layer.\n            Default: (dict(type='ReLU'), dict(type='Sigmoid')).\n            The last ConvModule uses Sigmoid by default.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 channels,\n                 ratio=16,\n                 conv_cfg=None,\n                 norm_cfg=None,\n                 act_cfg=(dict(type='ReLU'), dict(type='Sigmoid')),\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        if isinstance(act_cfg, dict):\n            act_cfg = (act_cfg, act_cfg)\n        assert len(act_cfg) == 2\n        assert mmengine.is_tuple_of(act_cfg, dict)\n        self.channels = channels\n        total_channel = sum(channels)\n        self.conv1 = ConvModule(\n            in_channels=total_channel,\n            out_channels=int(total_channel / ratio),\n            kernel_size=1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg[0])\n        self.conv2 = ConvModule(\n            in_channels=int(total_channel / ratio),\n            out_channels=total_channel,\n            kernel_size=1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg[1])\n\n    def forward(self, x):\n        mini_size = x[-1].size()[-2:]\n        out = [F.adaptive_avg_pool2d(s, mini_size) for s in x[:-1]] + [x[-1]]\n        out = torch.cat(out, dim=1)\n        out = self.conv1(out)\n        out = self.conv2(out)\n        out = torch.split(out, self.channels, dim=1)\n        out = [\n            s * F.interpolate(a, size=s.size()[-2:], mode='nearest')\n            for s, a in zip(x, out)\n        ]\n        return out\n\n\nclass ConditionalChannelWeighting(BaseModule):\n    \"\"\"Conditional channel weighting block.\n\n    Args:\n        in_channels (int): The input channels of the block.\n        stride (int): Stride of the 3x3 convolution layer.\n        reduce_ratio (int): channel reduction ratio.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 stride,\n                 reduce_ratio,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 with_cp=False,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        self.with_cp = with_cp\n        self.stride = stride\n        assert stride in [1, 2]\n\n        branch_channels = [channel // 2 for channel in in_channels]\n\n        self.cross_resolution_weighting = CrossResolutionWeighting(\n            branch_channels,\n            ratio=reduce_ratio,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg)\n\n        self.depthwise_convs = nn.ModuleList([\n            ConvModule(\n                channel,\n                channel,\n                kernel_size=3,\n                stride=self.stride,\n                padding=1,\n                groups=channel,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None) for channel in branch_channels\n        ])\n\n        self.spatial_weighting = nn.ModuleList([\n            SpatialWeighting(channels=channel, ratio=4)\n            for channel in branch_channels\n        ])\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            x = [s.chunk(2, dim=1) for s in x]\n            x1 = [s[0] for s in x]\n            x2 = [s[1] for s in x]\n\n            x2 = self.cross_resolution_weighting(x2)\n            x2 = [dw(s) for s, dw in zip(x2, self.depthwise_convs)]\n            x2 = [sw(s) for s, sw in zip(x2, self.spatial_weighting)]\n\n            out = [torch.cat([s1, s2], dim=1) for s1, s2 in zip(x1, x2)]\n            out = [channel_shuffle(s, 2) for s in out]\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n\n\nclass Stem(BaseModule):\n    \"\"\"Stem network block.\n\n    Args:\n        in_channels (int): The input channels of the block.\n        stem_channels (int): Output channels of the stem layer.\n        out_channels (int): The output channels of the block.\n        expand_ratio (int): adjusts number of channels of the hidden layer\n            in InvertedResidual by this amount.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 stem_channels,\n                 out_channels,\n                 expand_ratio,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 with_cp=False,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.with_cp = with_cp\n\n        self.conv1 = ConvModule(\n            in_channels=in_channels,\n            out_channels=stem_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            conv_cfg=self.conv_cfg,\n            norm_cfg=self.norm_cfg,\n            act_cfg=dict(type='ReLU'))\n\n        mid_channels = int(round(stem_channels * expand_ratio))\n        branch_channels = stem_channels // 2\n        if stem_channels == self.out_channels:\n            inc_channels = self.out_channels - branch_channels\n        else:\n            inc_channels = self.out_channels - stem_channels\n\n        self.branch1 = nn.Sequential(\n            ConvModule(\n                branch_channels,\n                branch_channels,\n                kernel_size=3,\n                stride=2,\n                padding=1,\n                groups=branch_channels,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None),\n            ConvModule(\n                branch_channels,\n                inc_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=dict(type='ReLU')),\n        )\n\n        self.expand_conv = ConvModule(\n            branch_channels,\n            mid_channels,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=dict(type='ReLU'))\n        self.depthwise_conv = ConvModule(\n            mid_channels,\n            mid_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            groups=mid_channels,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=None)\n        self.linear_conv = ConvModule(\n            mid_channels,\n            branch_channels\n            if stem_channels == self.out_channels else stem_channels,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=dict(type='ReLU'))\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            x = self.conv1(x)\n            x1, x2 = x.chunk(2, dim=1)\n\n            x2 = self.expand_conv(x2)\n            x2 = self.depthwise_conv(x2)\n            x2 = self.linear_conv(x2)\n\n            out = torch.cat((self.branch1(x1), x2), dim=1)\n\n            out = channel_shuffle(out, 2)\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n\n\nclass IterativeHead(BaseModule):\n    \"\"\"Extra iterative head for feature learning.\n\n    Args:\n        in_channels (int): The input channels of the block.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self, in_channels, norm_cfg=dict(type='BN'), init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        projects = []\n        num_branchs = len(in_channels)\n        self.in_channels = in_channels[::-1]\n\n        for i in range(num_branchs):\n            if i != num_branchs - 1:\n                projects.append(\n                    DepthwiseSeparableConvModule(\n                        in_channels=self.in_channels[i],\n                        out_channels=self.in_channels[i + 1],\n                        kernel_size=3,\n                        stride=1,\n                        padding=1,\n                        norm_cfg=norm_cfg,\n                        act_cfg=dict(type='ReLU'),\n                        dw_act_cfg=None,\n                        pw_act_cfg=dict(type='ReLU')))\n            else:\n                projects.append(\n                    DepthwiseSeparableConvModule(\n                        in_channels=self.in_channels[i],\n                        out_channels=self.in_channels[i],\n                        kernel_size=3,\n                        stride=1,\n                        padding=1,\n                        norm_cfg=norm_cfg,\n                        act_cfg=dict(type='ReLU'),\n                        dw_act_cfg=None,\n                        pw_act_cfg=dict(type='ReLU')))\n        self.projects = nn.ModuleList(projects)\n\n    def forward(self, x):\n        x = x[::-1]\n\n        y = []\n        last_x = None\n        for i, s in enumerate(x):\n            if last_x is not None:\n                last_x = F.interpolate(\n                    last_x,\n                    size=s.size()[-2:],\n                    mode='bilinear',\n                    align_corners=True)\n                s = s + last_x\n            s = self.projects[i](s)\n            y.append(s)\n            last_x = s\n\n        return y[::-1]\n\n\nclass ShuffleUnit(BaseModule):\n    \"\"\"InvertedResidual block for ShuffleNetV2 backbone.\n\n    Args:\n        in_channels (int): The input channels of the block.\n        out_channels (int): The output channels of the block.\n        stride (int): Stride of the 3x3 convolution layer. Default: 1\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 stride=1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 with_cp=False,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        self.stride = stride\n        self.with_cp = with_cp\n\n        branch_features = out_channels // 2\n        if self.stride == 1:\n            assert in_channels == branch_features * 2, (\n                f'in_channels ({in_channels}) should equal to '\n                f'branch_features * 2 ({branch_features * 2}) '\n                'when stride is 1')\n\n        if in_channels != branch_features * 2:\n            assert self.stride != 1, (\n                f'stride ({self.stride}) should not equal 1 when '\n                f'in_channels != branch_features * 2')\n\n        if self.stride > 1:\n            self.branch1 = nn.Sequential(\n                ConvModule(\n                    in_channels,\n                    in_channels,\n                    kernel_size=3,\n                    stride=self.stride,\n                    padding=1,\n                    groups=in_channels,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=None),\n                ConvModule(\n                    in_channels,\n                    branch_features,\n                    kernel_size=1,\n                    stride=1,\n                    padding=0,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg),\n            )\n\n        self.branch2 = nn.Sequential(\n            ConvModule(\n                in_channels if (self.stride > 1) else branch_features,\n                branch_features,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg),\n            ConvModule(\n                branch_features,\n                branch_features,\n                kernel_size=3,\n                stride=self.stride,\n                padding=1,\n                groups=branch_features,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None),\n            ConvModule(\n                branch_features,\n                branch_features,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg))\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            if self.stride > 1:\n                out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)\n            else:\n                x1, x2 = x.chunk(2, dim=1)\n                out = torch.cat((x1, self.branch2(x2)), dim=1)\n\n            out = channel_shuffle(out, 2)\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n\n\nclass LiteHRModule(BaseModule):\n    \"\"\"High-Resolution Module for LiteHRNet.\n\n    It contains conditional channel weighting blocks and\n    shuffle blocks.\n\n\n    Args:\n        num_branches (int): Number of branches in the module.\n        num_blocks (int): Number of blocks in the module.\n        in_channels (list(int)): Number of input image channels.\n        reduce_ratio (int): Channel reduction ratio.\n        module_type (str): 'LITE' or 'NAIVE'\n        multiscale_output (bool): Whether to output multi-scale features.\n        with_fuse (bool): Whether to use fuse layers.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n        norm_cfg (dict): dictionary to construct and config norm layer.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 num_branches,\n                 num_blocks,\n                 in_channels,\n                 reduce_ratio,\n                 module_type,\n                 multiscale_output=False,\n                 with_fuse=True,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 with_cp=False,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        self._check_branches(num_branches, in_channels)\n\n        self.in_channels = in_channels\n        self.num_branches = num_branches\n\n        self.module_type = module_type\n        self.multiscale_output = multiscale_output\n        self.with_fuse = with_fuse\n        self.norm_cfg = norm_cfg\n        self.conv_cfg = conv_cfg\n        self.with_cp = with_cp\n\n        if self.module_type.upper() == 'LITE':\n            self.layers = self._make_weighting_blocks(num_blocks, reduce_ratio)\n        elif self.module_type.upper() == 'NAIVE':\n            self.layers = self._make_naive_branches(num_branches, num_blocks)\n        else:\n            raise ValueError(\"module_type should be either 'LITE' or 'NAIVE'.\")\n        if self.with_fuse:\n            self.fuse_layers = self._make_fuse_layers()\n            self.relu = nn.ReLU()\n\n    def _check_branches(self, num_branches, in_channels):\n        \"\"\"Check input to avoid ValueError.\"\"\"\n        if num_branches != len(in_channels):\n            error_msg = f'NUM_BRANCHES({num_branches}) ' \\\n                f'!= NUM_INCHANNELS({len(in_channels)})'\n            raise ValueError(error_msg)\n\n    def _make_weighting_blocks(self, num_blocks, reduce_ratio, stride=1):\n        \"\"\"Make channel weighting blocks.\"\"\"\n        layers = []\n        for i in range(num_blocks):\n            layers.append(\n                ConditionalChannelWeighting(\n                    self.in_channels,\n                    stride=stride,\n                    reduce_ratio=reduce_ratio,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    with_cp=self.with_cp))\n\n        return nn.Sequential(*layers)\n\n    def _make_one_branch(self, branch_index, num_blocks, stride=1):\n        \"\"\"Make one branch.\"\"\"\n        layers = []\n        layers.append(\n            ShuffleUnit(\n                self.in_channels[branch_index],\n                self.in_channels[branch_index],\n                stride=stride,\n                conv_cfg=self.conv_cfg,\n                norm_cfg=self.norm_cfg,\n                act_cfg=dict(type='ReLU'),\n                with_cp=self.with_cp))\n        for i in range(1, num_blocks):\n            layers.append(\n                ShuffleUnit(\n                    self.in_channels[branch_index],\n                    self.in_channels[branch_index],\n                    stride=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    act_cfg=dict(type='ReLU'),\n                    with_cp=self.with_cp))\n\n        return nn.Sequential(*layers)\n\n    def _make_naive_branches(self, num_branches, num_blocks):\n        \"\"\"Make branches.\"\"\"\n        branches = []\n\n        for i in range(num_branches):\n            branches.append(self._make_one_branch(i, num_blocks))\n\n        return nn.ModuleList(branches)\n\n    def _make_fuse_layers(self):\n        \"\"\"Make fuse layer.\"\"\"\n        if self.num_branches == 1:\n            return None\n\n        num_branches = self.num_branches\n        in_channels = self.in_channels\n        fuse_layers = []\n        num_out_branches = num_branches if self.multiscale_output else 1\n        for i in range(num_out_branches):\n            fuse_layer = []\n            for j in range(num_branches):\n                if j > i:\n                    fuse_layer.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                in_channels[j],\n                                in_channels[i],\n                                kernel_size=1,\n                                stride=1,\n                                padding=0,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg, in_channels[i])[1],\n                            nn.Upsample(\n                                scale_factor=2**(j - i), mode='nearest')))\n                elif j == i:\n                    fuse_layer.append(None)\n                else:\n                    conv_downsamples = []\n                    for k in range(i - j):\n                        if k == i - j - 1:\n                            conv_downsamples.append(\n                                nn.Sequential(\n                                    build_conv_layer(\n                                        self.conv_cfg,\n                                        in_channels[j],\n                                        in_channels[j],\n                                        kernel_size=3,\n                                        stride=2,\n                                        padding=1,\n                                        groups=in_channels[j],\n                                        bias=False),\n                                    build_norm_layer(self.norm_cfg,\n                                                     in_channels[j])[1],\n                                    build_conv_layer(\n                                        self.conv_cfg,\n                                        in_channels[j],\n                                        in_channels[i],\n                                        kernel_size=1,\n                                        stride=1,\n                                        padding=0,\n                                        bias=False),\n                                    build_norm_layer(self.norm_cfg,\n                                                     in_channels[i])[1]))\n                        else:\n                            conv_downsamples.append(\n                                nn.Sequential(\n                                    build_conv_layer(\n                                        self.conv_cfg,\n                                        in_channels[j],\n                                        in_channels[j],\n                                        kernel_size=3,\n                                        stride=2,\n                                        padding=1,\n                                        groups=in_channels[j],\n                                        bias=False),\n                                    build_norm_layer(self.norm_cfg,\n                                                     in_channels[j])[1],\n                                    build_conv_layer(\n                                        self.conv_cfg,\n                                        in_channels[j],\n                                        in_channels[j],\n                                        kernel_size=1,\n                                        stride=1,\n                                        padding=0,\n                                        bias=False),\n                                    build_norm_layer(self.norm_cfg,\n                                                     in_channels[j])[1],\n                                    nn.ReLU(inplace=True)))\n                    fuse_layer.append(nn.Sequential(*conv_downsamples))\n            fuse_layers.append(nn.ModuleList(fuse_layer))\n\n        return nn.ModuleList(fuse_layers)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        if self.num_branches == 1:\n            return [self.layers[0](x[0])]\n\n        if self.module_type.upper() == 'LITE':\n            out = self.layers(x)\n        elif self.module_type.upper() == 'NAIVE':\n            for i in range(self.num_branches):\n                x[i] = self.layers[i](x[i])\n            out = x\n\n        if self.with_fuse:\n            out_fuse = []\n            for i in range(len(self.fuse_layers)):\n                # `y = 0` will lead to decreased accuracy (0.5~1 mAP)\n                y = out[0] if i == 0 else self.fuse_layers[i][0](out[0])\n                for j in range(self.num_branches):\n                    if i == j:\n                        y += out[j]\n                    else:\n                        y += self.fuse_layers[i][j](out[j])\n                out_fuse.append(self.relu(y))\n            out = out_fuse\n        if not self.multiscale_output:\n            out = [out[0]]\n        return out\n\n\n@MODELS.register_module()\nclass LiteHRNet(BaseBackbone):\n    \"\"\"Lite-HRNet backbone.\n\n    `Lite-HRNet: A Lightweight High-Resolution Network\n    <https://arxiv.org/abs/2104.06403>`_.\n\n    Code adapted from 'https://github.com/HRNet/Lite-HRNet'.\n\n    Args:\n        extra (dict): detailed configuration for each stage of HRNet.\n        in_channels (int): Number of input image channels. Default: 3.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n        norm_cfg (dict): dictionary to construct and config norm layer.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import LiteHRNet\n        >>> import torch\n        >>> extra=dict(\n        >>>    stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n        >>>    num_stages=3,\n        >>>    stages_spec=dict(\n        >>>        num_modules=(2, 4, 2),\n        >>>        num_branches=(2, 3, 4),\n        >>>        num_blocks=(2, 2, 2),\n        >>>        module_type=('LITE', 'LITE', 'LITE'),\n        >>>        with_fuse=(True, True, True),\n        >>>        reduce_ratios=(8, 8, 8),\n        >>>        num_channels=(\n        >>>            (40, 80),\n        >>>            (40, 80, 160),\n        >>>            (40, 80, 160, 320),\n        >>>        )),\n        >>>    with_head=False)\n        >>> self = LiteHRNet(extra, in_channels=1)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 1, 32, 32)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 40, 8, 8)\n    \"\"\"\n\n    def __init__(self,\n                 extra,\n                 in_channels=3,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 norm_eval=False,\n                 with_cp=False,\n                 init_cfg=[\n                     dict(type='Normal', std=0.001, layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        super().__init__(init_cfg=init_cfg)\n        self.extra = extra\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n\n        self.stem = Stem(\n            in_channels,\n            stem_channels=self.extra['stem']['stem_channels'],\n            out_channels=self.extra['stem']['out_channels'],\n            expand_ratio=self.extra['stem']['expand_ratio'],\n            conv_cfg=self.conv_cfg,\n            norm_cfg=self.norm_cfg)\n\n        self.num_stages = self.extra['num_stages']\n        self.stages_spec = self.extra['stages_spec']\n\n        num_channels_last = [\n            self.stem.out_channels,\n        ]\n        for i in range(self.num_stages):\n            num_channels = self.stages_spec['num_channels'][i]\n            num_channels = [num_channels[i] for i in range(len(num_channels))]\n            setattr(\n                self, f'transition{i}',\n                self._make_transition_layer(num_channels_last, num_channels))\n\n            stage, num_channels_last = self._make_stage(\n                self.stages_spec, i, num_channels, multiscale_output=True)\n            setattr(self, f'stage{i}', stage)\n\n        self.with_head = self.extra['with_head']\n        if self.with_head:\n            self.head_layer = IterativeHead(\n                in_channels=num_channels_last,\n                norm_cfg=self.norm_cfg,\n            )\n\n    def _make_transition_layer(self, num_channels_pre_layer,\n                               num_channels_cur_layer):\n        \"\"\"Make transition layer.\"\"\"\n        num_branches_cur = len(num_channels_cur_layer)\n        num_branches_pre = len(num_channels_pre_layer)\n\n        transition_layers = []\n        for i in range(num_branches_cur):\n            if i < num_branches_pre:\n                if num_channels_cur_layer[i] != num_channels_pre_layer[i]:\n                    transition_layers.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                num_channels_pre_layer[i],\n                                num_channels_pre_layer[i],\n                                kernel_size=3,\n                                stride=1,\n                                padding=1,\n                                groups=num_channels_pre_layer[i],\n                                bias=False),\n                            build_norm_layer(self.norm_cfg,\n                                             num_channels_pre_layer[i])[1],\n                            build_conv_layer(\n                                self.conv_cfg,\n                                num_channels_pre_layer[i],\n                                num_channels_cur_layer[i],\n                                kernel_size=1,\n                                stride=1,\n                                padding=0,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg,\n                                             num_channels_cur_layer[i])[1],\n                            nn.ReLU()))\n                else:\n                    transition_layers.append(None)\n            else:\n                conv_downsamples = []\n                for j in range(i + 1 - num_branches_pre):\n                    in_channels = num_channels_pre_layer[-1]\n                    out_channels = num_channels_cur_layer[i] \\\n                        if j == i - num_branches_pre else in_channels\n                    conv_downsamples.append(\n                        nn.Sequential(\n                            build_conv_layer(\n                                self.conv_cfg,\n                                in_channels,\n                                in_channels,\n                                kernel_size=3,\n                                stride=2,\n                                padding=1,\n                                groups=in_channels,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg, in_channels)[1],\n                            build_conv_layer(\n                                self.conv_cfg,\n                                in_channels,\n                                out_channels,\n                                kernel_size=1,\n                                stride=1,\n                                padding=0,\n                                bias=False),\n                            build_norm_layer(self.norm_cfg, out_channels)[1],\n                            nn.ReLU()))\n                transition_layers.append(nn.Sequential(*conv_downsamples))\n\n        return nn.ModuleList(transition_layers)\n\n    def _make_stage(self,\n                    stages_spec,\n                    stage_index,\n                    in_channels,\n                    multiscale_output=True):\n        num_modules = stages_spec['num_modules'][stage_index]\n        num_branches = stages_spec['num_branches'][stage_index]\n        num_blocks = stages_spec['num_blocks'][stage_index]\n        reduce_ratio = stages_spec['reduce_ratios'][stage_index]\n        with_fuse = stages_spec['with_fuse'][stage_index]\n        module_type = stages_spec['module_type'][stage_index]\n\n        modules = []\n        for i in range(num_modules):\n            # multi_scale_output is only used last module\n            if not multiscale_output and i == num_modules - 1:\n                reset_multiscale_output = False\n            else:\n                reset_multiscale_output = True\n\n            modules.append(\n                LiteHRModule(\n                    num_branches,\n                    num_blocks,\n                    in_channels,\n                    reduce_ratio,\n                    module_type,\n                    multiscale_output=reset_multiscale_output,\n                    with_fuse=with_fuse,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    with_cp=self.with_cp))\n            in_channels = modules[-1].in_channels\n\n        return nn.Sequential(*modules), in_channels\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        x = self.stem(x)\n\n        y_list = [x]\n        for i in range(self.num_stages):\n            x_list = []\n            transition = getattr(self, f'transition{i}')\n            for j in range(self.stages_spec['num_branches'][i]):\n                if transition[j]:\n                    if j >= len(y_list):\n                        x_list.append(transition[j](y_list[-1]))\n                    else:\n                        x_list.append(transition[j](y_list[j]))\n                else:\n                    x_list.append(y_list[j])\n            y_list = getattr(self, f'stage{i}')(x_list)\n\n        x = y_list\n        if self.with_head:\n            x = self.head_layer(x)\n\n        return (x[0], )\n\n    def train(self, mode=True):\n        \"\"\"Convert the model into training mode.\"\"\"\n        super().train(mode)\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/mobilenet_v2.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .utils import make_divisible\n\n\nclass InvertedResidual(BaseModule):\n    \"\"\"InvertedResidual block for MobileNetV2.\n\n    Args:\n        in_channels (int): The input channels of the InvertedResidual block.\n        out_channels (int): The output channels of the InvertedResidual block.\n        stride (int): Stride of the middle (first) 3x3 convolution.\n        expand_ratio (int): adjusts number of channels of the hidden layer\n            in InvertedResidual by this amount.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU6').\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 stride,\n                 expand_ratio,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU6'),\n                 with_cp=False,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.stride = stride\n        assert stride in [1, 2], f'stride must in [1, 2]. ' \\\n            f'But received {stride}.'\n        self.with_cp = with_cp\n        self.use_res_connect = self.stride == 1 and in_channels == out_channels\n        hidden_dim = int(round(in_channels * expand_ratio))\n\n        layers = []\n        if expand_ratio != 1:\n            layers.append(\n                ConvModule(\n                    in_channels=in_channels,\n                    out_channels=hidden_dim,\n                    kernel_size=1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n        layers.extend([\n            ConvModule(\n                in_channels=hidden_dim,\n                out_channels=hidden_dim,\n                kernel_size=3,\n                stride=stride,\n                padding=1,\n                groups=hidden_dim,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg),\n            ConvModule(\n                in_channels=hidden_dim,\n                out_channels=out_channels,\n                kernel_size=1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None)\n        ])\n        self.conv = nn.Sequential(*layers)\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            if self.use_res_connect:\n                return x + self.conv(x)\n            return self.conv(x)\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n\n\n@MODELS.register_module()\nclass MobileNetV2(BaseBackbone):\n    \"\"\"MobileNetV2 backbone.\n\n    Args:\n        widen_factor (float): Width multiplier, multiply number of\n            channels in each layer by this amount. Default: 1.0.\n        out_indices (None or Sequence[int]): Output from which stages.\n            Default: (7, ).\n        frozen_stages (int): Stages to be frozen (all param fixed).\n            Default: -1, which means not freezing any parameters.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU6').\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n    \"\"\"\n\n    # Parameters to build layers. 4 parameters are needed to construct a\n    # layer, from left to right: expand_ratio, channel, num_blocks, stride.\n    arch_settings = [[1, 16, 1, 1], [6, 24, 2, 2], [6, 32, 3, 2],\n                     [6, 64, 4, 2], [6, 96, 3, 1], [6, 160, 3, 2],\n                     [6, 320, 1, 1]]\n\n    def __init__(self,\n                 widen_factor=1.,\n                 out_indices=(7, ),\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU6'),\n                 norm_eval=False,\n                 with_cp=False,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.widen_factor = widen_factor\n        self.out_indices = out_indices\n        for index in out_indices:\n            if index not in range(0, 8):\n                raise ValueError('the item in out_indices must in '\n                                 f'range(0, 8). But received {index}')\n\n        if frozen_stages not in range(-1, 8):\n            raise ValueError('frozen_stages must be in range(-1, 8). '\n                             f'But received {frozen_stages}')\n        self.out_indices = out_indices\n        self.frozen_stages = frozen_stages\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n\n        self.in_channels = make_divisible(32 * widen_factor, 8)\n\n        self.conv1 = ConvModule(\n            in_channels=3,\n            out_channels=self.in_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            conv_cfg=self.conv_cfg,\n            norm_cfg=self.norm_cfg,\n            act_cfg=self.act_cfg)\n\n        self.layers = []\n\n        for i, layer_cfg in enumerate(self.arch_settings):\n            expand_ratio, channel, num_blocks, stride = layer_cfg\n            out_channels = make_divisible(channel * widen_factor, 8)\n            inverted_res_layer = self.make_layer(\n                out_channels=out_channels,\n                num_blocks=num_blocks,\n                stride=stride,\n                expand_ratio=expand_ratio)\n            layer_name = f'layer{i + 1}'\n            self.add_module(layer_name, inverted_res_layer)\n            self.layers.append(layer_name)\n\n        if widen_factor > 1.0:\n            self.out_channel = int(1280 * widen_factor)\n        else:\n            self.out_channel = 1280\n\n        layer = ConvModule(\n            in_channels=self.in_channels,\n            out_channels=self.out_channel,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            conv_cfg=self.conv_cfg,\n            norm_cfg=self.norm_cfg,\n            act_cfg=self.act_cfg)\n        self.add_module('conv2', layer)\n        self.layers.append('conv2')\n\n    def make_layer(self, out_channels, num_blocks, stride, expand_ratio):\n        \"\"\"Stack InvertedResidual blocks to build a layer for MobileNetV2.\n\n        Args:\n            out_channels (int): out_channels of block.\n            num_blocks (int): number of blocks.\n            stride (int): stride of the first block. Default: 1\n            expand_ratio (int): Expand the number of channels of the\n                hidden layer in InvertedResidual by this ratio. Default: 6.\n        \"\"\"\n        layers = []\n        for i in range(num_blocks):\n            if i >= 1:\n                stride = 1\n            layers.append(\n                InvertedResidual(\n                    self.in_channels,\n                    out_channels,\n                    stride,\n                    expand_ratio=expand_ratio,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    act_cfg=self.act_cfg,\n                    with_cp=self.with_cp))\n            self.in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n\n        outs = []\n        for i, layer_name in enumerate(self.layers):\n            layer = getattr(self, layer_name)\n            x = layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n\n        return tuple(outs)\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            for param in self.conv1.parameters():\n                param.requires_grad = False\n        for i in range(1, self.frozen_stages + 1):\n            layer = getattr(self, f'layer{i}')\n            layer.eval()\n            for param in layer.parameters():\n                param.requires_grad = False\n\n    def train(self, mode=True):\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/mobilenet_v3.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nfrom mmcv.cnn import ConvModule\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .utils import InvertedResidual\n\n\n@MODELS.register_module()\nclass MobileNetV3(BaseBackbone):\n    \"\"\"MobileNetV3 backbone.\n\n    Args:\n        arch (str): Architecture of mobilnetv3, from {small, big}.\n            Default: small.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        out_indices (None or Sequence[int]): Output from which stages.\n            Default: (-1, ), which means output tensors from final stage.\n        frozen_stages (int): Stages to be frozen (all param fixed).\n            Default: -1, which means not freezing any parameters.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save\n            some memory while slowing down the training speed.\n            Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm'])\n            ]``\n    \"\"\"\n    # Parameters to build each block:\n    #     [kernel size, mid channels, out channels, with_se, act type, stride]\n    arch_settings = {\n        'small': [[3, 16, 16, True, 'ReLU', 2],\n                  [3, 72, 24, False, 'ReLU', 2],\n                  [3, 88, 24, False, 'ReLU', 1],\n                  [5, 96, 40, True, 'HSwish', 2],\n                  [5, 240, 40, True, 'HSwish', 1],\n                  [5, 240, 40, True, 'HSwish', 1],\n                  [5, 120, 48, True, 'HSwish', 1],\n                  [5, 144, 48, True, 'HSwish', 1],\n                  [5, 288, 96, True, 'HSwish', 2],\n                  [5, 576, 96, True, 'HSwish', 1],\n                  [5, 576, 96, True, 'HSwish', 1]],\n        'big': [[3, 16, 16, False, 'ReLU', 1],\n                [3, 64, 24, False, 'ReLU', 2],\n                [3, 72, 24, False, 'ReLU', 1],\n                [5, 72, 40, True, 'ReLU', 2],\n                [5, 120, 40, True, 'ReLU', 1],\n                [5, 120, 40, True, 'ReLU', 1],\n                [3, 240, 80, False, 'HSwish', 2],\n                [3, 200, 80, False, 'HSwish', 1],\n                [3, 184, 80, False, 'HSwish', 1],\n                [3, 184, 80, False, 'HSwish', 1],\n                [3, 480, 112, True, 'HSwish', 1],\n                [3, 672, 112, True, 'HSwish', 1],\n                [5, 672, 160, True, 'HSwish', 1],\n                [5, 672, 160, True, 'HSwish', 2],\n                [5, 960, 160, True, 'HSwish', 1]]\n    }  # yapf: disable\n\n    def __init__(self,\n                 arch='small',\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 out_indices=(-1, ),\n                 frozen_stages=-1,\n                 norm_eval=False,\n                 with_cp=False,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(type='Constant', val=1, layer=['_BatchNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        assert arch in self.arch_settings\n        for index in out_indices:\n            if index not in range(-len(self.arch_settings[arch]),\n                                  len(self.arch_settings[arch])):\n                raise ValueError('the item in out_indices must in '\n                                 f'range(0, {len(self.arch_settings[arch])}). '\n                                 f'But received {index}')\n\n        if frozen_stages not in range(-1, len(self.arch_settings[arch])):\n            raise ValueError('frozen_stages must be in range(-1, '\n                             f'{len(self.arch_settings[arch])}). '\n                             f'But received {frozen_stages}')\n        self.arch = arch\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.out_indices = out_indices\n        self.frozen_stages = frozen_stages\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n\n        self.in_channels = 16\n        self.conv1 = ConvModule(\n            in_channels=3,\n            out_channels=self.in_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=dict(type='HSwish'))\n\n        self.layers = self._make_layer()\n        self.feat_dim = self.arch_settings[arch][-1][2]\n\n    def _make_layer(self):\n        layers = []\n        layer_setting = self.arch_settings[self.arch]\n        for i, params in enumerate(layer_setting):\n            (kernel_size, mid_channels, out_channels, with_se, act,\n             stride) = params\n            if with_se:\n                se_cfg = dict(\n                    channels=mid_channels,\n                    ratio=4,\n                    act_cfg=(dict(type='ReLU'),\n                             dict(type='HSigmoid', bias=1.0, divisor=2.0)))\n            else:\n                se_cfg = None\n\n            layer = InvertedResidual(\n                in_channels=self.in_channels,\n                out_channels=out_channels,\n                mid_channels=mid_channels,\n                kernel_size=kernel_size,\n                stride=stride,\n                se_cfg=se_cfg,\n                with_expand_conv=True,\n                conv_cfg=self.conv_cfg,\n                norm_cfg=self.norm_cfg,\n                act_cfg=dict(type=act),\n                with_cp=self.with_cp)\n            self.in_channels = out_channels\n            layer_name = f'layer{i + 1}'\n            self.add_module(layer_name, layer)\n            layers.append(layer_name)\n        return layers\n\n    def forward(self, x):\n        x = self.conv1(x)\n\n        outs = []\n        for i, layer_name in enumerate(self.layers):\n            layer = getattr(self, layer_name)\n            x = layer(x)\n            if i in self.out_indices or \\\n                    i - len(self.layers) in self.out_indices:\n                outs.append(x)\n\n        return tuple(outs)\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            for param in self.conv1.parameters():\n                param.requires_grad = False\n        for i in range(1, self.frozen_stages + 1):\n            layer = getattr(self, f'layer{i}')\n            layer.eval()\n            for param in layer.parameters():\n                param.requires_grad = False\n\n    def train(self, mode=True):\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/mspn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy as cp\nfrom collections import OrderedDict\n\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import ConvModule, MaxPool2d\nfrom mmengine.model import BaseModule\nfrom mmengine.runner import load_state_dict\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils import get_root_logger\nfrom .base_backbone import BaseBackbone\nfrom .resnet import Bottleneck as _Bottleneck\nfrom .utils import get_state_dict\n\n\nclass Bottleneck(_Bottleneck):\n    expansion = 4\n    \"\"\"Bottleneck block for MSPN.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        stride (int): stride of the block. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self, in_channels, out_channels, **kwargs):\n        super().__init__(in_channels, out_channels * 4, **kwargs)\n\n\nclass DownsampleModule(BaseModule):\n    \"\"\"Downsample module for MSPN.\n\n    Args:\n        block (nn.Module): Downsample block.\n        num_blocks (list): Number of blocks in each downsample unit.\n        num_units (int): Numbers of downsample units. Default: 4\n        has_skip (bool): Have skip connections from prior upsample\n            module or not. Default:False\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        in_channels (int): Number of channels of the input feature to\n            downsample module. Default: 64\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 block,\n                 num_blocks,\n                 num_units=4,\n                 has_skip=False,\n                 norm_cfg=dict(type='BN'),\n                 in_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.has_skip = has_skip\n        self.in_channels = in_channels\n        assert len(num_blocks) == num_units\n        self.num_blocks = num_blocks\n        self.num_units = num_units\n        self.norm_cfg = norm_cfg\n        self.layer1 = self._make_layer(block, in_channels, num_blocks[0])\n        for i in range(1, num_units):\n            module_name = f'layer{i + 1}'\n            self.add_module(\n                module_name,\n                self._make_layer(\n                    block, in_channels * pow(2, i), num_blocks[i], stride=2))\n\n    def _make_layer(self, block, out_channels, blocks, stride=1):\n        downsample = None\n        if stride != 1 or self.in_channels != out_channels * block.expansion:\n            downsample = ConvModule(\n                self.in_channels,\n                out_channels * block.expansion,\n                kernel_size=1,\n                stride=stride,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                act_cfg=None,\n                inplace=True)\n\n        units = list()\n        units.append(\n            block(\n                self.in_channels,\n                out_channels,\n                stride=stride,\n                downsample=downsample,\n                norm_cfg=self.norm_cfg))\n        self.in_channels = out_channels * block.expansion\n        for _ in range(1, blocks):\n            units.append(block(self.in_channels, out_channels))\n\n        return nn.Sequential(*units)\n\n    def forward(self, x, skip1, skip2):\n        out = list()\n        for i in range(self.num_units):\n            module_name = f'layer{i + 1}'\n            module_i = getattr(self, module_name)\n            x = module_i(x)\n            if self.has_skip:\n                x = x + skip1[i] + skip2[i]\n            out.append(x)\n        out.reverse()\n\n        return tuple(out)\n\n\nclass UpsampleUnit(BaseModule):\n    \"\"\"Upsample unit for upsample module.\n\n    Args:\n        ind (int): Indicates whether to interpolate (>0) and whether to\n           generate feature map for the next hourglass-like module.\n        num_units (int): Number of units that form a upsample module. Along\n            with ind and gen_cross_conv, nm_units is used to decide whether\n            to generate feature map for the next hourglass-like module.\n        in_channels (int): Channel number of the skip-in feature maps from\n            the corresponding downsample unit.\n        unit_channels (int): Channel number in this unit. Default:256.\n        gen_skip: (bool): Whether or not to generate skips for the posterior\n            downsample module. Default:False\n        gen_cross_conv (bool): Whether to generate feature map for the next\n            hourglass-like module. Default:False\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        out_channels (int): Number of channels of feature output by upsample\n            module. Must equal to in_channels of downsample module. Default:64\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 ind,\n                 num_units,\n                 in_channels,\n                 unit_channels=256,\n                 gen_skip=False,\n                 gen_cross_conv=False,\n                 norm_cfg=dict(type='BN'),\n                 out_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.num_units = num_units\n        self.norm_cfg = norm_cfg\n        self.in_skip = ConvModule(\n            in_channels,\n            unit_channels,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            norm_cfg=self.norm_cfg,\n            act_cfg=None,\n            inplace=True)\n        self.relu = nn.ReLU(inplace=True)\n\n        self.ind = ind\n        if self.ind > 0:\n            self.up_conv = ConvModule(\n                unit_channels,\n                unit_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                act_cfg=None,\n                inplace=True)\n\n        self.gen_skip = gen_skip\n        if self.gen_skip:\n            self.out_skip1 = ConvModule(\n                in_channels,\n                in_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                inplace=True)\n\n            self.out_skip2 = ConvModule(\n                unit_channels,\n                in_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                inplace=True)\n\n        self.gen_cross_conv = gen_cross_conv\n        if self.ind == num_units - 1 and self.gen_cross_conv:\n            self.cross_conv = ConvModule(\n                unit_channels,\n                out_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                inplace=True)\n\n    def forward(self, x, up_x):\n        out = self.in_skip(x)\n\n        if self.ind > 0:\n            up_x = F.interpolate(\n                up_x,\n                size=(x.size(2), x.size(3)),\n                mode='bilinear',\n                align_corners=True)\n            up_x = self.up_conv(up_x)\n            out = out + up_x\n        out = self.relu(out)\n\n        skip1 = None\n        skip2 = None\n        if self.gen_skip:\n            skip1 = self.out_skip1(x)\n            skip2 = self.out_skip2(out)\n\n        cross_conv = None\n        if self.ind == self.num_units - 1 and self.gen_cross_conv:\n            cross_conv = self.cross_conv(out)\n\n        return out, skip1, skip2, cross_conv\n\n\nclass UpsampleModule(BaseModule):\n    \"\"\"Upsample module for MSPN.\n\n    Args:\n        unit_channels (int): Channel number in the upsample units.\n            Default:256.\n        num_units (int): Numbers of upsample units. Default: 4\n        gen_skip (bool): Whether to generate skip for posterior downsample\n            module or not. Default:False\n        gen_cross_conv (bool): Whether to generate feature map for the next\n            hourglass-like module. Default:False\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        out_channels (int): Number of channels of feature output by upsample\n            module. Must equal to in_channels of downsample module. Default:64\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 unit_channels=256,\n                 num_units=4,\n                 gen_skip=False,\n                 gen_cross_conv=False,\n                 norm_cfg=dict(type='BN'),\n                 out_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = list()\n        for i in range(num_units):\n            self.in_channels.append(Bottleneck.expansion * out_channels *\n                                    pow(2, i))\n        self.in_channels.reverse()\n        self.num_units = num_units\n        self.gen_skip = gen_skip\n        self.gen_cross_conv = gen_cross_conv\n        self.norm_cfg = norm_cfg\n        for i in range(num_units):\n            module_name = f'up{i + 1}'\n            self.add_module(\n                module_name,\n                UpsampleUnit(\n                    i,\n                    self.num_units,\n                    self.in_channels[i],\n                    unit_channels,\n                    self.gen_skip,\n                    self.gen_cross_conv,\n                    norm_cfg=self.norm_cfg,\n                    out_channels=64))\n\n    def forward(self, x):\n        out = list()\n        skip1 = list()\n        skip2 = list()\n        cross_conv = None\n        for i in range(self.num_units):\n            module_i = getattr(self, f'up{i + 1}')\n            if i == 0:\n                outi, skip1_i, skip2_i, _ = module_i(x[i], None)\n            elif i == self.num_units - 1:\n                outi, skip1_i, skip2_i, cross_conv = module_i(x[i], out[i - 1])\n            else:\n                outi, skip1_i, skip2_i, _ = module_i(x[i], out[i - 1])\n            out.append(outi)\n            skip1.append(skip1_i)\n            skip2.append(skip2_i)\n        skip1.reverse()\n        skip2.reverse()\n\n        return out, skip1, skip2, cross_conv\n\n\nclass SingleStageNetwork(BaseModule):\n    \"\"\"Single_stage Network.\n\n    Args:\n        unit_channels (int): Channel number in the upsample units. Default:256.\n        num_units (int): Numbers of downsample/upsample units. Default: 4\n        gen_skip (bool): Whether to generate skip for posterior downsample\n            module or not. Default:False\n        gen_cross_conv (bool): Whether to generate feature map for the next\n            hourglass-like module. Default:False\n        has_skip (bool): Have skip connections from prior upsample\n            module or not. Default:False\n        num_blocks (list): Number of blocks in each downsample unit.\n            Default: [2, 2, 2, 2] Note: Make sure num_units==len(num_blocks)\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        in_channels (int): Number of channels of the feature from ResNetTop.\n            Default: 64.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 has_skip=False,\n                 gen_skip=False,\n                 gen_cross_conv=False,\n                 unit_channels=256,\n                 num_units=4,\n                 num_blocks=[2, 2, 2, 2],\n                 norm_cfg=dict(type='BN'),\n                 in_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        num_blocks = cp.deepcopy(num_blocks)\n        super().__init__(init_cfg=init_cfg)\n        assert len(num_blocks) == num_units\n        self.has_skip = has_skip\n        self.gen_skip = gen_skip\n        self.gen_cross_conv = gen_cross_conv\n        self.num_units = num_units\n        self.unit_channels = unit_channels\n        self.num_blocks = num_blocks\n        self.norm_cfg = norm_cfg\n\n        self.downsample = DownsampleModule(Bottleneck, num_blocks, num_units,\n                                           has_skip, norm_cfg, in_channels)\n        self.upsample = UpsampleModule(unit_channels, num_units, gen_skip,\n                                       gen_cross_conv, norm_cfg, in_channels)\n\n    def forward(self, x, skip1, skip2):\n        mid = self.downsample(x, skip1, skip2)\n        out, skip1, skip2, cross_conv = self.upsample(mid)\n\n        return out, skip1, skip2, cross_conv\n\n\nclass ResNetTop(BaseModule):\n    \"\"\"ResNet top for MSPN.\n\n    Args:\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        channels (int): Number of channels of the feature output by ResNetTop.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self, norm_cfg=dict(type='BN'), channels=64, init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.top = nn.Sequential(\n            ConvModule(\n                3,\n                channels,\n                kernel_size=7,\n                stride=2,\n                padding=3,\n                norm_cfg=norm_cfg,\n                inplace=True), MaxPool2d(kernel_size=3, stride=2, padding=1))\n\n    def forward(self, img):\n        return self.top(img)\n\n\n@MODELS.register_module()\nclass MSPN(BaseBackbone):\n    \"\"\"MSPN backbone. Paper ref: Li et al. \"Rethinking on Multi-Stage Networks\n    for Human Pose Estimation\" (CVPR 2020).\n\n    Args:\n        unit_channels (int): Number of Channels in an upsample unit.\n            Default: 256\n        num_stages (int): Number of stages in a multi-stage MSPN. Default: 4\n        num_units (int): Number of downsample/upsample units in a single-stage\n            network. Default: 4\n            Note: Make sure num_units == len(self.num_blocks)\n        num_blocks (list): Number of bottlenecks in each\n            downsample unit. Default: [2, 2, 2, 2]\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        res_top_channels (int): Number of channels of feature from ResNetTop.\n            Default: 64.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm']),\n                dict(\n                    type='Normal',\n                    std=0.01,\n                    layer=['Linear']),\n            ]``\n\n    Example:\n        >>> from mmpose.models import MSPN\n        >>> import torch\n        >>> self = MSPN(num_stages=2,num_units=2,num_blocks=[2,2])\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 511, 511)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_output in level_outputs:\n        ...     for feature in level_output:\n        ...         print(tuple(feature.shape))\n        ...\n        (1, 256, 64, 64)\n        (1, 256, 128, 128)\n        (1, 256, 64, 64)\n        (1, 256, 128, 128)\n    \"\"\"\n\n    def __init__(self,\n                 unit_channels=256,\n                 num_stages=4,\n                 num_units=4,\n                 num_blocks=[2, 2, 2, 2],\n                 norm_cfg=dict(type='BN'),\n                 res_top_channels=64,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm']),\n                     dict(type='Normal', std=0.01, layer=['Linear']),\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        num_blocks = cp.deepcopy(num_blocks)\n        super().__init__(init_cfg=init_cfg)\n        self.unit_channels = unit_channels\n        self.num_stages = num_stages\n        self.num_units = num_units\n        self.num_blocks = num_blocks\n        self.norm_cfg = norm_cfg\n\n        assert self.num_stages > 0\n        assert self.num_units > 1\n        assert self.num_units == len(self.num_blocks)\n        self.top = ResNetTop(norm_cfg=norm_cfg)\n        self.multi_stage_mspn = nn.ModuleList([])\n        for i in range(self.num_stages):\n            if i == 0:\n                has_skip = False\n            else:\n                has_skip = True\n            if i != self.num_stages - 1:\n                gen_skip = True\n                gen_cross_conv = True\n            else:\n                gen_skip = False\n                gen_cross_conv = False\n            self.multi_stage_mspn.append(\n                SingleStageNetwork(has_skip, gen_skip, gen_cross_conv,\n                                   unit_channels, num_units, num_blocks,\n                                   norm_cfg, res_top_channels))\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        out_feats = []\n        skip1 = None\n        skip2 = None\n        x = self.top(x)\n        for i in range(self.num_stages):\n            out, skip1, skip2, x = self.multi_stage_mspn[i](x, skip1, skip2)\n            out_feats.append(out)\n\n        return out_feats\n\n    def init_weights(self):\n        \"\"\"Initialize model weights.\"\"\"\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            logger = get_root_logger()\n            state_dict_tmp = get_state_dict(self.init_cfg['checkpoint'])\n            state_dict = OrderedDict()\n            state_dict['top'] = OrderedDict()\n            state_dict['bottlenecks'] = OrderedDict()\n            for k, v in state_dict_tmp.items():\n                if k.startswith('layer'):\n                    if 'downsample.0' in k:\n                        state_dict['bottlenecks'][k.replace(\n                            'downsample.0', 'downsample.conv')] = v\n                    elif 'downsample.1' in k:\n                        state_dict['bottlenecks'][k.replace(\n                            'downsample.1', 'downsample.bn')] = v\n                    else:\n                        state_dict['bottlenecks'][k] = v\n                elif k.startswith('conv1'):\n                    state_dict['top'][k.replace('conv1', 'top.0.conv')] = v\n                elif k.startswith('bn1'):\n                    state_dict['top'][k.replace('bn1', 'top.0.bn')] = v\n\n            load_state_dict(\n                self.top, state_dict['top'], strict=False, logger=logger)\n            for i in range(self.num_stages):\n                load_state_dict(\n                    self.multi_stage_mspn[i].downsample,\n                    state_dict['bottlenecks'],\n                    strict=False,\n                    logger=logger)\n        else:\n            super(MSPN, self).init_weights()\n"
  },
  {
    "path": "mmpose/models/backbones/pvt.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import Conv2d, build_activation_layer, build_norm_layer\nfrom mmcv.cnn.bricks.drop import build_dropout\nfrom mmcv.cnn.bricks.transformer import MultiheadAttention\nfrom mmengine.model import BaseModule, ModuleList, Sequential\nfrom mmengine.model.weight_init import trunc_normal_\nfrom mmengine.runner import load_state_dict\nfrom mmengine.utils import to_2tuple\n\nfrom mmpose.registry import MODELS\nfrom ...utils import get_root_logger\nfrom ..utils import PatchEmbed, nchw_to_nlc, nlc_to_nchw, pvt_convert\nfrom .utils import get_state_dict\n\n\nclass MixFFN(BaseModule):\n    \"\"\"An implementation of MixFFN of PVT.\n\n    The differences between MixFFN & FFN:\n        1. Use 1X1 Conv to replace Linear layer.\n        2. Introduce 3X3 Depth-wise Conv to encode positional information.\n\n    Args:\n        embed_dims (int): The feature dimension. Same as\n            `MultiheadAttention`.\n        feedforward_channels (int): The hidden dimension of FFNs.\n        act_cfg (dict, optional): The activation config for FFNs.\n            Default: dict(type='GELU').\n        ffn_drop (float, optional): Probability of an element to be\n            zeroed in FFN. Default 0.0.\n        dropout_layer (obj:`ConfigDict`): The dropout_layer used\n            when adding the shortcut.\n            Default: None.\n        use_conv (bool): If True, add 3x3 DWConv between two Linear layers.\n            Defaults: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 feedforward_channels,\n                 act_cfg=dict(type='GELU'),\n                 ffn_drop=0.,\n                 dropout_layer=None,\n                 use_conv=False,\n                 init_cfg=None):\n        super(MixFFN, self).__init__(init_cfg=init_cfg)\n\n        self.embed_dims = embed_dims\n        self.feedforward_channels = feedforward_channels\n        self.act_cfg = act_cfg\n        activate = build_activation_layer(act_cfg)\n\n        in_channels = embed_dims\n        fc1 = Conv2d(\n            in_channels=in_channels,\n            out_channels=feedforward_channels,\n            kernel_size=1,\n            stride=1,\n            bias=True)\n        if use_conv:\n            # 3x3 depth wise conv to provide positional encode information\n            dw_conv = Conv2d(\n                in_channels=feedforward_channels,\n                out_channels=feedforward_channels,\n                kernel_size=3,\n                stride=1,\n                padding=(3 - 1) // 2,\n                bias=True,\n                groups=feedforward_channels)\n        fc2 = Conv2d(\n            in_channels=feedforward_channels,\n            out_channels=in_channels,\n            kernel_size=1,\n            stride=1,\n            bias=True)\n        drop = nn.Dropout(ffn_drop)\n        layers = [fc1, activate, drop, fc2, drop]\n        if use_conv:\n            layers.insert(1, dw_conv)\n        self.layers = Sequential(*layers)\n        self.dropout_layer = build_dropout(\n            dropout_layer) if dropout_layer else torch.nn.Identity()\n\n    def forward(self, x, hw_shape, identity=None):\n        out = nlc_to_nchw(x, hw_shape)\n        out = self.layers(out)\n        out = nchw_to_nlc(out)\n        if identity is None:\n            identity = x\n        return identity + self.dropout_layer(out)\n\n\nclass SpatialReductionAttention(MultiheadAttention):\n    \"\"\"An implementation of Spatial Reduction Attention of PVT.\n\n    This module is modified from MultiheadAttention which is a module from\n    mmcv.cnn.bricks.transformer.\n\n    Args:\n        embed_dims (int): The embedding dimension.\n        num_heads (int): Parallel attention heads.\n        attn_drop (float): A Dropout layer on attn_output_weights.\n            Default: 0.0.\n        proj_drop (float): A Dropout layer after `nn.MultiheadAttention`.\n            Default: 0.0.\n        dropout_layer (obj:`ConfigDict`): The dropout_layer used\n            when adding the shortcut. Default: None.\n        batch_first (bool): Key, Query and Value are shape of\n            (batch, n, embed_dim)\n            or (n, batch, embed_dim). Default: False.\n        qkv_bias (bool): enable bias for qkv if True. Default: True.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='LN').\n        sr_ratio (int): The ratio of spatial reduction of Spatial Reduction\n            Attention of PVT. Default: 1.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 attn_drop=0.,\n                 proj_drop=0.,\n                 dropout_layer=None,\n                 batch_first=True,\n                 qkv_bias=True,\n                 norm_cfg=dict(type='LN'),\n                 sr_ratio=1,\n                 init_cfg=None):\n        super().__init__(\n            embed_dims,\n            num_heads,\n            attn_drop,\n            proj_drop,\n            batch_first=batch_first,\n            dropout_layer=dropout_layer,\n            bias=qkv_bias,\n            init_cfg=init_cfg)\n\n        self.sr_ratio = sr_ratio\n        if sr_ratio > 1:\n            self.sr = Conv2d(\n                in_channels=embed_dims,\n                out_channels=embed_dims,\n                kernel_size=sr_ratio,\n                stride=sr_ratio)\n            # The ret[0] of build_norm_layer is norm name.\n            self.norm = build_norm_layer(norm_cfg, embed_dims)[1]\n\n        # handle the BC-breaking from https://github.com/open-mmlab/mmcv/pull/1418 # noqa\n        from mmpose import digit_version, mmcv_version\n        if mmcv_version < digit_version('1.3.17'):\n            warnings.warn('The legacy version of forward function in'\n                          'SpatialReductionAttention is deprecated in'\n                          'mmcv>=1.3.17 and will no longer support in the'\n                          'future. Please upgrade your mmcv.')\n            self.forward = self.legacy_forward\n\n    def forward(self, x, hw_shape, identity=None):\n\n        x_q = x\n        if self.sr_ratio > 1:\n            x_kv = nlc_to_nchw(x, hw_shape)\n            x_kv = self.sr(x_kv)\n            x_kv = nchw_to_nlc(x_kv)\n            x_kv = self.norm(x_kv)\n        else:\n            x_kv = x\n\n        if identity is None:\n            identity = x_q\n\n        # Because the dataflow('key', 'query', 'value') of\n        # ``torch.nn.MultiheadAttention`` is (num_query, batch,\n        # embed_dims), We should adjust the shape of dataflow from\n        # batch_first (batch, num_query, embed_dims) to num_query_first\n        # (num_query ,batch, embed_dims), and recover ``attn_output``\n        # from num_query_first to batch_first.\n        if self.batch_first:\n            x_q = x_q.transpose(0, 1)\n            x_kv = x_kv.transpose(0, 1)\n\n        out = self.attn(query=x_q, key=x_kv, value=x_kv)[0]\n\n        if self.batch_first:\n            out = out.transpose(0, 1)\n\n        return identity + self.dropout_layer(self.proj_drop(out))\n\n    def legacy_forward(self, x, hw_shape, identity=None):\n        \"\"\"multi head attention forward in mmcv version < 1.3.17.\"\"\"\n        x_q = x\n        if self.sr_ratio > 1:\n            x_kv = nlc_to_nchw(x, hw_shape)\n            x_kv = self.sr(x_kv)\n            x_kv = nchw_to_nlc(x_kv)\n            x_kv = self.norm(x_kv)\n        else:\n            x_kv = x\n\n        if identity is None:\n            identity = x_q\n\n        out = self.attn(query=x_q, key=x_kv, value=x_kv)[0]\n\n        return identity + self.dropout_layer(self.proj_drop(out))\n\n\nclass PVTEncoderLayer(BaseModule):\n    \"\"\"Implements one encoder layer in PVT.\n\n    Args:\n        embed_dims (int): The feature dimension.\n        num_heads (int): Parallel attention heads.\n        feedforward_channels (int): The hidden dimension for FFNs.\n        drop_rate (float): Probability of an element to be zeroed.\n            after the feed forward layer. Default: 0.0.\n        attn_drop_rate (float): The drop out rate for attention layer.\n            Default: 0.0.\n        drop_path_rate (float): stochastic depth rate. Default: 0.0.\n        qkv_bias (bool): enable bias for qkv if True.\n            Default: True.\n        act_cfg (dict): The activation config for FFNs.\n            Default: dict(type='GELU').\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='LN').\n        sr_ratio (int): The ratio of spatial reduction of Spatial Reduction\n            Attention of PVT. Default: 1.\n        use_conv_ffn (bool): If True, use Convolutional FFN to replace FFN.\n            Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 feedforward_channels,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.,\n                 qkv_bias=True,\n                 act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='LN'),\n                 sr_ratio=1,\n                 use_conv_ffn=False,\n                 init_cfg=None):\n        super(PVTEncoderLayer, self).__init__(init_cfg=init_cfg)\n\n        # The ret[0] of build_norm_layer is norm name.\n        self.norm1 = build_norm_layer(norm_cfg, embed_dims)[1]\n\n        self.attn = SpatialReductionAttention(\n            embed_dims=embed_dims,\n            num_heads=num_heads,\n            attn_drop=attn_drop_rate,\n            proj_drop=drop_rate,\n            dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate),\n            qkv_bias=qkv_bias,\n            norm_cfg=norm_cfg,\n            sr_ratio=sr_ratio)\n\n        # The ret[0] of build_norm_layer is norm name.\n        self.norm2 = build_norm_layer(norm_cfg, embed_dims)[1]\n\n        self.ffn = MixFFN(\n            embed_dims=embed_dims,\n            feedforward_channels=feedforward_channels,\n            ffn_drop=drop_rate,\n            dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate),\n            use_conv=use_conv_ffn,\n            act_cfg=act_cfg)\n\n    def forward(self, x, hw_shape):\n        x = self.attn(self.norm1(x), hw_shape, identity=x)\n        x = self.ffn(self.norm2(x), hw_shape, identity=x)\n\n        return x\n\n\nclass AbsolutePositionEmbedding(BaseModule):\n    \"\"\"An implementation of the absolute position embedding in PVT.\n\n    Args:\n        pos_shape (int): The shape of the absolute position embedding.\n        pos_dim (int): The dimension of the absolute position embedding.\n        drop_rate (float): Probability of an element to be zeroed.\n            Default: 0.0.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self, pos_shape, pos_dim, drop_rate=0., init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n\n        if isinstance(pos_shape, int):\n            pos_shape = to_2tuple(pos_shape)\n        elif isinstance(pos_shape, tuple):\n            if len(pos_shape) == 1:\n                pos_shape = to_2tuple(pos_shape[0])\n            assert len(pos_shape) == 2, \\\n                f'The size of image should have length 1 or 2, ' \\\n                f'but got {len(pos_shape)}'\n        self.pos_shape = pos_shape\n        self.pos_dim = pos_dim\n\n        self.pos_embed = nn.Parameter(\n            torch.zeros(1, pos_shape[0] * pos_shape[1], pos_dim))\n        self.drop = nn.Dropout(p=drop_rate)\n\n    def init_weights(self):\n        trunc_normal_(self.pos_embed, std=0.02)\n\n    def resize_pos_embed(self, pos_embed, input_shape, mode='bilinear'):\n        \"\"\"Resize pos_embed weights.\n\n        Resize pos_embed using bilinear interpolate method.\n\n        Args:\n            pos_embed (torch.Tensor): Position embedding weights.\n            input_shape (tuple): Tuple for (downsampled input image height,\n                downsampled input image width).\n            mode (str): Algorithm used for upsampling:\n                ``'nearest'`` | ``'linear'`` | ``'bilinear'`` | ``'bicubic'`` |\n                ``'trilinear'``. Default: ``'bilinear'``.\n\n        Return:\n            torch.Tensor: The resized pos_embed of shape [B, L_new, C].\n        \"\"\"\n        assert pos_embed.ndim == 3, 'shape of pos_embed must be [B, L, C]'\n        pos_h, pos_w = self.pos_shape\n        pos_embed_weight = pos_embed[:, (-1 * pos_h * pos_w):]\n        pos_embed_weight = pos_embed_weight.reshape(\n            1, pos_h, pos_w, self.pos_dim).permute(0, 3, 1, 2).contiguous()\n        pos_embed_weight = F.interpolate(\n            pos_embed_weight, size=input_shape, mode=mode)\n        pos_embed_weight = torch.flatten(pos_embed_weight,\n                                         2).transpose(1, 2).contiguous()\n        pos_embed = pos_embed_weight\n\n        return pos_embed\n\n    def forward(self, x, hw_shape, mode='bilinear'):\n        pos_embed = self.resize_pos_embed(self.pos_embed, hw_shape, mode)\n        return self.drop(x + pos_embed)\n\n\n@MODELS.register_module()\nclass PyramidVisionTransformer(BaseModule):\n    \"\"\"Pyramid Vision Transformer (PVT)\n\n    Implementation of `Pyramid Vision Transformer: A Versatile Backbone for\n    Dense Prediction without Convolutions\n    <https://arxiv.org/pdf/2102.12122.pdf>`_.\n\n    Args:\n        pretrain_img_size (int | tuple[int]): The size of input image when\n            pretrain. Defaults: 224.\n        in_channels (int): Number of input channels. Default: 3.\n        embed_dims (int): Embedding dimension. Default: 64.\n        num_stags (int): The num of stages. Default: 4.\n        num_layers (Sequence[int]): The layer number of each transformer encode\n            layer. Default: [3, 4, 6, 3].\n        num_heads (Sequence[int]): The attention heads of each transformer\n            encode layer. Default: [1, 2, 5, 8].\n        patch_sizes (Sequence[int]): The patch_size of each patch embedding.\n            Default: [4, 2, 2, 2].\n        strides (Sequence[int]): The stride of each patch embedding.\n            Default: [4, 2, 2, 2].\n        paddings (Sequence[int]): The padding of each patch embedding.\n            Default: [0, 0, 0, 0].\n        sr_ratios (Sequence[int]): The spatial reduction rate of each\n            transformer encode layer. Default: [8, 4, 2, 1].\n        out_indices (Sequence[int] | int): Output from which stages.\n            Default: (0, 1, 2, 3).\n        mlp_ratios (Sequence[int]): The ratio of the mlp hidden dim to the\n            embedding dim of each transformer encode layer.\n            Default: [8, 8, 4, 4].\n        qkv_bias (bool): Enable bias for qkv if True. Default: True.\n        drop_rate (float): Probability of an element to be zeroed.\n            Default 0.0.\n        attn_drop_rate (float): The drop out rate for attention layer.\n            Default 0.0.\n        drop_path_rate (float): stochastic depth rate. Default 0.1.\n        use_abs_pos_embed (bool): If True, add absolute position embedding to\n            the patch embedding. Defaults: True.\n        use_conv_ffn (bool): If True, use Convolutional FFN to replace FFN.\n            Default: False.\n        act_cfg (dict): The activation config for FFNs.\n            Default: dict(type='GELU').\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='LN').\n        pretrained (str, optional): model pretrained path. Default: None.\n        convert_weights (bool): The flag indicates whether the\n            pre-trained model is from the original repo. We may need\n            to convert some keys to make it compatible.\n            Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='TruncNormal', std=.02, layer=['Linear']),\n                dict(type='Constant', val=1, layer=['LayerNorm']),\n                dict(type='Normal', std=0.01, layer=['Conv2d'])\n            ]``\n    \"\"\"\n\n    def __init__(self,\n                 pretrain_img_size=224,\n                 in_channels=3,\n                 embed_dims=64,\n                 num_stages=4,\n                 num_layers=[3, 4, 6, 3],\n                 num_heads=[1, 2, 5, 8],\n                 patch_sizes=[4, 2, 2, 2],\n                 strides=[4, 2, 2, 2],\n                 paddings=[0, 0, 0, 0],\n                 sr_ratios=[8, 4, 2, 1],\n                 out_indices=(0, 1, 2, 3),\n                 mlp_ratios=[8, 8, 4, 4],\n                 qkv_bias=True,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.1,\n                 use_abs_pos_embed=True,\n                 norm_after_stage=False,\n                 use_conv_ffn=False,\n                 act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='LN', eps=1e-6),\n                 convert_weights=True,\n                 init_cfg=[\n                     dict(type='TruncNormal', std=.02, layer=['Linear']),\n                     dict(type='Constant', val=1, layer=['LayerNorm']),\n                     dict(type='Kaiming', layer=['Conv2d'])\n                 ]):\n        super().__init__(init_cfg=init_cfg)\n\n        self.convert_weights = convert_weights\n        if isinstance(pretrain_img_size, int):\n            pretrain_img_size = to_2tuple(pretrain_img_size)\n        elif isinstance(pretrain_img_size, tuple):\n            if len(pretrain_img_size) == 1:\n                pretrain_img_size = to_2tuple(pretrain_img_size[0])\n            assert len(pretrain_img_size) == 2, \\\n                f'The size of image should have length 1 or 2, ' \\\n                f'but got {len(pretrain_img_size)}'\n\n        self.embed_dims = embed_dims\n\n        self.num_stages = num_stages\n        self.num_layers = num_layers\n        self.num_heads = num_heads\n        self.patch_sizes = patch_sizes\n        self.strides = strides\n        self.sr_ratios = sr_ratios\n        assert num_stages == len(num_layers) == len(num_heads) \\\n               == len(patch_sizes) == len(strides) == len(sr_ratios)\n\n        self.out_indices = out_indices\n        assert max(out_indices) < self.num_stages\n\n        # transformer encoder\n        dpr = [\n            x.item()\n            for x in torch.linspace(0, drop_path_rate, sum(num_layers))\n        ]  # stochastic num_layer decay rule\n\n        cur = 0\n        self.layers = ModuleList()\n        for i, num_layer in enumerate(num_layers):\n            embed_dims_i = embed_dims * num_heads[i]\n            patch_embed = PatchEmbed(\n                in_channels=in_channels,\n                embed_dims=embed_dims_i,\n                kernel_size=patch_sizes[i],\n                stride=strides[i],\n                padding=paddings[i],\n                bias=True,\n                norm_cfg=norm_cfg)\n\n            layers = ModuleList()\n            if use_abs_pos_embed:\n                pos_shape = pretrain_img_size // np.prod(patch_sizes[:i + 1])\n                pos_embed = AbsolutePositionEmbedding(\n                    pos_shape=pos_shape,\n                    pos_dim=embed_dims_i,\n                    drop_rate=drop_rate)\n                layers.append(pos_embed)\n            layers.extend([\n                PVTEncoderLayer(\n                    embed_dims=embed_dims_i,\n                    num_heads=num_heads[i],\n                    feedforward_channels=mlp_ratios[i] * embed_dims_i,\n                    drop_rate=drop_rate,\n                    attn_drop_rate=attn_drop_rate,\n                    drop_path_rate=dpr[cur + idx],\n                    qkv_bias=qkv_bias,\n                    act_cfg=act_cfg,\n                    norm_cfg=norm_cfg,\n                    sr_ratio=sr_ratios[i],\n                    use_conv_ffn=use_conv_ffn) for idx in range(num_layer)\n            ])\n            in_channels = embed_dims_i\n            # The ret[0] of build_norm_layer is norm name.\n            if norm_after_stage:\n                norm = build_norm_layer(norm_cfg, embed_dims_i)[1]\n            else:\n                norm = nn.Identity()\n            self.layers.append(ModuleList([patch_embed, layers, norm]))\n            cur += num_layer\n\n    def init_weights(self):\n        \"\"\"Initialize the weights in backbone.\"\"\"\n\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            logger = get_root_logger()\n            state_dict = get_state_dict(\n                self.init_cfg['checkpoint'], map_location='cpu')\n            logger.warn(f'Load pre-trained model for '\n                        f'{self.__class__.__name__} from original repo')\n\n            if self.convert_weights:\n                # Because pvt backbones are not supported by mmcls,\n                # so we need to convert pre-trained weights to match this\n                # implementation.\n                state_dict = pvt_convert(state_dict)\n            load_state_dict(self, state_dict, strict=False, logger=logger)\n\n        else:\n            super(PyramidVisionTransformer, self).init_weights()\n\n    def forward(self, x):\n        outs = []\n\n        for i, layer in enumerate(self.layers):\n            x, hw_shape = layer[0](x)\n\n            for block in layer[1]:\n                x = block(x, hw_shape)\n            x = layer[2](x)\n            x = nlc_to_nchw(x, hw_shape)\n            if i in self.out_indices:\n                outs.append(x)\n\n        return outs\n\n\n@MODELS.register_module()\nclass PyramidVisionTransformerV2(PyramidVisionTransformer):\n    \"\"\"Implementation of `PVTv2: Improved Baselines with Pyramid Vision\n    Transformer <https://arxiv.org/pdf/2106.13797.pdf>`_.\"\"\"\n\n    def __init__(self, **kwargs):\n        super(PyramidVisionTransformerV2, self).__init__(\n            patch_sizes=[7, 3, 3, 3],\n            paddings=[3, 1, 1, 1],\n            use_abs_pos_embed=False,\n            norm_after_stage=True,\n            use_conv_ffn=True,\n            **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/regnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport numpy as np\nimport torch.nn as nn\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\n\nfrom mmpose.registry import MODELS\nfrom .resnet import ResNet\nfrom .resnext import Bottleneck\n\n\n@MODELS.register_module()\nclass RegNet(ResNet):\n    \"\"\"RegNet backbone.\n\n    More details can be found in `paper <https://arxiv.org/abs/2003.13678>`__ .\n\n    Args:\n        arch (dict): The parameter of RegNets.\n            - w0 (int): initial width\n            - wa (float): slope of width\n            - wm (float): quantization parameter to quantize the width\n            - depth (int): depth of the backbone\n            - group_w (int): width of group\n            - bot_mul (float): bottleneck ratio, i.e. expansion of bottleneck.\n        strides (Sequence[int]): Strides of the first block of each stage.\n        base_channels (int): Base channels after stem layer.\n        in_channels (int): Number of input image channels. Default: 3.\n        dilations (Sequence[int]): Dilation of each stage.\n        out_indices (Sequence[int]): Output from which stages.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer. Default: \"pytorch\".\n        frozen_stages (int): Stages to be frozen (all param fixed). -1 means\n            not freezing any parameters. Default: -1.\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN', requires_grad=True).\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import RegNet\n        >>> import torch\n        >>> self = RegNet(\n                arch=dict(\n                    w0=88,\n                    wa=26.31,\n                    wm=2.25,\n                    group_w=48,\n                    depth=25,\n                    bot_mul=1.0),\n                 out_indices=(0, 1, 2, 3))\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 32, 32)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 96, 8, 8)\n        (1, 192, 4, 4)\n        (1, 432, 2, 2)\n        (1, 1008, 1, 1)\n    \"\"\"\n    arch_settings = {\n        'regnetx_400mf':\n        dict(w0=24, wa=24.48, wm=2.54, group_w=16, depth=22, bot_mul=1.0),\n        'regnetx_800mf':\n        dict(w0=56, wa=35.73, wm=2.28, group_w=16, depth=16, bot_mul=1.0),\n        'regnetx_1.6gf':\n        dict(w0=80, wa=34.01, wm=2.25, group_w=24, depth=18, bot_mul=1.0),\n        'regnetx_3.2gf':\n        dict(w0=88, wa=26.31, wm=2.25, group_w=48, depth=25, bot_mul=1.0),\n        'regnetx_4.0gf':\n        dict(w0=96, wa=38.65, wm=2.43, group_w=40, depth=23, bot_mul=1.0),\n        'regnetx_6.4gf':\n        dict(w0=184, wa=60.83, wm=2.07, group_w=56, depth=17, bot_mul=1.0),\n        'regnetx_8.0gf':\n        dict(w0=80, wa=49.56, wm=2.88, group_w=120, depth=23, bot_mul=1.0),\n        'regnetx_12gf':\n        dict(w0=168, wa=73.36, wm=2.37, group_w=112, depth=19, bot_mul=1.0),\n    }\n\n    def __init__(self,\n                 arch,\n                 in_channels=3,\n                 stem_channels=32,\n                 base_channels=32,\n                 strides=(2, 2, 2, 2),\n                 dilations=(1, 1, 1, 1),\n                 out_indices=(3, ),\n                 style='pytorch',\n                 deep_stem=False,\n                 avg_down=False,\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', requires_grad=True),\n                 norm_eval=False,\n                 with_cp=False,\n                 zero_init_residual=True,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super(ResNet, self).__init__(init_cfg=init_cfg)\n\n        # Generate RegNet parameters first\n        if isinstance(arch, str):\n            assert arch in self.arch_settings, \\\n                f'\"arch\": \"{arch}\" is not one of the' \\\n                ' arch_settings'\n            arch = self.arch_settings[arch]\n        elif not isinstance(arch, dict):\n            raise TypeError('Expect \"arch\" to be either a string '\n                            f'or a dict, got {type(arch)}')\n\n        widths, num_stages = self.generate_regnet(\n            arch['w0'],\n            arch['wa'],\n            arch['wm'],\n            arch['depth'],\n        )\n        # Convert to per stage format\n        stage_widths, stage_blocks = self.get_stages_from_blocks(widths)\n        # Generate group widths and bot muls\n        group_widths = [arch['group_w'] for _ in range(num_stages)]\n        self.bottleneck_ratio = [arch['bot_mul'] for _ in range(num_stages)]\n        # Adjust the compatibility of stage_widths and group_widths\n        stage_widths, group_widths = self.adjust_width_group(\n            stage_widths, self.bottleneck_ratio, group_widths)\n\n        # Group params by stage\n        self.stage_widths = stage_widths\n        self.group_widths = group_widths\n        self.depth = sum(stage_blocks)\n        self.stem_channels = stem_channels\n        self.base_channels = base_channels\n        self.num_stages = num_stages\n        assert 1 <= num_stages <= 4\n        self.strides = strides\n        self.dilations = dilations\n        assert len(strides) == len(dilations) == num_stages\n        self.out_indices = out_indices\n        assert max(out_indices) < num_stages\n        self.style = style\n        self.deep_stem = deep_stem\n        if self.deep_stem:\n            raise NotImplementedError(\n                'deep_stem has not been implemented for RegNet')\n        self.avg_down = avg_down\n        self.frozen_stages = frozen_stages\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.with_cp = with_cp\n        self.norm_eval = norm_eval\n        self.zero_init_residual = zero_init_residual\n        self.stage_blocks = stage_blocks[:num_stages]\n\n        self._make_stem_layer(in_channels, stem_channels)\n\n        _in_channels = stem_channels\n        self.res_layers = []\n        for i, num_blocks in enumerate(self.stage_blocks):\n            stride = self.strides[i]\n            dilation = self.dilations[i]\n            group_width = self.group_widths[i]\n            width = int(round(self.stage_widths[i] * self.bottleneck_ratio[i]))\n            stage_groups = width // group_width\n\n            res_layer = self.make_res_layer(\n                block=Bottleneck,\n                num_blocks=num_blocks,\n                in_channels=_in_channels,\n                out_channels=self.stage_widths[i],\n                expansion=1,\n                stride=stride,\n                dilation=dilation,\n                style=self.style,\n                avg_down=self.avg_down,\n                with_cp=self.with_cp,\n                conv_cfg=self.conv_cfg,\n                norm_cfg=self.norm_cfg,\n                base_channels=self.stage_widths[i],\n                groups=stage_groups,\n                width_per_group=group_width)\n            _in_channels = self.stage_widths[i]\n            layer_name = f'layer{i + 1}'\n            self.add_module(layer_name, res_layer)\n            self.res_layers.append(layer_name)\n\n        self._freeze_stages()\n\n        self.feat_dim = stage_widths[-1]\n\n    def _make_stem_layer(self, in_channels, base_channels):\n        self.conv1 = build_conv_layer(\n            self.conv_cfg,\n            in_channels,\n            base_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            bias=False)\n        self.norm1_name, norm1 = build_norm_layer(\n            self.norm_cfg, base_channels, postfix=1)\n        self.add_module(self.norm1_name, norm1)\n        self.relu = nn.ReLU(inplace=True)\n\n    @staticmethod\n    def generate_regnet(initial_width,\n                        width_slope,\n                        width_parameter,\n                        depth,\n                        divisor=8):\n        \"\"\"Generates per block width from RegNet parameters.\n\n        Args:\n            initial_width ([int]): Initial width of the backbone\n            width_slope ([float]): Slope of the quantized linear function\n            width_parameter ([int]): Parameter used to quantize the width.\n            depth ([int]): Depth of the backbone.\n            divisor (int, optional): The divisor of channels. Defaults to 8.\n\n        Returns:\n            list, int: return a list of widths of each stage and the number of\n                stages\n        \"\"\"\n        assert width_slope >= 0\n        assert initial_width > 0\n        assert width_parameter > 1\n        assert initial_width % divisor == 0\n        widths_cont = np.arange(depth) * width_slope + initial_width\n        ks = np.round(\n            np.log(widths_cont / initial_width) / np.log(width_parameter))\n        widths = initial_width * np.power(width_parameter, ks)\n        widths = np.round(np.divide(widths, divisor)) * divisor\n        num_stages = len(np.unique(widths))\n        widths, widths_cont = widths.astype(int).tolist(), widths_cont.tolist()\n        return widths, num_stages\n\n    @staticmethod\n    def quantize_float(number, divisor):\n        \"\"\"Converts a float to closest non-zero int divisible by divior.\n\n        Args:\n            number (int): Original number to be quantized.\n            divisor (int): Divisor used to quantize the number.\n\n        Returns:\n            int: quantized number that is divisible by devisor.\n        \"\"\"\n        return int(round(number / divisor) * divisor)\n\n    def adjust_width_group(self, widths, bottleneck_ratio, groups):\n        \"\"\"Adjusts the compatibility of widths and groups.\n\n        Args:\n            widths (list[int]): Width of each stage.\n            bottleneck_ratio (float): Bottleneck ratio.\n            groups (int): number of groups in each stage\n\n        Returns:\n            tuple(list): The adjusted widths and groups of each stage.\n        \"\"\"\n        bottleneck_width = [\n            int(w * b) for w, b in zip(widths, bottleneck_ratio)\n        ]\n        groups = [min(g, w_bot) for g, w_bot in zip(groups, bottleneck_width)]\n        bottleneck_width = [\n            self.quantize_float(w_bot, g)\n            for w_bot, g in zip(bottleneck_width, groups)\n        ]\n        widths = [\n            int(w_bot / b)\n            for w_bot, b in zip(bottleneck_width, bottleneck_ratio)\n        ]\n        return widths, groups\n\n    def get_stages_from_blocks(self, widths):\n        \"\"\"Gets widths/stage_blocks of network at each stage.\n\n        Args:\n            widths (list[int]): Width in each stage.\n\n        Returns:\n            tuple(list): width and depth of each stage\n        \"\"\"\n        width_diff = [\n            width != width_prev\n            for width, width_prev in zip(widths + [0], [0] + widths)\n        ]\n        stage_widths = [\n            width for width, diff in zip(widths, width_diff[:-1]) if diff\n        ]\n        stage_blocks = np.diff([\n            depth for depth, diff in zip(range(len(width_diff)), width_diff)\n            if diff\n        ]).tolist()\n        return stage_widths, stage_blocks\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.norm1(x)\n        x = self.relu(x)\n\n        outs = []\n        for i, layer_name in enumerate(self.res_layers):\n            res_layer = getattr(self, layer_name)\n            x = res_layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/backbones/resnest.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .resnet import Bottleneck as _Bottleneck\nfrom .resnet import ResLayer, ResNetV1d\n\n\nclass RSoftmax(nn.Module):\n    \"\"\"Radix Softmax module in ``SplitAttentionConv2d``.\n\n    Args:\n        radix (int): Radix of input.\n        groups (int): Groups of input.\n    \"\"\"\n\n    def __init__(self, radix, groups):\n        super().__init__()\n        self.radix = radix\n        self.groups = groups\n\n    def forward(self, x):\n        batch = x.size(0)\n        if self.radix > 1:\n            x = x.view(batch, self.groups, self.radix, -1).transpose(1, 2)\n            x = F.softmax(x, dim=1)\n            x = x.reshape(batch, -1)\n        else:\n            x = torch.sigmoid(x)\n        return x\n\n\nclass SplitAttentionConv2d(BaseModule):\n    \"\"\"Split-Attention Conv2d.\n\n    Args:\n        in_channels (int): Same as nn.Conv2d.\n        out_channels (int): Same as nn.Conv2d.\n        kernel_size (int | tuple[int]): Same as nn.Conv2d.\n        stride (int | tuple[int]): Same as nn.Conv2d.\n        padding (int | tuple[int]): Same as nn.Conv2d.\n        dilation (int | tuple[int]): Same as nn.Conv2d.\n        groups (int): Same as nn.Conv2d.\n        radix (int): Radix of SpltAtConv2d. Default: 2\n        reduction_factor (int): Reduction factor of SplitAttentionConv2d.\n            Default: 4.\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer. Default: None.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 channels,\n                 kernel_size,\n                 stride=1,\n                 padding=0,\n                 dilation=1,\n                 groups=1,\n                 radix=2,\n                 reduction_factor=4,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        inter_channels = max(in_channels * radix // reduction_factor, 32)\n        self.radix = radix\n        self.groups = groups\n        self.channels = channels\n        self.conv = build_conv_layer(\n            conv_cfg,\n            in_channels,\n            channels * radix,\n            kernel_size,\n            stride=stride,\n            padding=padding,\n            dilation=dilation,\n            groups=groups * radix,\n            bias=False)\n        self.norm0_name, norm0 = build_norm_layer(\n            norm_cfg, channels * radix, postfix=0)\n        self.add_module(self.norm0_name, norm0)\n        self.relu = nn.ReLU(inplace=True)\n        self.fc1 = build_conv_layer(\n            None, channels, inter_channels, 1, groups=self.groups)\n        self.norm1_name, norm1 = build_norm_layer(\n            norm_cfg, inter_channels, postfix=1)\n        self.add_module(self.norm1_name, norm1)\n        self.fc2 = build_conv_layer(\n            None, inter_channels, channels * radix, 1, groups=self.groups)\n        self.rsoftmax = RSoftmax(radix, groups)\n\n    @property\n    def norm0(self):\n        return getattr(self, self.norm0_name)\n\n    @property\n    def norm1(self):\n        return getattr(self, self.norm1_name)\n\n    def forward(self, x):\n        x = self.conv(x)\n        x = self.norm0(x)\n        x = self.relu(x)\n\n        batch, rchannel = x.shape[:2]\n        if self.radix > 1:\n            splits = x.view(batch, self.radix, -1, *x.shape[2:])\n            gap = splits.sum(dim=1)\n        else:\n            gap = x\n        gap = F.adaptive_avg_pool2d(gap, 1)\n        gap = self.fc1(gap)\n\n        gap = self.norm1(gap)\n        gap = self.relu(gap)\n\n        atten = self.fc2(gap)\n        atten = self.rsoftmax(atten).view(batch, -1, 1, 1)\n\n        if self.radix > 1:\n            attens = atten.view(batch, self.radix, -1, *atten.shape[2:])\n            out = torch.sum(attens * splits, dim=1)\n        else:\n            out = atten * x\n        return out.contiguous()\n\n\nclass Bottleneck(_Bottleneck):\n    \"\"\"Bottleneck block for ResNeSt.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        groups (int): Groups of conv2.\n        width_per_group (int): Width per group of conv2. 64x4d indicates\n            ``groups=64, width_per_group=4`` and 32x8d indicates\n            ``groups=32, width_per_group=8``.\n        radix (int): Radix of SpltAtConv2d. Default: 2\n        reduction_factor (int): Reduction factor of SplitAttentionConv2d.\n            Default: 4.\n        avg_down_stride (bool): Whether to use average pool for stride in\n            Bottleneck. Default: True.\n        stride (int): stride of the block. Default: 1\n        dilation (int): dilation of convolution. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 groups=1,\n                 width_per_group=4,\n                 base_channels=64,\n                 radix=2,\n                 reduction_factor=4,\n                 avg_down_stride=True,\n                 **kwargs):\n        super().__init__(in_channels, out_channels, **kwargs)\n\n        self.groups = groups\n        self.width_per_group = width_per_group\n\n        # For ResNet bottleneck, middle channels are determined by expansion\n        # and out_channels, but for ResNeXt bottleneck, it is determined by\n        # groups and width_per_group and the stage it is located in.\n        if groups != 1:\n            assert self.mid_channels % base_channels == 0\n            self.mid_channels = (\n                groups * width_per_group * self.mid_channels // base_channels)\n\n        self.avg_down_stride = avg_down_stride and self.conv2_stride > 1\n\n        self.norm1_name, norm1 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=1)\n        self.norm3_name, norm3 = build_norm_layer(\n            self.norm_cfg, self.out_channels, postfix=3)\n\n        self.conv1 = build_conv_layer(\n            self.conv_cfg,\n            self.in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=self.conv1_stride,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = SplitAttentionConv2d(\n            self.mid_channels,\n            self.mid_channels,\n            kernel_size=3,\n            stride=1 if self.avg_down_stride else self.conv2_stride,\n            padding=self.dilation,\n            dilation=self.dilation,\n            groups=groups,\n            radix=radix,\n            reduction_factor=reduction_factor,\n            conv_cfg=self.conv_cfg,\n            norm_cfg=self.norm_cfg)\n        delattr(self, self.norm2_name)\n\n        if self.avg_down_stride:\n            self.avd_layer = nn.AvgPool2d(3, self.conv2_stride, padding=1)\n\n        self.conv3 = build_conv_layer(\n            self.conv_cfg,\n            self.mid_channels,\n            self.out_channels,\n            kernel_size=1,\n            bias=False)\n        self.add_module(self.norm3_name, norm3)\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            identity = x\n\n            out = self.conv1(x)\n            out = self.norm1(out)\n            out = self.relu(out)\n\n            out = self.conv2(out)\n\n            if self.avg_down_stride:\n                out = self.avd_layer(out)\n\n            out = self.conv3(out)\n            out = self.norm3(out)\n\n            if self.downsample is not None:\n                identity = self.downsample(x)\n\n            out += identity\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        out = self.relu(out)\n\n        return out\n\n\n@MODELS.register_module()\nclass ResNeSt(ResNetV1d):\n    \"\"\"ResNeSt backbone.\n\n    Please refer to the `paper <https://arxiv.org/pdf/2004.08955.pdf>`__\n    for details.\n\n    Args:\n        depth (int): Network depth, from {50, 101, 152, 200}.\n        groups (int): Groups of conv2 in Bottleneck. Default: 32.\n        width_per_group (int): Width per group of conv2 in Bottleneck.\n            Default: 4.\n        radix (int): Radix of SpltAtConv2d. Default: 2\n        reduction_factor (int): Reduction factor of SplitAttentionConv2d.\n            Default: 4.\n        avg_down_stride (bool): Whether to use average pool for stride in\n            Bottleneck. Default: True.\n        in_channels (int): Number of input image channels. Default: 3.\n        stem_channels (int): Output channels of the stem layer. Default: 64.\n        num_stages (int): Stages of the network. Default: 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n            Default: ``(1, 2, 2, 2)``.\n        dilations (Sequence[int]): Dilation of each stage.\n            Default: ``(1, 1, 1, 1)``.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. Default: ``(3, )``.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.\n            Default: False.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        conv_cfg (dict | None): The config dict for conv layers. Default: None.\n        norm_cfg (dict): The config dict for norm layers.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n    \"\"\"\n\n    arch_settings = {\n        50: (Bottleneck, (3, 4, 6, 3)),\n        101: (Bottleneck, (3, 4, 23, 3)),\n        152: (Bottleneck, (3, 8, 36, 3)),\n        200: (Bottleneck, (3, 24, 36, 3)),\n        269: (Bottleneck, (3, 30, 48, 8))\n    }\n\n    def __init__(self,\n                 depth,\n                 groups=1,\n                 width_per_group=4,\n                 radix=2,\n                 reduction_factor=4,\n                 avg_down_stride=True,\n                 **kwargs):\n        self.groups = groups\n        self.width_per_group = width_per_group\n        self.radix = radix\n        self.reduction_factor = reduction_factor\n        self.avg_down_stride = avg_down_stride\n        super().__init__(depth=depth, **kwargs)\n\n    def make_res_layer(self, **kwargs):\n        return ResLayer(\n            groups=self.groups,\n            width_per_group=self.width_per_group,\n            base_channels=self.base_channels,\n            radix=self.radix,\n            reduction_factor=self.reduction_factor,\n            avg_down_stride=self.avg_down_stride,\n            **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/resnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import ConvModule, build_conv_layer, build_norm_layer\nfrom mmengine.model import BaseModule, constant_init\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass BasicBlock(BaseModule):\n    \"\"\"BasicBlock for ResNet.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        expansion (int): The ratio of ``out_channels/mid_channels`` where\n            ``mid_channels`` is the output channels of conv1. This is a\n            reserved argument in BasicBlock and should always be 1. Default: 1.\n        stride (int): stride of the block. Default: 1\n        dilation (int): dilation of convolution. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None.\n        style (str): `pytorch` or `caffe`. It is unused and reserved for\n            unified API with Bottleneck.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 expansion=1,\n                 stride=1,\n                 dilation=1,\n                 downsample=None,\n                 style='pytorch',\n                 with_cp=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.expansion = expansion\n        assert self.expansion == 1\n        assert out_channels % expansion == 0\n        self.mid_channels = out_channels // expansion\n        self.stride = stride\n        self.dilation = dilation\n        self.style = style\n        self.with_cp = with_cp\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n\n        self.norm1_name, norm1 = build_norm_layer(\n            norm_cfg, self.mid_channels, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(\n            norm_cfg, out_channels, postfix=2)\n\n        self.conv1 = build_conv_layer(\n            conv_cfg,\n            in_channels,\n            self.mid_channels,\n            3,\n            stride=stride,\n            padding=dilation,\n            dilation=dilation,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = build_conv_layer(\n            conv_cfg,\n            self.mid_channels,\n            out_channels,\n            3,\n            padding=1,\n            bias=False)\n        self.add_module(self.norm2_name, norm2)\n\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n\n    @property\n    def norm1(self):\n        \"\"\"nn.Module: the normalization layer named \"norm1\" \"\"\"\n        return getattr(self, self.norm1_name)\n\n    @property\n    def norm2(self):\n        \"\"\"nn.Module: the normalization layer named \"norm2\" \"\"\"\n        return getattr(self, self.norm2_name)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        def _inner_forward(x):\n            identity = x\n\n            out = self.conv1(x)\n            out = self.norm1(out)\n            out = self.relu(out)\n\n            out = self.conv2(out)\n            out = self.norm2(out)\n\n            if self.downsample is not None:\n                identity = self.downsample(x)\n\n            out += identity\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        out = self.relu(out)\n\n        return out\n\n\nclass Bottleneck(BaseModule):\n    \"\"\"Bottleneck block for ResNet.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        expansion (int): The ratio of ``out_channels/mid_channels`` where\n            ``mid_channels`` is the input/output channels of conv2. Default: 4.\n        stride (int): stride of the block. Default: 1\n        dilation (int): dilation of convolution. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None.\n        style (str): ``\"pytorch\"`` or ``\"caffe\"``. If set to \"pytorch\", the\n            stride-two layer is the 3x3 conv layer, otherwise the stride-two\n            layer is the first 1x1 conv layer. Default: \"pytorch\".\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 expansion=4,\n                 stride=1,\n                 dilation=1,\n                 downsample=None,\n                 style='pytorch',\n                 with_cp=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        assert style in ['pytorch', 'caffe']\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.expansion = expansion\n        assert out_channels % expansion == 0\n        self.mid_channels = out_channels // expansion\n        self.stride = stride\n        self.dilation = dilation\n        self.style = style\n        self.with_cp = with_cp\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n\n        if self.style == 'pytorch':\n            self.conv1_stride = 1\n            self.conv2_stride = stride\n        else:\n            self.conv1_stride = stride\n            self.conv2_stride = 1\n\n        self.norm1_name, norm1 = build_norm_layer(\n            norm_cfg, self.mid_channels, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(\n            norm_cfg, self.mid_channels, postfix=2)\n        self.norm3_name, norm3 = build_norm_layer(\n            norm_cfg, out_channels, postfix=3)\n\n        self.conv1 = build_conv_layer(\n            conv_cfg,\n            in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=self.conv1_stride,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = build_conv_layer(\n            conv_cfg,\n            self.mid_channels,\n            self.mid_channels,\n            kernel_size=3,\n            stride=self.conv2_stride,\n            padding=dilation,\n            dilation=dilation,\n            bias=False)\n\n        self.add_module(self.norm2_name, norm2)\n        self.conv3 = build_conv_layer(\n            conv_cfg,\n            self.mid_channels,\n            out_channels,\n            kernel_size=1,\n            bias=False)\n        self.add_module(self.norm3_name, norm3)\n\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n\n    @property\n    def norm1(self):\n        \"\"\"nn.Module: the normalization layer named \"norm1\" \"\"\"\n        return getattr(self, self.norm1_name)\n\n    @property\n    def norm2(self):\n        \"\"\"nn.Module: the normalization layer named \"norm2\" \"\"\"\n        return getattr(self, self.norm2_name)\n\n    @property\n    def norm3(self):\n        \"\"\"nn.Module: the normalization layer named \"norm3\" \"\"\"\n        return getattr(self, self.norm3_name)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        def _inner_forward(x):\n            identity = x\n\n            out = self.conv1(x)\n            out = self.norm1(out)\n            out = self.relu(out)\n\n            out = self.conv2(out)\n            out = self.norm2(out)\n            out = self.relu(out)\n\n            out = self.conv3(out)\n            out = self.norm3(out)\n\n            if self.downsample is not None:\n                identity = self.downsample(x)\n\n            out += identity\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        out = self.relu(out)\n\n        return out\n\n\ndef get_expansion(block, expansion=None):\n    \"\"\"Get the expansion of a residual block.\n\n    The block expansion will be obtained by the following order:\n\n    1. If ``expansion`` is given, just return it.\n    2. If ``block`` has the attribute ``expansion``, then return\n       ``block.expansion``.\n    3. Return the default value according the the block type:\n       1 for ``BasicBlock`` and 4 for ``Bottleneck``.\n\n    Args:\n        block (class): The block class.\n        expansion (int | None): The given expansion ratio.\n\n    Returns:\n        int: The expansion of the block.\n    \"\"\"\n    if isinstance(expansion, int):\n        assert expansion > 0\n    elif expansion is None:\n        if hasattr(block, 'expansion'):\n            expansion = block.expansion\n        elif issubclass(block, BasicBlock):\n            expansion = 1\n        elif issubclass(block, Bottleneck):\n            expansion = 4\n        else:\n            raise TypeError(f'expansion is not specified for {block.__name__}')\n    else:\n        raise TypeError('expansion must be an integer or None')\n\n    return expansion\n\n\nclass ResLayer(nn.Sequential):\n    \"\"\"ResLayer to build ResNet style backbone.\n\n    Args:\n        block (nn.Module): Residual block used to build ResLayer.\n        num_blocks (int): Number of blocks.\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        expansion (int, optional): The expansion for BasicBlock/Bottleneck.\n            If not specified, it will firstly be obtained via\n            ``block.expansion``. If the block has no attribute \"expansion\",\n            the following default values will be used: 1 for BasicBlock and\n            4 for Bottleneck. Default: None.\n        stride (int): stride of the first block. Default: 1.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        downsample_first (bool): Downsample at the first block or last block.\n            False for Hourglass, True for ResNet. Default: True\n    \"\"\"\n\n    def __init__(self,\n                 block,\n                 num_blocks,\n                 in_channels,\n                 out_channels,\n                 expansion=None,\n                 stride=1,\n                 avg_down=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 downsample_first=True,\n                 **kwargs):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        self.block = block\n        self.expansion = get_expansion(block, expansion)\n\n        downsample = None\n        if stride != 1 or in_channels != out_channels:\n            downsample = []\n            conv_stride = stride\n            if avg_down and stride != 1:\n                conv_stride = 1\n                downsample.append(\n                    nn.AvgPool2d(\n                        kernel_size=stride,\n                        stride=stride,\n                        ceil_mode=True,\n                        count_include_pad=False))\n            downsample.extend([\n                build_conv_layer(\n                    conv_cfg,\n                    in_channels,\n                    out_channels,\n                    kernel_size=1,\n                    stride=conv_stride,\n                    bias=False),\n                build_norm_layer(norm_cfg, out_channels)[1]\n            ])\n            downsample = nn.Sequential(*downsample)\n\n        layers = []\n        if downsample_first:\n            layers.append(\n                block(\n                    in_channels=in_channels,\n                    out_channels=out_channels,\n                    expansion=self.expansion,\n                    stride=stride,\n                    downsample=downsample,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    **kwargs))\n            in_channels = out_channels\n            for _ in range(1, num_blocks):\n                layers.append(\n                    block(\n                        in_channels=in_channels,\n                        out_channels=out_channels,\n                        expansion=self.expansion,\n                        stride=1,\n                        conv_cfg=conv_cfg,\n                        norm_cfg=norm_cfg,\n                        **kwargs))\n        else:  # downsample_first=False is for HourglassModule\n            for i in range(0, num_blocks - 1):\n                layers.append(\n                    block(\n                        in_channels=in_channels,\n                        out_channels=in_channels,\n                        expansion=self.expansion,\n                        stride=1,\n                        conv_cfg=conv_cfg,\n                        norm_cfg=norm_cfg,\n                        **kwargs))\n            layers.append(\n                block(\n                    in_channels=in_channels,\n                    out_channels=out_channels,\n                    expansion=self.expansion,\n                    stride=stride,\n                    downsample=downsample,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    **kwargs))\n\n        super().__init__(*layers)\n\n\n@MODELS.register_module()\nclass ResNet(BaseBackbone):\n    \"\"\"ResNet backbone.\n\n    Please refer to the `paper <https://arxiv.org/abs/1512.03385>`__ for\n    details.\n\n    Args:\n        depth (int): Network depth, from {18, 34, 50, 101, 152}.\n        in_channels (int): Number of input image channels. Default: 3.\n        stem_channels (int): Output channels of the stem layer. Default: 64.\n        base_channels (int): Middle channels of the first stage. Default: 64.\n        num_stages (int): Stages of the network. Default: 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n            Default: ``(1, 2, 2, 2)``.\n        dilations (Sequence[int]): Dilation of each stage.\n            Default: ``(1, 1, 1, 1)``.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. Default: ``(3, )``.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.\n            Default: False.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        conv_cfg (dict | None): The config dict for conv layers. Default: None.\n        norm_cfg (dict): The config dict for norm layers.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import ResNet\n        >>> import torch\n        >>> self = ResNet(depth=18, out_indices=(0, 1, 2, 3))\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 32, 32)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 64, 8, 8)\n        (1, 128, 4, 4)\n        (1, 256, 2, 2)\n        (1, 512, 1, 1)\n    \"\"\"\n\n    arch_settings = {\n        18: (BasicBlock, (2, 2, 2, 2)),\n        34: (BasicBlock, (3, 4, 6, 3)),\n        50: (Bottleneck, (3, 4, 6, 3)),\n        101: (Bottleneck, (3, 4, 23, 3)),\n        152: (Bottleneck, (3, 8, 36, 3))\n    }\n\n    def __init__(self,\n                 depth,\n                 in_channels=3,\n                 stem_channels=64,\n                 base_channels=64,\n                 expansion=None,\n                 num_stages=4,\n                 strides=(1, 2, 2, 2),\n                 dilations=(1, 1, 1, 1),\n                 out_indices=(3, ),\n                 style='pytorch',\n                 deep_stem=False,\n                 avg_down=False,\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', requires_grad=True),\n                 norm_eval=False,\n                 with_cp=False,\n                 zero_init_residual=True,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super(ResNet, self).__init__(init_cfg)\n        if depth not in self.arch_settings:\n            raise KeyError(f'invalid depth {depth} for resnet')\n        self.depth = depth\n        self.stem_channels = stem_channels\n        self.base_channels = base_channels\n        self.num_stages = num_stages\n        assert 1 <= num_stages <= 4\n        self.strides = strides\n        self.dilations = dilations\n        assert len(strides) == len(dilations) == num_stages\n        self.out_indices = out_indices\n        assert max(out_indices) < num_stages\n        self.style = style\n        self.deep_stem = deep_stem\n        self.avg_down = avg_down\n        self.frozen_stages = frozen_stages\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.with_cp = with_cp\n        self.norm_eval = norm_eval\n        self.zero_init_residual = zero_init_residual\n        self.block, stage_blocks = self.arch_settings[depth]\n        self.stage_blocks = stage_blocks[:num_stages]\n        self.expansion = get_expansion(self.block, expansion)\n\n        self._make_stem_layer(in_channels, stem_channels)\n\n        self.res_layers = []\n        _in_channels = stem_channels\n        _out_channels = base_channels * self.expansion\n        for i, num_blocks in enumerate(self.stage_blocks):\n            stride = strides[i]\n            dilation = dilations[i]\n            res_layer = self.make_res_layer(\n                block=self.block,\n                num_blocks=num_blocks,\n                in_channels=_in_channels,\n                out_channels=_out_channels,\n                expansion=self.expansion,\n                stride=stride,\n                dilation=dilation,\n                style=self.style,\n                avg_down=self.avg_down,\n                with_cp=with_cp,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg)\n            _in_channels = _out_channels\n            _out_channels *= 2\n            layer_name = f'layer{i + 1}'\n            self.add_module(layer_name, res_layer)\n            self.res_layers.append(layer_name)\n\n        self._freeze_stages()\n\n        self.feat_dim = res_layer[-1].out_channels\n\n    def make_res_layer(self, **kwargs):\n        \"\"\"Make a ResLayer.\"\"\"\n        return ResLayer(**kwargs)\n\n    @property\n    def norm1(self):\n        \"\"\"nn.Module: the normalization layer named \"norm1\" \"\"\"\n        return getattr(self, self.norm1_name)\n\n    def _make_stem_layer(self, in_channels, stem_channels):\n        \"\"\"Make stem layer.\"\"\"\n        if self.deep_stem:\n            self.stem = nn.Sequential(\n                ConvModule(\n                    in_channels,\n                    stem_channels // 2,\n                    kernel_size=3,\n                    stride=2,\n                    padding=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    inplace=True),\n                ConvModule(\n                    stem_channels // 2,\n                    stem_channels // 2,\n                    kernel_size=3,\n                    stride=1,\n                    padding=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    inplace=True),\n                ConvModule(\n                    stem_channels // 2,\n                    stem_channels,\n                    kernel_size=3,\n                    stride=1,\n                    padding=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    inplace=True))\n        else:\n            self.conv1 = build_conv_layer(\n                self.conv_cfg,\n                in_channels,\n                stem_channels,\n                kernel_size=7,\n                stride=2,\n                padding=3,\n                bias=False)\n            self.norm1_name, norm1 = build_norm_layer(\n                self.norm_cfg, stem_channels, postfix=1)\n            self.add_module(self.norm1_name, norm1)\n            self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n\n    def _freeze_stages(self):\n        \"\"\"Freeze parameters.\"\"\"\n        if self.frozen_stages >= 0:\n            if self.deep_stem:\n                self.stem.eval()\n                for param in self.stem.parameters():\n                    param.requires_grad = False\n            else:\n                self.norm1.eval()\n                for m in [self.conv1, self.norm1]:\n                    for param in m.parameters():\n                        param.requires_grad = False\n\n        for i in range(1, self.frozen_stages + 1):\n            m = getattr(self, f'layer{i}')\n            m.eval()\n            for param in m.parameters():\n                param.requires_grad = False\n\n    def init_weights(self):\n        \"\"\"Initialize the weights in backbone.\"\"\"\n        super(ResNet, self).init_weights()\n\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            # Suppress zero_init_residual if use pretrained model.\n            return\n\n        if self.zero_init_residual:\n            for m in self.modules():\n                if isinstance(m, Bottleneck):\n                    constant_init(m.norm3, 0)\n                elif isinstance(m, BasicBlock):\n                    constant_init(m.norm2, 0)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        if self.deep_stem:\n            x = self.stem(x)\n        else:\n            x = self.conv1(x)\n            x = self.norm1(x)\n            x = self.relu(x)\n        x = self.maxpool(x)\n        outs = []\n        for i, layer_name in enumerate(self.res_layers):\n            res_layer = getattr(self, layer_name)\n            x = res_layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n        return tuple(outs)\n\n    def train(self, mode=True):\n        \"\"\"Convert the model into training mode.\"\"\"\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                # trick: eval have effect on BatchNorm only\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n\n\n@MODELS.register_module()\nclass ResNetV1d(ResNet):\n    r\"\"\"ResNetV1d variant described in `Bag of Tricks\n    <https://arxiv.org/pdf/1812.01187.pdf>`__.\n\n    Compared with default ResNet(ResNetV1b), ResNetV1d replaces the 7x7 conv in\n    the input stem with three 3x3 convs. And in the downsampling block, a 2x2\n    avg_pool with stride 2 is added before conv, whose stride is changed to 1.\n    \"\"\"\n\n    def __init__(self, **kwargs):\n        super().__init__(deep_stem=True, avg_down=True, **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/resnext.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\n\nfrom mmpose.registry import MODELS\nfrom .resnet import Bottleneck as _Bottleneck\nfrom .resnet import ResLayer, ResNet\n\n\nclass Bottleneck(_Bottleneck):\n    \"\"\"Bottleneck block for ResNeXt.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        groups (int): Groups of conv2.\n        width_per_group (int): Width per group of conv2. 64x4d indicates\n            ``groups=64, width_per_group=4`` and 32x8d indicates\n            ``groups=32, width_per_group=8``.\n        stride (int): stride of the block. Default: 1\n        dilation (int): dilation of convolution. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 base_channels=64,\n                 groups=32,\n                 width_per_group=4,\n                 **kwargs):\n        super().__init__(in_channels, out_channels, **kwargs)\n        self.groups = groups\n        self.width_per_group = width_per_group\n\n        # For ResNet bottleneck, middle channels are determined by expansion\n        # and out_channels, but for ResNeXt bottleneck, it is determined by\n        # groups and width_per_group and the stage it is located in.\n        if groups != 1:\n            assert self.mid_channels % base_channels == 0\n            self.mid_channels = (\n                groups * width_per_group * self.mid_channels // base_channels)\n\n        self.norm1_name, norm1 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=2)\n        self.norm3_name, norm3 = build_norm_layer(\n            self.norm_cfg, self.out_channels, postfix=3)\n\n        self.conv1 = build_conv_layer(\n            self.conv_cfg,\n            self.in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=self.conv1_stride,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = build_conv_layer(\n            self.conv_cfg,\n            self.mid_channels,\n            self.mid_channels,\n            kernel_size=3,\n            stride=self.conv2_stride,\n            padding=self.dilation,\n            dilation=self.dilation,\n            groups=groups,\n            bias=False)\n\n        self.add_module(self.norm2_name, norm2)\n        self.conv3 = build_conv_layer(\n            self.conv_cfg,\n            self.mid_channels,\n            self.out_channels,\n            kernel_size=1,\n            bias=False)\n        self.add_module(self.norm3_name, norm3)\n\n\n@MODELS.register_module()\nclass ResNeXt(ResNet):\n    \"\"\"ResNeXt backbone.\n\n    Please refer to the `paper <https://arxiv.org/abs/1611.05431>`__ for\n    details.\n\n    Args:\n        depth (int): Network depth, from {50, 101, 152}.\n        groups (int): Groups of conv2 in Bottleneck. Default: 32.\n        width_per_group (int): Width per group of conv2 in Bottleneck.\n            Default: 4.\n        in_channels (int): Number of input image channels. Default: 3.\n        stem_channels (int): Output channels of the stem layer. Default: 64.\n        num_stages (int): Stages of the network. Default: 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n            Default: ``(1, 2, 2, 2)``.\n        dilations (Sequence[int]): Dilation of each stage.\n            Default: ``(1, 1, 1, 1)``.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. Default: ``(3, )``.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.\n            Default: False.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        conv_cfg (dict | None): The config dict for conv layers. Default: None.\n        norm_cfg (dict): The config dict for norm layers.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n     Example:\n        >>> from mmpose.models import ResNeXt\n        >>> import torch\n        >>> self = ResNeXt(depth=50, out_indices=(0, 1, 2, 3))\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 32, 32)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 256, 8, 8)\n        (1, 512, 4, 4)\n        (1, 1024, 2, 2)\n        (1, 2048, 1, 1)\n    \"\"\"\n\n    arch_settings = {\n        50: (Bottleneck, (3, 4, 6, 3)),\n        101: (Bottleneck, (3, 4, 23, 3)),\n        152: (Bottleneck, (3, 8, 36, 3))\n    }\n\n    def __init__(self, depth, groups=32, width_per_group=4, **kwargs):\n        self.groups = groups\n        self.width_per_group = width_per_group\n        super().__init__(depth, **kwargs)\n\n    def make_res_layer(self, **kwargs):\n        return ResLayer(\n            groups=self.groups,\n            width_per_group=self.width_per_group,\n            base_channels=self.base_channels,\n            **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/rsn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy as cp\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import ConvModule, MaxPool2d\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass RSB(BaseModule):\n    \"\"\"Residual Steps block for RSN. Paper ref: Cai et al. \"Learning Delicate\n    Local Representations for Multi-Person Pose Estimation\" (ECCV 2020).\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        num_steps (int): Numbers of steps in RSB\n        stride (int): stride of the block. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None.\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        expand_times (int): Times by which the in_channels are expanded.\n            Default:26.\n        res_top_channels (int): Number of channels of feature output by\n            ResNet_top. Default:64.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    expansion = 1\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 num_steps=4,\n                 stride=1,\n                 downsample=None,\n                 with_cp=False,\n                 norm_cfg=dict(type='BN'),\n                 expand_times=26,\n                 res_top_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        assert num_steps > 1\n        self.in_channels = in_channels\n        self.branch_channels = self.in_channels * expand_times\n        self.branch_channels //= res_top_channels\n        self.out_channels = out_channels\n        self.stride = stride\n        self.downsample = downsample\n        self.with_cp = with_cp\n        self.norm_cfg = norm_cfg\n        self.num_steps = num_steps\n        self.conv_bn_relu1 = ConvModule(\n            self.in_channels,\n            self.num_steps * self.branch_channels,\n            kernel_size=1,\n            stride=self.stride,\n            padding=0,\n            norm_cfg=self.norm_cfg,\n            inplace=False)\n        for i in range(self.num_steps):\n            for j in range(i + 1):\n                module_name = f'conv_bn_relu2_{i + 1}_{j + 1}'\n                self.add_module(\n                    module_name,\n                    ConvModule(\n                        self.branch_channels,\n                        self.branch_channels,\n                        kernel_size=3,\n                        stride=1,\n                        padding=1,\n                        norm_cfg=self.norm_cfg,\n                        inplace=False))\n        self.conv_bn3 = ConvModule(\n            self.num_steps * self.branch_channels,\n            self.out_channels * self.expansion,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            act_cfg=None,\n            norm_cfg=self.norm_cfg,\n            inplace=False)\n        self.relu = nn.ReLU(inplace=False)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        identity = x\n        x = self.conv_bn_relu1(x)\n        spx = torch.split(x, self.branch_channels, 1)\n        outputs = list()\n        outs = list()\n        for i in range(self.num_steps):\n            outputs_i = list()\n            outputs.append(outputs_i)\n            for j in range(i + 1):\n                if j == 0:\n                    inputs = spx[i]\n                else:\n                    inputs = outputs[i][j - 1]\n                if i > j:\n                    inputs = inputs + outputs[i - 1][j]\n                module_name = f'conv_bn_relu2_{i + 1}_{j + 1}'\n                module_i_j = getattr(self, module_name)\n                outputs[i].append(module_i_j(inputs))\n\n            outs.append(outputs[i][i])\n        out = torch.cat(tuple(outs), 1)\n        out = self.conv_bn3(out)\n\n        if self.downsample is not None:\n            identity = self.downsample(identity)\n        out = out + identity\n\n        out = self.relu(out)\n\n        return out\n\n\nclass Downsample_module(BaseModule):\n    \"\"\"Downsample module for RSN.\n\n    Args:\n        block (nn.Module): Downsample block.\n        num_blocks (list): Number of blocks in each downsample unit.\n        num_units (int): Numbers of downsample units. Default: 4\n        has_skip (bool): Have skip connections from prior upsample\n            module or not. Default:False\n        num_steps (int): Number of steps in a block. Default:4\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        in_channels (int): Number of channels of the input feature to\n            downsample module. Default: 64\n        expand_times (int): Times by which the in_channels are expanded.\n            Default:26.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 block,\n                 num_blocks,\n                 num_steps=4,\n                 num_units=4,\n                 has_skip=False,\n                 norm_cfg=dict(type='BN'),\n                 in_channels=64,\n                 expand_times=26,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.has_skip = has_skip\n        self.in_channels = in_channels\n        assert len(num_blocks) == num_units\n        self.num_blocks = num_blocks\n        self.num_units = num_units\n        self.num_steps = num_steps\n        self.norm_cfg = norm_cfg\n        self.layer1 = self._make_layer(\n            block,\n            in_channels,\n            num_blocks[0],\n            expand_times=expand_times,\n            res_top_channels=in_channels)\n        for i in range(1, num_units):\n            module_name = f'layer{i + 1}'\n            self.add_module(\n                module_name,\n                self._make_layer(\n                    block,\n                    in_channels * pow(2, i),\n                    num_blocks[i],\n                    stride=2,\n                    expand_times=expand_times,\n                    res_top_channels=in_channels))\n\n    def _make_layer(self,\n                    block,\n                    out_channels,\n                    blocks,\n                    stride=1,\n                    expand_times=26,\n                    res_top_channels=64):\n        downsample = None\n        if stride != 1 or self.in_channels != out_channels * block.expansion:\n            downsample = ConvModule(\n                self.in_channels,\n                out_channels * block.expansion,\n                kernel_size=1,\n                stride=stride,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                act_cfg=None,\n                inplace=True)\n\n        units = list()\n        units.append(\n            block(\n                self.in_channels,\n                out_channels,\n                num_steps=self.num_steps,\n                stride=stride,\n                downsample=downsample,\n                norm_cfg=self.norm_cfg,\n                expand_times=expand_times,\n                res_top_channels=res_top_channels))\n        self.in_channels = out_channels * block.expansion\n        for _ in range(1, blocks):\n            units.append(\n                block(\n                    self.in_channels,\n                    out_channels,\n                    num_steps=self.num_steps,\n                    expand_times=expand_times,\n                    res_top_channels=res_top_channels))\n\n        return nn.Sequential(*units)\n\n    def forward(self, x, skip1, skip2):\n        out = list()\n        for i in range(self.num_units):\n            module_name = f'layer{i + 1}'\n            module_i = getattr(self, module_name)\n            x = module_i(x)\n            if self.has_skip:\n                x = x + skip1[i] + skip2[i]\n            out.append(x)\n        out.reverse()\n\n        return tuple(out)\n\n\nclass Upsample_unit(BaseModule):\n    \"\"\"Upsample unit for upsample module.\n\n    Args:\n        ind (int): Indicates whether to interpolate (>0) and whether to\n           generate feature map for the next hourglass-like module.\n        num_units (int): Number of units that form a upsample module. Along\n            with ind and gen_cross_conv, nm_units is used to decide whether\n            to generate feature map for the next hourglass-like module.\n        in_channels (int): Channel number of the skip-in feature maps from\n            the corresponding downsample unit.\n        unit_channels (int): Channel number in this unit. Default:256.\n        gen_skip: (bool): Whether or not to generate skips for the posterior\n            downsample module. Default:False\n        gen_cross_conv (bool): Whether to generate feature map for the next\n            hourglass-like module. Default:False\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        out_channels (in): Number of channels of feature output by upsample\n            module. Must equal to in_channels of downsample module. Default:64\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 ind,\n                 num_units,\n                 in_channels,\n                 unit_channels=256,\n                 gen_skip=False,\n                 gen_cross_conv=False,\n                 norm_cfg=dict(type='BN'),\n                 out_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.num_units = num_units\n        self.norm_cfg = norm_cfg\n        self.in_skip = ConvModule(\n            in_channels,\n            unit_channels,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            norm_cfg=self.norm_cfg,\n            act_cfg=None,\n            inplace=True)\n        self.relu = nn.ReLU(inplace=True)\n\n        self.ind = ind\n        if self.ind > 0:\n            self.up_conv = ConvModule(\n                unit_channels,\n                unit_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                act_cfg=None,\n                inplace=True)\n\n        self.gen_skip = gen_skip\n        if self.gen_skip:\n            self.out_skip1 = ConvModule(\n                in_channels,\n                in_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                inplace=True)\n\n            self.out_skip2 = ConvModule(\n                unit_channels,\n                in_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                inplace=True)\n\n        self.gen_cross_conv = gen_cross_conv\n        if self.ind == num_units - 1 and self.gen_cross_conv:\n            self.cross_conv = ConvModule(\n                unit_channels,\n                out_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=self.norm_cfg,\n                inplace=True)\n\n    def forward(self, x, up_x):\n        out = self.in_skip(x)\n\n        if self.ind > 0:\n            up_x = F.interpolate(\n                up_x,\n                size=(x.size(2), x.size(3)),\n                mode='bilinear',\n                align_corners=True)\n            up_x = self.up_conv(up_x)\n            out = out + up_x\n        out = self.relu(out)\n\n        skip1 = None\n        skip2 = None\n        if self.gen_skip:\n            skip1 = self.out_skip1(x)\n            skip2 = self.out_skip2(out)\n\n        cross_conv = None\n        if self.ind == self.num_units - 1 and self.gen_cross_conv:\n            cross_conv = self.cross_conv(out)\n\n        return out, skip1, skip2, cross_conv\n\n\nclass Upsample_module(BaseModule):\n    \"\"\"Upsample module for RSN.\n\n    Args:\n        unit_channels (int): Channel number in the upsample units.\n            Default:256.\n        num_units (int): Numbers of upsample units. Default: 4\n        gen_skip (bool): Whether to generate skip for posterior downsample\n            module or not. Default:False\n        gen_cross_conv (bool): Whether to generate feature map for the next\n            hourglass-like module. Default:False\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        out_channels (int): Number of channels of feature output by upsample\n            module. Must equal to in_channels of downsample module. Default:64\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 unit_channels=256,\n                 num_units=4,\n                 gen_skip=False,\n                 gen_cross_conv=False,\n                 norm_cfg=dict(type='BN'),\n                 out_channels=64,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = list()\n        for i in range(num_units):\n            self.in_channels.append(RSB.expansion * out_channels * pow(2, i))\n        self.in_channels.reverse()\n        self.num_units = num_units\n        self.gen_skip = gen_skip\n        self.gen_cross_conv = gen_cross_conv\n        self.norm_cfg = norm_cfg\n        for i in range(num_units):\n            module_name = f'up{i + 1}'\n            self.add_module(\n                module_name,\n                Upsample_unit(\n                    i,\n                    self.num_units,\n                    self.in_channels[i],\n                    unit_channels,\n                    self.gen_skip,\n                    self.gen_cross_conv,\n                    norm_cfg=self.norm_cfg,\n                    out_channels=64))\n\n    def forward(self, x):\n        out = list()\n        skip1 = list()\n        skip2 = list()\n        cross_conv = None\n        for i in range(self.num_units):\n            module_i = getattr(self, f'up{i + 1}')\n            if i == 0:\n                outi, skip1_i, skip2_i, _ = module_i(x[i], None)\n            elif i == self.num_units - 1:\n                outi, skip1_i, skip2_i, cross_conv = module_i(x[i], out[i - 1])\n            else:\n                outi, skip1_i, skip2_i, _ = module_i(x[i], out[i - 1])\n            out.append(outi)\n            skip1.append(skip1_i)\n            skip2.append(skip2_i)\n        skip1.reverse()\n        skip2.reverse()\n\n        return out, skip1, skip2, cross_conv\n\n\nclass Single_stage_RSN(BaseModule):\n    \"\"\"Single_stage Residual Steps Network.\n\n    Args:\n        unit_channels (int): Channel number in the upsample units. Default:256.\n        num_units (int): Numbers of downsample/upsample units. Default: 4\n        gen_skip (bool): Whether to generate skip for posterior downsample\n            module or not. Default:False\n        gen_cross_conv (bool): Whether to generate feature map for the next\n            hourglass-like module. Default:False\n        has_skip (bool): Have skip connections from prior upsample\n            module or not. Default:False\n        num_steps (int): Number of steps in RSB. Default: 4\n        num_blocks (list): Number of blocks in each downsample unit.\n            Default: [2, 2, 2, 2] Note: Make sure num_units==len(num_blocks)\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        in_channels (int): Number of channels of the feature from ResNet_Top.\n            Default: 64.\n        expand_times (int): Times by which the in_channels are expanded in RSB.\n            Default:26.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 has_skip=False,\n                 gen_skip=False,\n                 gen_cross_conv=False,\n                 unit_channels=256,\n                 num_units=4,\n                 num_steps=4,\n                 num_blocks=[2, 2, 2, 2],\n                 norm_cfg=dict(type='BN'),\n                 in_channels=64,\n                 expand_times=26,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        num_blocks = cp.deepcopy(num_blocks)\n        super().__init__(init_cfg=init_cfg)\n        assert len(num_blocks) == num_units\n        self.has_skip = has_skip\n        self.gen_skip = gen_skip\n        self.gen_cross_conv = gen_cross_conv\n        self.num_units = num_units\n        self.num_steps = num_steps\n        self.unit_channels = unit_channels\n        self.num_blocks = num_blocks\n        self.norm_cfg = norm_cfg\n\n        self.downsample = Downsample_module(RSB, num_blocks, num_steps,\n                                            num_units, has_skip, norm_cfg,\n                                            in_channels, expand_times)\n        self.upsample = Upsample_module(unit_channels, num_units, gen_skip,\n                                        gen_cross_conv, norm_cfg, in_channels)\n\n    def forward(self, x, skip1, skip2):\n        mid = self.downsample(x, skip1, skip2)\n        out, skip1, skip2, cross_conv = self.upsample(mid)\n\n        return out, skip1, skip2, cross_conv\n\n\nclass ResNet_top(BaseModule):\n    \"\"\"ResNet top for RSN.\n\n    Args:\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        channels (int): Number of channels of the feature output by ResNet_top.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self, norm_cfg=dict(type='BN'), channels=64, init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.top = nn.Sequential(\n            ConvModule(\n                3,\n                channels,\n                kernel_size=7,\n                stride=2,\n                padding=3,\n                norm_cfg=norm_cfg,\n                inplace=True), MaxPool2d(kernel_size=3, stride=2, padding=1))\n\n    def forward(self, img):\n        return self.top(img)\n\n\n@MODELS.register_module()\nclass RSN(BaseBackbone):\n    \"\"\"Residual Steps Network backbone. Paper ref: Cai et al. \"Learning\n    Delicate Local Representations for Multi-Person Pose Estimation\" (ECCV\n    2020).\n\n    Args:\n        unit_channels (int): Number of Channels in an upsample unit.\n            Default: 256\n        num_stages (int): Number of stages in a multi-stage RSN. Default: 4\n        num_units (int): NUmber of downsample/upsample units in a single-stage\n            RSN. Default: 4 Note: Make sure num_units == len(self.num_blocks)\n        num_blocks (list): Number of RSBs (Residual Steps Block) in each\n            downsample unit. Default: [2, 2, 2, 2]\n        num_steps (int): Number of steps in a RSB. Default:4\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        res_top_channels (int): Number of channels of feature from ResNet_top.\n            Default: 64.\n        expand_times (int): Times by which the in_channels are expanded in RSB.\n            Default:26.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm']),\n                dict(\n                    type='Normal',\n                    std=0.01,\n                    layer=['Linear']),\n            ]``\n    Example:\n        >>> from mmpose.models import RSN\n        >>> import torch\n        >>> self = RSN(num_stages=2,num_units=2,num_blocks=[2,2])\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 511, 511)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_output in level_outputs:\n        ...     for feature in level_output:\n        ...         print(tuple(feature.shape))\n        ...\n        (1, 256, 64, 64)\n        (1, 256, 128, 128)\n        (1, 256, 64, 64)\n        (1, 256, 128, 128)\n    \"\"\"\n\n    def __init__(self,\n                 unit_channels=256,\n                 num_stages=4,\n                 num_units=4,\n                 num_blocks=[2, 2, 2, 2],\n                 num_steps=4,\n                 norm_cfg=dict(type='BN'),\n                 res_top_channels=64,\n                 expand_times=26,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm']),\n                     dict(type='Normal', std=0.01, layer=['Linear']),\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = cp.deepcopy(norm_cfg)\n        num_blocks = cp.deepcopy(num_blocks)\n        super().__init__(init_cfg=init_cfg)\n        self.unit_channels = unit_channels\n        self.num_stages = num_stages\n        self.num_units = num_units\n        self.num_blocks = num_blocks\n        self.num_steps = num_steps\n        self.norm_cfg = norm_cfg\n\n        assert self.num_stages > 0\n        assert self.num_steps > 1\n        assert self.num_units > 1\n        assert self.num_units == len(self.num_blocks)\n        self.top = ResNet_top(norm_cfg=norm_cfg)\n        self.multi_stage_rsn = nn.ModuleList([])\n        for i in range(self.num_stages):\n            if i == 0:\n                has_skip = False\n            else:\n                has_skip = True\n            if i != self.num_stages - 1:\n                gen_skip = True\n                gen_cross_conv = True\n            else:\n                gen_skip = False\n                gen_cross_conv = False\n            self.multi_stage_rsn.append(\n                Single_stage_RSN(has_skip, gen_skip, gen_cross_conv,\n                                 unit_channels, num_units, num_steps,\n                                 num_blocks, norm_cfg, res_top_channels,\n                                 expand_times))\n\n    def forward(self, x):\n        \"\"\"Model forward function.\"\"\"\n        out_feats = []\n        skip1 = None\n        skip2 = None\n        x = self.top(x)\n        for i in range(self.num_stages):\n            out, skip1, skip2, x = self.multi_stage_rsn[i](x, skip1, skip2)\n            out_feats.append(out)\n\n        return out_feats\n"
  },
  {
    "path": "mmpose/models/backbones/scnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .resnet import Bottleneck, ResNet\n\n\nclass SCConv(BaseModule):\n    \"\"\"SCConv (Self-calibrated Convolution)\n\n    Args:\n        in_channels (int): The input channels of the SCConv.\n        out_channels (int): The output channel of the SCConv.\n        stride (int): stride of SCConv.\n        pooling_r (int): size of pooling for scconv.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 stride,\n                 pooling_r,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', momentum=0.1),\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n\n        assert in_channels == out_channels\n\n        self.k2 = nn.Sequential(\n            nn.AvgPool2d(kernel_size=pooling_r, stride=pooling_r),\n            build_conv_layer(\n                conv_cfg,\n                in_channels,\n                in_channels,\n                kernel_size=3,\n                stride=1,\n                padding=1,\n                bias=False),\n            build_norm_layer(norm_cfg, in_channels)[1],\n        )\n        self.k3 = nn.Sequential(\n            build_conv_layer(\n                conv_cfg,\n                in_channels,\n                in_channels,\n                kernel_size=3,\n                stride=1,\n                padding=1,\n                bias=False),\n            build_norm_layer(norm_cfg, in_channels)[1],\n        )\n        self.k4 = nn.Sequential(\n            build_conv_layer(\n                conv_cfg,\n                in_channels,\n                in_channels,\n                kernel_size=3,\n                stride=stride,\n                padding=1,\n                bias=False),\n            build_norm_layer(norm_cfg, out_channels)[1],\n            nn.ReLU(inplace=True),\n        )\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        identity = x\n\n        out = torch.sigmoid(\n            torch.add(identity, F.interpolate(self.k2(x),\n                                              identity.size()[2:])))\n        out = torch.mul(self.k3(x), out)\n        out = self.k4(out)\n\n        return out\n\n\nclass SCBottleneck(Bottleneck):\n    \"\"\"SC(Self-calibrated) Bottleneck.\n\n    Args:\n        in_channels (int): The input channels of the SCBottleneck block.\n        out_channels (int): The output channel of the SCBottleneck block.\n    \"\"\"\n\n    pooling_r = 4\n\n    def __init__(self, in_channels, out_channels, **kwargs):\n        super().__init__(in_channels, out_channels, **kwargs)\n        self.mid_channels = out_channels // self.expansion // 2\n\n        self.norm1_name, norm1 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=2)\n        self.norm3_name, norm3 = build_norm_layer(\n            self.norm_cfg, out_channels, postfix=3)\n\n        self.conv1 = build_conv_layer(\n            self.conv_cfg,\n            in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=1,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n\n        self.k1 = nn.Sequential(\n            build_conv_layer(\n                self.conv_cfg,\n                self.mid_channels,\n                self.mid_channels,\n                kernel_size=3,\n                stride=self.stride,\n                padding=1,\n                bias=False),\n            build_norm_layer(self.norm_cfg, self.mid_channels)[1],\n            nn.ReLU(inplace=True))\n\n        self.conv2 = build_conv_layer(\n            self.conv_cfg,\n            in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=1,\n            bias=False)\n        self.add_module(self.norm2_name, norm2)\n\n        self.scconv = SCConv(self.mid_channels, self.mid_channels, self.stride,\n                             self.pooling_r, self.conv_cfg, self.norm_cfg)\n\n        self.conv3 = build_conv_layer(\n            self.conv_cfg,\n            self.mid_channels * 2,\n            out_channels,\n            kernel_size=1,\n            stride=1,\n            bias=False)\n        self.add_module(self.norm3_name, norm3)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        def _inner_forward(x):\n            identity = x\n\n            out_a = self.conv1(x)\n            out_a = self.norm1(out_a)\n            out_a = self.relu(out_a)\n\n            out_a = self.k1(out_a)\n\n            out_b = self.conv2(x)\n            out_b = self.norm2(out_b)\n            out_b = self.relu(out_b)\n\n            out_b = self.scconv(out_b)\n\n            out = self.conv3(torch.cat([out_a, out_b], dim=1))\n            out = self.norm3(out)\n\n            if self.downsample is not None:\n                identity = self.downsample(x)\n\n            out += identity\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        out = self.relu(out)\n\n        return out\n\n\n@MODELS.register_module()\nclass SCNet(ResNet):\n    \"\"\"SCNet backbone.\n\n    Improving Convolutional Networks with Self-Calibrated Convolutions,\n    Jiang-Jiang Liu, Qibin Hou, Ming-Ming Cheng, Changhu Wang, Jiashi Feng,\n    IEEE CVPR, 2020.\n    http://mftp.mmcheng.net/Papers/20cvprSCNet.pdf\n\n    Args:\n        depth (int): Depth of scnet, from {50, 101}.\n        in_channels (int): Number of input image channels. Normally 3.\n        base_channels (int): Number of base channels of hidden layer.\n        num_stages (int): SCNet stages, normally 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n        dilations (Sequence[int]): Dilation of each stage.\n        out_indices (Sequence[int]): Output from which stages.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters.\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity.\n\n    Example:\n        >>> from mmpose.models import SCNet\n        >>> import torch\n        >>> self = SCNet(depth=50, out_indices=(0, 1, 2, 3))\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 224, 224)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 256, 56, 56)\n        (1, 512, 28, 28)\n        (1, 1024, 14, 14)\n        (1, 2048, 7, 7)\n    \"\"\"\n\n    arch_settings = {\n        50: (SCBottleneck, [3, 4, 6, 3]),\n        101: (SCBottleneck, [3, 4, 23, 3])\n    }\n\n    def __init__(self, depth, **kwargs):\n        if depth not in self.arch_settings:\n            raise KeyError(f'invalid depth {depth} for SCNet')\n        super().__init__(depth, **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/seresnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.utils.checkpoint as cp\n\nfrom mmpose.registry import MODELS\nfrom .resnet import Bottleneck, ResLayer, ResNet\nfrom .utils.se_layer import SELayer\n\n\nclass SEBottleneck(Bottleneck):\n    \"\"\"SEBottleneck block for SEResNet.\n\n    Args:\n        in_channels (int): The input channels of the SEBottleneck block.\n        out_channels (int): The output channel of the SEBottleneck block.\n        se_ratio (int): Squeeze ratio in SELayer. Default: 16\n    \"\"\"\n\n    def __init__(self, in_channels, out_channels, se_ratio=16, **kwargs):\n        super().__init__(in_channels, out_channels, **kwargs)\n        self.se_layer = SELayer(out_channels, ratio=se_ratio)\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            identity = x\n\n            out = self.conv1(x)\n            out = self.norm1(out)\n            out = self.relu(out)\n\n            out = self.conv2(out)\n            out = self.norm2(out)\n            out = self.relu(out)\n\n            out = self.conv3(out)\n            out = self.norm3(out)\n\n            out = self.se_layer(out)\n\n            if self.downsample is not None:\n                identity = self.downsample(x)\n\n            out += identity\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        out = self.relu(out)\n\n        return out\n\n\n@MODELS.register_module()\nclass SEResNet(ResNet):\n    \"\"\"SEResNet backbone.\n\n    Please refer to the `paper <https://arxiv.org/abs/1709.01507>`__ for\n    details.\n\n    Args:\n        depth (int): Network depth, from {50, 101, 152}.\n        se_ratio (int): Squeeze ratio in SELayer. Default: 16.\n        in_channels (int): Number of input image channels. Default: 3.\n        stem_channels (int): Output channels of the stem layer. Default: 64.\n        num_stages (int): Stages of the network. Default: 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n            Default: ``(1, 2, 2, 2)``.\n        dilations (Sequence[int]): Dilation of each stage.\n            Default: ``(1, 1, 1, 1)``.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. Default: ``(3, )``.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.\n            Default: False.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        conv_cfg (dict | None): The config dict for conv layers. Default: None.\n        norm_cfg (dict): The config dict for norm layers.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import SEResNet\n        >>> import torch\n        >>> self = SEResNet(depth=50, out_indices=(0, 1, 2, 3))\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 224, 224)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 256, 56, 56)\n        (1, 512, 28, 28)\n        (1, 1024, 14, 14)\n        (1, 2048, 7, 7)\n    \"\"\"\n\n    arch_settings = {\n        50: (SEBottleneck, (3, 4, 6, 3)),\n        101: (SEBottleneck, (3, 4, 23, 3)),\n        152: (SEBottleneck, (3, 8, 36, 3))\n    }\n\n    def __init__(self, depth, se_ratio=16, **kwargs):\n        if depth not in self.arch_settings:\n            raise KeyError(f'invalid depth {depth} for SEResNet')\n        self.se_ratio = se_ratio\n        super().__init__(depth, **kwargs)\n\n    def make_res_layer(self, **kwargs):\n        return ResLayer(se_ratio=self.se_ratio, **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/seresnext.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\n\nfrom mmpose.registry import MODELS\nfrom .resnet import ResLayer\nfrom .seresnet import SEBottleneck as _SEBottleneck\nfrom .seresnet import SEResNet\n\n\nclass SEBottleneck(_SEBottleneck):\n    \"\"\"SEBottleneck block for SEResNeXt.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        base_channels (int): Middle channels of the first stage. Default: 64.\n        groups (int): Groups of conv2.\n        width_per_group (int): Width per group of conv2. 64x4d indicates\n            ``groups=64, width_per_group=4`` and 32x8d indicates\n            ``groups=32, width_per_group=8``.\n        stride (int): stride of the block. Default: 1\n        dilation (int): dilation of convolution. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None\n        se_ratio (int): Squeeze ratio in SELayer. Default: 16\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 base_channels=64,\n                 groups=32,\n                 width_per_group=4,\n                 se_ratio=16,\n                 **kwargs):\n        super().__init__(in_channels, out_channels, se_ratio, **kwargs)\n        self.groups = groups\n        self.width_per_group = width_per_group\n\n        # We follow the same rational of ResNext to compute mid_channels.\n        # For SEResNet bottleneck, middle channels are determined by expansion\n        # and out_channels, but for SEResNeXt bottleneck, it is determined by\n        # groups and width_per_group and the stage it is located in.\n        if groups != 1:\n            assert self.mid_channels % base_channels == 0\n            self.mid_channels = (\n                groups * width_per_group * self.mid_channels // base_channels)\n\n        self.norm1_name, norm1 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(\n            self.norm_cfg, self.mid_channels, postfix=2)\n        self.norm3_name, norm3 = build_norm_layer(\n            self.norm_cfg, self.out_channels, postfix=3)\n\n        self.conv1 = build_conv_layer(\n            self.conv_cfg,\n            self.in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=self.conv1_stride,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = build_conv_layer(\n            self.conv_cfg,\n            self.mid_channels,\n            self.mid_channels,\n            kernel_size=3,\n            stride=self.conv2_stride,\n            padding=self.dilation,\n            dilation=self.dilation,\n            groups=groups,\n            bias=False)\n\n        self.add_module(self.norm2_name, norm2)\n        self.conv3 = build_conv_layer(\n            self.conv_cfg,\n            self.mid_channels,\n            self.out_channels,\n            kernel_size=1,\n            bias=False)\n        self.add_module(self.norm3_name, norm3)\n\n\n@MODELS.register_module()\nclass SEResNeXt(SEResNet):\n    \"\"\"SEResNeXt backbone.\n\n    Please refer to the `paper <https://arxiv.org/abs/1709.01507>`__ for\n    details.\n\n    Args:\n        depth (int): Network depth, from {50, 101, 152}.\n        groups (int): Groups of conv2 in Bottleneck. Default: 32.\n        width_per_group (int): Width per group of conv2 in Bottleneck.\n            Default: 4.\n        se_ratio (int): Squeeze ratio in SELayer. Default: 16.\n        in_channels (int): Number of input image channels. Default: 3.\n        stem_channels (int): Output channels of the stem layer. Default: 64.\n        num_stages (int): Stages of the network. Default: 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n            Default: ``(1, 2, 2, 2)``.\n        dilations (Sequence[int]): Dilation of each stage.\n            Default: ``(1, 1, 1, 1)``.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. Default: ``(3, )``.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.\n            Default: False.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        conv_cfg (dict | None): The config dict for conv layers. Default: None.\n        norm_cfg (dict): The config dict for norm layers.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import SEResNeXt\n        >>> import torch\n        >>> self = SEResNet(depth=50, out_indices=(0, 1, 2, 3))\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 3, 224, 224)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 256, 56, 56)\n        (1, 512, 28, 28)\n        (1, 1024, 14, 14)\n        (1, 2048, 7, 7)\n    \"\"\"\n\n    arch_settings = {\n        50: (SEBottleneck, (3, 4, 6, 3)),\n        101: (SEBottleneck, (3, 4, 23, 3)),\n        152: (SEBottleneck, (3, 8, 36, 3))\n    }\n\n    def __init__(self, depth, groups=32, width_per_group=4, **kwargs):\n        self.groups = groups\n        self.width_per_group = width_per_group\n        super().__init__(depth, **kwargs)\n\n    def make_res_layer(self, **kwargs):\n        return ResLayer(\n            groups=self.groups,\n            width_per_group=self.width_per_group,\n            base_channels=self.base_channels,\n            **kwargs)\n"
  },
  {
    "path": "mmpose/models/backbones/shufflenet_v1.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch\nimport torch.nn as nn\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import ConvModule, build_activation_layer\nfrom mmengine.model import BaseModule\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .utils import channel_shuffle, make_divisible\n\n\nclass ShuffleUnit(BaseModule):\n    \"\"\"ShuffleUnit block.\n\n    ShuffleNet unit with pointwise group convolution (GConv) and channel\n    shuffle.\n\n    Args:\n        in_channels (int): The input channels of the ShuffleUnit.\n        out_channels (int): The output channels of the ShuffleUnit.\n        groups (int, optional): The number of groups to be used in grouped 1x1\n            convolutions in each ShuffleUnit. Default: 3\n        first_block (bool, optional): Whether it is the first ShuffleUnit of a\n            sequential ShuffleUnits. Default: True, which means not using the\n            grouped 1x1 convolution.\n        combine (str, optional): The ways to combine the input and output\n            branches. Default: 'add'.\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        with_cp (bool, optional): Use checkpoint or not. Using checkpoint\n            will save some memory while slowing down the training speed.\n            Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n\n    Returns:\n        Tensor: The output tensor.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 groups=3,\n                 first_block=True,\n                 combine='add',\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 with_cp=False,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.first_block = first_block\n        self.combine = combine\n        self.groups = groups\n        self.bottleneck_channels = self.out_channels // 4\n        self.with_cp = with_cp\n\n        if self.combine == 'add':\n            self.depthwise_stride = 1\n            self._combine_func = self._add\n            assert in_channels == out_channels, (\n                'in_channels must be equal to out_channels when combine '\n                'is add')\n        elif self.combine == 'concat':\n            self.depthwise_stride = 2\n            self._combine_func = self._concat\n            self.out_channels -= self.in_channels\n            self.avgpool = nn.AvgPool2d(kernel_size=3, stride=2, padding=1)\n        else:\n            raise ValueError(f'Cannot combine tensors with {self.combine}. '\n                             'Only \"add\" and \"concat\" are supported')\n\n        self.first_1x1_groups = 1 if first_block else self.groups\n        self.g_conv_1x1_compress = ConvModule(\n            in_channels=self.in_channels,\n            out_channels=self.bottleneck_channels,\n            kernel_size=1,\n            groups=self.first_1x1_groups,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n\n        self.depthwise_conv3x3_bn = ConvModule(\n            in_channels=self.bottleneck_channels,\n            out_channels=self.bottleneck_channels,\n            kernel_size=3,\n            stride=self.depthwise_stride,\n            padding=1,\n            groups=self.bottleneck_channels,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=None)\n\n        self.g_conv_1x1_expand = ConvModule(\n            in_channels=self.bottleneck_channels,\n            out_channels=self.out_channels,\n            kernel_size=1,\n            groups=self.groups,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=None)\n\n        self.act = build_activation_layer(act_cfg)\n\n    @staticmethod\n    def _add(x, out):\n        # residual connection\n        return x + out\n\n    @staticmethod\n    def _concat(x, out):\n        # concatenate along channel axis\n        return torch.cat((x, out), 1)\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            residual = x\n\n            out = self.g_conv_1x1_compress(x)\n            out = self.depthwise_conv3x3_bn(out)\n\n            if self.groups > 1:\n                out = channel_shuffle(out, self.groups)\n\n            out = self.g_conv_1x1_expand(out)\n\n            if self.combine == 'concat':\n                residual = self.avgpool(residual)\n                out = self.act(out)\n                out = self._combine_func(residual, out)\n            else:\n                out = self._combine_func(residual, out)\n                out = self.act(out)\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n\n\n@MODELS.register_module()\nclass ShuffleNetV1(BaseBackbone):\n    \"\"\"ShuffleNetV1 backbone.\n\n    Args:\n        groups (int, optional): The number of groups to be used in grouped 1x1\n            convolutions in each ShuffleUnit. Default: 3.\n        widen_factor (float, optional): Width multiplier - adjusts the number\n            of channels in each layer by this amount. Default: 1.0.\n        out_indices (Sequence[int]): Output from which stages.\n            Default: (2, )\n        frozen_stages (int): Stages to be frozen (all param fixed).\n            Default: -1, which means not freezing any parameters.\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.01, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    bias=0.0001\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n    \"\"\"\n\n    def __init__(self,\n                 groups=3,\n                 widen_factor=1.0,\n                 out_indices=(2, ),\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 norm_eval=False,\n                 with_cp=False,\n                 init_cfg=[\n                     dict(type='Normal', std=0.01, layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         bias=0.0001,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.stage_blocks = [4, 8, 4]\n        self.groups = groups\n\n        for index in out_indices:\n            if index not in range(0, 3):\n                raise ValueError('the item in out_indices must in '\n                                 f'range(0, 3). But received {index}')\n\n        if frozen_stages not in range(-1, 3):\n            raise ValueError('frozen_stages must be in range(-1, 3). '\n                             f'But received {frozen_stages}')\n        self.out_indices = out_indices\n        self.frozen_stages = frozen_stages\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n\n        if groups == 1:\n            channels = (144, 288, 576)\n        elif groups == 2:\n            channels = (200, 400, 800)\n        elif groups == 3:\n            channels = (240, 480, 960)\n        elif groups == 4:\n            channels = (272, 544, 1088)\n        elif groups == 8:\n            channels = (384, 768, 1536)\n        else:\n            raise ValueError(f'{groups} groups is not supported for 1x1 '\n                             'Grouped Convolutions')\n\n        channels = [make_divisible(ch * widen_factor, 8) for ch in channels]\n\n        self.in_channels = int(24 * widen_factor)\n\n        self.conv1 = ConvModule(\n            in_channels=3,\n            out_channels=self.in_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n\n        self.layers = nn.ModuleList()\n        for i, num_blocks in enumerate(self.stage_blocks):\n            first_block = (i == 0)\n            layer = self.make_layer(channels[i], num_blocks, first_block)\n            self.layers.append(layer)\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            for param in self.conv1.parameters():\n                param.requires_grad = False\n        for i in range(self.frozen_stages):\n            layer = self.layers[i]\n            layer.eval()\n            for param in layer.parameters():\n                param.requires_grad = False\n\n    def init_weights(self, pretrained=None):\n        super(ShuffleNetV1, self).init_weights()\n\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            return\n\n        for name, m in self.named_modules():\n            if isinstance(m, nn.Conv2d) and 'conv1' not in name:\n                nn.init.normal_(m.weight, mean=0, std=1.0 / m.weight.shape[1])\n\n    def make_layer(self, out_channels, num_blocks, first_block=False):\n        \"\"\"Stack ShuffleUnit blocks to make a layer.\n\n        Args:\n            out_channels (int): out_channels of the block.\n            num_blocks (int): Number of blocks.\n            first_block (bool, optional): Whether is the first ShuffleUnit of a\n                sequential ShuffleUnits. Default: False, which means using\n                the grouped 1x1 convolution.\n        \"\"\"\n        layers = []\n        for i in range(num_blocks):\n            first_block = first_block if i == 0 else False\n            combine_mode = 'concat' if i == 0 else 'add'\n            layers.append(\n                ShuffleUnit(\n                    self.in_channels,\n                    out_channels,\n                    groups=self.groups,\n                    first_block=first_block,\n                    combine=combine_mode,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    act_cfg=self.act_cfg,\n                    with_cp=self.with_cp))\n            self.in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.maxpool(x)\n\n        outs = []\n        for i, layer in enumerate(self.layers):\n            x = layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n\n        return tuple(outs)\n\n    def train(self, mode=True):\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/shufflenet_v2.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch\nimport torch.nn as nn\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .utils import channel_shuffle\n\n\nclass InvertedResidual(BaseModule):\n    \"\"\"InvertedResidual block for ShuffleNetV2 backbone.\n\n    Args:\n        in_channels (int): The input channels of the block.\n        out_channels (int): The output channels of the block.\n        stride (int): Stride of the 3x3 convolution layer. Default: 1\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 stride=1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 with_cp=False,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.stride = stride\n        self.with_cp = with_cp\n\n        branch_features = out_channels // 2\n        if self.stride == 1:\n            assert in_channels == branch_features * 2, (\n                f'in_channels ({in_channels}) should equal to '\n                f'branch_features * 2 ({branch_features * 2}) '\n                'when stride is 1')\n\n        if in_channels != branch_features * 2:\n            assert self.stride != 1, (\n                f'stride ({self.stride}) should not equal 1 when '\n                f'in_channels != branch_features * 2')\n\n        if self.stride > 1:\n            self.branch1 = nn.Sequential(\n                ConvModule(\n                    in_channels,\n                    in_channels,\n                    kernel_size=3,\n                    stride=self.stride,\n                    padding=1,\n                    groups=in_channels,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=None),\n                ConvModule(\n                    in_channels,\n                    branch_features,\n                    kernel_size=1,\n                    stride=1,\n                    padding=0,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg),\n            )\n\n        self.branch2 = nn.Sequential(\n            ConvModule(\n                in_channels if (self.stride > 1) else branch_features,\n                branch_features,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg),\n            ConvModule(\n                branch_features,\n                branch_features,\n                kernel_size=3,\n                stride=self.stride,\n                padding=1,\n                groups=branch_features,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None),\n            ConvModule(\n                branch_features,\n                branch_features,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg))\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            if self.stride > 1:\n                out = torch.cat((self.branch1(x), self.branch2(x)), dim=1)\n            else:\n                x1, x2 = x.chunk(2, dim=1)\n                out = torch.cat((x1, self.branch2(x2)), dim=1)\n\n            out = channel_shuffle(out, 2)\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n\n\n@MODELS.register_module()\nclass ShuffleNetV2(BaseBackbone):\n    \"\"\"ShuffleNetV2 backbone.\n\n    Args:\n        widen_factor (float): Width multiplier - adjusts the number of\n            channels in each layer by this amount. Default: 1.0.\n        out_indices (Sequence[int]): Output from which stages.\n            Default: (0, 1, 2, 3).\n        frozen_stages (int): Stages to be frozen (all param fixed).\n            Default: -1, which means not freezing any parameters.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.01, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    bias=0.0001\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n    \"\"\"\n\n    def __init__(self,\n                 widen_factor=1.0,\n                 out_indices=(3, ),\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 norm_eval=False,\n                 with_cp=False,\n                 init_cfg=[\n                     dict(type='Normal', std=0.01, layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         bias=0.0001,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.stage_blocks = [4, 8, 4]\n        for index in out_indices:\n            if index not in range(0, 4):\n                raise ValueError('the item in out_indices must in '\n                                 f'range(0, 4). But received {index}')\n\n        if frozen_stages not in range(-1, 4):\n            raise ValueError('frozen_stages must be in range(-1, 4). '\n                             f'But received {frozen_stages}')\n        self.out_indices = out_indices\n        self.frozen_stages = frozen_stages\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n\n        if widen_factor == 0.5:\n            channels = [48, 96, 192, 1024]\n        elif widen_factor == 1.0:\n            channels = [116, 232, 464, 1024]\n        elif widen_factor == 1.5:\n            channels = [176, 352, 704, 1024]\n        elif widen_factor == 2.0:\n            channels = [244, 488, 976, 2048]\n        else:\n            raise ValueError('widen_factor must be in [0.5, 1.0, 1.5, 2.0]. '\n                             f'But received {widen_factor}')\n\n        self.in_channels = 24\n        self.conv1 = ConvModule(\n            in_channels=3,\n            out_channels=self.in_channels,\n            kernel_size=3,\n            stride=2,\n            padding=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n\n        self.layers = nn.ModuleList()\n        for i, num_blocks in enumerate(self.stage_blocks):\n            layer = self._make_layer(channels[i], num_blocks)\n            self.layers.append(layer)\n\n        output_channels = channels[-1]\n        self.layers.append(\n            ConvModule(\n                in_channels=self.in_channels,\n                out_channels=output_channels,\n                kernel_size=1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg))\n\n    def _make_layer(self, out_channels, num_blocks):\n        \"\"\"Stack blocks to make a layer.\n\n        Args:\n            out_channels (int): out_channels of the block.\n            num_blocks (int): number of blocks.\n        \"\"\"\n        layers = []\n        for i in range(num_blocks):\n            stride = 2 if i == 0 else 1\n            layers.append(\n                InvertedResidual(\n                    in_channels=self.in_channels,\n                    out_channels=out_channels,\n                    stride=stride,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    act_cfg=self.act_cfg,\n                    with_cp=self.with_cp))\n            self.in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            for param in self.conv1.parameters():\n                param.requires_grad = False\n\n        for i in range(self.frozen_stages):\n            m = self.layers[i]\n            m.eval()\n            for param in m.parameters():\n                param.requires_grad = False\n\n    def init_weights(self):\n        super(ShuffleNetV2, self).init_weights()\n\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            return\n\n        for name, m in self.named_modules():\n            if isinstance(m, nn.Conv2d) and 'conv1' not in name:\n                nn.init.normal_(m.weight, mean=0, std=1.0 / m.weight.shape[1])\n\n    def forward(self, x):\n        x = self.conv1(x)\n        x = self.maxpool(x)\n\n        outs = []\n        for i, layer in enumerate(self.layers):\n            x = layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n\n        return tuple(outs)\n\n    def train(self, mode=True):\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, nn.BatchNorm2d):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/swin.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import build_norm_layer\nfrom mmcv.cnn.bricks.transformer import FFN, build_dropout\nfrom mmengine.model import BaseModule\nfrom mmengine.model.weight_init import trunc_normal_\nfrom mmengine.runner import load_state_dict\nfrom mmengine.utils import to_2tuple\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils import get_root_logger\nfrom ..utils.transformer import PatchEmbed, PatchMerging\nfrom .base_backbone import BaseBackbone\nfrom .utils import get_state_dict\nfrom .utils.ckpt_convert import swin_converter\n\n\nclass WindowMSA(BaseModule):\n    \"\"\"Window based multi-head self-attention (W-MSA) module with relative\n    position bias.\n\n    Args:\n        embed_dims (int): Number of input channels.\n        num_heads (int): Number of attention heads.\n        window_size (tuple[int]): The height and width of the window.\n        qkv_bias (bool, optional):  If True, add a learnable bias to q, k, v.\n            Default: True.\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        attn_drop_rate (float, optional): Dropout ratio of attention weight.\n            Default: 0.0\n        proj_drop_rate (float, optional): Dropout ratio of output. Default: 0.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 window_size,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 attn_drop_rate=0.,\n                 proj_drop_rate=0.,\n                 init_cfg=None):\n\n        super().__init__(init_cfg=init_cfg)\n        self.embed_dims = embed_dims\n        self.window_size = window_size  # Wh, Ww\n        self.num_heads = num_heads\n        head_embed_dims = embed_dims // num_heads\n        self.scale = qk_scale or head_embed_dims**-0.5\n\n        # define a parameter table of relative position bias\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1),\n                        num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n\n        # About 2x faster than original impl\n        Wh, Ww = self.window_size\n        rel_index_coords = self.double_step_seq(2 * Ww - 1, Wh, 1, Ww)\n        rel_position_index = rel_index_coords + rel_index_coords.T\n        rel_position_index = rel_position_index.flip(1).contiguous()\n        self.register_buffer('relative_position_index', rel_position_index)\n\n        self.qkv = nn.Linear(embed_dims, embed_dims * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop_rate)\n        self.proj = nn.Linear(embed_dims, embed_dims)\n        self.proj_drop = nn.Dropout(proj_drop_rate)\n\n        self.softmax = nn.Softmax(dim=-1)\n\n    def init_weights(self):\n        trunc_normal_(self.relative_position_bias_table, std=0.02)\n\n    def forward(self, x, mask=None):\n        \"\"\"\n        Args:\n\n            x (tensor): input features with shape of (num_windows*B, N, C)\n            mask (tensor | None, Optional): mask with shape of (num_windows,\n                Wh*Ww, Wh*Ww), value should be between (-inf, 0].\n        \"\"\"\n        B, N, C = x.shape\n        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads,\n                                  C // self.num_heads).permute(2, 0, 3, 1, 4)\n        # make torchscript happy (cannot use tensor as tuple)\n        q, k, v = qkv[0], qkv[1], qkv[2]\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        relative_position_bias = self.relative_position_bias_table[\n            self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1],\n                self.window_size[0] * self.window_size[1],\n                -1)  # Wh*Ww,Wh*Ww,nH\n        relative_position_bias = relative_position_bias.permute(\n            2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n        attn = attn + relative_position_bias.unsqueeze(0)\n\n        if mask is not None:\n            nW = mask.shape[0]\n            attn = attn.view(B // nW, nW, self.num_heads, N,\n                             N) + mask.unsqueeze(1).unsqueeze(0)\n            attn = attn.view(-1, self.num_heads, N, N)\n        attn = self.softmax(attn)\n\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n    @staticmethod\n    def double_step_seq(step1, len1, step2, len2):\n        seq1 = torch.arange(0, step1 * len1, step1)\n        seq2 = torch.arange(0, step2 * len2, step2)\n        return (seq1[:, None] + seq2[None, :]).reshape(1, -1)\n\n\nclass ShiftWindowMSA(BaseModule):\n    \"\"\"Shifted Window Multihead Self-Attention Module.\n\n    Args:\n        embed_dims (int): Number of input channels.\n        num_heads (int): Number of attention heads.\n        window_size (int): The height and width of the window.\n        shift_size (int, optional): The shift step of each window towards\n            right-bottom. If zero, act as regular window-msa. Defaults to 0.\n        qkv_bias (bool, optional): If True, add a learnable bias to q, k, v.\n            Default: True\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Defaults: None.\n        attn_drop_rate (float, optional): Dropout ratio of attention weight.\n            Defaults: 0.\n        proj_drop_rate (float, optional): Dropout ratio of output.\n            Defaults: 0.\n        dropout_layer (dict, optional): The dropout_layer used before output.\n            Defaults: dict(type='DropPath', drop_prob=0.).\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 window_size,\n                 shift_size=0,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 attn_drop_rate=0,\n                 proj_drop_rate=0,\n                 dropout_layer=dict(type='DropPath', drop_prob=0.),\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n\n        self.window_size = window_size\n        self.shift_size = shift_size\n        assert 0 <= self.shift_size < self.window_size\n\n        self.w_msa = WindowMSA(\n            embed_dims=embed_dims,\n            num_heads=num_heads,\n            window_size=to_2tuple(window_size),\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop_rate=attn_drop_rate,\n            proj_drop_rate=proj_drop_rate)\n\n        self.drop = build_dropout(dropout_layer)\n\n    def forward(self, query, hw_shape):\n        B, L, C = query.shape\n        H, W = hw_shape\n        assert L == H * W, 'input feature has wrong size'\n        query = query.view(B, H, W, C)\n\n        # pad feature maps to multiples of window size\n        pad_r = (self.window_size - W % self.window_size) % self.window_size\n        pad_b = (self.window_size - H % self.window_size) % self.window_size\n        query = F.pad(query, (0, 0, 0, pad_r, 0, pad_b))\n        H_pad, W_pad = query.shape[1], query.shape[2]\n\n        # cyclic shift\n        if self.shift_size > 0:\n            shifted_query = torch.roll(\n                query,\n                shifts=(-self.shift_size, -self.shift_size),\n                dims=(1, 2))\n\n            # calculate attention mask for SW-MSA\n            img_mask = torch.zeros((1, H_pad, W_pad, 1), device=query.device)\n            h_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            w_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            cnt = 0\n            for h in h_slices:\n                for w in w_slices:\n                    img_mask[:, h, w, :] = cnt\n                    cnt += 1\n\n            # nW, window_size, window_size, 1\n            mask_windows = self.window_partition(img_mask)\n            mask_windows = mask_windows.view(\n                -1, self.window_size * self.window_size)\n            attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)\n            attn_mask = attn_mask.masked_fill(attn_mask != 0,\n                                              float(-100.0)).masked_fill(\n                                                  attn_mask == 0, float(0.0))\n        else:\n            shifted_query = query\n            attn_mask = None\n\n        # nW*B, window_size, window_size, C\n        query_windows = self.window_partition(shifted_query)\n        # nW*B, window_size*window_size, C\n        query_windows = query_windows.view(-1, self.window_size**2, C)\n\n        # W-MSA/SW-MSA (nW*B, window_size*window_size, C)\n        attn_windows = self.w_msa(query_windows, mask=attn_mask)\n\n        # merge windows\n        attn_windows = attn_windows.view(-1, self.window_size,\n                                         self.window_size, C)\n\n        # B H' W' C\n        shifted_x = self.window_reverse(attn_windows, H_pad, W_pad)\n        # reverse cyclic shift\n        if self.shift_size > 0:\n            x = torch.roll(\n                shifted_x,\n                shifts=(self.shift_size, self.shift_size),\n                dims=(1, 2))\n        else:\n            x = shifted_x\n\n        if pad_r > 0 or pad_b:\n            x = x[:, :H, :W, :].contiguous()\n\n        x = x.view(B, H * W, C)\n\n        x = self.drop(x)\n        return x\n\n    def window_reverse(self, windows, H, W):\n        \"\"\"\n        Args:\n            windows: (num_windows*B, window_size, window_size, C)\n            H (int): Height of image\n            W (int): Width of image\n        Returns:\n            x: (B, H, W, C)\n        \"\"\"\n        window_size = self.window_size\n        B = int(windows.shape[0] / (H * W / window_size / window_size))\n        x = windows.view(B, H // window_size, W // window_size, window_size,\n                         window_size, -1)\n        x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)\n        return x\n\n    def window_partition(self, x):\n        \"\"\"\n        Args:\n            x: (B, H, W, C)\n        Returns:\n            windows: (num_windows*B, window_size, window_size, C)\n        \"\"\"\n        B, H, W, C = x.shape\n        window_size = self.window_size\n        x = x.view(B, H // window_size, window_size, W // window_size,\n                   window_size, C)\n        windows = x.permute(0, 1, 3, 2, 4, 5).contiguous()\n        windows = windows.view(-1, window_size, window_size, C)\n        return windows\n\n\nclass SwinBlock(BaseModule):\n    \"\"\"\"\n    Args:\n        embed_dims (int): The feature dimension.\n        num_heads (int): Parallel attention heads.\n        feedforward_channels (int): The hidden dimension for FFNs.\n        window_size (int, optional): The local window scale. Default: 7.\n        shift (bool, optional): whether to shift window or not. Default False.\n        qkv_bias (bool, optional): enable bias for qkv if True. Default: True.\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        drop_rate (float, optional): Dropout rate. Default: 0.\n        attn_drop_rate (float, optional): Attention dropout rate. Default: 0.\n        drop_path_rate (float, optional): Stochastic depth rate. Default: 0.\n        act_cfg (dict, optional): The config dict of activation function.\n            Default: dict(type='GELU').\n        norm_cfg (dict, optional): The config dict of normalization.\n            Default: dict(type='LN').\n        with_cp (bool, optional): Use checkpoint or not. Using checkpoint\n            will save some memory while slowing down the training speed.\n            Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 feedforward_channels,\n                 window_size=7,\n                 shift=False,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.,\n                 act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='LN'),\n                 with_cp=False,\n                 init_cfg=None):\n\n        super(SwinBlock, self).__init__(init_cfg=init_cfg)\n\n        self.with_cp = with_cp\n\n        self.norm1 = build_norm_layer(norm_cfg, embed_dims)[1]\n        self.attn = ShiftWindowMSA(\n            embed_dims=embed_dims,\n            num_heads=num_heads,\n            window_size=window_size,\n            shift_size=window_size // 2 if shift else 0,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop_rate=attn_drop_rate,\n            proj_drop_rate=drop_rate,\n            dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate))\n\n        self.norm2 = build_norm_layer(norm_cfg, embed_dims)[1]\n        self.ffn = FFN(\n            embed_dims=embed_dims,\n            feedforward_channels=feedforward_channels,\n            num_fcs=2,\n            ffn_drop=drop_rate,\n            dropout_layer=dict(type='DropPath', drop_prob=drop_path_rate),\n            act_cfg=act_cfg,\n            add_identity=True,\n            init_cfg=None)\n\n    def forward(self, x, hw_shape):\n\n        def _inner_forward(x):\n            identity = x\n            x = self.norm1(x)\n            x = self.attn(x, hw_shape)\n\n            x = x + identity\n\n            identity = x\n            x = self.norm2(x)\n            x = self.ffn(x, identity=identity)\n\n            return x\n\n        if self.with_cp and x.requires_grad:\n            x = cp.checkpoint(_inner_forward, x)\n        else:\n            x = _inner_forward(x)\n\n        return x\n\n\nclass SwinBlockSequence(BaseModule):\n    \"\"\"Implements one stage in Swin Transformer.\n\n    Args:\n        embed_dims (int): The feature dimension.\n        num_heads (int): Parallel attention heads.\n        feedforward_channels (int): The hidden dimension for FFNs.\n        depth (int): The number of blocks in this stage.\n        window_size (int, optional): The local window scale. Default: 7.\n        qkv_bias (bool, optional): enable bias for qkv if True. Default: True.\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        drop_rate (float, optional): Dropout rate. Default: 0.\n        attn_drop_rate (float, optional): Attention dropout rate. Default: 0.\n        drop_path_rate (float | list[float], optional): Stochastic depth\n            rate. Default: 0.\n        downsample (nn.Module | None, optional): The downsample operation\n            module. Default: None.\n        act_cfg (dict, optional): The config dict of activation function.\n            Default: dict(type='GELU').\n        norm_cfg (dict, optional): The config dict of normalization.\n            Default: dict(type='LN').\n        with_cp (bool, optional): Use checkpoint or not. Using checkpoint\n            will save some memory while slowing down the training speed.\n            Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 embed_dims,\n                 num_heads,\n                 feedforward_channels,\n                 depth,\n                 window_size=7,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.,\n                 downsample=None,\n                 act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='LN'),\n                 with_cp=False,\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n\n        if isinstance(drop_path_rate, list):\n            drop_path_rates = drop_path_rate\n            assert len(drop_path_rates) == depth\n        else:\n            drop_path_rates = [deepcopy(drop_path_rate) for _ in range(depth)]\n\n        self.blocks = nn.ModuleList()\n        for i in range(depth):\n            block = SwinBlock(\n                embed_dims=embed_dims,\n                num_heads=num_heads,\n                feedforward_channels=feedforward_channels,\n                window_size=window_size,\n                shift=False if i % 2 == 0 else True,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop_rate=drop_rate,\n                attn_drop_rate=attn_drop_rate,\n                drop_path_rate=drop_path_rates[i],\n                act_cfg=act_cfg,\n                norm_cfg=norm_cfg,\n                with_cp=with_cp)\n            self.blocks.append(block)\n\n        self.downsample = downsample\n\n    def forward(self, x, hw_shape):\n        for block in self.blocks:\n            x = block(x, hw_shape)\n\n        if self.downsample:\n            x_down, down_hw_shape = self.downsample(x, hw_shape)\n            return x_down, down_hw_shape, x, hw_shape\n        else:\n            return x, hw_shape, x, hw_shape\n\n\n@MODELS.register_module()\nclass SwinTransformer(BaseBackbone):\n    \"\"\" Swin Transformer\n    A PyTorch implement of : `Swin Transformer:\n    Hierarchical Vision Transformer using Shifted Windows`  -\n        https://arxiv.org/abs/2103.14030\n\n    Inspiration from\n    https://github.com/microsoft/Swin-Transformer\n\n    Args:\n        pretrain_img_size (int | tuple[int]): The size of input image when\n            pretrain. Defaults: 224.\n        in_channels (int): The num of input channels.\n            Defaults: 3.\n        embed_dims (int): The feature dimension. Default: 96.\n        patch_size (int | tuple[int]): Patch size. Default: 4.\n        window_size (int): Window size. Default: 7.\n        mlp_ratio (int): Ratio of mlp hidden dim to embedding dim.\n            Default: 4.\n        depths (tuple[int]): Depths of each Swin Transformer stage.\n            Default: (2, 2, 6, 2).\n        num_heads (tuple[int]): Parallel attention heads of each Swin\n            Transformer stage. Default: (3, 6, 12, 24).\n        strides (tuple[int]): The patch merging or patch embedding stride of\n            each Swin Transformer stage. (In swin, we set kernel size equal to\n            stride.) Default: (4, 2, 2, 2).\n        out_indices (tuple[int]): Output from which stages.\n            Default: (0, 1, 2, 3).\n        qkv_bias (bool, optional): If True, add a learnable bias to query, key,\n            value. Default: True\n        qk_scale (float | None, optional): Override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        patch_norm (bool): If add a norm layer for patch embed and patch\n            merging. Default: True.\n        drop_rate (float): Dropout rate. Defaults: 0.\n        attn_drop_rate (float): Attention dropout rate. Default: 0.\n        drop_path_rate (float): Stochastic depth rate. Defaults: 0.1.\n        use_abs_pos_embed (bool): If True, add absolute position embedding to\n            the patch embedding. Defaults: False.\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='LN').\n        norm_cfg (dict): Config dict for normalization layer at\n            output of backone. Defaults: dict(type='LN').\n        with_cp (bool, optional): Use checkpoint or not. Using checkpoint\n            will save some memory while slowing down the training speed.\n            Default: False.\n        pretrained (str, optional): model pretrained path. Default: None.\n        convert_weights (bool): The flag indicates whether the\n            pre-trained model is from the original repo. We may need\n            to convert some keys to make it compatible.\n            Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            Default: -1 (-1 means not freezing any parameters).\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: ``[\n                dict(type='TruncNormal', std=.02, layer=['Linear']),\n                dict(type='Constant', val=1, layer=['LayerNorm']),\n            ]``\n    \"\"\"\n\n    def __init__(self,\n                 pretrain_img_size=224,\n                 in_channels=3,\n                 embed_dims=96,\n                 patch_size=4,\n                 window_size=7,\n                 mlp_ratio=4,\n                 depths=(2, 2, 6, 2),\n                 num_heads=(3, 6, 12, 24),\n                 strides=(4, 2, 2, 2),\n                 out_indices=(0, 1, 2, 3),\n                 qkv_bias=True,\n                 qk_scale=None,\n                 patch_norm=True,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.1,\n                 use_abs_pos_embed=False,\n                 act_cfg=dict(type='GELU'),\n                 norm_cfg=dict(type='LN'),\n                 with_cp=False,\n                 convert_weights=False,\n                 frozen_stages=-1,\n                 init_cfg=[\n                     dict(type='TruncNormal', std=.02, layer=['Linear']),\n                     dict(type='Constant', val=1, layer=['LayerNorm']),\n                 ]):\n        self.convert_weights = convert_weights\n        self.frozen_stages = frozen_stages\n        if isinstance(pretrain_img_size, int):\n            pretrain_img_size = to_2tuple(pretrain_img_size)\n        elif isinstance(pretrain_img_size, tuple):\n            if len(pretrain_img_size) == 1:\n                pretrain_img_size = to_2tuple(pretrain_img_size[0])\n            assert len(pretrain_img_size) == 2, \\\n                f'The size of image should have length 1 or 2, ' \\\n                f'but got {len(pretrain_img_size)}'\n\n        super(SwinTransformer, self).__init__(init_cfg=init_cfg)\n\n        num_layers = len(depths)\n        self.out_indices = out_indices\n        self.use_abs_pos_embed = use_abs_pos_embed\n\n        assert strides[0] == patch_size, 'Use non-overlapping patch embed.'\n\n        self.patch_embed = PatchEmbed(\n            in_channels=in_channels,\n            embed_dims=embed_dims,\n            conv_type='Conv2d',\n            kernel_size=patch_size,\n            stride=strides[0],\n            norm_cfg=norm_cfg if patch_norm else None,\n            init_cfg=None)\n\n        if self.use_abs_pos_embed:\n            patch_row = pretrain_img_size[0] // patch_size\n            patch_col = pretrain_img_size[1] // patch_size\n            num_patches = patch_row * patch_col\n            self.absolute_pos_embed = nn.Parameter(\n                torch.zeros((1, num_patches, embed_dims)))\n\n        self.drop_after_pos = nn.Dropout(p=drop_rate)\n\n        # set stochastic depth decay rule\n        total_depth = sum(depths)\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, total_depth)\n        ]\n\n        self.stages = nn.ModuleList()\n        in_channels = embed_dims\n        for i in range(num_layers):\n            if i < num_layers - 1:\n                downsample = PatchMerging(\n                    in_channels=in_channels,\n                    out_channels=2 * in_channels,\n                    stride=strides[i + 1],\n                    norm_cfg=norm_cfg if patch_norm else None,\n                    init_cfg=None)\n            else:\n                downsample = None\n\n            stage = SwinBlockSequence(\n                embed_dims=in_channels,\n                num_heads=num_heads[i],\n                feedforward_channels=mlp_ratio * in_channels,\n                depth=depths[i],\n                window_size=window_size,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop_rate=drop_rate,\n                attn_drop_rate=attn_drop_rate,\n                drop_path_rate=dpr[sum(depths[:i]):sum(depths[:i + 1])],\n                downsample=downsample,\n                act_cfg=act_cfg,\n                norm_cfg=norm_cfg,\n                with_cp=with_cp)\n            self.stages.append(stage)\n            if downsample:\n                in_channels = downsample.out_channels\n\n        self.num_features = [int(embed_dims * 2**i) for i in range(num_layers)]\n        # Add a norm layer for each output\n        for i in out_indices:\n            layer = build_norm_layer(norm_cfg, self.num_features[i])[1]\n            layer_name = f'norm{i}'\n            self.add_module(layer_name, layer)\n\n    def train(self, mode=True):\n        \"\"\"Convert the model into training mode while keep layers freezed.\"\"\"\n        super(SwinTransformer, self).train(mode)\n        self._freeze_stages()\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            self.patch_embed.eval()\n            for param in self.patch_embed.parameters():\n                param.requires_grad = False\n            if self.use_abs_pos_embed:\n                self.absolute_pos_embed.requires_grad = False\n            self.drop_after_pos.eval()\n\n        for i in range(1, self.frozen_stages + 1):\n\n            if (i - 1) in self.out_indices:\n                norm_layer = getattr(self, f'norm{i-1}')\n                norm_layer.eval()\n                for param in norm_layer.parameters():\n                    param.requires_grad = False\n\n            m = self.stages[i - 1]\n            m.eval()\n            for param in m.parameters():\n                param.requires_grad = False\n\n    def init_weights(self, pretrained=None):\n        \"\"\"Initialize the weights in backbone.\n\n        Args:\n            pretrained (str, optional): Path to pre-trained weights.\n                Defaults to None.\n        \"\"\"\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            # Suppress zero_init_residual if use pretrained model.\n            logger = get_root_logger()\n            state_dict = get_state_dict(\n                self.init_cfg['checkpoint'], map_location='cpu')\n            if self.convert_weights:\n                # supported loading weight from original repo\n                state_dict = swin_converter(state_dict)\n\n            # strip prefix of state_dict\n            if list(state_dict.keys())[0].startswith('module.'):\n                state_dict = {k[7:]: v for k, v in state_dict.items()}\n\n            # reshape absolute position embedding\n            if state_dict.get('absolute_pos_embed') is not None:\n                absolute_pos_embed = state_dict['absolute_pos_embed']\n                N1, L, C1 = absolute_pos_embed.size()\n                N2, C2, H, W = self.absolute_pos_embed.size()\n                if N1 != N2 or C1 != C2 or L != H * W:\n                    logger.warning('Error in loading absolute_pos_embed, pass')\n                else:\n                    state_dict['absolute_pos_embed'] = absolute_pos_embed.view(\n                        N2, H, W, C2).permute(0, 3, 1, 2).contiguous()\n\n            # interpolate position bias table if needed\n            relative_position_bias_table_keys = [\n                k for k in state_dict.keys()\n                if 'relative_position_bias_table' in k\n            ]\n            for table_key in relative_position_bias_table_keys:\n                table_pretrained = state_dict[table_key]\n                table_current = self.state_dict()[table_key]\n                L1, nH1 = table_pretrained.size()\n                L2, nH2 = table_current.size()\n                if nH1 != nH2:\n                    logger.warning(f'Error in loading {table_key}, pass')\n                elif L1 != L2:\n                    S1 = int(L1**0.5)\n                    S2 = int(L2**0.5)\n                    table_pretrained_resized = F.interpolate(\n                        table_pretrained.permute(1, 0).reshape(1, nH1, S1, S1),\n                        size=(S2, S2),\n                        mode='bicubic')\n                    state_dict[table_key] = table_pretrained_resized.view(\n                        nH2, L2).permute(1, 0).contiguous()\n\n            # load state_dict\n            load_state_dict(self, state_dict, strict=False, logger=logger)\n\n        else:\n            super(SwinTransformer, self).init_weights()\n            if self.use_abs_pos_embed:\n                trunc_normal_(self.absolute_pos_embed, std=0.02)\n\n    def forward(self, x):\n        x, hw_shape = self.patch_embed(x)\n\n        if self.use_abs_pos_embed:\n            x = x + self.absolute_pos_embed\n        x = self.drop_after_pos(x)\n\n        outs = []\n        for i, stage in enumerate(self.stages):\n            x, hw_shape, out, out_hw_shape = stage(x, hw_shape)\n            if i in self.out_indices:\n                norm_layer = getattr(self, f'norm{i}')\n                out = norm_layer(out)\n                out = out.view(-1, *out_hw_shape,\n                               self.num_features[i]).permute(0, 3, 1,\n                                                             2).contiguous()\n                outs.append(out)\n\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/backbones/tcn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, build_conv_layer\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom ..utils.regularizations import WeightNormClipHook\nfrom .base_backbone import BaseBackbone\n\n\nclass BasicTemporalBlock(BaseModule):\n    \"\"\"Basic block for VideoPose3D.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        mid_channels (int): The output channels of conv1. Default: 1024.\n        kernel_size (int): Size of the convolving kernel. Default: 3.\n        dilation (int): Spacing between kernel elements. Default: 3.\n        dropout (float): Dropout rate. Default: 0.25.\n        causal (bool): Use causal convolutions instead of symmetric\n            convolutions (for real-time applications). Default: False.\n        residual (bool): Use residual connection. Default: True.\n        use_stride_conv (bool): Use optimized TCN that designed\n            specifically for single-frame batching, i.e. where batches have\n            input length = receptive field, and output length = 1. This\n            implementation replaces dilated convolutions with strided\n            convolutions to avoid generating unused intermediate results.\n            Default: False.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: dict(type='Conv1d').\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN1d').\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 mid_channels=1024,\n                 kernel_size=3,\n                 dilation=3,\n                 dropout=0.25,\n                 causal=False,\n                 residual=True,\n                 use_stride_conv=False,\n                 conv_cfg=dict(type='Conv1d'),\n                 norm_cfg=dict(type='BN1d'),\n                 init_cfg=None):\n        # Protect mutable default arguments\n        conv_cfg = copy.deepcopy(conv_cfg)\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.mid_channels = mid_channels\n        self.kernel_size = kernel_size\n        self.dilation = dilation\n        self.dropout = dropout\n        self.causal = causal\n        self.residual = residual\n        self.use_stride_conv = use_stride_conv\n\n        self.pad = (kernel_size - 1) * dilation // 2\n        if use_stride_conv:\n            self.stride = kernel_size\n            self.causal_shift = kernel_size // 2 if causal else 0\n            self.dilation = 1\n        else:\n            self.stride = 1\n            self.causal_shift = kernel_size // 2 * dilation if causal else 0\n\n        self.conv1 = nn.Sequential(\n            ConvModule(\n                in_channels,\n                mid_channels,\n                kernel_size=kernel_size,\n                stride=self.stride,\n                dilation=self.dilation,\n                bias='auto',\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg))\n        self.conv2 = nn.Sequential(\n            ConvModule(\n                mid_channels,\n                out_channels,\n                kernel_size=1,\n                bias='auto',\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg))\n\n        if residual and in_channels != out_channels:\n            self.short_cut = build_conv_layer(conv_cfg, in_channels,\n                                              out_channels, 1)\n        else:\n            self.short_cut = None\n\n        self.dropout = nn.Dropout(dropout) if dropout > 0 else None\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        if self.use_stride_conv:\n            assert self.causal_shift + self.kernel_size // 2 < x.shape[2]\n        else:\n            assert 0 <= self.pad + self.causal_shift < x.shape[2] - \\\n                self.pad + self.causal_shift <= x.shape[2]\n\n        out = self.conv1(x)\n        if self.dropout is not None:\n            out = self.dropout(out)\n\n        out = self.conv2(out)\n        if self.dropout is not None:\n            out = self.dropout(out)\n\n        if self.residual:\n            if self.use_stride_conv:\n                res = x[:, :, self.causal_shift +\n                        self.kernel_size // 2::self.kernel_size]\n            else:\n                res = x[:, :,\n                        (self.pad + self.causal_shift):(x.shape[2] - self.pad +\n                                                        self.causal_shift)]\n\n            if self.short_cut is not None:\n                res = self.short_cut(res)\n            out = out + res\n\n        return out\n\n\n@MODELS.register_module()\nclass TCN(BaseBackbone):\n    \"\"\"TCN backbone.\n\n    Temporal Convolutional Networks.\n    More details can be found in the\n    `paper <https://arxiv.org/abs/1811.11742>`__ .\n\n    Args:\n        in_channels (int): Number of input channels, which equals to\n            num_keypoints * num_features.\n        stem_channels (int): Number of feature channels. Default: 1024.\n        num_blocks (int): NUmber of basic temporal convolutional blocks.\n            Default: 2.\n        kernel_sizes (Sequence[int]): Sizes of the convolving kernel of\n            each basic block. Default: ``(3, 3, 3)``.\n        dropout (float): Dropout rate. Default: 0.25.\n        causal (bool): Use causal convolutions instead of symmetric\n            convolutions (for real-time applications).\n            Default: False.\n        residual (bool): Use residual connection. Default: True.\n        use_stride_conv (bool): Use TCN backbone optimized for\n            single-frame batching, i.e. where batches have input length =\n            receptive field, and output length = 1. This implementation\n            replaces dilated convolutions with strided convolutions to avoid\n            generating unused intermediate results. The weights are\n            interchangeable with the reference implementation. Default: False\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: dict(type='Conv1d').\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN1d').\n        max_norm (float|None): if not None, the weight of convolution layers\n            will be clipped to have a maximum norm of max_norm.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(\n                    type='Kaiming',\n                    mode='fan_in',\n                    nonlinearity='relu',\n                    layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n\n    Example:\n        >>> from mmpose.models import TCN\n        >>> import torch\n        >>> self = TCN(in_channels=34)\n        >>> self.eval()\n        >>> inputs = torch.rand(1, 34, 243)\n        >>> level_outputs = self.forward(inputs)\n        >>> for level_out in level_outputs:\n        ...     print(tuple(level_out.shape))\n        (1, 1024, 235)\n        (1, 1024, 217)\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 stem_channels=1024,\n                 num_blocks=2,\n                 kernel_sizes=(3, 3, 3),\n                 dropout=0.25,\n                 causal=False,\n                 residual=True,\n                 use_stride_conv=False,\n                 conv_cfg=dict(type='Conv1d'),\n                 norm_cfg=dict(type='BN1d'),\n                 max_norm=None,\n                 init_cfg=[\n                     dict(\n                         type='Kaiming',\n                         mode='fan_in',\n                         nonlinearity='relu',\n                         layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        conv_cfg = copy.deepcopy(conv_cfg)\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__()\n        self.in_channels = in_channels\n        self.stem_channels = stem_channels\n        self.num_blocks = num_blocks\n        self.kernel_sizes = kernel_sizes\n        self.dropout = dropout\n        self.causal = causal\n        self.residual = residual\n        self.use_stride_conv = use_stride_conv\n        self.max_norm = max_norm\n\n        assert num_blocks == len(kernel_sizes) - 1\n        for ks in kernel_sizes:\n            assert ks % 2 == 1, 'Only odd filter widths are supported.'\n\n        self.expand_conv = ConvModule(\n            in_channels,\n            stem_channels,\n            kernel_size=kernel_sizes[0],\n            stride=kernel_sizes[0] if use_stride_conv else 1,\n            bias='auto',\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg)\n\n        dilation = kernel_sizes[0]\n        self.tcn_blocks = nn.ModuleList()\n        for i in range(1, num_blocks + 1):\n            self.tcn_blocks.append(\n                BasicTemporalBlock(\n                    in_channels=stem_channels,\n                    out_channels=stem_channels,\n                    mid_channels=stem_channels,\n                    kernel_size=kernel_sizes[i],\n                    dilation=dilation,\n                    dropout=dropout,\n                    causal=causal,\n                    residual=residual,\n                    use_stride_conv=use_stride_conv,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg))\n            dilation *= kernel_sizes[i]\n\n        if self.max_norm is not None:\n            # Apply weight norm clip to conv layers\n            weight_clip = WeightNormClipHook(self.max_norm)\n            for module in self.modules():\n                if isinstance(module, nn.modules.conv._ConvNd):\n                    weight_clip.register(module)\n\n        self.dropout = nn.Dropout(dropout) if dropout > 0 else None\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        x = self.expand_conv(x)\n\n        if self.dropout is not None:\n            x = self.dropout(x)\n\n        outs = []\n        for i in range(self.num_blocks):\n            x = self.tcn_blocks[i](x)\n            outs.append(x)\n\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/backbones/utils/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .channel_shuffle import channel_shuffle\nfrom .inverted_residual import InvertedResidual\nfrom .make_divisible import make_divisible\nfrom .se_layer import SELayer\nfrom .utils import get_state_dict, load_checkpoint\n\n__all__ = [\n    'channel_shuffle', 'make_divisible', 'InvertedResidual', 'SELayer',\n    'load_checkpoint', 'get_state_dict'\n]\n"
  },
  {
    "path": "mmpose/models/backbones/utils/channel_shuffle.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\n\n\ndef channel_shuffle(x, groups):\n    \"\"\"Channel Shuffle operation.\n\n    This function enables cross-group information flow for multiple groups\n    convolution layers.\n\n    Args:\n        x (Tensor): The input tensor.\n        groups (int): The number of groups to divide the input tensor\n            in the channel dimension.\n\n    Returns:\n        Tensor: The output tensor after channel shuffle operation.\n    \"\"\"\n\n    batch_size, num_channels, height, width = x.size()\n    assert (num_channels % groups == 0), ('num_channels should be '\n                                          'divisible by groups')\n    channels_per_group = num_channels // groups\n\n    x = x.view(batch_size, groups, channels_per_group, height, width)\n    x = torch.transpose(x, 1, 2).contiguous()\n    x = x.view(batch_size, groups * channels_per_group, height, width)\n\n    return x\n"
  },
  {
    "path": "mmpose/models/backbones/utils/ckpt_convert.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\n# This script consists of several convert functions which\n# can modify the weights of model in original repo to be\n# pre-trained weights.\n\nfrom collections import OrderedDict\n\n\ndef swin_converter(ckpt):\n\n    new_ckpt = OrderedDict()\n\n    def correct_unfold_reduction_order(x):\n        out_channel, in_channel = x.shape\n        x = x.reshape(out_channel, 4, in_channel // 4)\n        x = x[:, [0, 2, 1, 3], :].transpose(1,\n                                            2).reshape(out_channel, in_channel)\n        return x\n\n    def correct_unfold_norm_order(x):\n        in_channel = x.shape[0]\n        x = x.reshape(4, in_channel // 4)\n        x = x[[0, 2, 1, 3], :].transpose(0, 1).reshape(in_channel)\n        return x\n\n    for k, v in ckpt.items():\n        if k.startswith('head'):\n            continue\n        elif k.startswith('layers'):\n            new_v = v\n            if 'attn.' in k:\n                new_k = k.replace('attn.', 'attn.w_msa.')\n            elif 'mlp.' in k:\n                if 'mlp.fc1.' in k:\n                    new_k = k.replace('mlp.fc1.', 'ffn.layers.0.0.')\n                elif 'mlp.fc2.' in k:\n                    new_k = k.replace('mlp.fc2.', 'ffn.layers.1.')\n                else:\n                    new_k = k.replace('mlp.', 'ffn.')\n            elif 'downsample' in k:\n                new_k = k\n                if 'reduction.' in k:\n                    new_v = correct_unfold_reduction_order(v)\n                elif 'norm.' in k:\n                    new_v = correct_unfold_norm_order(v)\n            else:\n                new_k = k\n            new_k = new_k.replace('layers', 'stages', 1)\n        elif k.startswith('patch_embed'):\n            new_v = v\n            if 'proj' in k:\n                new_k = k.replace('proj', 'projection')\n            else:\n                new_k = k\n        else:\n            new_v = v\n            new_k = k\n\n        new_ckpt['backbone.' + new_k] = new_v\n\n    return new_ckpt\n"
  },
  {
    "path": "mmpose/models/backbones/utils/inverted_residual.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import ConvModule\n\nfrom .se_layer import SELayer\n\n\nclass InvertedResidual(nn.Module):\n    \"\"\"Inverted Residual Block.\n\n    Args:\n        in_channels (int): The input channels of this Module.\n        out_channels (int): The output channels of this Module.\n        mid_channels (int): The input channels of the depthwise convolution.\n        kernel_size (int): The kernel size of the depthwise convolution.\n            Default: 3.\n        groups (None or int): The group number of the depthwise convolution.\n            Default: None, which means group number = mid_channels.\n        stride (int): The stride of the depthwise convolution. Default: 1.\n        se_cfg (dict): Config dict for se layer. Default: None, which means no\n            se layer.\n        with_expand_conv (bool): Use expand conv or not. If set False,\n            mid_channels must be the same with in_channels.\n            Default: True.\n        conv_cfg (dict): Config dict for convolution layer. Default: None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='ReLU').\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n\n    Returns:\n        Tensor: The output tensor.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 mid_channels,\n                 kernel_size=3,\n                 groups=None,\n                 stride=1,\n                 se_cfg=None,\n                 with_expand_conv=True,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 with_cp=False):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        act_cfg = copy.deepcopy(act_cfg)\n        super().__init__()\n        self.with_res_shortcut = (stride == 1 and in_channels == out_channels)\n        assert stride in [1, 2]\n        self.with_cp = with_cp\n        self.with_se = se_cfg is not None\n        self.with_expand_conv = with_expand_conv\n\n        if groups is None:\n            groups = mid_channels\n\n        if self.with_se:\n            assert isinstance(se_cfg, dict)\n        if not self.with_expand_conv:\n            assert mid_channels == in_channels\n\n        if self.with_expand_conv:\n            self.expand_conv = ConvModule(\n                in_channels=in_channels,\n                out_channels=mid_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n        self.depthwise_conv = ConvModule(\n            in_channels=mid_channels,\n            out_channels=mid_channels,\n            kernel_size=kernel_size,\n            stride=stride,\n            padding=kernel_size // 2,\n            groups=groups,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        if self.with_se:\n            self.se = SELayer(**se_cfg)\n        self.linear_conv = ConvModule(\n            in_channels=mid_channels,\n            out_channels=out_channels,\n            kernel_size=1,\n            stride=1,\n            padding=0,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=None)\n\n    def forward(self, x):\n\n        def _inner_forward(x):\n            out = x\n\n            if self.with_expand_conv:\n                out = self.expand_conv(out)\n\n            out = self.depthwise_conv(out)\n\n            if self.with_se:\n                out = self.se(out)\n\n            out = self.linear_conv(out)\n\n            if self.with_res_shortcut:\n                return x + out\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        return out\n"
  },
  {
    "path": "mmpose/models/backbones/utils/make_divisible.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\ndef make_divisible(value, divisor, min_value=None, min_ratio=0.9):\n    \"\"\"Make divisible function.\n\n    This function rounds the channel number down to the nearest value that can\n    be divisible by the divisor.\n\n    Args:\n        value (int): The original channel number.\n        divisor (int): The divisor to fully divide the channel number.\n        min_value (int, optional): The minimum value of the output channel.\n            Default: None, means that the minimum value equal to the divisor.\n        min_ratio (float, optional): The minimum ratio of the rounded channel\n            number to the original channel number. Default: 0.9.\n    Returns:\n        int: The modified output channel number\n    \"\"\"\n\n    if min_value is None:\n        min_value = divisor\n    new_value = max(min_value, int(value + divisor / 2) // divisor * divisor)\n    # Make sure that round down does not go down by more than (1-min_ratio).\n    if new_value < min_ratio * value:\n        new_value += divisor\n    return new_value\n"
  },
  {
    "path": "mmpose/models/backbones/utils/se_layer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport mmengine\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule\n\n\nclass SELayer(nn.Module):\n    \"\"\"Squeeze-and-Excitation Module.\n\n    Args:\n        channels (int): The input (and output) channels of the SE layer.\n        ratio (int): Squeeze ratio in SELayer, the intermediate channel will be\n            ``int(channels/ratio)``. Default: 16.\n        conv_cfg (None or dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        act_cfg (dict or Sequence[dict]): Config dict for activation layer.\n            If act_cfg is a dict, two activation layers will be configurated\n            by this dict. If act_cfg is a sequence of dicts, the first\n            activation layer will be configurated by the first dict and the\n            second activation layer will be configurated by the second dict.\n            Default: (dict(type='ReLU'), dict(type='Sigmoid'))\n    \"\"\"\n\n    def __init__(self,\n                 channels,\n                 ratio=16,\n                 conv_cfg=None,\n                 act_cfg=(dict(type='ReLU'), dict(type='Sigmoid'))):\n        super().__init__()\n        if isinstance(act_cfg, dict):\n            act_cfg = (act_cfg, act_cfg)\n        assert len(act_cfg) == 2\n        assert mmengine.is_tuple_of(act_cfg, dict)\n        self.global_avgpool = nn.AdaptiveAvgPool2d(1)\n        self.conv1 = ConvModule(\n            in_channels=channels,\n            out_channels=int(channels / ratio),\n            kernel_size=1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            act_cfg=act_cfg[0])\n        self.conv2 = ConvModule(\n            in_channels=int(channels / ratio),\n            out_channels=channels,\n            kernel_size=1,\n            stride=1,\n            conv_cfg=conv_cfg,\n            act_cfg=act_cfg[1])\n\n    def forward(self, x):\n        out = self.global_avgpool(x)\n        out = self.conv1(out)\n        out = self.conv2(out)\n        return x * out\n"
  },
  {
    "path": "mmpose/models/backbones/utils/utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import OrderedDict\n\nfrom mmengine.runner import CheckpointLoader, load_state_dict\n\n\ndef load_checkpoint(model,\n                    filename,\n                    map_location='cpu',\n                    strict=False,\n                    logger=None):\n    \"\"\"Load checkpoint from a file or URI.\n\n    Args:\n        model (Module): Module to load checkpoint.\n        filename (str): Accept local filepath, URL, ``torchvision://xxx``,\n            ``open-mmlab://xxx``.\n        map_location (str): Same as :func:`torch.load`.\n        strict (bool): Whether to allow different params for the model and\n            checkpoint.\n        logger (:mod:`logging.Logger` or None): The logger for error message.\n\n    Returns:\n        dict or OrderedDict: The loaded checkpoint.\n    \"\"\"\n    checkpoint = CheckpointLoader.load_checkpoint(filename, map_location)\n    # OrderedDict is a subclass of dict\n    if not isinstance(checkpoint, dict):\n        raise RuntimeError(\n            f'No state_dict found in checkpoint file {filename}')\n    # get state_dict from checkpoint\n    if 'state_dict' in checkpoint:\n        state_dict_tmp = checkpoint['state_dict']\n    elif 'model' in checkpoint:\n        state_dict_tmp = checkpoint['model']\n    else:\n        state_dict_tmp = checkpoint\n\n    state_dict = OrderedDict()\n    # strip prefix of state_dict\n    for k, v in state_dict_tmp.items():\n        if k.startswith('module.backbone.'):\n            state_dict[k[16:]] = v\n        elif k.startswith('module.'):\n            state_dict[k[7:]] = v\n        elif k.startswith('backbone.'):\n            state_dict[k[9:]] = v\n        else:\n            state_dict[k] = v\n    # load state_dict\n    load_state_dict(model, state_dict, strict, logger)\n    return checkpoint\n\n\ndef get_state_dict(filename, map_location='cpu'):\n    \"\"\"Get state_dict from a file or URI.\n\n    Args:\n        filename (str): Accept local filepath, URL, ``torchvision://xxx``,\n            ``open-mmlab://xxx``.\n        map_location (str): Same as :func:`torch.load`.\n\n    Returns:\n        OrderedDict: The state_dict.\n    \"\"\"\n    checkpoint = CheckpointLoader.load_checkpoint(filename, map_location)\n    # OrderedDict is a subclass of dict\n    if not isinstance(checkpoint, dict):\n        raise RuntimeError(\n            f'No state_dict found in checkpoint file {filename}')\n    # get state_dict from checkpoint\n    if 'state_dict' in checkpoint:\n        state_dict_tmp = checkpoint['state_dict']\n    else:\n        state_dict_tmp = checkpoint\n\n    state_dict = OrderedDict()\n    # strip prefix of state_dict\n    for k, v in state_dict_tmp.items():\n        if k.startswith('module.backbone.'):\n            state_dict[k[16:]] = v\n        elif k.startswith('module.'):\n            state_dict[k[7:]] = v\n        elif k.startswith('backbone.'):\n            state_dict[k[9:]] = v\n        else:\n            state_dict[k] = v\n\n    return state_dict\n"
  },
  {
    "path": "mmpose/models/backbones/v2v_net.py",
    "content": "# ------------------------------------------------------------------------------\n# Copyright and License Information\n# Adapted from\n# https://github.com/microsoft/voxelpose-pytorch/blob/main/lib/models/v2v_net.py\n# Original Licence: MIT License\n# ------------------------------------------------------------------------------\n\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass Basic3DBlock(BaseModule):\n    \"\"\"A basic 3D convolutional block.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        kernel_size (int): Kernel size of the convolution operation\n        conv_cfg (dict): Dictionary to construct and config conv layer.\n            Default: dict(type='Conv3d')\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n            Default: dict(type='BN3d')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size,\n                 conv_cfg=dict(type='Conv3d'),\n                 norm_cfg=dict(type='BN3d'),\n                 init_cfg=None):\n        super(Basic3DBlock, self).__init__(init_cfg=init_cfg)\n        self.block = ConvModule(\n            in_channels,\n            out_channels,\n            kernel_size,\n            stride=1,\n            padding=((kernel_size - 1) // 2),\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            bias=True)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        return self.block(x)\n\n\nclass Res3DBlock(BaseModule):\n    \"\"\"A residual 3D convolutional block.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        kernel_size (int): Kernel size of the convolution operation\n            Default: 3\n        conv_cfg (dict): Dictionary to construct and config conv layer.\n            Default: dict(type='Conv3d')\n        norm_cfg (dict): Dictionary to construct and config norm layer.\n            Default: dict(type='BN3d')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size=3,\n                 conv_cfg=dict(type='Conv3d'),\n                 norm_cfg=dict(type='BN3d'),\n                 init_cfg=None):\n        super(Res3DBlock, self).__init__(init_cfg=init_cfg)\n        self.res_branch = nn.Sequential(\n            ConvModule(\n                in_channels,\n                out_channels,\n                kernel_size,\n                stride=1,\n                padding=((kernel_size - 1) // 2),\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                bias=True),\n            ConvModule(\n                out_channels,\n                out_channels,\n                kernel_size,\n                stride=1,\n                padding=((kernel_size - 1) // 2),\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None,\n                bias=True))\n\n        if in_channels == out_channels:\n            self.skip_con = nn.Sequential()\n        else:\n            self.skip_con = ConvModule(\n                in_channels,\n                out_channels,\n                1,\n                stride=1,\n                padding=0,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=None,\n                bias=True)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        res = self.res_branch(x)\n        skip = self.skip_con(x)\n        return F.relu(res + skip, True)\n\n\nclass Pool3DBlock(BaseModule):\n    \"\"\"A 3D max-pool block.\n\n    Args:\n        pool_size (int): Pool size of the 3D max-pool layer\n    \"\"\"\n\n    def __init__(self, pool_size):\n        super(Pool3DBlock, self).__init__()\n        self.pool_size = pool_size\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        return F.max_pool3d(\n            x, kernel_size=self.pool_size, stride=self.pool_size)\n\n\nclass Upsample3DBlock(BaseModule):\n    \"\"\"A 3D upsample block.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        kernel_size (int): Kernel size of the transposed convolution operation.\n            Default: 2\n        stride (int):  Kernel size of the transposed convolution operation.\n            Default: 2\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size=2,\n                 stride=2,\n                 init_cfg=None):\n        super(Upsample3DBlock, self).__init__(init_cfg=init_cfg)\n        assert kernel_size == 2\n        assert stride == 2\n        self.block = nn.Sequential(\n            nn.ConvTranspose3d(\n                in_channels,\n                out_channels,\n                kernel_size=kernel_size,\n                stride=stride,\n                padding=0,\n                output_padding=0), nn.BatchNorm3d(out_channels), nn.ReLU(True))\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        return self.block(x)\n\n\nclass EncoderDecorder(BaseModule):\n    \"\"\"An encoder-decoder block.\n\n    Args:\n        in_channels (int): Input channels of this block\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self, in_channels=32, init_cfg=None):\n        super(EncoderDecorder, self).__init__(init_cfg=init_cfg)\n\n        self.encoder_pool1 = Pool3DBlock(2)\n        self.encoder_res1 = Res3DBlock(in_channels, in_channels * 2)\n        self.encoder_pool2 = Pool3DBlock(2)\n        self.encoder_res2 = Res3DBlock(in_channels * 2, in_channels * 4)\n\n        self.mid_res = Res3DBlock(in_channels * 4, in_channels * 4)\n\n        self.decoder_res2 = Res3DBlock(in_channels * 4, in_channels * 4)\n        self.decoder_upsample2 = Upsample3DBlock(in_channels * 4,\n                                                 in_channels * 2, 2, 2)\n        self.decoder_res1 = Res3DBlock(in_channels * 2, in_channels * 2)\n        self.decoder_upsample1 = Upsample3DBlock(in_channels * 2, in_channels,\n                                                 2, 2)\n\n        self.skip_res1 = Res3DBlock(in_channels, in_channels)\n        self.skip_res2 = Res3DBlock(in_channels * 2, in_channels * 2)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        skip_x1 = self.skip_res1(x)\n        x = self.encoder_pool1(x)\n        x = self.encoder_res1(x)\n\n        skip_x2 = self.skip_res2(x)\n        x = self.encoder_pool2(x)\n        x = self.encoder_res2(x)\n\n        x = self.mid_res(x)\n\n        x = self.decoder_res2(x)\n        x = self.decoder_upsample2(x)\n        x = x + skip_x2\n\n        x = self.decoder_res1(x)\n        x = self.decoder_upsample1(x)\n        x = x + skip_x1\n\n        return x\n\n\n@MODELS.register_module()\nclass V2VNet(BaseBackbone):\n    \"\"\"V2VNet.\n\n    Please refer to the `paper <https://arxiv.org/abs/1711.07399>`\n        for details.\n\n    Args:\n        input_channels (int):\n            Number of channels of the input feature volume.\n        output_channels (int):\n            Number of channels of the output volume.\n        mid_channels (int):\n            Input and output channels of the encoder-decoder block.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: ``dict(\n                type='Normal',\n                std=0.001,\n                layer=['Conv3d', 'ConvTranspose3d']\n            )``\n    \"\"\"\n\n    def __init__(self,\n                 input_channels,\n                 output_channels,\n                 mid_channels=32,\n                 init_cfg=dict(\n                     type='Normal',\n                     std=0.001,\n                     layer=['Conv3d', 'ConvTranspose3d'])):\n        super(V2VNet, self).__init__(init_cfg=init_cfg)\n\n        self.front_layers = nn.Sequential(\n            Basic3DBlock(input_channels, mid_channels // 2, 7),\n            Res3DBlock(mid_channels // 2, mid_channels),\n        )\n\n        self.encoder_decoder = EncoderDecorder(in_channels=mid_channels)\n\n        self.output_layer = nn.Conv3d(\n            mid_channels, output_channels, kernel_size=1, stride=1, padding=0)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        x = self.front_layers(x)\n        x = self.encoder_decoder(x)\n        x = self.output_layer(x)\n\n        return (x, )\n"
  },
  {
    "path": "mmpose/models/backbones/vgg.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\ndef make_vgg_layer(in_channels,\n                   out_channels,\n                   num_blocks,\n                   conv_cfg=None,\n                   norm_cfg=None,\n                   act_cfg=dict(type='ReLU'),\n                   dilation=1,\n                   with_norm=False,\n                   ceil_mode=False):\n    layers = []\n    for _ in range(num_blocks):\n        layer = ConvModule(\n            in_channels=in_channels,\n            out_channels=out_channels,\n            kernel_size=3,\n            dilation=dilation,\n            padding=dilation,\n            bias=True,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        layers.append(layer)\n        in_channels = out_channels\n    layers.append(nn.MaxPool2d(kernel_size=2, stride=2, ceil_mode=ceil_mode))\n\n    return layers\n\n\n@MODELS.register_module()\nclass VGG(BaseBackbone):\n    \"\"\"VGG backbone.\n\n    Args:\n        depth (int): Depth of vgg, from {11, 13, 16, 19}.\n        with_norm (bool): Use BatchNorm or not.\n        num_classes (int): number of classes for classification.\n        num_stages (int): VGG stages, normally 5.\n        dilations (Sequence[int]): Dilation of each stage.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. When it is None, the default behavior depends on\n            whether num_classes is specified. If num_classes <= 0, the default\n            value is (4, ), outputting the last feature map before classifier.\n            If num_classes > 0, the default value is (5, ), outputting the\n            classification score. Default: None.\n        frozen_stages (int): Stages to be frozen (all param fixed). -1 means\n            not freezing any parameters.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        ceil_mode (bool): Whether to use ceil_mode of MaxPool. Default: False.\n        with_last_pool (bool): Whether to keep the last pooling before\n            classifier. Default: True.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Kaiming', layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm']),\n                dict(\n                    type='Normal',\n                    std=0.01,\n                    layer=['Linear']),\n            ]``\n    \"\"\"\n\n    # Parameters to build layers. Each element specifies the number of conv in\n    # each stage. For example, VGG11 contains 11 layers with learnable\n    # parameters. 11 is computed as 11 = (1 + 1 + 2 + 2 + 2) + 3,\n    # where 3 indicates the last three fully-connected layers.\n    arch_settings = {\n        11: (1, 1, 2, 2, 2),\n        13: (2, 2, 2, 2, 2),\n        16: (2, 2, 3, 3, 3),\n        19: (2, 2, 4, 4, 4)\n    }\n\n    def __init__(self,\n                 depth,\n                 num_classes=-1,\n                 num_stages=5,\n                 dilations=(1, 1, 1, 1, 1),\n                 out_indices=None,\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=None,\n                 act_cfg=dict(type='ReLU'),\n                 norm_eval=False,\n                 ceil_mode=False,\n                 with_last_pool=True,\n                 init_cfg=[\n                     dict(type='Kaiming', layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm']),\n                     dict(type='Normal', std=0.01, layer=['Linear']),\n                 ]):\n        super().__init__(init_cfg=init_cfg)\n        if depth not in self.arch_settings:\n            raise KeyError(f'invalid depth {depth} for vgg')\n        assert num_stages >= 1 and num_stages <= 5\n        stage_blocks = self.arch_settings[depth]\n        self.stage_blocks = stage_blocks[:num_stages]\n        assert len(dilations) == num_stages\n\n        self.num_classes = num_classes\n        self.frozen_stages = frozen_stages\n        self.norm_eval = norm_eval\n        with_norm = norm_cfg is not None\n\n        if out_indices is None:\n            out_indices = (5, ) if num_classes > 0 else (4, )\n        assert max(out_indices) <= num_stages\n        self.out_indices = out_indices\n\n        self.in_channels = 3\n        start_idx = 0\n        vgg_layers = []\n        self.range_sub_modules = []\n        for i, num_blocks in enumerate(self.stage_blocks):\n            num_modules = num_blocks + 1\n            end_idx = start_idx + num_modules\n            dilation = dilations[i]\n            out_channels = 64 * 2**i if i < 4 else 512\n            vgg_layer = make_vgg_layer(\n                self.in_channels,\n                out_channels,\n                num_blocks,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg,\n                dilation=dilation,\n                with_norm=with_norm,\n                ceil_mode=ceil_mode)\n            vgg_layers.extend(vgg_layer)\n            self.in_channels = out_channels\n            self.range_sub_modules.append([start_idx, end_idx])\n            start_idx = end_idx\n        if not with_last_pool:\n            vgg_layers.pop(-1)\n            self.range_sub_modules[-1][1] -= 1\n        self.module_name = 'features'\n        self.add_module(self.module_name, nn.Sequential(*vgg_layers))\n\n        if self.num_classes > 0:\n            self.classifier = nn.Sequential(\n                nn.Linear(512 * 7 * 7, 4096),\n                nn.ReLU(True),\n                nn.Dropout(),\n                nn.Linear(4096, 4096),\n                nn.ReLU(True),\n                nn.Dropout(),\n                nn.Linear(4096, num_classes),\n            )\n\n    def forward(self, x):\n        outs = []\n        vgg_layers = getattr(self, self.module_name)\n        for i in range(len(self.stage_blocks)):\n            for j in range(*self.range_sub_modules[i]):\n                vgg_layer = vgg_layers[j]\n                x = vgg_layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n        if self.num_classes > 0:\n            x = x.view(x.size(0), -1)\n            x = self.classifier(x)\n            outs.append(x)\n\n        return tuple(outs)\n\n    def _freeze_stages(self):\n        vgg_layers = getattr(self, self.module_name)\n        for i in range(self.frozen_stages):\n            for j in range(*self.range_sub_modules[i]):\n                m = vgg_layers[j]\n                m.eval()\n                for param in m.parameters():\n                    param.requires_grad = False\n\n    def train(self, mode=True):\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                # trick: eval have effect on BatchNorm only\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/vipnas_mbv3.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nfrom mmcv.cnn import ConvModule\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\nfrom .utils import InvertedResidual\n\n\n@MODELS.register_module()\nclass ViPNAS_MobileNetV3(BaseBackbone):\n    \"\"\"ViPNAS_MobileNetV3 backbone.\n\n    \"ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\"\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2105.10154>`__ .\n\n    Args:\n        wid (list(int)): Searched width config for each stage.\n        expan (list(int)): Searched expansion ratio config for each stage.\n        dep (list(int)): Searched depth config for each stage.\n        ks (list(int)): Searched kernel size config for each stage.\n        group (list(int)): Searched group number config for each stage.\n        att (list(bool)): Searched attention config for each stage.\n        stride (list(int)): Stride config for each stage.\n        act (list(dict)): Activation config for each stage.\n        conv_cfg (dict): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN').\n        frozen_stages (int): Stages to be frozen (all param fixed).\n            Default: -1, which means not freezing any parameters.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save\n            some memory while slowing down the training speed.\n            Default: False.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n    \"\"\"\n\n    def __init__(\n        self,\n        wid=[16, 16, 24, 40, 80, 112, 160],\n        expan=[None, 1, 5, 4, 5, 5, 6],\n        dep=[None, 1, 4, 4, 4, 4, 4],\n        ks=[3, 3, 7, 7, 5, 7, 5],\n        group=[None, 8, 120, 20, 100, 280, 240],\n        att=[None, True, True, False, True, True, True],\n        stride=[2, 1, 2, 2, 2, 1, 2],\n        act=['HSwish', 'ReLU', 'ReLU', 'ReLU', 'HSwish', 'HSwish', 'HSwish'],\n        conv_cfg=None,\n        norm_cfg=dict(type='BN'),\n        frozen_stages=-1,\n        norm_eval=False,\n        with_cp=False,\n        init_cfg=[\n            dict(type='Normal', std=0.001, layer=['Conv2d']),\n            dict(type='Constant', val=1, layer=['_BatchNorm', 'GroupNorm'])\n        ],\n    ):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        self.wid = wid\n        self.expan = expan\n        self.dep = dep\n        self.ks = ks\n        self.group = group\n        self.att = att\n        self.stride = stride\n        self.act = act\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.frozen_stages = frozen_stages\n        self.norm_eval = norm_eval\n        self.with_cp = with_cp\n\n        self.conv1 = ConvModule(\n            in_channels=3,\n            out_channels=self.wid[0],\n            kernel_size=self.ks[0],\n            stride=self.stride[0],\n            padding=self.ks[0] // 2,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=dict(type=self.act[0]))\n\n        self.layers = self._make_layer()\n\n    def _make_layer(self):\n        layers = []\n        layer_index = 0\n        for i, dep in enumerate(self.dep[1:]):\n            mid_channels = self.wid[i + 1] * self.expan[i + 1]\n\n            if self.att[i + 1]:\n                se_cfg = dict(\n                    channels=mid_channels,\n                    ratio=4,\n                    act_cfg=(dict(type='ReLU'),\n                             dict(type='HSigmoid', bias=1.0, divisor=2.0)))\n            else:\n                se_cfg = None\n\n            if self.expan[i + 1] == 1:\n                with_expand_conv = False\n            else:\n                with_expand_conv = True\n\n            for j in range(dep):\n                if j == 0:\n                    stride = self.stride[i + 1]\n                    in_channels = self.wid[i]\n                else:\n                    stride = 1\n                    in_channels = self.wid[i + 1]\n\n                layer = InvertedResidual(\n                    in_channels=in_channels,\n                    out_channels=self.wid[i + 1],\n                    mid_channels=mid_channels,\n                    kernel_size=self.ks[i + 1],\n                    groups=self.group[i + 1],\n                    stride=stride,\n                    se_cfg=se_cfg,\n                    with_expand_conv=with_expand_conv,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    act_cfg=dict(type=self.act[i + 1]),\n                    with_cp=self.with_cp)\n                layer_index += 1\n                layer_name = f'layer{layer_index}'\n                self.add_module(layer_name, layer)\n                layers.append(layer_name)\n        return layers\n\n    def forward(self, x):\n        x = self.conv1(x)\n\n        for i, layer_name in enumerate(self.layers):\n            layer = getattr(self, layer_name)\n            x = layer(x)\n\n        return (x, )\n\n    def _freeze_stages(self):\n        if self.frozen_stages >= 0:\n            for param in self.conv1.parameters():\n                param.requires_grad = False\n        for i in range(1, self.frozen_stages + 1):\n            layer = getattr(self, f'layer{i}')\n            layer.eval()\n            for param in layer.parameters():\n                param.requires_grad = False\n\n    def train(self, mode=True):\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/backbones/vipnas_resnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\n\nimport torch.nn as nn\nimport torch.utils.checkpoint as cp\nfrom mmcv.cnn import ConvModule, build_conv_layer, build_norm_layer\nfrom mmcv.cnn.bricks import ContextBlock\nfrom mmengine.model import BaseModule, Sequential\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm\n\nfrom mmpose.registry import MODELS\nfrom .base_backbone import BaseBackbone\n\n\nclass ViPNAS_Bottleneck(BaseModule):\n    \"\"\"Bottleneck block for ViPNAS_ResNet.\n\n    Args:\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        expansion (int): The ratio of ``out_channels/mid_channels`` where\n            ``mid_channels`` is the input/output channels of conv2. Default: 4.\n        stride (int): stride of the block. Default: 1\n        dilation (int): dilation of convolution. Default: 1\n        downsample (nn.Module): downsample operation on identity branch.\n            Default: None.\n        style (str): ``\"pytorch\"`` or ``\"caffe\"``. If set to \"pytorch\", the\n            stride-two layer is the 3x3 conv layer, otherwise the stride-two\n            layer is the first 1x1 conv layer. Default: \"pytorch\".\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed.\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        kernel_size (int): kernel size of conv2 searched in ViPANS.\n        groups (int): group number of conv2 searched in ViPNAS.\n        attention (bool): whether to use attention module in the end of\n            the block.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 expansion=4,\n                 stride=1,\n                 dilation=1,\n                 downsample=None,\n                 style='pytorch',\n                 with_cp=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 kernel_size=3,\n                 groups=1,\n                 attention=False,\n                 init_cfg=None):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        assert style in ['pytorch', 'caffe']\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.expansion = expansion\n        assert out_channels % expansion == 0\n        self.mid_channels = out_channels // expansion\n        self.stride = stride\n        self.dilation = dilation\n        self.style = style\n        self.with_cp = with_cp\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n\n        if self.style == 'pytorch':\n            self.conv1_stride = 1\n            self.conv2_stride = stride\n        else:\n            self.conv1_stride = stride\n            self.conv2_stride = 1\n\n        self.norm1_name, norm1 = build_norm_layer(\n            norm_cfg, self.mid_channels, postfix=1)\n        self.norm2_name, norm2 = build_norm_layer(\n            norm_cfg, self.mid_channels, postfix=2)\n        self.norm3_name, norm3 = build_norm_layer(\n            norm_cfg, out_channels, postfix=3)\n\n        self.conv1 = build_conv_layer(\n            conv_cfg,\n            in_channels,\n            self.mid_channels,\n            kernel_size=1,\n            stride=self.conv1_stride,\n            bias=False)\n        self.add_module(self.norm1_name, norm1)\n        self.conv2 = build_conv_layer(\n            conv_cfg,\n            self.mid_channels,\n            self.mid_channels,\n            kernel_size=kernel_size,\n            stride=self.conv2_stride,\n            padding=kernel_size // 2,\n            groups=groups,\n            dilation=dilation,\n            bias=False)\n\n        self.add_module(self.norm2_name, norm2)\n        self.conv3 = build_conv_layer(\n            conv_cfg,\n            self.mid_channels,\n            out_channels,\n            kernel_size=1,\n            bias=False)\n        self.add_module(self.norm3_name, norm3)\n\n        if attention:\n            self.attention = ContextBlock(out_channels,\n                                          max(1.0 / 16, 16.0 / out_channels))\n        else:\n            self.attention = None\n\n        self.relu = nn.ReLU(inplace=True)\n        self.downsample = downsample\n\n    @property\n    def norm1(self):\n        \"\"\"nn.Module: the normalization layer named \"norm1\" \"\"\"\n        return getattr(self, self.norm1_name)\n\n    @property\n    def norm2(self):\n        \"\"\"nn.Module: the normalization layer named \"norm2\" \"\"\"\n        return getattr(self, self.norm2_name)\n\n    @property\n    def norm3(self):\n        \"\"\"nn.Module: the normalization layer named \"norm3\" \"\"\"\n        return getattr(self, self.norm3_name)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        def _inner_forward(x):\n            identity = x\n\n            out = self.conv1(x)\n            out = self.norm1(out)\n            out = self.relu(out)\n\n            out = self.conv2(out)\n            out = self.norm2(out)\n            out = self.relu(out)\n\n            out = self.conv3(out)\n            out = self.norm3(out)\n\n            if self.attention is not None:\n                out = self.attention(out)\n\n            if self.downsample is not None:\n                identity = self.downsample(x)\n\n            out += identity\n\n            return out\n\n        if self.with_cp and x.requires_grad:\n            out = cp.checkpoint(_inner_forward, x)\n        else:\n            out = _inner_forward(x)\n\n        out = self.relu(out)\n\n        return out\n\n\ndef get_expansion(block, expansion=None):\n    \"\"\"Get the expansion of a residual block.\n\n    The block expansion will be obtained by the following order:\n\n    1. If ``expansion`` is given, just return it.\n    2. If ``block`` has the attribute ``expansion``, then return\n       ``block.expansion``.\n    3. Return the default value according the the block type:\n       4 for ``ViPNAS_Bottleneck``.\n\n    Args:\n        block (class): The block class.\n        expansion (int | None): The given expansion ratio.\n\n    Returns:\n        int: The expansion of the block.\n    \"\"\"\n    if isinstance(expansion, int):\n        assert expansion > 0\n    elif expansion is None:\n        if hasattr(block, 'expansion'):\n            expansion = block.expansion\n        elif issubclass(block, ViPNAS_Bottleneck):\n            expansion = 1\n        else:\n            raise TypeError(f'expansion is not specified for {block.__name__}')\n    else:\n        raise TypeError('expansion must be an integer or None')\n\n    return expansion\n\n\nclass ViPNAS_ResLayer(Sequential):\n    \"\"\"ViPNAS_ResLayer to build ResNet style backbone.\n\n    Args:\n        block (nn.Module): Residual block used to build ViPNAS ResLayer.\n        num_blocks (int): Number of blocks.\n        in_channels (int): Input channels of this block.\n        out_channels (int): Output channels of this block.\n        expansion (int, optional): The expansion for BasicBlock/Bottleneck.\n            If not specified, it will firstly be obtained via\n            ``block.expansion``. If the block has no attribute \"expansion\",\n            the following default values will be used: 1 for BasicBlock and\n            4 for Bottleneck. Default: None.\n        stride (int): stride of the first block. Default: 1.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False\n        conv_cfg (dict): dictionary to construct and config conv layer.\n            Default: None\n        norm_cfg (dict): dictionary to construct and config norm layer.\n            Default: dict(type='BN')\n        downsample_first (bool): Downsample at the first block or last block.\n            False for Hourglass, True for ResNet. Default: True\n        kernel_size (int): Kernel Size of the corresponding convolution layer\n            searched in the block.\n        groups (int): Group number of the corresponding convolution layer\n            searched in the block.\n        attention (bool): Whether to use attention module in the end of the\n            block.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 block,\n                 num_blocks,\n                 in_channels,\n                 out_channels,\n                 expansion=None,\n                 stride=1,\n                 avg_down=False,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN'),\n                 downsample_first=True,\n                 kernel_size=3,\n                 groups=1,\n                 attention=False,\n                 init_cfg=None,\n                 **kwargs):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        self.block = block\n        self.expansion = get_expansion(block, expansion)\n\n        downsample = None\n        if stride != 1 or in_channels != out_channels:\n            downsample = []\n            conv_stride = stride\n            if avg_down and stride != 1:\n                conv_stride = 1\n                downsample.append(\n                    nn.AvgPool2d(\n                        kernel_size=stride,\n                        stride=stride,\n                        ceil_mode=True,\n                        count_include_pad=False))\n            downsample.extend([\n                build_conv_layer(\n                    conv_cfg,\n                    in_channels,\n                    out_channels,\n                    kernel_size=1,\n                    stride=conv_stride,\n                    bias=False),\n                build_norm_layer(norm_cfg, out_channels)[1]\n            ])\n            downsample = nn.Sequential(*downsample)\n\n        layers = []\n        if downsample_first:\n            layers.append(\n                block(\n                    in_channels=in_channels,\n                    out_channels=out_channels,\n                    expansion=self.expansion,\n                    stride=stride,\n                    downsample=downsample,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    kernel_size=kernel_size,\n                    groups=groups,\n                    attention=attention,\n                    **kwargs))\n            in_channels = out_channels\n            for _ in range(1, num_blocks):\n                layers.append(\n                    block(\n                        in_channels=in_channels,\n                        out_channels=out_channels,\n                        expansion=self.expansion,\n                        stride=1,\n                        conv_cfg=conv_cfg,\n                        norm_cfg=norm_cfg,\n                        kernel_size=kernel_size,\n                        groups=groups,\n                        attention=attention,\n                        **kwargs))\n        else:  # downsample_first=False is for HourglassModule\n            for i in range(0, num_blocks - 1):\n                layers.append(\n                    block(\n                        in_channels=in_channels,\n                        out_channels=in_channels,\n                        expansion=self.expansion,\n                        stride=1,\n                        conv_cfg=conv_cfg,\n                        norm_cfg=norm_cfg,\n                        kernel_size=kernel_size,\n                        groups=groups,\n                        attention=attention,\n                        **kwargs))\n            layers.append(\n                block(\n                    in_channels=in_channels,\n                    out_channels=out_channels,\n                    expansion=self.expansion,\n                    stride=stride,\n                    downsample=downsample,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    kernel_size=kernel_size,\n                    groups=groups,\n                    attention=attention,\n                    **kwargs))\n\n        super().__init__(*layers, init_cfg=init_cfg)\n\n\n@MODELS.register_module()\nclass ViPNAS_ResNet(BaseBackbone):\n    \"\"\"ViPNAS_ResNet backbone.\n\n    \"ViPNAS: Efficient Video Pose Estimation via Neural Architecture Search\"\n    More details can be found in the `paper\n    <https://arxiv.org/abs/2105.10154>`__ .\n\n    Args:\n        depth (int): Network depth, from {18, 34, 50, 101, 152}.\n        in_channels (int): Number of input image channels. Default: 3.\n        num_stages (int): Stages of the network. Default: 4.\n        strides (Sequence[int]): Strides of the first block of each stage.\n            Default: ``(1, 2, 2, 2)``.\n        dilations (Sequence[int]): Dilation of each stage.\n            Default: ``(1, 1, 1, 1)``.\n        out_indices (Sequence[int]): Output from which stages. If only one\n            stage is specified, a single tensor (feature map) is returned,\n            otherwise multiple stages are specified, a tuple of tensors will\n            be returned. Default: ``(3, )``.\n        style (str): `pytorch` or `caffe`. If set to \"pytorch\", the stride-two\n            layer is the 3x3 conv layer, otherwise the stride-two layer is\n            the first 1x1 conv layer.\n        deep_stem (bool): Replace 7x7 conv in input stem with 3 3x3 conv.\n            Default: False.\n        avg_down (bool): Use AvgPool instead of stride conv when\n            downsampling in the bottleneck. Default: False.\n        frozen_stages (int): Stages to be frozen (stop grad and set eval mode).\n            -1 means not freezing any parameters. Default: -1.\n        conv_cfg (dict | None): The config dict for conv layers. Default: None.\n        norm_cfg (dict): The config dict for norm layers.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        with_cp (bool): Use checkpoint or not. Using checkpoint will save some\n            memory while slowing down the training speed. Default: False.\n        zero_init_residual (bool): Whether to use zero init for last norm layer\n            in resblocks to let them behave as identity. Default: True.\n        wid (list(int)): Searched width config for each stage.\n        expan (list(int)): Searched expansion ratio config for each stage.\n        dep (list(int)): Searched depth config for each stage.\n        ks (list(int)): Searched kernel size config for each stage.\n        group (list(int)): Searched group number config for each stage.\n        att (list(bool)): Searched attention config for each stage.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default:\n            ``[\n                dict(type='Normal', std=0.001, layer=['Conv2d']),\n                dict(\n                    type='Constant',\n                    val=1,\n                    layer=['_BatchNorm', 'GroupNorm'])\n            ]``\n    \"\"\"\n\n    arch_settings = {\n        50: ViPNAS_Bottleneck,\n    }\n\n    def __init__(self,\n                 depth,\n                 in_channels=3,\n                 num_stages=4,\n                 strides=(1, 2, 2, 2),\n                 dilations=(1, 1, 1, 1),\n                 out_indices=(3, ),\n                 style='pytorch',\n                 deep_stem=False,\n                 avg_down=False,\n                 frozen_stages=-1,\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', requires_grad=True),\n                 norm_eval=False,\n                 with_cp=False,\n                 zero_init_residual=True,\n                 wid=[48, 80, 160, 304, 608],\n                 expan=[None, 1, 1, 1, 1],\n                 dep=[None, 4, 6, 7, 3],\n                 ks=[7, 3, 5, 5, 5],\n                 group=[None, 16, 16, 16, 16],\n                 att=[None, True, False, True, True],\n                 init_cfg=[\n                     dict(type='Normal', std=0.001, layer=['Conv2d']),\n                     dict(\n                         type='Constant',\n                         val=1,\n                         layer=['_BatchNorm', 'GroupNorm'])\n                 ]):\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        super().__init__(init_cfg=init_cfg)\n        if depth not in self.arch_settings:\n            raise KeyError(f'invalid depth {depth} for resnet')\n        self.depth = depth\n        self.stem_channels = dep[0]\n        self.num_stages = num_stages\n        assert 1 <= num_stages <= 4\n        self.strides = strides\n        self.dilations = dilations\n        assert len(strides) == len(dilations) == num_stages\n        self.out_indices = out_indices\n        assert max(out_indices) < num_stages\n        self.style = style\n        self.deep_stem = deep_stem\n        self.avg_down = avg_down\n        self.frozen_stages = frozen_stages\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.with_cp = with_cp\n        self.norm_eval = norm_eval\n        self.zero_init_residual = zero_init_residual\n        self.block = self.arch_settings[depth]\n        self.stage_blocks = dep[1:1 + num_stages]\n\n        self._make_stem_layer(in_channels, wid[0], ks[0])\n\n        self.res_layers = []\n        _in_channels = wid[0]\n        for i, num_blocks in enumerate(self.stage_blocks):\n            expansion = get_expansion(self.block, expan[i + 1])\n            _out_channels = wid[i + 1] * expansion\n            stride = strides[i]\n            dilation = dilations[i]\n            res_layer = self.make_res_layer(\n                block=self.block,\n                num_blocks=num_blocks,\n                in_channels=_in_channels,\n                out_channels=_out_channels,\n                expansion=expansion,\n                stride=stride,\n                dilation=dilation,\n                style=self.style,\n                avg_down=self.avg_down,\n                with_cp=with_cp,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                kernel_size=ks[i + 1],\n                groups=group[i + 1],\n                attention=att[i + 1])\n            _in_channels = _out_channels\n            layer_name = f'layer{i + 1}'\n            self.add_module(layer_name, res_layer)\n            self.res_layers.append(layer_name)\n\n        self._freeze_stages()\n\n        self.feat_dim = res_layer[-1].out_channels\n\n    def make_res_layer(self, **kwargs):\n        \"\"\"Make a ViPNAS ResLayer.\"\"\"\n        return ViPNAS_ResLayer(**kwargs)\n\n    @property\n    def norm1(self):\n        \"\"\"nn.Module: the normalization layer named \"norm1\" \"\"\"\n        return getattr(self, self.norm1_name)\n\n    def _make_stem_layer(self, in_channels, stem_channels, kernel_size):\n        \"\"\"Make stem layer.\"\"\"\n        if self.deep_stem:\n            self.stem = nn.Sequential(\n                ConvModule(\n                    in_channels,\n                    stem_channels // 2,\n                    kernel_size=3,\n                    stride=2,\n                    padding=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    inplace=True),\n                ConvModule(\n                    stem_channels // 2,\n                    stem_channels // 2,\n                    kernel_size=3,\n                    stride=1,\n                    padding=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    inplace=True),\n                ConvModule(\n                    stem_channels // 2,\n                    stem_channels,\n                    kernel_size=3,\n                    stride=1,\n                    padding=1,\n                    conv_cfg=self.conv_cfg,\n                    norm_cfg=self.norm_cfg,\n                    inplace=True))\n        else:\n            self.conv1 = build_conv_layer(\n                self.conv_cfg,\n                in_channels,\n                stem_channels,\n                kernel_size=kernel_size,\n                stride=2,\n                padding=kernel_size // 2,\n                bias=False)\n            self.norm1_name, norm1 = build_norm_layer(\n                self.norm_cfg, stem_channels, postfix=1)\n            self.add_module(self.norm1_name, norm1)\n            self.relu = nn.ReLU(inplace=True)\n        self.maxpool = nn.MaxPool2d(kernel_size=3, stride=2, padding=1)\n\n    def _freeze_stages(self):\n        \"\"\"Freeze parameters.\"\"\"\n        if self.frozen_stages >= 0:\n            if self.deep_stem:\n                self.stem.eval()\n                for param in self.stem.parameters():\n                    param.requires_grad = False\n            else:\n                self.norm1.eval()\n                for m in [self.conv1, self.norm1]:\n                    for param in m.parameters():\n                        param.requires_grad = False\n\n        for i in range(1, self.frozen_stages + 1):\n            m = getattr(self, f'layer{i}')\n            m.eval()\n            for param in m.parameters():\n                param.requires_grad = False\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        if self.deep_stem:\n            x = self.stem(x)\n        else:\n            x = self.conv1(x)\n            x = self.norm1(x)\n            x = self.relu(x)\n        x = self.maxpool(x)\n        outs = []\n        for i, layer_name in enumerate(self.res_layers):\n            res_layer = getattr(self, layer_name)\n            x = res_layer(x)\n            if i in self.out_indices:\n                outs.append(x)\n        return tuple(outs)\n\n    def train(self, mode=True):\n        \"\"\"Convert the model into training mode.\"\"\"\n        super().train(mode)\n        self._freeze_stages()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                # trick: eval have effect on BatchNorm only\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/builder.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\n\nfrom mmpose.registry import MODELS\n\nBACKBONES = MODELS\nNECKS = MODELS\nHEADS = MODELS\nLOSSES = MODELS\nPOSE_ESTIMATORS = MODELS\n\n\ndef build_backbone(cfg):\n    \"\"\"Build backbone.\"\"\"\n    return BACKBONES.build(cfg)\n\n\ndef build_neck(cfg):\n    \"\"\"Build neck.\"\"\"\n    return NECKS.build(cfg)\n\n\ndef build_head(cfg):\n    \"\"\"Build head.\"\"\"\n    return HEADS.build(cfg)\n\n\ndef build_loss(cfg):\n    \"\"\"Build loss.\"\"\"\n    return LOSSES.build(cfg)\n\n\ndef build_pose_estimator(cfg):\n    \"\"\"Build pose estimator.\"\"\"\n    return POSE_ESTIMATORS.build(cfg)\n\n\ndef build_posenet(cfg):\n    \"\"\"Build posenet.\"\"\"\n    warnings.warn(\n        '``build_posenet`` will be deprecated soon, '\n        'please use ``build_pose_estimator`` instead.', DeprecationWarning)\n    return build_pose_estimator(cfg)\n"
  },
  {
    "path": "mmpose/models/data_preprocessors/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .batch_augmentation import BatchSyncRandomResize\nfrom .data_preprocessor import PoseDataPreprocessor\n\n__all__ = [\n    'PoseDataPreprocessor',\n    'BatchSyncRandomResize',\n]\n"
  },
  {
    "path": "mmpose/models/data_preprocessors/batch_augmentation.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport random\nfrom typing import List, Tuple\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmengine import MessageHub\nfrom mmengine.dist import barrier, broadcast, get_dist_info\nfrom mmengine.structures import PixelData\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\nfrom mmpose.structures import PoseDataSample\n\n\n@MODELS.register_module()\nclass BatchSyncRandomResize(nn.Module):\n    \"\"\"Batch random resize which synchronizes the random size across ranks.\n\n    Args:\n        random_size_range (tuple): The multi-scale random range during\n            multi-scale training.\n        interval (int): The iter interval of change\n            image size. Defaults to 10.\n        size_divisor (int): Image size divisible factor.\n            Defaults to 32.\n    \"\"\"\n\n    def __init__(self,\n                 random_size_range: Tuple[int, int],\n                 interval: int = 10,\n                 size_divisor: int = 32) -> None:\n        super().__init__()\n        self.rank, self.world_size = get_dist_info()\n        self._input_size = None\n        self._random_size_range = (round(random_size_range[0] / size_divisor),\n                                   round(random_size_range[1] / size_divisor))\n        self._interval = interval\n        self._size_divisor = size_divisor\n\n    def forward(self, inputs: Tensor, data_samples: List[PoseDataSample]\n                ) -> Tuple[Tensor, List[PoseDataSample]]:\n        \"\"\"resize a batch of images and bboxes to shape ``self._input_size``\"\"\"\n        h, w = inputs.shape[-2:]\n        if self._input_size is None:\n            self._input_size = (h, w)\n        scale_y = self._input_size[0] / h\n        scale_x = self._input_size[1] / w\n        if scale_x != 1 or scale_y != 1:\n            inputs = F.interpolate(\n                inputs,\n                size=self._input_size,\n                mode='bilinear',\n                align_corners=False)\n            for data_sample in data_samples:\n                img_shape = (int(data_sample.img_shape[0] * scale_y),\n                             int(data_sample.img_shape[1] * scale_x))\n                pad_shape = (int(data_sample.pad_shape[0] * scale_y),\n                             int(data_sample.pad_shape[1] * scale_x))\n                data_sample.set_metainfo({\n                    'img_shape': img_shape,\n                    'pad_shape': pad_shape,\n                    'batch_input_shape': self._input_size\n                })\n\n                if 'gt_instance_labels' not in data_sample:\n                    continue\n\n                if 'bboxes' in data_sample.gt_instance_labels:\n                    data_sample.gt_instance_labels.bboxes[..., 0::2] *= scale_x\n                    data_sample.gt_instance_labels.bboxes[..., 1::2] *= scale_y\n\n                if 'keypoints' in data_sample.gt_instance_labels:\n                    data_sample.gt_instance_labels.keypoints[..., 0] *= scale_x\n                    data_sample.gt_instance_labels.keypoints[..., 1] *= scale_y\n\n                if 'areas' in data_sample.gt_instance_labels:\n                    data_sample.gt_instance_labels.areas *= scale_x * scale_y\n\n                if 'gt_fields' in data_sample \\\n                        and 'heatmap_mask' in data_sample.gt_fields:\n\n                    mask = data_sample.gt_fields.heatmap_mask.unsqueeze(0)\n                    gt_fields = PixelData()\n                    gt_fields.set_field(\n                        F.interpolate(\n                            mask.float(),\n                            size=self._input_size,\n                            mode='bilinear',\n                            align_corners=False).squeeze(0), 'heatmap_mask')\n\n                    data_sample.gt_fields = gt_fields\n\n        message_hub = MessageHub.get_current_instance()\n        if (message_hub.get_info('iter') + 1) % self._interval == 0:\n            self._input_size = self._get_random_size(\n                aspect_ratio=float(w / h), device=inputs.device)\n        return inputs, data_samples\n\n    def _get_random_size(self, aspect_ratio: float,\n                         device: torch.device) -> Tuple[int, int]:\n        \"\"\"Randomly generate a shape in ``_random_size_range`` and broadcast to\n        all ranks.\"\"\"\n        tensor = torch.LongTensor(2).to(device)\n        if self.rank == 0:\n            size = random.randint(*self._random_size_range)\n            size = (self._size_divisor * size,\n                    self._size_divisor * int(aspect_ratio * size))\n            tensor[0] = size[0]\n            tensor[1] = size[1]\n        barrier()\n        broadcast(tensor, 0)\n        input_size = (tensor[0].item(), tensor[1].item())\n        return input_size\n"
  },
  {
    "path": "mmpose/models/data_preprocessors/data_preprocessor.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Sequence, Union\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom mmengine.model import ImgDataPreprocessor\nfrom mmengine.utils import is_seq_of\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass PoseDataPreprocessor(ImgDataPreprocessor):\n    \"\"\"Image pre-processor for pose estimation tasks.\n\n    Comparing with the :class:`ImgDataPreprocessor`,\n\n    1. It will additionally append batch_input_shape\n    to data_samples considering the DETR-based pose estimation tasks.\n\n    2. Support image augmentation transforms on batched data.\n\n    It provides the data pre-processing as follows\n\n    - Collate and move data to the target device.\n    - Pad inputs to the maximum size of current batch with defined\n      ``pad_value``. The padding size can be divisible by a defined\n      ``pad_size_divisor``\n    - Stack inputs to batch_inputs.\n    - Convert inputs from bgr to rgb if the shape of input is (3, H, W).\n    - Normalize image with defined std and mean.\n    - Apply batch augmentation transforms.\n\n    Args:\n        mean (sequence of float, optional): The pixel mean of R, G, B\n            channels. Defaults to None.\n        std (sequence of float, optional): The pixel standard deviation\n            of R, G, B channels. Defaults to None.\n        pad_size_divisor (int): The size of padded image should be\n            divisible by ``pad_size_divisor``. Defaults to 1.\n        pad_value (float or int): The padded pixel value. Defaults to 0.\n        bgr_to_rgb (bool): whether to convert image from BGR to RGB.\n            Defaults to False.\n        rgb_to_bgr (bool): whether to convert image from RGB to BGR.\n            Defaults to False.\n        non_blocking (bool): Whether block current process\n            when transferring data to device. Defaults to False.\n        batch_augments: (list of dict, optional): Configs of augmentation\n            transforms on batched data. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 mean: Sequence[float] = None,\n                 std: Sequence[float] = None,\n                 pad_size_divisor: int = 1,\n                 pad_value: Union[float, int] = 0,\n                 bgr_to_rgb: bool = False,\n                 rgb_to_bgr: bool = False,\n                 non_blocking: Optional[bool] = False,\n                 batch_augments: Optional[List[dict]] = None):\n        super().__init__(\n            mean=mean,\n            std=std,\n            pad_size_divisor=pad_size_divisor,\n            pad_value=pad_value,\n            bgr_to_rgb=bgr_to_rgb,\n            rgb_to_bgr=rgb_to_bgr,\n            non_blocking=non_blocking)\n\n        if batch_augments is not None:\n            self.batch_augments = nn.ModuleList(\n                [MODELS.build(aug) for aug in batch_augments])\n        else:\n            self.batch_augments = None\n\n    def forward(self, data: dict, training: bool = False) -> dict:\n        \"\"\"Perform normalization, padding and bgr2rgb conversion based on\n        ``BaseDataPreprocessor``.\n\n        Args:\n            data (dict): Data sampled from dataloader.\n            training (bool): Whether to enable training time augmentation.\n\n        Returns:\n            dict: Data in the same format as the model input.\n        \"\"\"\n        batch_pad_shape = self._get_pad_shape(data)\n        data = super().forward(data=data, training=training)\n        inputs, data_samples = data['inputs'], data['data_samples']\n\n        # update metainfo since the image shape might change\n        batch_input_shape = tuple(inputs[0].size()[-2:])\n        for data_sample, pad_shape in zip(data_samples, batch_pad_shape):\n            data_sample.set_metainfo({\n                'batch_input_shape': batch_input_shape,\n                'pad_shape': pad_shape\n            })\n\n        # apply batch augmentations\n        if training and self.batch_augments is not None:\n            for batch_aug in self.batch_augments:\n                inputs, data_samples = batch_aug(inputs, data_samples)\n\n        return {'inputs': inputs, 'data_samples': data_samples}\n\n    def _get_pad_shape(self, data: dict) -> List[tuple]:\n        \"\"\"Get the pad_shape of each image based on data and\n        pad_size_divisor.\"\"\"\n        _batch_inputs = data['inputs']\n        # Process data with `pseudo_collate`.\n        if is_seq_of(_batch_inputs, torch.Tensor):\n            batch_pad_shape = []\n            for ori_input in _batch_inputs:\n                pad_h = int(\n                    np.ceil(ori_input.shape[1] /\n                            self.pad_size_divisor)) * self.pad_size_divisor\n                pad_w = int(\n                    np.ceil(ori_input.shape[2] /\n                            self.pad_size_divisor)) * self.pad_size_divisor\n                batch_pad_shape.append((pad_h, pad_w))\n        # Process data with `default_collate`.\n        elif isinstance(_batch_inputs, torch.Tensor):\n            assert _batch_inputs.dim() == 4, (\n                'The input of `ImgDataPreprocessor` should be a NCHW tensor '\n                'or a list of tensor, but got a tensor with shape: '\n                f'{_batch_inputs.shape}')\n            pad_h = int(\n                np.ceil(_batch_inputs.shape[1] /\n                        self.pad_size_divisor)) * self.pad_size_divisor\n            pad_w = int(\n                np.ceil(_batch_inputs.shape[2] /\n                        self.pad_size_divisor)) * self.pad_size_divisor\n            batch_pad_shape = [(pad_h, pad_w)] * _batch_inputs.shape[0]\n        else:\n            raise TypeError('Output of `cast_data` should be a dict '\n                            'or a tuple with inputs and data_samples, but got'\n                            f'{type(data)}: {data}')\n        return batch_pad_shape\n"
  },
  {
    "path": "mmpose/models/distillers/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .dwpose_distiller import DWPoseDistiller\n\n__all__ = ['DWPoseDistiller']\n"
  },
  {
    "path": "mmpose/models/distillers/dwpose_distiller.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta\nfrom typing import Tuple\n\nimport torch\nimport torch.nn as nn\nfrom mmengine.config import Config\nfrom mmengine.logging import MessageHub\nfrom mmengine.model import BaseModel\nfrom mmengine.runner.checkpoint import load_checkpoint\nfrom torch import Tensor\n\nfrom mmpose.evaluation.functional import simcc_pck_accuracy\nfrom mmpose.models import build_pose_estimator\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ForwardResults, OptConfigType, OptMultiConfig,\n                                 OptSampleList, SampleList)\n\n\n@MODELS.register_module()\nclass DWPoseDistiller(BaseModel, metaclass=ABCMeta):\n    \"\"\"Distiller introduced in `DWPose`_ by Yang et al (2023). This distiller\n    is designed for distillation of RTMPose.\n\n    It typically consists of teacher_model and student_model. Please use the\n    script `tools/misc/pth_transfer.py` to transfer the distilled model to the\n    original RTMPose model.\n\n    Args:\n        teacher_cfg (str): Config file of the teacher model.\n        student_cfg (str): Config file of the student model.\n        two_dis (bool): Whether this is the second stage of distillation.\n            Defaults to False.\n        distill_cfg (dict): Config for distillation. Defaults to None.\n        teacher_pretrained (str): Path of the pretrained teacher model.\n            Defaults to None.\n        train_cfg (dict, optional): The runtime config for training process.\n            Defaults to ``None``\n        data_preprocessor (dict, optional): The data preprocessing config to\n            build the instance of :class:`BaseDataPreprocessor`. Defaults to\n            ``None``\n        init_cfg (dict, optional): The config to control the initialization.\n            Defaults to ``None``\n\n    .. _`DWPose`: https://arxiv.org/abs/2307.15880\n    \"\"\"\n\n    def __init__(self,\n                 teacher_cfg,\n                 student_cfg,\n                 two_dis=False,\n                 distill_cfg=None,\n                 teacher_pretrained=None,\n                 train_cfg: OptConfigType = None,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None):\n        super().__init__(\n            data_preprocessor=data_preprocessor, init_cfg=init_cfg)\n\n        self.teacher = build_pose_estimator(\n            (Config.fromfile(teacher_cfg)).model)\n        self.teacher_pretrained = teacher_pretrained\n        self.teacher.eval()\n        for param in self.teacher.parameters():\n            param.requires_grad = False\n\n        self.student = build_pose_estimator(\n            (Config.fromfile(student_cfg)).model)\n\n        self.distill_cfg = distill_cfg\n        self.distill_losses = nn.ModuleDict()\n        if self.distill_cfg is not None:\n            for item_loc in distill_cfg:\n                for item_loss in item_loc.methods:\n                    loss_name = item_loss.name\n                    use_this = item_loss.use_this\n                    if use_this:\n                        self.distill_losses[loss_name] = MODELS.build(\n                            item_loss)\n\n        self.two_dis = two_dis\n        self.train_cfg = train_cfg if train_cfg else self.student.train_cfg\n        self.test_cfg = self.student.test_cfg\n        self.metainfo = self.student.metainfo\n\n    def init_weights(self):\n        if self.teacher_pretrained is not None:\n            load_checkpoint(\n                self.teacher, self.teacher_pretrained, map_location='cpu')\n        self.student.init_weights()\n\n    def set_epoch(self):\n        \"\"\"Set epoch for distiller.\n\n        Used for the decay of distillation loss.\n        \"\"\"\n        self.message_hub = MessageHub.get_current_instance()\n        self.epoch = self.message_hub.get_info('epoch')\n        self.max_epochs = self.message_hub.get_info('max_epochs')\n\n    def forward(self,\n                inputs: torch.Tensor,\n                data_samples: OptSampleList,\n                mode: str = 'tensor') -> ForwardResults:\n        if mode == 'loss':\n            return self.loss(inputs, data_samples)\n        elif mode == 'predict':\n            # use customed metainfo to override the default metainfo\n            if self.metainfo is not None:\n                for data_sample in data_samples:\n                    data_sample.set_metainfo(self.metainfo)\n            return self.predict(inputs, data_samples)\n        elif mode == 'tensor':\n            return self._forward(inputs)\n        else:\n            raise RuntimeError(f'Invalid mode \"{mode}\". '\n                               'Only supports loss, predict and tensor mode.')\n\n    def loss(self, inputs: Tensor, data_samples: SampleList) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W).\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples.\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        self.set_epoch()\n\n        losses = dict()\n\n        with torch.no_grad():\n            fea_t = self.teacher.extract_feat(inputs)\n            lt_x, lt_y = self.teacher.head(fea_t)\n            pred_t = (lt_x, lt_y)\n\n        if not self.two_dis:\n            fea_s = self.student.extract_feat(inputs)\n            ori_loss, pred, gt, target_weight = self.head_loss(\n                fea_s, data_samples, train_cfg=self.train_cfg)\n            losses.update(ori_loss)\n        else:\n            ori_loss, pred, gt, target_weight = self.head_loss(\n                fea_t, data_samples, train_cfg=self.train_cfg)\n\n        all_keys = self.distill_losses.keys()\n\n        if 'loss_fea' in all_keys:\n            loss_name = 'loss_fea'\n            losses[loss_name] = self.distill_losses[loss_name](fea_s[-1],\n                                                               fea_t[-1])\n            if not self.two_dis:\n                losses[loss_name] = (\n                    1 - self.epoch / self.max_epochs) * losses[loss_name]\n\n        if 'loss_logit' in all_keys:\n            loss_name = 'loss_logit'\n            losses[loss_name] = self.distill_losses[loss_name](\n                pred, pred_t, self.student.head.loss_module.beta,\n                target_weight)\n            if not self.two_dis:\n                losses[loss_name] = (\n                    1 - self.epoch / self.max_epochs) * losses[loss_name]\n\n        return losses\n\n    def predict(self, inputs, data_samples):\n        \"\"\"Predict results from a batch of inputs and data samples with post-\n        processing.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W)\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n\n        Returns:\n            list[:obj:`PoseDataSample`]: The pose estimation results of the\n            input images. The return value is `PoseDataSample` instances with\n            ``pred_instances`` and ``pred_fields``(optional) field , and\n            ``pred_instances`` usually contains the following keys:\n\n                - keypoints (Tensor): predicted keypoint coordinates in shape\n                    (num_instances, K, D) where K is the keypoint number and D\n                    is the keypoint dimension\n                - keypoint_scores (Tensor): predicted keypoint scores in shape\n                    (num_instances, K)\n        \"\"\"\n        if self.two_dis:\n            assert self.student.with_head, (\n                'The model must have head to perform prediction.')\n\n            if self.test_cfg.get('flip_test', False):\n                _feats = self.extract_feat(inputs)\n                _feats_flip = self.extract_feat(inputs.flip(-1))\n                feats = [_feats, _feats_flip]\n            else:\n                feats = self.extract_feat(inputs)\n\n            preds = self.student.head.predict(\n                feats, data_samples, test_cfg=self.student.test_cfg)\n\n            if isinstance(preds, tuple):\n                batch_pred_instances, batch_pred_fields = preds\n            else:\n                batch_pred_instances = preds\n                batch_pred_fields = None\n\n            results = self.student.add_pred_to_datasample(\n                batch_pred_instances, batch_pred_fields, data_samples)\n\n            return results\n        else:\n            return self.student.predict(inputs, data_samples)\n\n    def extract_feat(self, inputs: Tensor) -> Tuple[Tensor]:\n        \"\"\"Extract features.\n\n        Args:\n            inputs (Tensor): Image tensor with shape (N, C, H ,W).\n\n        Returns:\n            tuple[Tensor]: Multi-level features that may have various\n            resolutions.\n        \"\"\"\n        x = self.teacher.extract_feat(inputs)\n        return x\n\n    def head_loss(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        train_cfg: OptConfigType = {},\n    ) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_x, pred_y = self.student.head.forward(feats)\n\n        gt_x = torch.cat([\n            d.gt_instance_labels.keypoint_x_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        gt_y = torch.cat([\n            d.gt_instance_labels.keypoint_y_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        keypoint_weights = torch.cat(\n            [\n                d.gt_instance_labels.keypoint_weights\n                for d in batch_data_samples\n            ],\n            dim=0,\n        )\n\n        pred_simcc = (pred_x, pred_y)\n        gt_simcc = (gt_x, gt_y)\n\n        # calculate losses\n        losses = dict()\n        loss = self.student.head.loss_module(pred_simcc, gt_simcc,\n                                             keypoint_weights)\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = simcc_pck_accuracy(\n            output=to_numpy(pred_simcc),\n            target=to_numpy(gt_simcc),\n            simcc_split_ratio=self.student.head.simcc_split_ratio,\n            mask=to_numpy(keypoint_weights) > 0,\n        )\n\n        acc_pose = torch.tensor(avg_acc, device=gt_x.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses, pred_simcc, gt_simcc, keypoint_weights\n\n    def _forward(self, inputs: Tensor):\n        \"\"\"Network forward process. Usually includes backbone, neck and head\n        forward without any post-processing.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W).\n\n        Returns:\n            Union[Tensor | Tuple[Tensor]]: forward output of the network.\n        \"\"\"\n        return self.student._forward(inputs)\n"
  },
  {
    "path": "mmpose/models/heads/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .base_head import BaseHead\nfrom .coord_cls_heads import RTMCCHead, RTMWHead, SimCCHead\nfrom .heatmap_heads import (AssociativeEmbeddingHead, CIDHead, CPMHead,\n                            HeatmapHead, InternetHead, MSPNHead, ViPNASHead)\nfrom .hybrid_heads import DEKRHead, RTMOHead, VisPredictHead\nfrom .regression_heads import (DSNTHead, IntegralRegressionHead,\n                               MotionRegressionHead, RegressionHead, RLEHead,\n                               TemporalRegressionHead,\n                               TrajectoryRegressionHead)\nfrom .transformer_heads import EDPoseHead\n\n__all__ = [\n    'BaseHead', 'HeatmapHead', 'CPMHead', 'MSPNHead', 'ViPNASHead',\n    'RegressionHead', 'IntegralRegressionHead', 'SimCCHead', 'RLEHead',\n    'DSNTHead', 'AssociativeEmbeddingHead', 'DEKRHead', 'VisPredictHead',\n    'CIDHead', 'RTMCCHead', 'TemporalRegressionHead',\n    'TrajectoryRegressionHead', 'MotionRegressionHead', 'EDPoseHead',\n    'InternetHead', 'RTMWHead', 'RTMOHead'\n]\n"
  },
  {
    "path": "mmpose/models/heads/base_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta, abstractmethod\nfrom typing import Tuple, Union\n\nfrom mmengine.model import BaseModule\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor\n\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (Features, InstanceList, OptConfigType,\n                                 OptSampleList, Predictions)\n\n\nclass BaseHead(BaseModule, metaclass=ABCMeta):\n    \"\"\"Base head. A subclass should override :meth:`predict` and :meth:`loss`.\n\n    Args:\n        init_cfg (dict, optional): The extra init config of layers.\n            Defaults to None.\n    \"\"\"\n\n    @abstractmethod\n    def forward(self, feats: Tuple[Tensor]):\n        \"\"\"Forward the network.\"\"\"\n\n    @abstractmethod\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: OptConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\"\"\"\n\n    @abstractmethod\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: OptConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n    def decode(self, batch_outputs: Union[Tensor,\n                                          Tuple[Tensor]]) -> InstanceList:\n        \"\"\"Decode keypoints from outputs.\n\n        Args:\n            batch_outputs (Tensor | Tuple[Tensor]): The network outputs of\n                a data batch\n\n        Returns:\n            List[InstanceData]: A list of InstanceData, each contains the\n            decoded pose information of the instances of one data sample.\n        \"\"\"\n\n        def _pack_and_call(args, func):\n            if not isinstance(args, tuple):\n                args = (args, )\n            return func(*args)\n\n        if self.decoder is None:\n            raise RuntimeError(\n                f'The decoder has not been set in {self.__class__.__name__}. '\n                'Please set the decoder configs in the init parameters to '\n                'enable head methods `head.predict()` and `head.decode()`')\n\n        if self.decoder.support_batch_decoding:\n            batch_keypoints, batch_scores = _pack_and_call(\n                batch_outputs, self.decoder.batch_decode)\n            if isinstance(batch_scores, tuple) and len(batch_scores) == 2:\n                batch_scores, batch_visibility = batch_scores\n            else:\n                batch_visibility = [None] * len(batch_keypoints)\n\n        else:\n            batch_output_np = to_numpy(batch_outputs, unzip=True)\n            batch_keypoints = []\n            batch_scores = []\n            batch_visibility = []\n            for outputs in batch_output_np:\n                keypoints, scores = _pack_and_call(outputs,\n                                                   self.decoder.decode)\n                batch_keypoints.append(keypoints)\n                if isinstance(scores, tuple) and len(scores) == 2:\n                    batch_scores.append(scores[0])\n                    batch_visibility.append(scores[1])\n                else:\n                    batch_scores.append(scores)\n                    batch_visibility.append(None)\n\n        preds = []\n        for keypoints, scores, visibility in zip(batch_keypoints, batch_scores,\n                                                 batch_visibility):\n            pred = InstanceData(keypoints=keypoints, keypoint_scores=scores)\n            if visibility is not None:\n                pred.keypoints_visible = visibility\n            preds.append(pred)\n\n        return preds\n"
  },
  {
    "path": "mmpose/models/heads/coord_cls_heads/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .rtmcc_head import RTMCCHead\nfrom .rtmw_head import RTMWHead\nfrom .simcc_head import SimCCHead\n\n__all__ = ['SimCCHead', 'RTMCCHead', 'RTMWHead']\n"
  },
  {
    "path": "mmpose/models/heads/coord_cls_heads/rtmcc_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nfrom mmengine.dist import get_dist_info\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.codecs.utils import get_simcc_normalized\nfrom mmpose.evaluation.functional import simcc_pck_accuracy\nfrom mmpose.models.utils.rtmcc_block import RTMCCBlock, ScaleNorm\nfrom mmpose.models.utils.tta import flip_vectors\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptSampleList)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass RTMCCHead(BaseHead):\n    \"\"\"Top-down head introduced in RTMPose (2023). The head is composed of a\n    large-kernel convolutional layer, a fully-connected layer and a Gated\n    Attention Unit to generate 1d representation from low-resolution feature\n    maps.\n\n    Args:\n        in_channels (int | sequence[int]): Number of channels in the input\n            feature map.\n        out_channels (int): Number of channels in the output heatmap.\n        input_size (tuple): Size of input image in shape [w, h].\n        in_featuremap_size (int | sequence[int]): Size of input feature map.\n        simcc_split_ratio (float): Split ratio of pixels.\n            Default: 2.0.\n        final_layer_kernel_size (int): Kernel size of the convolutional layer.\n            Default: 1.\n        gau_cfg (Config): Config dict for the Gated Attention Unit.\n            Default: dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='ReLU',\n                use_rel_bias=False,\n                pos_enc=False).\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KLDiscretLoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: Union[int, Sequence[int]],\n        out_channels: int,\n        input_size: Tuple[int, int],\n        in_featuremap_size: Tuple[int, int],\n        simcc_split_ratio: float = 2.0,\n        final_layer_kernel_size: int = 1,\n        gau_cfg: ConfigType = dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='ReLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss: ConfigType = dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder: OptConfigType = None,\n        init_cfg: OptConfigType = None,\n    ):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.input_size = input_size\n        self.in_featuremap_size = in_featuremap_size\n        self.simcc_split_ratio = simcc_split_ratio\n\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        if isinstance(in_channels, (tuple, list)):\n            raise ValueError(\n                f'{self.__class__.__name__} does not support selecting '\n                'multiple input features.')\n\n        # Define SimCC layers\n        flatten_dims = self.in_featuremap_size[0] * self.in_featuremap_size[1]\n\n        self.final_layer = nn.Conv2d(\n            in_channels,\n            out_channels,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2)\n        self.mlp = nn.Sequential(\n            ScaleNorm(flatten_dims),\n            nn.Linear(flatten_dims, gau_cfg['hidden_dims'], bias=False))\n\n        W = int(self.input_size[0] * self.simcc_split_ratio)\n        H = int(self.input_size[1] * self.simcc_split_ratio)\n\n        self.gau = RTMCCBlock(\n            self.out_channels,\n            gau_cfg['hidden_dims'],\n            gau_cfg['hidden_dims'],\n            s=gau_cfg['s'],\n            expansion_factor=gau_cfg['expansion_factor'],\n            dropout_rate=gau_cfg['dropout_rate'],\n            drop_path=gau_cfg['drop_path'],\n            attn_type='self-attn',\n            act_fn=gau_cfg['act_fn'],\n            use_rel_bias=gau_cfg['use_rel_bias'],\n            pos_enc=gau_cfg['pos_enc'])\n\n        self.cls_x = nn.Linear(gau_cfg['hidden_dims'], W, bias=False)\n        self.cls_y = nn.Linear(gau_cfg['hidden_dims'], H, bias=False)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tuple[Tensor, Tensor]:\n        \"\"\"Forward the network.\n\n        The input is the featuremap extracted by backbone and the\n        output is the simcc representation.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            pred_x (Tensor): 1d representation of x.\n            pred_y (Tensor): 1d representation of y.\n        \"\"\"\n        feats = feats[-1]\n\n        feats = self.final_layer(feats)  # -> B, K, H, W\n\n        # flatten the output heatmap\n        feats = torch.flatten(feats, 2)\n\n        feats = self.mlp(feats)  # -> B, K, hidden\n\n        feats = self.gau(feats)\n\n        pred_x = self.cls_x(feats)\n        pred_y = self.cls_y(feats)\n\n        return pred_x, pred_y\n\n    def predict(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        test_cfg: OptConfigType = {},\n    ) -> InstanceList:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            List[InstanceData]: The pose predictions, each contains\n            the following fields:\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n                - keypoint_x_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the x direction\n                - keypoint_y_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the y direction\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n\n            _batch_pred_x, _batch_pred_y = self.forward(_feats)\n\n            _batch_pred_x_flip, _batch_pred_y_flip = self.forward(_feats_flip)\n            _batch_pred_x_flip, _batch_pred_y_flip = flip_vectors(\n                _batch_pred_x_flip,\n                _batch_pred_y_flip,\n                flip_indices=flip_indices)\n\n            batch_pred_x = (_batch_pred_x + _batch_pred_x_flip) * 0.5\n            batch_pred_y = (_batch_pred_y + _batch_pred_y_flip) * 0.5\n        else:\n            batch_pred_x, batch_pred_y = self.forward(feats)\n\n        preds = self.decode((batch_pred_x, batch_pred_y))\n\n        if test_cfg.get('output_heatmaps', False):\n            rank, _ = get_dist_info()\n            if rank == 0:\n                warnings.warn('The predicted simcc values are normalized for '\n                              'visualization. This may cause discrepancy '\n                              'between the keypoint scores and the 1D heatmaps'\n                              '.')\n\n            # normalize the predicted 1d distribution\n            batch_pred_x = get_simcc_normalized(batch_pred_x)\n            batch_pred_y = get_simcc_normalized(batch_pred_y)\n\n            B, K, _ = batch_pred_x.shape\n            # B, K, Wx -> B, K, Wx, 1\n            x = batch_pred_x.reshape(B, K, 1, -1)\n            # B, K, Wy -> B, K, 1, Wy\n            y = batch_pred_y.reshape(B, K, -1, 1)\n            # B, K, Wx, Wy\n            batch_heatmaps = torch.matmul(y, x)\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n\n            for pred_instances, pred_x, pred_y in zip(preds,\n                                                      to_numpy(batch_pred_x),\n                                                      to_numpy(batch_pred_y)):\n\n                pred_instances.keypoint_x_labels = pred_x[None]\n                pred_instances.keypoint_y_labels = pred_y[None]\n\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        train_cfg: OptConfigType = {},\n    ) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_x, pred_y = self.forward(feats)\n\n        gt_x = torch.cat([\n            d.gt_instance_labels.keypoint_x_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        gt_y = torch.cat([\n            d.gt_instance_labels.keypoint_y_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        keypoint_weights = torch.cat(\n            [\n                d.gt_instance_labels.keypoint_weights\n                for d in batch_data_samples\n            ],\n            dim=0,\n        )\n\n        pred_simcc = (pred_x, pred_y)\n        gt_simcc = (gt_x, gt_y)\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_simcc, gt_simcc, keypoint_weights)\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = simcc_pck_accuracy(\n            output=to_numpy(pred_simcc),\n            target=to_numpy(gt_simcc),\n            simcc_split_ratio=self.simcc_split_ratio,\n            mask=to_numpy(keypoint_weights) > 0,\n        )\n\n        acc_pose = torch.tensor(avg_acc, device=gt_x.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(type='Normal', layer=['Conv2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1),\n            dict(type='Normal', layer=['Linear'], std=0.01, bias=0),\n        ]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/coord_cls_heads/rtmw_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nfrom mmcv.cnn import ConvModule\nfrom mmengine.dist import get_dist_info\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.codecs.utils import get_simcc_normalized\nfrom mmpose.evaluation.functional import simcc_pck_accuracy\nfrom mmpose.models.utils.rtmcc_block import RTMCCBlock, ScaleNorm\nfrom mmpose.models.utils.tta import flip_vectors\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptSampleList)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass RTMWHead(BaseHead):\n    \"\"\"Top-down head introduced in RTMPose-Wholebody (2023).\n\n    Args:\n        in_channels (int | sequence[int]): Number of channels in the input\n            feature map.\n        out_channels (int): Number of channels in the output heatmap.\n        input_size (tuple): Size of input image in shape [w, h].\n        in_featuremap_size (int | sequence[int]): Size of input feature map.\n        simcc_split_ratio (float): Split ratio of pixels.\n            Default: 2.0.\n        final_layer_kernel_size (int): Kernel size of the convolutional layer.\n            Default: 1.\n        gau_cfg (Config): Config dict for the Gated Attention Unit.\n            Default: dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='ReLU',\n                use_rel_bias=False,\n                pos_enc=False).\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KLDiscretLoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: Union[int, Sequence[int]],\n        out_channels: int,\n        input_size: Tuple[int, int],\n        in_featuremap_size: Tuple[int, int],\n        simcc_split_ratio: float = 2.0,\n        final_layer_kernel_size: int = 1,\n        gau_cfg: ConfigType = dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='ReLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss: ConfigType = dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder: OptConfigType = None,\n        init_cfg: OptConfigType = None,\n    ):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.input_size = input_size\n        self.in_featuremap_size = in_featuremap_size\n        self.simcc_split_ratio = simcc_split_ratio\n\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        if isinstance(in_channels, (tuple, list)):\n            raise ValueError(\n                f'{self.__class__.__name__} does not support selecting '\n                'multiple input features.')\n\n        # Define SimCC layers\n        flatten_dims = self.in_featuremap_size[0] * self.in_featuremap_size[1]\n\n        ps = 2\n        self.ps = nn.PixelShuffle(ps)\n        self.conv_dec = ConvModule(\n            in_channels // ps**2,\n            in_channels // 4,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            act_cfg=dict(type='ReLU'))\n\n        self.final_layer = ConvModule(\n            in_channels,\n            out_channels,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            act_cfg=dict(type='ReLU'))\n        self.final_layer2 = ConvModule(\n            in_channels // ps + in_channels // 4,\n            out_channels,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            act_cfg=dict(type='ReLU'))\n\n        self.mlp = nn.Sequential(\n            ScaleNorm(flatten_dims),\n            nn.Linear(flatten_dims, gau_cfg['hidden_dims'] // 2, bias=False))\n\n        self.mlp2 = nn.Sequential(\n            ScaleNorm(flatten_dims * ps**2),\n            nn.Linear(\n                flatten_dims * ps**2, gau_cfg['hidden_dims'] // 2, bias=False))\n\n        W = int(self.input_size[0] * self.simcc_split_ratio)\n        H = int(self.input_size[1] * self.simcc_split_ratio)\n\n        self.gau = RTMCCBlock(\n            self.out_channels,\n            gau_cfg['hidden_dims'],\n            gau_cfg['hidden_dims'],\n            s=gau_cfg['s'],\n            expansion_factor=gau_cfg['expansion_factor'],\n            dropout_rate=gau_cfg['dropout_rate'],\n            drop_path=gau_cfg['drop_path'],\n            attn_type='self-attn',\n            act_fn=gau_cfg['act_fn'],\n            use_rel_bias=gau_cfg['use_rel_bias'],\n            pos_enc=gau_cfg['pos_enc'])\n\n        self.cls_x = nn.Linear(gau_cfg['hidden_dims'], W, bias=False)\n        self.cls_y = nn.Linear(gau_cfg['hidden_dims'], H, bias=False)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tuple[Tensor, Tensor]:\n        \"\"\"Forward the network.\n\n        The input is the featuremap extracted by backbone and the\n        output is the simcc representation.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            pred_x (Tensor): 1d representation of x.\n            pred_y (Tensor): 1d representation of y.\n        \"\"\"\n        # enc_b  n / 2, h, w\n        # enc_t  n,     h, w\n        enc_b, enc_t = feats\n\n        feats_t = self.final_layer(enc_t)\n        feats_t = torch.flatten(feats_t, 2)\n        feats_t = self.mlp(feats_t)\n\n        dec_t = self.ps(enc_t)\n        dec_t = self.conv_dec(dec_t)\n        enc_b = torch.cat([dec_t, enc_b], dim=1)\n\n        feats_b = self.final_layer2(enc_b)\n        feats_b = torch.flatten(feats_b, 2)\n        feats_b = self.mlp2(feats_b)\n\n        feats = torch.cat([feats_t, feats_b], dim=2)\n\n        feats = self.gau(feats)\n\n        pred_x = self.cls_x(feats)\n        pred_y = self.cls_y(feats)\n\n        return pred_x, pred_y\n\n    def predict(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        test_cfg: OptConfigType = {},\n    ) -> InstanceList:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            List[InstanceData]: The pose predictions, each contains\n            the following fields:\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n                - keypoint_x_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the x direction\n                - keypoint_y_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the y direction\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n\n            _batch_pred_x, _batch_pred_y = self.forward(_feats)\n\n            _batch_pred_x_flip, _batch_pred_y_flip = self.forward(_feats_flip)\n            _batch_pred_x_flip, _batch_pred_y_flip = flip_vectors(\n                _batch_pred_x_flip,\n                _batch_pred_y_flip,\n                flip_indices=flip_indices)\n\n            batch_pred_x = (_batch_pred_x + _batch_pred_x_flip) * 0.5\n            batch_pred_y = (_batch_pred_y + _batch_pred_y_flip) * 0.5\n        else:\n            batch_pred_x, batch_pred_y = self.forward(feats)\n\n        preds = self.decode((batch_pred_x, batch_pred_y))\n\n        if test_cfg.get('output_heatmaps', False):\n            rank, _ = get_dist_info()\n            if rank == 0:\n                warnings.warn('The predicted simcc values are normalized for '\n                              'visualization. This may cause discrepancy '\n                              'between the keypoint scores and the 1D heatmaps'\n                              '.')\n\n            # normalize the predicted 1d distribution\n            batch_pred_x = get_simcc_normalized(batch_pred_x)\n            batch_pred_y = get_simcc_normalized(batch_pred_y)\n\n            B, K, _ = batch_pred_x.shape\n            # B, K, Wx -> B, K, Wx, 1\n            x = batch_pred_x.reshape(B, K, 1, -1)\n            # B, K, Wy -> B, K, 1, Wy\n            y = batch_pred_y.reshape(B, K, -1, 1)\n            # B, K, Wx, Wy\n            batch_heatmaps = torch.matmul(y, x)\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n\n            for pred_instances, pred_x, pred_y in zip(preds,\n                                                      to_numpy(batch_pred_x),\n                                                      to_numpy(batch_pred_y)):\n\n                pred_instances.keypoint_x_labels = pred_x[None]\n                pred_instances.keypoint_y_labels = pred_y[None]\n\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        train_cfg: OptConfigType = {},\n    ) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_x, pred_y = self.forward(feats)\n\n        gt_x = torch.cat([\n            d.gt_instance_labels.keypoint_x_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        gt_y = torch.cat([\n            d.gt_instance_labels.keypoint_y_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        keypoint_weights = torch.cat(\n            [\n                d.gt_instance_labels.keypoint_weights\n                for d in batch_data_samples\n            ],\n            dim=0,\n        )\n\n        pred_simcc = (pred_x, pred_y)\n        gt_simcc = (gt_x, gt_y)\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_simcc, gt_simcc, keypoint_weights)\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = simcc_pck_accuracy(\n            output=to_numpy(pred_simcc),\n            target=to_numpy(gt_simcc),\n            simcc_split_ratio=self.simcc_split_ratio,\n            mask=to_numpy(keypoint_weights) > 0,\n        )\n\n        acc_pose = torch.tensor(avg_acc, device=gt_x.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(type='Normal', layer=['Conv2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1),\n            dict(type='Normal', layer=['Linear'], std=0.01, bias=0),\n        ]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/coord_cls_heads/simcc_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nfrom mmcv.cnn import build_conv_layer\nfrom mmengine.dist import get_dist_info\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.codecs.utils import get_simcc_normalized\nfrom mmpose.evaluation.functional import simcc_pck_accuracy\nfrom mmpose.models.utils.tta import flip_vectors\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptSampleList)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass SimCCHead(BaseHead):\n    \"\"\"Top-down heatmap head introduced in `SimCC`_ by Li et al (2022). The\n    head is composed of a few deconvolutional layers followed by a fully-\n    connected layer to generate 1d representation from low-resolution feature\n    maps.\n\n    Args:\n        in_channels (int | sequence[int]): Number of channels in the input\n            feature map\n        out_channels (int): Number of channels in the output heatmap\n        input_size (tuple): Input image size in shape [w, h]\n        in_featuremap_size (int | sequence[int]): Size of input feature map\n        simcc_split_ratio (float): Split ratio of pixels\n        deconv_type (str, optional): The type of deconv head which should\n            be one of the following options:\n\n                - ``'heatmap'``: make deconv layers in `HeatmapHead`\n                - ``'vipnas'``: make deconv layers in `ViPNASHead`\n\n            Defaults to ``'Heatmap'``\n        deconv_out_channels (sequence[int]): The output channel number of each\n            deconv layer. Defaults to ``(256, 256, 256)``\n        deconv_kernel_sizes (sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.Defaults to\n            ``(4, 4, 4)``\n        deconv_num_groups (Sequence[int], optional): The group number of each\n            deconv layer. Defaults to ``(16, 16, 16)``\n        conv_out_channels (sequence[int], optional): The output channel number\n            of each intermediate conv layer. ``None`` means no intermediate\n            conv layer between deconv layers and the final conv layer.\n            Defaults to ``None``\n        conv_kernel_sizes (sequence[int | tuple], optional): The kernel size\n            of each intermediate conv layer. Defaults to ``None``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KLDiscretLoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`SimCC`: https://arxiv.org/abs/2107.03332\n    \"\"\"\n\n    _version = 2\n\n    def __init__(\n        self,\n        in_channels: Union[int, Sequence[int]],\n        out_channels: int,\n        input_size: Tuple[int, int],\n        in_featuremap_size: Tuple[int, int],\n        simcc_split_ratio: float = 2.0,\n        deconv_type: str = 'heatmap',\n        deconv_out_channels: OptIntSeq = (256, 256, 256),\n        deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n        deconv_num_groups: OptIntSeq = (16, 16, 16),\n        conv_out_channels: OptIntSeq = None,\n        conv_kernel_sizes: OptIntSeq = None,\n        final_layer: dict = dict(kernel_size=1),\n        loss: ConfigType = dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder: OptConfigType = None,\n        init_cfg: OptConfigType = None,\n    ):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        if deconv_type not in {'heatmap', 'vipnas'}:\n            raise ValueError(\n                f'{self.__class__.__name__} got invalid `deconv_type` value'\n                f'{deconv_type}. Should be one of '\n                '{\"heatmap\", \"vipnas\"}')\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.input_size = input_size\n        self.in_featuremap_size = in_featuremap_size\n        self.simcc_split_ratio = simcc_split_ratio\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        num_deconv = len(deconv_out_channels) if deconv_out_channels else 0\n        if num_deconv != 0:\n            self.heatmap_size = tuple(\n                [s * (2**num_deconv) for s in in_featuremap_size])\n\n            # deconv layers + 1x1 conv\n            self.deconv_head = self._make_deconv_head(\n                in_channels=in_channels,\n                out_channels=out_channels,\n                deconv_type=deconv_type,\n                deconv_out_channels=deconv_out_channels,\n                deconv_kernel_sizes=deconv_kernel_sizes,\n                deconv_num_groups=deconv_num_groups,\n                conv_out_channels=conv_out_channels,\n                conv_kernel_sizes=conv_kernel_sizes,\n                final_layer=final_layer)\n\n            if final_layer is not None:\n                in_channels = out_channels\n            else:\n                in_channels = deconv_out_channels[-1]\n\n        else:\n            self.deconv_head = None\n\n            if final_layer is not None:\n                cfg = dict(\n                    type='Conv2d',\n                    in_channels=in_channels,\n                    out_channels=out_channels,\n                    kernel_size=1)\n                cfg.update(final_layer)\n                self.final_layer = build_conv_layer(cfg)\n            else:\n                self.final_layer = None\n\n            self.heatmap_size = in_featuremap_size\n\n        # Define SimCC layers\n        flatten_dims = self.heatmap_size[0] * self.heatmap_size[1]\n\n        W = int(self.input_size[0] * self.simcc_split_ratio)\n        H = int(self.input_size[1] * self.simcc_split_ratio)\n\n        self.mlp_head_x = nn.Linear(flatten_dims, W)\n        self.mlp_head_y = nn.Linear(flatten_dims, H)\n\n    def _make_deconv_head(\n        self,\n        in_channels: Union[int, Sequence[int]],\n        out_channels: int,\n        deconv_type: str = 'heatmap',\n        deconv_out_channels: OptIntSeq = (256, 256, 256),\n        deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n        deconv_num_groups: OptIntSeq = (16, 16, 16),\n        conv_out_channels: OptIntSeq = None,\n        conv_kernel_sizes: OptIntSeq = None,\n        final_layer: dict = dict(kernel_size=1)\n    ) -> nn.Module:\n        \"\"\"Create deconvolutional layers by given parameters.\"\"\"\n\n        if deconv_type == 'heatmap':\n            deconv_head = MODELS.build(\n                dict(\n                    type='HeatmapHead',\n                    in_channels=self.in_channels,\n                    out_channels=out_channels,\n                    deconv_out_channels=deconv_out_channels,\n                    deconv_kernel_sizes=deconv_kernel_sizes,\n                    conv_out_channels=conv_out_channels,\n                    conv_kernel_sizes=conv_kernel_sizes,\n                    final_layer=final_layer))\n        else:\n            deconv_head = MODELS.build(\n                dict(\n                    type='ViPNASHead',\n                    in_channels=in_channels,\n                    out_channels=out_channels,\n                    deconv_out_channels=deconv_out_channels,\n                    deconv_num_groups=deconv_num_groups,\n                    conv_out_channels=conv_out_channels,\n                    conv_kernel_sizes=conv_kernel_sizes,\n                    final_layer=final_layer))\n\n        return deconv_head\n\n    def forward(self, feats: Tuple[Tensor]) -> Tuple[Tensor, Tensor]:\n        \"\"\"Forward the network.\n\n        The input is the featuremap extracted by backbone and the\n        output is the simcc representation.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            pred_x (Tensor): 1d representation of x.\n            pred_y (Tensor): 1d representation of y.\n        \"\"\"\n        if self.deconv_head is None:\n            feats = feats[-1]\n            if self.final_layer is not None:\n                feats = self.final_layer(feats)\n        else:\n            feats = self.deconv_head(feats)\n\n        # flatten the output heatmap\n        x = torch.flatten(feats, 2)\n\n        pred_x = self.mlp_head_x(x)\n        pred_y = self.mlp_head_y(x)\n\n        return pred_x, pred_y\n\n    def predict(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        test_cfg: OptConfigType = {},\n    ) -> InstanceList:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            List[InstanceData]: The pose predictions, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n                - keypoint_x_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the x direction\n                - keypoint_y_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the y direction\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n\n            _batch_pred_x, _batch_pred_y = self.forward(_feats)\n\n            _batch_pred_x_flip, _batch_pred_y_flip = self.forward(_feats_flip)\n            _batch_pred_x_flip, _batch_pred_y_flip = flip_vectors(\n                _batch_pred_x_flip,\n                _batch_pred_y_flip,\n                flip_indices=flip_indices)\n\n            batch_pred_x = (_batch_pred_x + _batch_pred_x_flip) * 0.5\n            batch_pred_y = (_batch_pred_y + _batch_pred_y_flip) * 0.5\n        else:\n            batch_pred_x, batch_pred_y = self.forward(feats)\n\n        preds = self.decode((batch_pred_x, batch_pred_y))\n\n        if test_cfg.get('output_heatmaps', False):\n            rank, _ = get_dist_info()\n            if rank == 0:\n                warnings.warn('The predicted simcc values are normalized for '\n                              'visualization. This may cause discrepancy '\n                              'between the keypoint scores and the 1D heatmaps'\n                              '.')\n\n            # normalize the predicted 1d distribution\n            sigma = self.decoder.sigma\n            batch_pred_x = get_simcc_normalized(batch_pred_x, sigma[0])\n            batch_pred_y = get_simcc_normalized(batch_pred_y, sigma[1])\n\n            B, K, _ = batch_pred_x.shape\n            # B, K, Wx -> B, K, Wx, 1\n            x = batch_pred_x.reshape(B, K, 1, -1)\n            # B, K, Wy -> B, K, 1, Wy\n            y = batch_pred_y.reshape(B, K, -1, 1)\n            # B, K, Wx, Wy\n            batch_heatmaps = torch.matmul(y, x)\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n\n            for pred_instances, pred_x, pred_y in zip(preds,\n                                                      to_numpy(batch_pred_x),\n                                                      to_numpy(batch_pred_y)):\n\n                pred_instances.keypoint_x_labels = pred_x[None]\n                pred_instances.keypoint_y_labels = pred_y[None]\n\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        train_cfg: OptConfigType = {},\n    ) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_x, pred_y = self.forward(feats)\n\n        gt_x = torch.cat([\n            d.gt_instance_labels.keypoint_x_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        gt_y = torch.cat([\n            d.gt_instance_labels.keypoint_y_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        keypoint_weights = torch.cat(\n            [\n                d.gt_instance_labels.keypoint_weights\n                for d in batch_data_samples\n            ],\n            dim=0,\n        )\n\n        pred_simcc = (pred_x, pred_y)\n        gt_simcc = (gt_x, gt_y)\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_simcc, gt_simcc, keypoint_weights)\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = simcc_pck_accuracy(\n            output=to_numpy(pred_simcc),\n            target=to_numpy(gt_simcc),\n            simcc_split_ratio=self.simcc_split_ratio,\n            mask=to_numpy(keypoint_weights) > 0,\n        )\n\n        acc_pose = torch.tensor(avg_acc, device=gt_x.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(\n                type='Normal', layer=['Conv2d', 'ConvTranspose2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1),\n            dict(type='Normal', layer=['Linear'], std=0.01, bias=0),\n        ]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .ae_head import AssociativeEmbeddingHead\nfrom .cid_head import CIDHead\nfrom .cpm_head import CPMHead\nfrom .heatmap_head import HeatmapHead\nfrom .internet_head import InternetHead\nfrom .mspn_head import MSPNHead\nfrom .vipnas_head import ViPNASHead\n\n__all__ = [\n    'HeatmapHead', 'CPMHead', 'MSPNHead', 'ViPNASHead',\n    'AssociativeEmbeddingHead', 'CIDHead', 'InternetHead'\n]\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/ae_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Sequence, Tuple, Union\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom mmengine.utils import is_list_of\nfrom torch import Tensor\n\nfrom mmpose.models.utils.tta import aggregate_heatmaps, flip_heatmaps\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, Features, InstanceList,\n                                 OptConfigType, OptSampleList, Predictions)\nfrom .heatmap_head import HeatmapHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass AssociativeEmbeddingHead(HeatmapHead):\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 num_keypoints: int,\n                 tag_dim: int = 1,\n                 tag_per_keypoint: bool = True,\n                 deconv_out_channels: OptIntSeq = (256, 256, 256),\n                 deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n                 conv_out_channels: OptIntSeq = None,\n                 conv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 keypoint_loss: ConfigType = dict(type='KeypointMSELoss'),\n                 tag_loss: ConfigType = dict(type='AssociativeEmbeddingLoss'),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if tag_per_keypoint:\n            out_channels = num_keypoints * (1 + tag_dim)\n        else:\n            out_channels = num_keypoints + tag_dim\n\n        loss = dict(\n            type='CombinedLoss',\n            losses=dict(keypoint_loss=keypoint_loss, tag_loss=tag_loss))\n\n        super().__init__(\n            in_channels=in_channels,\n            out_channels=out_channels,\n            deconv_out_channels=deconv_out_channels,\n            deconv_kernel_sizes=deconv_kernel_sizes,\n            conv_out_channels=conv_out_channels,\n            conv_kernel_sizes=conv_kernel_sizes,\n            final_layer=final_layer,\n            loss=loss,\n            decoder=decoder,\n            init_cfg=init_cfg)\n\n        self.num_keypoints = num_keypoints\n        self.tag_dim = tag_dim\n        self.tag_per_keypoint = tag_per_keypoint\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Features): The features which could be in following forms:\n\n                - Tuple[Tensor]: multi-stage features from the backbone\n                - List[Tuple[Tensor]]: multiple features for TTA where either\n                    `flip_test` or `multiscale_test` is applied\n                - List[List[Tuple[Tensor]]]: multiple features for TTA where\n                    both `flip_test` and `multiscale_test` are applied\n\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n        # test configs\n        multiscale_test = test_cfg.get('multiscale_test', False)\n        flip_test = test_cfg.get('flip_test', False)\n        shift_heatmap = test_cfg.get('shift_heatmap', False)\n        align_corners = test_cfg.get('align_corners', False)\n        restore_heatmap_size = test_cfg.get('restore_heatmap_size', False)\n        output_heatmaps = test_cfg.get('output_heatmaps', False)\n\n        # enable multi-scale test\n        if multiscale_test:\n            # TTA: multi-scale test\n            assert is_list_of(feats, list if flip_test else tuple)\n        else:\n            assert is_list_of(feats, tuple if flip_test else Tensor)\n            feats = [feats]\n\n        # resize heatmaps to align with with input size\n        if restore_heatmap_size:\n            img_shape = batch_data_samples[0].metainfo['img_shape']\n            assert all(d.metainfo['img_shape'] == img_shape\n                       for d in batch_data_samples)\n            img_h, img_w = img_shape\n            heatmap_size = (img_w, img_h)\n        else:\n            heatmap_size = None\n\n        multiscale_heatmaps = []\n        multiscale_tags = []\n\n        for scale_idx, _feats in enumerate(feats):\n            if not flip_test:\n                _heatmaps, _tags = self.forward(_feats)\n\n            else:\n                # TTA: flip test\n                assert isinstance(_feats, list) and len(_feats) == 2\n                flip_indices = batch_data_samples[0].metainfo['flip_indices']\n                # original\n                _feats_orig, _feats_flip = _feats\n                _heatmaps_orig, _tags_orig = self.forward(_feats_orig)\n\n                # flipped\n                _heatmaps_flip, _tags_flip = self.forward(_feats_flip)\n                _heatmaps_flip = flip_heatmaps(\n                    _heatmaps_flip,\n                    flip_mode='heatmap',\n                    flip_indices=flip_indices,\n                    shift_heatmap=shift_heatmap)\n                _tags_flip = self._flip_tags(\n                    _tags_flip,\n                    flip_indices=flip_indices,\n                    shift_heatmap=shift_heatmap)\n\n                # aggregated heatmaps\n                _heatmaps = aggregate_heatmaps(\n                    [_heatmaps_orig, _heatmaps_flip],\n                    size=heatmap_size,\n                    align_corners=align_corners,\n                    mode='average')\n\n                # aggregated tags (only at original scale)\n                if scale_idx == 0:\n                    _tags = aggregate_heatmaps([_tags_orig, _tags_flip],\n                                               size=heatmap_size,\n                                               align_corners=align_corners,\n                                               mode='concat')\n                else:\n                    _tags = None\n\n            multiscale_heatmaps.append(_heatmaps)\n            multiscale_tags.append(_tags)\n\n        # aggregate multi-scale heatmaps\n        if len(feats) > 1:\n            batch_heatmaps = aggregate_heatmaps(\n                multiscale_heatmaps,\n                align_corners=align_corners,\n                mode='average')\n        else:\n            batch_heatmaps = multiscale_heatmaps[0]\n        # only keep tags at original scale\n        batch_tags = multiscale_tags[0]\n\n        batch_outputs = tuple([batch_heatmaps, batch_tags])\n        preds = self.decode(batch_outputs)\n\n        if output_heatmaps:\n            pred_fields = []\n            for _heatmaps, _tags in zip(batch_heatmaps.detach(),\n                                        batch_tags.detach()):\n                pred_fields.append(PixelData(heatmaps=_heatmaps, tags=_tags))\n\n            return preds, pred_fields\n        else:\n            return preds\n\n    def _flip_tags(self,\n                   tags: Tensor,\n                   flip_indices: List[int],\n                   shift_heatmap: bool = True):\n        \"\"\"Flip the tagging heatmaps horizontally for test-time augmentation.\n\n        Args:\n            tags (Tensor): batched tagging heatmaps to flip\n            flip_indices (List[int]): The indices of each keypoint's symmetric\n            keypoint\n            shift_heatmap (bool): Shift the flipped heatmaps to align with the\n            original heatmaps and improve accuracy. Defaults to ``True``\n\n        Returns:\n            Tensor: flipped tagging heatmaps\n        \"\"\"\n        B, C, H, W = tags.shape\n        K = self.num_keypoints\n        L = self.tag_dim\n\n        tags = tags.flip(-1)\n\n        if self.tag_per_keypoint:\n            assert C == K * L\n            tags = tags.view(B, L, K, H, W)\n            tags = tags[:, :, flip_indices]\n            tags = tags.view(B, C, H, W)\n\n        if shift_heatmap:\n            tags[..., 1:] = tags[..., :-1].clone()\n\n        return tags\n\n    def decode(self, batch_outputs: Union[Tensor,\n                                          Tuple[Tensor]]) -> InstanceList:\n        \"\"\"Decode keypoints from outputs.\n\n        Args:\n            batch_outputs (Tensor | Tuple[Tensor]): The network outputs of\n                a data batch\n\n        Returns:\n            List[InstanceData]: A list of InstanceData, each contains the\n            decoded pose information of the instances of one data sample.\n        \"\"\"\n\n        def _pack_and_call(args, func):\n            if not isinstance(args, tuple):\n                args = (args, )\n            return func(*args)\n\n        if self.decoder is None:\n            raise RuntimeError(\n                f'The decoder has not been set in {self.__class__.__name__}. '\n                'Please set the decoder configs in the init parameters to '\n                'enable head methods `head.predict()` and `head.decode()`')\n\n        if self.decoder.support_batch_decoding:\n            batch_keypoints, batch_scores, batch_instance_scores = \\\n                _pack_and_call(batch_outputs, self.decoder.batch_decode)\n\n        else:\n            batch_output_np = to_numpy(batch_outputs, unzip=True)\n            batch_keypoints = []\n            batch_scores = []\n            batch_instance_scores = []\n            for outputs in batch_output_np:\n                keypoints, scores, instance_scores = _pack_and_call(\n                    outputs, self.decoder.decode)\n                batch_keypoints.append(keypoints)\n                batch_scores.append(scores)\n                batch_instance_scores.append(instance_scores)\n\n        preds = [\n            InstanceData(\n                bbox_scores=instance_scores,\n                keypoints=keypoints,\n                keypoint_scores=scores)\n            for keypoints, scores, instance_scores in zip(\n                batch_keypoints, batch_scores, batch_instance_scores)\n        ]\n\n        return preds\n\n    def forward(self, feats: Tuple[Tensor]) -> Tuple[Tensor, Tensor]:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the heatmaps and tags.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            tuple:\n            - heatmaps (Tensor): output heatmaps\n            - tags (Tensor): output tags\n        \"\"\"\n\n        output = super().forward(feats)\n        heatmaps = output[:, :self.num_keypoints]\n        tags = output[:, self.num_keypoints:]\n        return heatmaps, tags\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        pred_heatmaps, pred_tags = self.forward(feats)\n\n        if not self.tag_per_keypoint:\n            pred_tags = pred_tags.repeat((1, self.num_keypoints, 1, 1))\n\n        gt_heatmaps = torch.stack(\n            [d.gt_fields.heatmaps for d in batch_data_samples])\n        gt_masks = torch.stack(\n            [d.gt_fields.heatmap_mask for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n        keypoint_indices = [\n            d.gt_instance_labels.keypoint_indices for d in batch_data_samples\n        ]\n\n        loss_kpt = self.loss_module.keypoint_loss(pred_heatmaps, gt_heatmaps,\n                                                  keypoint_weights, gt_masks)\n\n        loss_pull, loss_push = self.loss_module.tag_loss(\n            pred_tags, keypoint_indices)\n\n        losses = {\n            'loss_kpt': loss_kpt,\n            'loss_pull': loss_pull,\n            'loss_push': loss_push\n        }\n\n        return losses\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/cid_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Dict, Optional, Sequence, Tuple, Union\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import build_conv_layer\nfrom mmengine.model import BaseModule, ModuleDict\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import Tensor\n\nfrom mmpose.models.utils.tta import flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.typing import (ConfigType, Features, OptConfigType,\n                                 OptSampleList, Predictions)\nfrom ..base_head import BaseHead\n\n\ndef smooth_heatmaps(heatmaps: Tensor, blur_kernel_size: int) -> Tensor:\n    \"\"\"Smooth the heatmaps by blurring and averaging.\n\n    Args:\n        heatmaps (Tensor): The heatmaps to smooth.\n        blur_kernel_size (int): The kernel size for blurring the heatmaps.\n\n    Returns:\n        Tensor: The smoothed heatmaps.\n    \"\"\"\n    smoothed_heatmaps = torch.nn.functional.avg_pool2d(\n        heatmaps, blur_kernel_size, 1, (blur_kernel_size - 1) // 2)\n    smoothed_heatmaps = (heatmaps + smoothed_heatmaps) / 2.0\n    return smoothed_heatmaps\n\n\nclass TruncSigmoid(nn.Sigmoid):\n    \"\"\"A sigmoid activation function that truncates the output to the given\n    range.\n\n    Args:\n        min (float, optional): The minimum value to clamp the output to.\n            Defaults to 0.0\n        max (float, optional): The maximum value to clamp the output to.\n            Defaults to 1.0\n    \"\"\"\n\n    def __init__(self, min: float = 0.0, max: float = 1.0):\n        super(TruncSigmoid, self).__init__()\n        self.min = min\n        self.max = max\n\n    def forward(self, input: Tensor) -> Tensor:\n        \"\"\"Computes the truncated sigmoid activation of the input tensor.\"\"\"\n        output = torch.sigmoid(input)\n        output = output.clamp(min=self.min, max=self.max)\n        return output\n\n\nclass IIAModule(BaseModule):\n    \"\"\"Instance Information Abstraction module introduced in `CID`. This module\n    extracts the feature representation vectors for each instance.\n\n    Args:\n        in_channels (int): Number of channels in the input feature tensor\n        out_channels (int): Number of channels of the output heatmaps\n        clamp_delta (float, optional): A small value that prevents the sigmoid\n            activation from becoming saturated. Defaults to 1e-4.\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: int,\n        out_channels: int,\n        clamp_delta: float = 1e-4,\n        init_cfg: OptConfigType = None,\n    ):\n        super().__init__(init_cfg=init_cfg)\n\n        self.keypoint_root_conv = build_conv_layer(\n            dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=1))\n        self.sigmoid = TruncSigmoid(min=clamp_delta, max=1 - clamp_delta)\n\n    def forward(self, feats: Tensor):\n        heatmaps = self.keypoint_root_conv(feats)\n        heatmaps = self.sigmoid(heatmaps)\n        return heatmaps\n\n    def _sample_feats(self, feats: Tensor, indices: Tensor) -> Tensor:\n        \"\"\"Extract feature vectors at the specified indices from the input\n        feature map.\n\n        Args:\n            feats (Tensor): Input feature map.\n            indices (Tensor): Indices of the feature vectors to extract.\n\n        Returns:\n            Tensor: Extracted feature vectors.\n        \"\"\"\n        assert indices.dtype == torch.long\n        if indices.shape[1] == 3:\n            b, w, h = [ind.squeeze(-1) for ind in indices.split(1, -1)]\n            instance_feats = feats[b, :, h, w]\n        elif indices.shape[1] == 2:\n            w, h = [ind.squeeze(-1) for ind in indices.split(1, -1)]\n            instance_feats = feats[:, :, h, w]\n            instance_feats = instance_feats.permute(0, 2, 1)\n            instance_feats = instance_feats.reshape(-1,\n                                                    instance_feats.shape[-1])\n\n        else:\n            raise ValueError(f'`indices` should have 2 or 3 channels, '\n                             f'but got f{indices.shape[1]}')\n        return instance_feats\n\n    def _hierarchical_pool(self, heatmaps: Tensor) -> Tensor:\n        \"\"\"Conduct max pooling on the input heatmaps with different kernel size\n        according to the input size.\n\n        Args:\n            heatmaps (Tensor): Input heatmaps.\n\n        Returns:\n            Tensor: Result of hierarchical pooling.\n        \"\"\"\n        map_size = (heatmaps.shape[-1] + heatmaps.shape[-2]) / 2.0\n        if map_size > 300:\n            maxm = torch.nn.functional.max_pool2d(heatmaps, 7, 1, 3)\n        elif map_size > 200:\n            maxm = torch.nn.functional.max_pool2d(heatmaps, 5, 1, 2)\n        else:\n            maxm = torch.nn.functional.max_pool2d(heatmaps, 3, 1, 1)\n        return maxm\n\n    def forward_train(self, feats: Tensor, instance_coords: Tensor,\n                      instance_imgids: Tensor) -> Tuple[Tensor, Tensor]:\n        \"\"\"Forward pass during training.\n\n        Args:\n            feats (Tensor): Input feature tensor.\n            instance_coords (Tensor): Coordinates of the instance roots.\n            instance_imgids (Tensor): Sample indices of each instances\n                in the batch.\n\n        Returns:\n            Tuple[Tensor, Tensor]: Extracted feature vectors and heatmaps\n                for the instances.\n        \"\"\"\n        heatmaps = self.forward(feats)\n        indices = torch.cat((instance_imgids[:, None], instance_coords), dim=1)\n        instance_feats = self._sample_feats(feats, indices)\n\n        return instance_feats, heatmaps\n\n    def forward_test(\n        self, feats: Tensor, test_cfg: Dict\n    ) -> Tuple[Optional[Tensor], Optional[Tensor], Optional[Tensor]]:\n        \"\"\"Forward pass during testing.\n\n        Args:\n            feats (Tensor): Input feature tensor.\n            test_cfg (Dict): Testing configuration, including:\n                - blur_kernel_size (int, optional): Kernel size for blurring\n                    the heatmaps. Defaults to 3.\n                - max_instances (int, optional): Maximum number of instances\n                    to extract. Defaults to 30.\n                - score_threshold (float, optional): Minimum score for\n                    extracting an instance. Defaults to 0.01.\n                - flip_test (bool, optional): Whether to compute the average\n                    of the heatmaps across the batch dimension.\n                    Defaults to False.\n\n        Returns:\n            A tuple of Tensor including extracted feature vectors,\n            coordinates, and scores of the instances. Any of these can be\n            empty Tensor if no instances are extracted.\n        \"\"\"\n        blur_kernel_size = test_cfg.get('blur_kernel_size', 3)\n        max_instances = test_cfg.get('max_instances', 30)\n        score_threshold = test_cfg.get('score_threshold', 0.01)\n        H, W = feats.shape[-2:]\n\n        # compute heatmaps\n        heatmaps = self.forward(feats).narrow(1, -1, 1)\n        if test_cfg.get('flip_test', False):\n            heatmaps = heatmaps.mean(dim=0, keepdims=True)\n        smoothed_heatmaps = smooth_heatmaps(heatmaps, blur_kernel_size)\n\n        # decode heatmaps\n        maximums = self._hierarchical_pool(smoothed_heatmaps)\n        maximums = torch.eq(maximums, smoothed_heatmaps).float()\n        maximums = (smoothed_heatmaps * maximums).reshape(-1)\n        scores, pos_ind = maximums.topk(max_instances, dim=0)\n        select_ind = (scores > (score_threshold)).nonzero().squeeze(1)\n        scores, pos_ind = scores[select_ind], pos_ind[select_ind]\n\n        # sample feature vectors from feature map\n        instance_coords = torch.stack((pos_ind % W, pos_ind // W), dim=1)\n        instance_feats = self._sample_feats(feats, instance_coords)\n\n        return instance_feats, instance_coords, scores\n\n\nclass ChannelAttention(nn.Module):\n    \"\"\"Channel-wise attention module introduced in `CID`.\n\n    Args:\n        in_channels (int): The number of channels of the input instance\n            vectors.\n        out_channels (int): The number of channels of the transformed instance\n            vectors.\n    \"\"\"\n\n    def __init__(self, in_channels: int, out_channels: int):\n        super(ChannelAttention, self).__init__()\n        self.atn = nn.Linear(in_channels, out_channels)\n\n    def forward(self, global_feats: Tensor, instance_feats: Tensor) -> Tensor:\n        \"\"\"Applies attention to the channel dimension of the input tensor.\"\"\"\n\n        instance_feats = self.atn(instance_feats).unsqueeze(2).unsqueeze(3)\n        return global_feats * instance_feats\n\n\nclass SpatialAttention(nn.Module):\n    \"\"\"Spatial-wise attention module introduced in `CID`.\n\n    Args:\n        in_channels (int): The number of channels of the input instance\n            vectors.\n        out_channels (int): The number of channels of the transformed instance\n            vectors.\n    \"\"\"\n\n    def __init__(self, in_channels, out_channels):\n        super(SpatialAttention, self).__init__()\n        self.atn = nn.Linear(in_channels, out_channels)\n        self.feat_stride = 4\n        self.conv = nn.Conv2d(3, 1, 5, 1, 2)\n\n    def _get_pixel_coords(self, heatmap_size: Tuple, device: str = 'cpu'):\n        \"\"\"Get pixel coordinates for each element in the heatmap.\n\n        Args:\n            heatmap_size (tuple): Size of the heatmap in (W, H) format.\n            device (str): Device to put the resulting tensor on.\n\n        Returns:\n            Tensor of shape (batch_size, num_pixels, 2) containing the pixel\n            coordinates for each element in the heatmap.\n        \"\"\"\n        w, h = heatmap_size\n        y, x = torch.meshgrid(torch.arange(h), torch.arange(w))\n        pixel_coords = torch.stack((x, y), dim=-1).reshape(-1, 2)\n        pixel_coords = pixel_coords.float().to(device) + 0.5\n        return pixel_coords\n\n    def forward(self, global_feats: Tensor, instance_feats: Tensor,\n                instance_coords: Tensor) -> Tensor:\n        \"\"\"Perform spatial attention.\n\n        Args:\n            global_feats (Tensor): Tensor containing the global features.\n            instance_feats (Tensor): Tensor containing the instance feature\n                vectors.\n            instance_coords (Tensor): Tensor containing the root coordinates\n                of the instances.\n\n        Returns:\n            Tensor containing the modulated global features.\n        \"\"\"\n        B, C, H, W = global_feats.size()\n\n        instance_feats = self.atn(instance_feats).reshape(B, C, 1, 1)\n        feats = global_feats * instance_feats.expand_as(global_feats)\n        fsum = torch.sum(feats, dim=1, keepdim=True)\n\n        pixel_coords = self._get_pixel_coords((W, H), feats.device)\n        relative_coords = instance_coords.reshape(\n            -1, 1, 2) - pixel_coords.reshape(1, -1, 2)\n        relative_coords = relative_coords.permute(0, 2, 1) / 32.0\n        relative_coords = relative_coords.reshape(B, 2, H, W)\n\n        input_feats = torch.cat((fsum, relative_coords), dim=1)\n        mask = self.conv(input_feats).sigmoid()\n        return global_feats * mask\n\n\nclass GFDModule(BaseModule):\n    \"\"\"Global Feature Decoupling module introduced in `CID`. This module\n    extracts the decoupled heatmaps for each instance.\n\n    Args:\n        in_channels (int): Number of channels in the input feature map\n        out_channels (int): Number of channels of the output heatmaps\n            for each instance\n        gfd_channels (int): Number of channels in the transformed feature map\n        clamp_delta (float, optional): A small value that prevents the sigmoid\n            activation from becoming saturated. Defaults to 1e-4.\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: int,\n        out_channels: int,\n        gfd_channels: int,\n        clamp_delta: float = 1e-4,\n        init_cfg: OptConfigType = None,\n    ):\n        super().__init__(init_cfg=init_cfg)\n\n        self.conv_down = build_conv_layer(\n            dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=gfd_channels,\n                kernel_size=1))\n\n        self.channel_attention = ChannelAttention(in_channels, gfd_channels)\n        self.spatial_attention = SpatialAttention(in_channels, gfd_channels)\n        self.fuse_attention = build_conv_layer(\n            dict(\n                type='Conv2d',\n                in_channels=gfd_channels * 2,\n                out_channels=gfd_channels,\n                kernel_size=1))\n        self.heatmap_conv = build_conv_layer(\n            dict(\n                type='Conv2d',\n                in_channels=gfd_channels,\n                out_channels=out_channels,\n                kernel_size=1))\n        self.sigmoid = TruncSigmoid(min=clamp_delta, max=1 - clamp_delta)\n\n    def forward(\n        self,\n        feats: Tensor,\n        instance_feats: Tensor,\n        instance_coords: Tensor,\n        instance_imgids: Tensor,\n    ) -> Tensor:\n        \"\"\"Extract decoupled heatmaps for each instance.\n\n        Args:\n            feats (Tensor): Input feature maps.\n            instance_feats (Tensor): Tensor containing the instance feature\n                vectors.\n            instance_coords (Tensor): Tensor containing the root coordinates\n                of the instances.\n            instance_imgids (Tensor): Sample indices of each instances\n                in the batch.\n\n        Returns:\n            A tensor containing decoupled heatmaps.\n        \"\"\"\n\n        global_feats = self.conv_down(feats)\n        global_feats = global_feats[instance_imgids]\n        cond_instance_feats = torch.cat(\n            (self.channel_attention(global_feats, instance_feats),\n             self.spatial_attention(global_feats, instance_feats,\n                                    instance_coords)),\n            dim=1)\n\n        cond_instance_feats = self.fuse_attention(cond_instance_feats)\n        cond_instance_feats = torch.nn.functional.relu(cond_instance_feats)\n        cond_instance_feats = self.heatmap_conv(cond_instance_feats)\n        heatmaps = self.sigmoid(cond_instance_feats)\n\n        return heatmaps\n\n\n@MODELS.register_module()\nclass CIDHead(BaseHead):\n    \"\"\"Contextual Instance Decoupling head introduced in `Contextual Instance\n    Decoupling for Robust Multi-Person Pose Estimation (CID)`_ by Wang et al\n    (2022). The head is composed of an Instance Information Abstraction (IIA)\n    module and a Global Feature Decoupling (GFD) module.\n\n    Args:\n        in_channels (int | Sequence[int]): Number of channels in the input\n            feature map\n        num_keypoints (int): Number of keypoints\n        gfd_channels (int): Number of filters in GFD module\n        max_train_instances (int): Maximum number of instances in a batch\n            during training. Defaults to 200\n        heatmap_loss (Config): Config of the heatmap loss. Defaults to use\n            :class:`KeypointMSELoss`\n        coupled_heatmap_loss (Config): Config of the loss for coupled heatmaps.\n            Defaults to use :class:`SoftWeightSmoothL1Loss`\n        decoupled_heatmap_loss (Config): Config of the loss for decoupled\n            heatmaps. Defaults to use :class:`SoftWeightSmoothL1Loss`\n        contrastive_loss (Config): Config of the contrastive loss for\n            representation vectors of instances. Defaults to use\n            :class:`InfoNCELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`CID`: https://openaccess.thecvf.com/content/CVPR2022/html/Wang_\n    Contextual_Instance_Decoupling_for_Robust_Multi-Person_Pose_Estimation_\n    CVPR_2022_paper.html\n    \"\"\"\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 gfd_channels: int,\n                 num_keypoints: int,\n                 prior_prob: float = 0.01,\n                 coupled_heatmap_loss: OptConfigType = dict(\n                     type='FocalHeatmapLoss'),\n                 decoupled_heatmap_loss: OptConfigType = dict(\n                     type='FocalHeatmapLoss'),\n                 contrastive_loss: OptConfigType = dict(type='InfoNCELoss'),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_keypoints = num_keypoints\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # build sub-modules\n        bias_value = -math.log((1 - prior_prob) / prior_prob)\n        self.iia_module = IIAModule(\n            in_channels,\n            num_keypoints + 1,\n            init_cfg=init_cfg + [\n                dict(\n                    type='Normal',\n                    layer=['Conv2d', 'Linear'],\n                    std=0.001,\n                    override=dict(\n                        name='keypoint_root_conv',\n                        type='Normal',\n                        std=0.001,\n                        bias=bias_value))\n            ])\n        self.gfd_module = GFDModule(\n            in_channels,\n            num_keypoints,\n            gfd_channels,\n            init_cfg=init_cfg + [\n                dict(\n                    type='Normal',\n                    layer=['Conv2d', 'Linear'],\n                    std=0.001,\n                    override=dict(\n                        name='heatmap_conv',\n                        type='Normal',\n                        std=0.001,\n                        bias=bias_value))\n            ])\n\n        # build losses\n        self.loss_module = ModuleDict(\n            dict(\n                heatmap_coupled=MODELS.build(coupled_heatmap_loss),\n                heatmap_decoupled=MODELS.build(decoupled_heatmap_loss),\n                contrastive=MODELS.build(contrastive_loss),\n            ))\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(type='Normal', layer=['Conv2d', 'Linear'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1)\n        ]\n        return init_cfg\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the heatmap.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output heatmap.\n        \"\"\"\n        feats = feats[-1]\n        instance_info = self.iia_module.forward_test(feats, {})\n        instance_feats, instance_coords, instance_scores = instance_info\n        instance_imgids = torch.zeros(\n            instance_coords.size(0), dtype=torch.long, device=feats.device)\n        instance_heatmaps = self.gfd_module(feats, instance_feats,\n                                            instance_coords, instance_imgids)\n\n        return instance_heatmaps\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n        metainfo = batch_data_samples[0].metainfo\n\n        if test_cfg.get('flip_test', False):\n            assert isinstance(feats, list) and len(feats) == 2\n\n            feats_flipped = flip_heatmaps(feats[1][-1], shift_heatmap=False)\n            feats = torch.cat((feats[0][-1], feats_flipped))\n        else:\n            feats = feats[-1]\n\n        instance_info = self.iia_module.forward_test(feats, test_cfg)\n        instance_feats, instance_coords, instance_scores = instance_info\n        if len(instance_coords) > 0:\n            instance_imgids = torch.zeros(\n                instance_coords.size(0), dtype=torch.long, device=feats.device)\n            if test_cfg.get('flip_test', False):\n                instance_coords = torch.cat((instance_coords, instance_coords))\n                instance_imgids = torch.cat(\n                    (instance_imgids, instance_imgids + 1))\n            instance_heatmaps = self.gfd_module(feats, instance_feats,\n                                                instance_coords,\n                                                instance_imgids)\n            if test_cfg.get('flip_test', False):\n                flip_indices = batch_data_samples[0].metainfo['flip_indices']\n                instance_heatmaps, instance_heatmaps_flip = torch.chunk(\n                    instance_heatmaps, 2, dim=0)\n                instance_heatmaps_flip = \\\n                    instance_heatmaps_flip[:, flip_indices, :, :]\n                instance_heatmaps = (instance_heatmaps +\n                                     instance_heatmaps_flip) / 2.0\n            instance_heatmaps = smooth_heatmaps(\n                instance_heatmaps, test_cfg.get('blur_kernel_size', 3))\n\n            preds = self.decode((instance_heatmaps, instance_scores[:, None]))\n            preds = InstanceData.cat(preds)\n            preds.keypoints[..., 0] += metainfo['input_size'][\n                0] / instance_heatmaps.shape[-1] / 2.0\n            preds.keypoints[..., 1] += metainfo['input_size'][\n                1] / instance_heatmaps.shape[-2] / 2.0\n            preds = [preds]\n\n        else:\n            preds = [\n                InstanceData(\n                    keypoints=np.empty((0, self.num_keypoints, 2)),\n                    keypoint_scores=np.empty((0, self.num_keypoints)))\n            ]\n            instance_heatmaps = torch.empty(0, self.num_keypoints,\n                                            *feats.shape[-2:])\n\n        if test_cfg.get('output_heatmaps', False):\n            pred_fields = [\n                PixelData(\n                    heatmaps=instance_heatmaps.reshape(\n                        -1, *instance_heatmaps.shape[-2:]))\n            ]\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n\n        # load targets\n        gt_heatmaps, gt_instance_coords, keypoint_weights = [], [], []\n        heatmap_mask = []\n        instance_imgids, gt_instance_heatmaps = [], []\n        for i, d in enumerate(batch_data_samples):\n            gt_heatmaps.append(d.gt_fields.heatmaps)\n            gt_instance_coords.append(d.gt_instance_labels.instance_coords)\n            keypoint_weights.append(d.gt_instance_labels.keypoint_weights)\n            instance_imgids.append(\n                torch.ones(\n                    len(d.gt_instance_labels.instance_coords),\n                    dtype=torch.long) * i)\n\n            instance_heatmaps = d.gt_fields.instance_heatmaps.reshape(\n                -1, self.num_keypoints,\n                *d.gt_fields.instance_heatmaps.shape[1:])\n            gt_instance_heatmaps.append(instance_heatmaps)\n\n            if 'heatmap_mask' in d.gt_fields:\n                heatmap_mask.append(d.gt_fields.heatmap_mask)\n\n        gt_heatmaps = torch.stack(gt_heatmaps)\n        heatmap_mask = torch.stack(heatmap_mask) if heatmap_mask else None\n\n        gt_instance_coords = torch.cat(gt_instance_coords, dim=0)\n        gt_instance_heatmaps = torch.cat(gt_instance_heatmaps, dim=0)\n        keypoint_weights = torch.cat(keypoint_weights, dim=0)\n        instance_imgids = torch.cat(instance_imgids).to(gt_heatmaps.device)\n\n        # feed-forward\n        feats = feats[-1]\n        pred_instance_feats, pred_heatmaps = self.iia_module.forward_train(\n            feats, gt_instance_coords, instance_imgids)\n\n        # conpute contrastive loss\n        contrastive_loss = 0\n        for i in range(len(batch_data_samples)):\n            pred_instance_feat = pred_instance_feats[instance_imgids == i]\n            contrastive_loss += self.loss_module['contrastive'](\n                pred_instance_feat)\n        contrastive_loss = contrastive_loss / max(1, len(instance_imgids))\n\n        # limit the number of instances\n        max_train_instances = train_cfg.get('max_train_instances', -1)\n        if (max_train_instances > 0\n                and len(instance_imgids) > max_train_instances):\n            selected_indices = torch.randperm(\n                len(instance_imgids),\n                device=gt_heatmaps.device,\n                dtype=torch.long)[:max_train_instances]\n            gt_instance_coords = gt_instance_coords[selected_indices]\n            keypoint_weights = keypoint_weights[selected_indices]\n            gt_instance_heatmaps = gt_instance_heatmaps[selected_indices]\n            instance_imgids = instance_imgids[selected_indices]\n            pred_instance_feats = pred_instance_feats[selected_indices]\n\n        # calculate the decoupled heatmaps for each instance\n        pred_instance_heatmaps = self.gfd_module(feats, pred_instance_feats,\n                                                 gt_instance_coords,\n                                                 instance_imgids)\n\n        # calculate losses\n        losses = {\n            'loss/heatmap_coupled':\n            self.loss_module['heatmap_coupled'](pred_heatmaps, gt_heatmaps,\n                                                None, heatmap_mask)\n        }\n        if len(instance_imgids) > 0:\n            losses.update({\n                'loss/heatmap_decoupled':\n                self.loss_module['heatmap_decoupled'](pred_instance_heatmaps,\n                                                      gt_instance_heatmaps,\n                                                      keypoint_weights),\n                'loss/contrastive':\n                contrastive_loss\n            })\n\n        return losses\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to convert old-version state dict of\n        :class:`CIDHead` (before MMPose v1.0.0) to a compatible format\n        of :class:`CIDHead`.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n        version = local_meta.get('version', None)\n        if version and version >= self._version:\n            return\n\n        # convert old-version state dict\n        keys = list(state_dict.keys())\n        for k in keys:\n            if 'keypoint_center_conv' in k:\n                v = state_dict.pop(k)\n                k = k.replace('keypoint_center_conv',\n                              'iia_module.keypoint_root_conv')\n                state_dict[k] = v\n\n            if 'conv_down' in k:\n                v = state_dict.pop(k)\n                k = k.replace('conv_down', 'gfd_module.conv_down')\n                state_dict[k] = v\n\n            if 'c_attn' in k:\n                v = state_dict.pop(k)\n                k = k.replace('c_attn', 'gfd_module.channel_attention')\n                state_dict[k] = v\n\n            if 's_attn' in k:\n                v = state_dict.pop(k)\n                k = k.replace('s_attn', 'gfd_module.spatial_attention')\n                state_dict[k] = v\n\n            if 'fuse_attn' in k:\n                v = state_dict.pop(k)\n                k = k.replace('fuse_attn', 'gfd_module.fuse_attention')\n                state_dict[k] = v\n\n            if 'heatmap_conv' in k:\n                v = state_dict.pop(k)\n                k = k.replace('heatmap_conv', 'gfd_module.heatmap_conv')\n                state_dict[k] = v\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/cpm_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Sequence, Union\n\nimport torch\nfrom mmcv.cnn import build_conv_layer, build_upsample_layer\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import pose_pck_accuracy\nfrom mmpose.models.utils.tta import flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (Features, MultiConfig, OptConfigType,\n                                 OptSampleList, Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass CPMHead(BaseHead):\n    \"\"\"Multi-stage heatmap head introduced in `Convolutional Pose Machines`_ by\n    Wei et al (2016) and used by `Stacked Hourglass Networks`_ by Newell et al\n    (2016). The head consists of multiple branches, each of which has some\n    deconv layers and a simple conv2d layer.\n\n    Args:\n        in_channels (int | Sequence[int]): Number of channels in the input\n            feature maps.\n        out_channels (int): Number of channels in the output heatmaps.\n        num_stages (int): Number of stages.\n        deconv_out_channels (Sequence[int], optional): The output channel\n            number of each deconv layer. Defaults to ``(256, 256, 256)``\n        deconv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.\n            Defaults to ``(4, 4, 4)``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config | List[Config]): Config of the keypoint loss of different\n            stages. Defaults to use :class:`KeypointMSELoss`.\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`Convolutional Pose Machines`: https://arxiv.org/abs/1602.00134\n    .. _`Stacked Hourglass Networks`: https://arxiv.org/abs/1603.06937\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 out_channels: int,\n                 num_stages: int,\n                 deconv_out_channels: OptIntSeq = None,\n                 deconv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 loss: MultiConfig = dict(\n                     type='KeypointMSELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n        super().__init__(init_cfg)\n\n        self.num_stages = num_stages\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n\n        if isinstance(loss, list):\n            if len(loss) != num_stages:\n                raise ValueError(\n                    f'The length of loss_module({len(loss)}) did not match '\n                    f'`num_stages`({num_stages})')\n            self.loss_module = nn.ModuleList(\n                MODELS.build(_loss) for _loss in loss)\n        else:\n            self.loss_module = MODELS.build(loss)\n\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # build multi-stage deconv layers\n        self.multi_deconv_layers = nn.ModuleList([])\n        if deconv_out_channels:\n            if deconv_kernel_sizes is None or len(deconv_out_channels) != len(\n                    deconv_kernel_sizes):\n                raise ValueError(\n                    '\"deconv_out_channels\" and \"deconv_kernel_sizes\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {deconv_out_channels} and '\n                    f'{deconv_kernel_sizes}')\n\n            for _ in range(self.num_stages):\n                deconv_layers = self._make_deconv_layers(\n                    in_channels=in_channels,\n                    layer_out_channels=deconv_out_channels,\n                    layer_kernel_sizes=deconv_kernel_sizes,\n                )\n                self.multi_deconv_layers.append(deconv_layers)\n            in_channels = deconv_out_channels[-1]\n        else:\n            for _ in range(self.num_stages):\n                self.multi_deconv_layers.append(nn.Identity())\n\n        # build multi-stage final layers\n        self.multi_final_layers = nn.ModuleList([])\n        if final_layer is not None:\n            cfg = dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=1)\n            cfg.update(final_layer)\n            for _ in range(self.num_stages):\n                self.multi_final_layers.append(build_conv_layer(cfg))\n        else:\n            for _ in range(self.num_stages):\n                self.multi_final_layers.append(nn.Identity())\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(\n                type='Normal', layer=['Conv2d', 'ConvTranspose2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1)\n        ]\n        return init_cfg\n\n    def _make_deconv_layers(self, in_channels: int,\n                            layer_out_channels: Sequence[int],\n                            layer_kernel_sizes: Sequence[int]) -> nn.Module:\n        \"\"\"Create deconvolutional layers by given parameters.\"\"\"\n\n        layers = []\n        for out_channels, kernel_size in zip(layer_out_channels,\n                                             layer_kernel_sizes):\n            if kernel_size == 4:\n                padding = 1\n                output_padding = 0\n            elif kernel_size == 3:\n                padding = 1\n                output_padding = 1\n            elif kernel_size == 2:\n                padding = 0\n                output_padding = 0\n            else:\n                raise ValueError(f'Unsupported kernel size {kernel_size} for'\n                                 'deconvlutional layers in '\n                                 f'{self.__class__.__name__}')\n            cfg = dict(\n                type='deconv',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=kernel_size,\n                stride=2,\n                padding=padding,\n                output_padding=output_padding,\n                bias=False)\n            layers.append(build_upsample_layer(cfg))\n            layers.append(nn.BatchNorm2d(num_features=out_channels))\n            layers.append(nn.ReLU(inplace=True))\n            in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    def forward(self, feats: Sequence[Tensor]) -> List[Tensor]:\n        \"\"\"Forward the network. The input is multi-stage feature maps and the\n        output is a list of heatmaps from multiple stages.\n\n        Args:\n            feats (Sequence[Tensor]): Multi-stage feature maps.\n\n        Returns:\n            List[Tensor]: A list of output heatmaps from multiple stages.\n        \"\"\"\n        out = []\n        assert len(feats) == self.num_stages, (\n            f'The length of feature maps did not match the '\n            f'`num_stages` in {self.__class__.__name__}')\n        for i in range(self.num_stages):\n            y = self.multi_deconv_layers[i](feats[i])\n            y = self.multi_final_layers[i](y)\n            out.append(y)\n\n        return out\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: OptConfigType = {}) -> Predictions:\n        \"\"\"Predict results from multi-stage feature maps.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n            _batch_heatmaps = self.forward(_feats)[-1]\n            _batch_heatmaps_flip = flip_heatmaps(\n                self.forward(_feats_flip)[-1],\n                flip_mode=test_cfg.get('flip_mode', 'heatmap'),\n                flip_indices=flip_indices,\n                shift_heatmap=test_cfg.get('shift_heatmap', False))\n            batch_heatmaps = (_batch_heatmaps + _batch_heatmaps_flip) * 0.5\n        else:\n            multi_stage_heatmaps = self.forward(feats)\n            batch_heatmaps = multi_stage_heatmaps[-1]\n\n        preds = self.decode(batch_heatmaps)\n\n        if test_cfg.get('output_heatmaps', False):\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(self,\n             feats: Sequence[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: OptConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Sequence[Tensor]): Multi-stage feature maps.\n            batch_data_samples (List[:obj:`PoseDataSample`]): The Data\n                Samples. It usually includes information such as\n                `gt_instances`.\n            train_cfg (Config, optional): The training config.\n\n        Returns:\n            dict: A dictionary of loss components.\n        \"\"\"\n        multi_stage_pred_heatmaps = self.forward(feats)\n\n        gt_heatmaps = torch.stack(\n            [d.gt_fields.heatmaps for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n\n        # calculate losses over multiple stages\n        losses = dict()\n        for i in range(self.num_stages):\n            if isinstance(self.loss_module, nn.ModuleList):\n                # use different loss_module over different stages\n                loss_func = self.loss_module[i]\n            else:\n                # use the same loss_module over different stages\n                loss_func = self.loss_module\n\n            # the `gt_heatmaps` and `keypoint_weights` used to calculate loss\n            # for different stages are the same\n            loss_i = loss_func(multi_stage_pred_heatmaps[i], gt_heatmaps,\n                               keypoint_weights)\n\n            if 'loss_kpt' not in losses:\n                losses['loss_kpt'] = loss_i\n            else:\n                losses['loss_kpt'] += loss_i\n\n        # calculate accuracy\n        _, avg_acc, _ = pose_pck_accuracy(\n            output=to_numpy(multi_stage_pred_heatmaps[-1]),\n            target=to_numpy(gt_heatmaps),\n            mask=to_numpy(keypoint_weights) > 0)\n\n        acc_pose = torch.tensor(avg_acc, device=gt_heatmaps.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/heatmap_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nfrom mmcv.cnn import build_conv_layer, build_upsample_layer\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import pose_pck_accuracy\nfrom mmpose.models.utils.tta import flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, Features, OptConfigType,\n                                 OptSampleList, Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass HeatmapHead(BaseHead):\n    \"\"\"Top-down heatmap head introduced in `Simple Baselines`_ by Xiao et al\n    (2018). The head is composed of a few deconvolutional layers followed by a\n    convolutional layer to generate heatmaps from low-resolution feature maps.\n\n    Args:\n        in_channels (int | Sequence[int]): Number of channels in the input\n            feature map\n        out_channels (int): Number of channels in the output heatmap\n        deconv_out_channels (Sequence[int], optional): The output channel\n            number of each deconv layer. Defaults to ``(256, 256, 256)``\n        deconv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.Defaults to\n            ``(4, 4, 4)``\n        conv_out_channels (Sequence[int], optional): The output channel number\n            of each intermediate conv layer. ``None`` means no intermediate\n            conv layer between deconv layers and the final conv layer.\n            Defaults to ``None``\n        conv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each intermediate conv layer. Defaults to ``None``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KeypointMSELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`Simple Baselines`: https://arxiv.org/abs/1804.06208\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 out_channels: int,\n                 deconv_out_channels: OptIntSeq = (256, 256, 256),\n                 deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n                 conv_out_channels: OptIntSeq = None,\n                 conv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 loss: ConfigType = dict(\n                     type='KeypointMSELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        if deconv_out_channels:\n            if deconv_kernel_sizes is None or len(deconv_out_channels) != len(\n                    deconv_kernel_sizes):\n                raise ValueError(\n                    '\"deconv_out_channels\" and \"deconv_kernel_sizes\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {deconv_out_channels} and '\n                    f'{deconv_kernel_sizes}')\n\n            self.deconv_layers = self._make_deconv_layers(\n                in_channels=in_channels,\n                layer_out_channels=deconv_out_channels,\n                layer_kernel_sizes=deconv_kernel_sizes,\n            )\n            in_channels = deconv_out_channels[-1]\n        else:\n            self.deconv_layers = nn.Identity()\n\n        if conv_out_channels:\n            if conv_kernel_sizes is None or len(conv_out_channels) != len(\n                    conv_kernel_sizes):\n                raise ValueError(\n                    '\"conv_out_channels\" and \"conv_kernel_sizes\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {conv_out_channels} and '\n                    f'{conv_kernel_sizes}')\n\n            self.conv_layers = self._make_conv_layers(\n                in_channels=in_channels,\n                layer_out_channels=conv_out_channels,\n                layer_kernel_sizes=conv_kernel_sizes)\n            in_channels = conv_out_channels[-1]\n        else:\n            self.conv_layers = nn.Identity()\n\n        if final_layer is not None:\n            cfg = dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=1)\n            cfg.update(final_layer)\n            self.final_layer = build_conv_layer(cfg)\n        else:\n            self.final_layer = nn.Identity()\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    def _make_conv_layers(self, in_channels: int,\n                          layer_out_channels: Sequence[int],\n                          layer_kernel_sizes: Sequence[int]) -> nn.Module:\n        \"\"\"Create convolutional layers by given parameters.\"\"\"\n\n        layers = []\n        for out_channels, kernel_size in zip(layer_out_channels,\n                                             layer_kernel_sizes):\n            padding = (kernel_size - 1) // 2\n            cfg = dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=kernel_size,\n                stride=1,\n                padding=padding)\n            layers.append(build_conv_layer(cfg))\n            layers.append(nn.BatchNorm2d(num_features=out_channels))\n            layers.append(nn.ReLU(inplace=True))\n            in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    def _make_deconv_layers(self, in_channels: int,\n                            layer_out_channels: Sequence[int],\n                            layer_kernel_sizes: Sequence[int]) -> nn.Module:\n        \"\"\"Create deconvolutional layers by given parameters.\"\"\"\n\n        layers = []\n        for out_channels, kernel_size in zip(layer_out_channels,\n                                             layer_kernel_sizes):\n            if kernel_size == 4:\n                padding = 1\n                output_padding = 0\n            elif kernel_size == 3:\n                padding = 1\n                output_padding = 1\n            elif kernel_size == 2:\n                padding = 0\n                output_padding = 0\n            else:\n                raise ValueError(f'Unsupported kernel size {kernel_size} for'\n                                 'deconvlutional layers in '\n                                 f'{self.__class__.__name__}')\n            cfg = dict(\n                type='deconv',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=kernel_size,\n                stride=2,\n                padding=padding,\n                output_padding=output_padding,\n                bias=False)\n            layers.append(build_upsample_layer(cfg))\n            layers.append(nn.BatchNorm2d(num_features=out_channels))\n            layers.append(nn.ReLU(inplace=True))\n            in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(\n                type='Normal', layer=['Conv2d', 'ConvTranspose2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1)\n        ]\n        return init_cfg\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the heatmap.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output heatmap.\n        \"\"\"\n        x = feats[-1]\n\n        x = self.deconv_layers(x)\n        x = self.conv_layers(x)\n        x = self.final_layer(x)\n\n        return x\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n            _batch_heatmaps = self.forward(_feats)\n            _batch_heatmaps_flip = flip_heatmaps(\n                self.forward(_feats_flip),\n                flip_mode=test_cfg.get('flip_mode', 'heatmap'),\n                flip_indices=flip_indices,\n                shift_heatmap=test_cfg.get('shift_heatmap', False))\n            batch_heatmaps = (_batch_heatmaps + _batch_heatmaps_flip) * 0.5\n        else:\n            batch_heatmaps = self.forward(feats)\n\n        preds = self.decode(batch_heatmaps)\n\n        if test_cfg.get('output_heatmaps', False):\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        pred_fields = self.forward(feats)\n        gt_heatmaps = torch.stack(\n            [d.gt_fields.heatmaps for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_fields, gt_heatmaps, keypoint_weights)\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        if train_cfg.get('compute_acc', True):\n            _, avg_acc, _ = pose_pck_accuracy(\n                output=to_numpy(pred_fields),\n                target=to_numpy(gt_heatmaps),\n                mask=to_numpy(keypoint_weights) > 0)\n\n            acc_pose = torch.tensor(avg_acc, device=gt_heatmaps.device)\n            losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to convert old-version state dict of\n        :class:`TopdownHeatmapSimpleHead` (before MMPose v1.0.0) to a\n        compatible format of :class:`HeatmapHead`.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n        version = local_meta.get('version', None)\n        if version and version >= self._version:\n            return\n\n        # convert old-version state dict\n        keys = list(state_dict.keys())\n        for _k in keys:\n            if not _k.startswith(prefix):\n                continue\n            v = state_dict.pop(_k)\n            k = _k[len(prefix):]\n            # In old version, \"final_layer\" includes both intermediate\n            # conv layers (new \"conv_layers\") and final conv layers (new\n            # \"final_layer\").\n            #\n            # If there is no intermediate conv layer, old \"final_layer\" will\n            # have keys like \"final_layer.xxx\", which should be still\n            # named \"final_layer.xxx\";\n            #\n            # If there are intermediate conv layers, old \"final_layer\"  will\n            # have keys like \"final_layer.n.xxx\", where the weights of the last\n            # one should be renamed \"final_layer.xxx\", and others should be\n            # renamed \"conv_layers.n.xxx\"\n            k_parts = k.split('.')\n            if k_parts[0] == 'final_layer':\n                if len(k_parts) == 3:\n                    assert isinstance(self.conv_layers, nn.Sequential)\n                    idx = int(k_parts[1])\n                    if idx < len(self.conv_layers):\n                        # final_layer.n.xxx -> conv_layers.n.xxx\n                        k_new = 'conv_layers.' + '.'.join(k_parts[1:])\n                    else:\n                        # final_layer.n.xxx -> final_layer.xxx\n                        k_new = 'final_layer.' + k_parts[2]\n                else:\n                    # final_layer.xxx remains final_layer.xxx\n                    k_new = k\n            else:\n                k_new = k\n\n            state_dict[prefix + k_new] = v\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/internet_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nimport torch.nn.functional as F\nfrom mmengine.model import normal_init\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import multilabel_classification_accuracy\nfrom mmpose.models.necks import GlobalAveragePooling\nfrom mmpose.models.utils.tta import flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, Features, InstanceList,\n                                 OptConfigType, OptSampleList, Predictions)\nfrom ..base_head import BaseHead\nfrom .heatmap_head import HeatmapHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\ndef make_linear_layers(feat_dims, relu_final=False):\n    \"\"\"Make linear layers.\"\"\"\n    layers = []\n    for i in range(len(feat_dims) - 1):\n        layers.append(nn.Linear(feat_dims[i], feat_dims[i + 1]))\n        if i < len(feat_dims) - 2 or \\\n                (i == len(feat_dims) - 2 and relu_final):\n            layers.append(nn.ReLU(inplace=True))\n    return nn.Sequential(*layers)\n\n\nclass Heatmap3DHead(HeatmapHead):\n    \"\"\"Heatmap3DHead is a sub-module of Interhand3DHead, and outputs 3D\n    heatmaps. Heatmap3DHead is composed of (>=0) number of deconv layers and a\n    simple conv2d layer.\n\n    Args:\n        in_channels (int): Number of input channels.\n        out_channels (int): Number of output channels.\n        depth_size (int): Number of depth discretization size. Defaults to 64.\n        deconv_out_channels (Sequence[int], optional): The output channel\n            number of each deconv layer. Defaults to ``(256, 256, 256)``\n        deconv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.Defaults to\n            ``(4, 4, 4)``.\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``.\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 out_channels: int,\n                 depth_size: int = 64,\n                 deconv_out_channels: OptIntSeq = (256, 256, 256),\n                 deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n                 final_layer: dict = dict(kernel_size=1),\n                 init_cfg: OptConfigType = None):\n\n        super().__init__(\n            in_channels=in_channels,\n            out_channels=out_channels,\n            deconv_out_channels=deconv_out_channels,\n            deconv_kernel_sizes=deconv_kernel_sizes,\n            final_layer=final_layer,\n            init_cfg=init_cfg)\n\n        assert out_channels % depth_size == 0\n        self.depth_size = depth_size\n\n    def forward(self, feats: Tensor) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the heatmap.\n\n        Args:\n            feats (Tensor): Feature map.\n\n        Returns:\n            Tensor: output heatmap.\n        \"\"\"\n\n        x = self.deconv_layers(feats)\n        x = self.final_layer(x)\n        N, C, H, W = x.shape\n        # reshape the 2D heatmap to 3D heatmap\n        x = x.reshape(N, C // self.depth_size, self.depth_size, H, W)\n\n        return x\n\n\nclass Heatmap1DHead(nn.Module):\n    \"\"\"Heatmap1DHead is a sub-module of Interhand3DHead, and outputs 1D\n    heatmaps.\n\n    Args:\n        in_channels (int): Number of input channels. Defaults to 2048.\n        heatmap_size (int): Heatmap size. Defaults to 64.\n        hidden_dims (Sequence[int]): Number of feature dimension of FC layers.\n            Defaults to ``(512, )``.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int = 2048,\n                 heatmap_size: int = 64,\n                 hidden_dims: Sequence[int] = (512, )):\n\n        super().__init__()\n\n        self.in_channels = in_channels\n        self.heatmap_size = heatmap_size\n\n        feature_dims = [in_channels, *hidden_dims, heatmap_size]\n        self.fc = make_linear_layers(feature_dims, relu_final=False)\n\n    def soft_argmax_1d(self, heatmap1d):\n        heatmap1d = F.softmax(heatmap1d, 1)\n        accu = heatmap1d * torch.arange(\n            self.heatmap_size, dtype=heatmap1d.dtype,\n            device=heatmap1d.device)[None, :]\n        coord = accu.sum(dim=1)\n        return coord\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output heatmap.\n        \"\"\"\n        x = self.fc(feats)\n        x = self.soft_argmax_1d(x).view(-1, 1)\n        return x\n\n    def init_weights(self):\n        \"\"\"Initialize model weights.\"\"\"\n        for m in self.fc.modules():\n            if isinstance(m, nn.Linear):\n                normal_init(m, mean=0, std=0.01, bias=0)\n\n\nclass MultilabelClassificationHead(nn.Module):\n    \"\"\"MultilabelClassificationHead is a sub-module of Interhand3DHead, and\n    outputs hand type classification.\n\n    Args:\n        in_channels (int): Number of input channels. Defaults to 2048.\n        num_labels (int): Number of labels. Defaults to 2.\n        hidden_dims (Sequence[int]): Number of hidden dimension of FC layers.\n            Defaults to ``(512, )``.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int = 2048,\n                 num_labels: int = 2,\n                 hidden_dims: Sequence[int] = (512, )):\n\n        super().__init__()\n\n        self.in_channels = in_channels\n\n        feature_dims = [in_channels, *hidden_dims, num_labels]\n        self.fc = make_linear_layers(feature_dims, relu_final=False)\n\n    def init_weights(self):\n        for m in self.fc.modules():\n            if isinstance(m, nn.Linear):\n                normal_init(m, mean=0, std=0.01, bias=0)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n        labels = self.fc(x)\n        return labels\n\n\n@MODELS.register_module()\nclass InternetHead(BaseHead):\n    \"\"\"Internet head introduced in `Interhand 2.6M`_ by Moon et al (2020).\n\n    Args:\n        keypoint_head_cfg (dict): Configs of Heatmap3DHead for hand\n            keypoint estimation.\n        root_head_cfg (dict): Configs of Heatmap1DHead for relative\n            hand root depth estimation.\n        hand_type_head_cfg (dict): Configs of ``MultilabelClassificationHead``\n            for hand type classification.\n        loss (Config): Config of the keypoint loss.\n            Default: :class:`KeypointMSELoss`.\n        loss_root_depth (dict): Config for relative root depth loss.\n            Default: :class:`SmoothL1Loss`.\n        loss_hand_type (dict): Config for hand type classification\n            loss. Default: :class:`BCELoss`.\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Default: ``None``.\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`Interhand 2.6M`: https://arxiv.org/abs/2008.09309\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 keypoint_head_cfg: ConfigType,\n                 root_head_cfg: ConfigType,\n                 hand_type_head_cfg: ConfigType,\n                 loss: ConfigType = dict(\n                     type='KeypointMSELoss', use_target_weight=True),\n                 loss_root_depth: ConfigType = dict(\n                     type='L1Loss', use_target_weight=True),\n                 loss_hand_type: ConfigType = dict(\n                     type='BCELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        super().__init__()\n\n        # build sub-module heads\n        self.right_hand_head = Heatmap3DHead(**keypoint_head_cfg)\n        self.left_hand_head = Heatmap3DHead(**keypoint_head_cfg)\n        self.root_head = Heatmap1DHead(**root_head_cfg)\n        self.hand_type_head = MultilabelClassificationHead(\n            **hand_type_head_cfg)\n        self.neck = GlobalAveragePooling()\n\n        self.loss_module = MODELS.build(loss)\n        self.root_loss_module = MODELS.build(loss_root_depth)\n        self.hand_loss_module = MODELS.build(loss_hand_type)\n\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the heatmap.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tuple[Tensor]: Output heatmap, root depth estimation and hand type\n                classification.\n        \"\"\"\n        x = feats[-1]\n        outputs = []\n        outputs.append(\n            torch.cat([self.right_hand_head(x),\n                       self.left_hand_head(x)], dim=1))\n        x = self.neck(x)\n        outputs.append(self.root_head(x))\n        outputs.append(self.hand_type_head(x))\n        return outputs\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            InstanceList: Return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n            _batch_outputs = self.forward(_feats)\n            _batch_heatmaps = _batch_outputs[0]\n\n            _batch_outputs_flip = self.forward(_feats_flip)\n            _batch_heatmaps_flip = flip_heatmaps(\n                _batch_outputs_flip[0],\n                flip_mode=test_cfg.get('flip_mode', 'heatmap'),\n                flip_indices=flip_indices,\n                shift_heatmap=test_cfg.get('shift_heatmap', False))\n\n            batch_heatmaps = (_batch_heatmaps + _batch_heatmaps_flip) * 0.5\n\n            # flip relative hand root depth\n            _batch_root = _batch_outputs[1]\n            _batch_root_flip = -_batch_outputs_flip[1]\n            batch_root = (_batch_root + _batch_root_flip) * 0.5\n\n            # flip hand type\n            _batch_type = _batch_outputs[2]\n            _batch_type_flip = torch.empty_like(_batch_outputs_flip[2])\n            _batch_type_flip[:, 0] = _batch_type[:, 1]\n            _batch_type_flip[:, 1] = _batch_type[:, 0]\n            batch_type = (_batch_type + _batch_type_flip) * 0.5\n\n            batch_outputs = [batch_heatmaps, batch_root, batch_type]\n\n        else:\n            batch_outputs = self.forward(feats)\n\n        preds = self.decode(tuple(batch_outputs))\n\n        return preds\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        pred_fields = self.forward(feats)\n        pred_heatmaps = pred_fields[0]\n        _, K, D, W, H = pred_heatmaps.shape\n        gt_heatmaps = torch.stack([\n            d.gt_fields.heatmaps.reshape(K, D, W, H)\n            for d in batch_data_samples\n        ])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n\n        # hand keypoint loss\n        loss = self.loss_module(pred_heatmaps, gt_heatmaps, keypoint_weights)\n        losses.update(loss_kpt=loss)\n\n        # relative root depth loss\n        gt_roots = torch.stack(\n            [d.gt_instance_labels.root_depth for d in batch_data_samples])\n        root_weights = torch.stack([\n            d.gt_instance_labels.root_depth_weight for d in batch_data_samples\n        ])\n        loss_root = self.root_loss_module(pred_fields[1], gt_roots,\n                                          root_weights)\n        losses.update(loss_rel_root=loss_root)\n\n        # hand type loss\n        gt_types = torch.stack([\n            d.gt_instance_labels.type.reshape(-1) for d in batch_data_samples\n        ])\n        type_weights = torch.stack(\n            [d.gt_instance_labels.type_weight for d in batch_data_samples])\n        loss_type = self.hand_loss_module(pred_fields[2], gt_types,\n                                          type_weights)\n        losses.update(loss_hand_type=loss_type)\n\n        # calculate accuracy\n        if train_cfg.get('compute_acc', True):\n            acc = multilabel_classification_accuracy(\n                pred=to_numpy(pred_fields[2]),\n                gt=to_numpy(gt_types),\n                mask=to_numpy(type_weights))\n\n            acc_pose = torch.tensor(acc, device=gt_types.device)\n            losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    def decode(self, batch_outputs: Union[Tensor,\n                                          Tuple[Tensor]]) -> InstanceList:\n        \"\"\"Decode keypoints from outputs.\n\n        Args:\n            batch_outputs (Tensor | Tuple[Tensor]): The network outputs of\n                a data batch\n\n        Returns:\n            List[InstanceData]: A list of InstanceData, each contains the\n            decoded pose information of the instances of one data sample.\n        \"\"\"\n\n        def _pack_and_call(args, func):\n            if not isinstance(args, tuple):\n                args = (args, )\n            return func(*args)\n\n        if self.decoder is None:\n            raise RuntimeError(\n                f'The decoder has not been set in {self.__class__.__name__}. '\n                'Please set the decoder configs in the init parameters to '\n                'enable head methods `head.predict()` and `head.decode()`')\n\n        batch_output_np = to_numpy(batch_outputs[0], unzip=True)\n        batch_root_np = to_numpy(batch_outputs[1], unzip=True)\n        batch_type_np = to_numpy(batch_outputs[2], unzip=True)\n        batch_keypoints = []\n        batch_scores = []\n        batch_roots = []\n        batch_types = []\n        for outputs, roots, types in zip(batch_output_np, batch_root_np,\n                                         batch_type_np):\n            keypoints, scores, rel_root_depth, hand_type = _pack_and_call(\n                tuple([outputs, roots, types]), self.decoder.decode)\n            batch_keypoints.append(keypoints)\n            batch_scores.append(scores)\n            batch_roots.append(rel_root_depth)\n            batch_types.append(hand_type)\n\n        preds = [\n            InstanceData(\n                keypoints=keypoints,\n                keypoint_scores=scores,\n                rel_root_depth=rel_root_depth,\n                hand_type=hand_type)\n            for keypoints, scores, rel_root_depth, hand_type in zip(\n                batch_keypoints, batch_scores, batch_roots, batch_types)\n        ]\n\n        return preds\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/mspn_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nfrom typing import List, Optional, Sequence, Union\n\nimport torch\nfrom mmcv.cnn import (ConvModule, DepthwiseSeparableConvModule, Linear,\n                      build_activation_layer, build_norm_layer)\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import pose_pck_accuracy\nfrom mmpose.models.utils.tta import flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, MultiConfig, OptConfigType,\n                                 OptSampleList, Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\nMSMUFeatures = Sequence[Sequence[Tensor]]  # Multi-stage multi-unit features\n\n\nclass PRM(nn.Module):\n    \"\"\"Pose Refine Machine.\n\n    Please refer to \"Learning Delicate Local Representations\n    for Multi-Person Pose Estimation\" (ECCV 2020).\n\n    Args:\n        out_channels (int): Number of the output channels, equals to\n            the number of keypoints.\n        norm_cfg (Config): Config to construct the norm layer.\n            Defaults to ``dict(type='BN')``\n    \"\"\"\n\n    def __init__(self,\n                 out_channels: int,\n                 norm_cfg: ConfigType = dict(type='BN')):\n        super().__init__()\n\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        self.out_channels = out_channels\n        self.global_pooling = nn.AdaptiveAvgPool2d((1, 1))\n        self.middle_path = nn.Sequential(\n            Linear(self.out_channels, self.out_channels),\n            build_norm_layer(dict(type='BN1d'), out_channels)[1],\n            build_activation_layer(dict(type='ReLU')),\n            Linear(self.out_channels, self.out_channels),\n            build_norm_layer(dict(type='BN1d'), out_channels)[1],\n            build_activation_layer(dict(type='ReLU')),\n            build_activation_layer(dict(type='Sigmoid')))\n\n        self.bottom_path = nn.Sequential(\n            ConvModule(\n                self.out_channels,\n                self.out_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=norm_cfg,\n                inplace=False),\n            DepthwiseSeparableConvModule(\n                self.out_channels,\n                1,\n                kernel_size=9,\n                stride=1,\n                padding=4,\n                norm_cfg=norm_cfg,\n                inplace=False), build_activation_layer(dict(type='Sigmoid')))\n        self.conv_bn_relu_prm_1 = ConvModule(\n            self.out_channels,\n            self.out_channels,\n            kernel_size=3,\n            stride=1,\n            padding=1,\n            norm_cfg=norm_cfg,\n            inplace=False)\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward the network. The input heatmaps will be refined.\n\n        Args:\n            x (Tensor): The input heatmaps.\n\n        Returns:\n            Tensor: output heatmaps.\n        \"\"\"\n        out = self.conv_bn_relu_prm_1(x)\n        out_1 = out\n\n        out_2 = self.global_pooling(out_1)\n        out_2 = out_2.view(out_2.size(0), -1)\n        out_2 = self.middle_path(out_2)\n        out_2 = out_2.unsqueeze(2)\n        out_2 = out_2.unsqueeze(3)\n\n        out_3 = self.bottom_path(out_1)\n        out = out_1 * (1 + out_2 * out_3)\n\n        return out\n\n\nclass PredictHeatmap(nn.Module):\n    \"\"\"Predict the heatmap for an input feature.\n\n    Args:\n        unit_channels (int): Number of input channels.\n        out_channels (int): Number of output channels.\n        out_shape (tuple): Shape of the output heatmaps.\n        use_prm (bool): Whether to use pose refine machine. Default: False.\n        norm_cfg (Config): Config to construct the norm layer.\n            Defaults to ``dict(type='BN')``\n    \"\"\"\n\n    def __init__(self,\n                 unit_channels: int,\n                 out_channels: int,\n                 out_shape: tuple,\n                 use_prm: bool = False,\n                 norm_cfg: ConfigType = dict(type='BN')):\n\n        super().__init__()\n\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n        self.unit_channels = unit_channels\n        self.out_channels = out_channels\n        self.out_shape = out_shape\n        self.use_prm = use_prm\n        if use_prm:\n            self.prm = PRM(out_channels, norm_cfg=norm_cfg)\n        self.conv_layers = nn.Sequential(\n            ConvModule(\n                unit_channels,\n                unit_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0,\n                norm_cfg=norm_cfg,\n                inplace=False),\n            ConvModule(\n                unit_channels,\n                out_channels,\n                kernel_size=3,\n                stride=1,\n                padding=1,\n                norm_cfg=norm_cfg,\n                act_cfg=None,\n                inplace=False))\n\n    def forward(self, feature: Tensor) -> Tensor:\n        \"\"\"Forward the network.\n\n        Args:\n            feature (Tensor): The input feature maps.\n\n        Returns:\n            Tensor: output heatmaps.\n        \"\"\"\n        feature = self.conv_layers(feature)\n        output = nn.functional.interpolate(\n            feature, size=self.out_shape, mode='bilinear', align_corners=True)\n        if self.use_prm:\n            output = self.prm(output)\n        return output\n\n\n@MODELS.register_module()\nclass MSPNHead(BaseHead):\n    \"\"\"Multi-stage multi-unit heatmap head introduced in `Multi-Stage Pose\n    estimation Network (MSPN)`_ by Li et al (2019), and used by `Residual Steps\n    Networks (RSN)`_ by Cai et al (2020). The head consists of multiple stages\n    and each stage consists of multiple units. Each unit of each stage has some\n    conv layers.\n\n    Args:\n        num_stages (int): Number of stages.\n        num_units (int): Number of units in each stage.\n        out_shape (tuple): The output shape of the output heatmaps.\n        unit_channels (int): Number of input channels.\n        out_channels (int): Number of output channels.\n        out_shape (tuple): Shape of the output heatmaps.\n        use_prm (bool): Whether to use pose refine machine (PRM).\n            Defaults to ``False``.\n        norm_cfg (Config): Config to construct the norm layer.\n            Defaults to ``dict(type='BN')``\n        loss (Config | List[Config]): Config of the keypoint loss for\n            different stages and different units.\n            Defaults to use :class:`KeypointMSELoss`.\n        level_indices (Sequence[int]): The indices that specified the level\n            of target heatmaps.\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`MSPN`: https://arxiv.org/abs/1901.00148\n    .. _`RSN`: https://arxiv.org/abs/2003.04030\n    \"\"\"\n    _version = 2\n\n    def __init__(self,\n                 num_stages: int = 4,\n                 num_units: int = 4,\n                 out_shape: tuple = (64, 48),\n                 unit_channels: int = 256,\n                 out_channels: int = 17,\n                 use_prm: bool = False,\n                 norm_cfg: ConfigType = dict(type='BN'),\n                 level_indices: Sequence[int] = [],\n                 loss: MultiConfig = dict(\n                     type='KeypointMSELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n        super().__init__(init_cfg)\n\n        self.num_stages = num_stages\n        self.num_units = num_units\n        self.out_shape = out_shape\n        self.unit_channels = unit_channels\n        self.out_channels = out_channels\n        if len(level_indices) != num_stages * num_units:\n            raise ValueError(\n                f'The length of level_indices({len(level_indices)}) did not '\n                f'match `num_stages`({num_stages}) * `num_units`({num_units})')\n\n        self.level_indices = level_indices\n\n        if isinstance(loss, list) and len(loss) != num_stages * num_units:\n            raise ValueError(\n                f'The length of loss_module({len(loss)}) did not match '\n                f'`num_stages`({num_stages}) * `num_units`({num_units})')\n\n        if isinstance(loss, list):\n            if len(loss) != num_stages * num_units:\n                raise ValueError(\n                    f'The length of loss_module({len(loss)}) did not match '\n                    f'`num_stages`({num_stages}) * `num_units`({num_units})')\n            self.loss_module = nn.ModuleList(\n                MODELS.build(_loss) for _loss in loss)\n        else:\n            self.loss_module = MODELS.build(loss)\n\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Protect mutable default arguments\n        norm_cfg = copy.deepcopy(norm_cfg)\n\n        self.predict_layers = nn.ModuleList([])\n        for i in range(self.num_stages):\n            for j in range(self.num_units):\n                self.predict_layers.append(\n                    PredictHeatmap(\n                        unit_channels,\n                        out_channels,\n                        out_shape,\n                        use_prm,\n                        norm_cfg=norm_cfg))\n\n    @property\n    def default_init_cfg(self):\n        \"\"\"Default config for weight initialization.\"\"\"\n        init_cfg = [\n            dict(type='Kaiming', layer='Conv2d'),\n            dict(type='Normal', layer='Linear', std=0.01),\n            dict(type='Constant', layer='BatchNorm2d', val=1),\n        ]\n        return init_cfg\n\n    def forward(self, feats: Sequence[Sequence[Tensor]]) -> List[Tensor]:\n        \"\"\"Forward the network. The input is multi-stage multi-unit feature\n        maps and the output is a list of heatmaps from multiple stages.\n\n        Args:\n            feats (Sequence[Sequence[Tensor]]): Feature maps from multiple\n                stages and units.\n\n        Returns:\n            List[Tensor]: A list of output heatmaps from multiple stages\n                and units.\n        \"\"\"\n        out = []\n        assert len(feats) == self.num_stages, (\n            f'The length of feature maps did not match the '\n            f'`num_stages` in {self.__class__.__name__}')\n        for feat in feats:\n            assert len(feat) == self.num_units, (\n                f'The length of feature maps did not match the '\n                f'`num_units` in {self.__class__.__name__}')\n            for f in feat:\n                assert f.shape[1] == self.unit_channels, (\n                    f'The number of feature map channels did not match the '\n                    f'`unit_channels` in {self.__class__.__name__}')\n\n        for i in range(self.num_stages):\n            for j in range(self.num_units):\n                y = self.predict_layers[i * self.num_units + j](feats[i][j])\n                out.append(y)\n        return out\n\n    def predict(self,\n                feats: Union[MSMUFeatures, List[MSMUFeatures]],\n                batch_data_samples: OptSampleList,\n                test_cfg: OptConfigType = {}) -> Predictions:\n        \"\"\"Predict results from multi-stage feature maps.\n\n        Args:\n            feats (Sequence[Sequence[Tensor]]): Multi-stage multi-unit\n                features (or multiple MSMU features for TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The Data\n                Samples. It usually includes information such as\n                `gt_instance_labels`.\n            test_cfg (Config, optional): The testing/inference config\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n        # multi-stage multi-unit batch heatmaps\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n            _batch_heatmaps = self.forward(_feats)[-1]\n            _batch_heatmaps_flip = flip_heatmaps(\n                self.forward(_feats_flip)[-1],\n                flip_mode=test_cfg.get('flip_mode', 'heatmap'),\n                flip_indices=flip_indices,\n                shift_heatmap=test_cfg.get('shift_heatmap', False))\n            batch_heatmaps = (_batch_heatmaps + _batch_heatmaps_flip) * 0.5\n        else:\n            msmu_batch_heatmaps = self.forward(feats)\n            batch_heatmaps = msmu_batch_heatmaps[-1]\n\n        preds = self.decode(batch_heatmaps)\n\n        if test_cfg.get('output_heatmaps', False):\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(self,\n             feats: MSMUFeatures,\n             batch_data_samples: OptSampleList,\n             train_cfg: OptConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Note:\n            - batch_size: B\n            - num_output_heatmap_levels: L\n            - num_keypoints: K\n            - heatmaps height: H\n            - heatmaps weight: W\n            - num_instances: N (usually 1 in topdown heatmap heads)\n\n        Args:\n            feats (Sequence[Sequence[Tensor]]): Feature maps from multiple\n                stages and units\n            batch_data_samples (List[:obj:`PoseDataSample`]): The Data\n                Samples. It usually includes information such as\n                `gt_instance_labels` and `gt_fields`.\n            train_cfg (Config, optional): The training config\n\n        Returns:\n            dict: A dictionary of loss components.\n        \"\"\"\n        # multi-stage multi-unit predict heatmaps\n        msmu_pred_heatmaps = self.forward(feats)\n\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ],\n                                     dim=1)\n        keypoint_weights = keypoint_weights.transpose(0, 1)  # [B*N, L, K]\n\n        # calculate losses over multiple stages and multiple units\n        losses = dict()\n        for i in range(self.num_stages * self.num_units):\n            if isinstance(self.loss_module, nn.ModuleList):\n                # use different loss_module over different stages and units\n                loss_func = self.loss_module[i]\n            else:\n                # use the same loss_module over different stages and units\n                loss_func = self.loss_module\n\n            # select `gt_heatmaps` and `keypoint_weights` for different level\n            # according to `self.level_indices` to calculate loss\n            gt_heatmaps = torch.stack([\n                d.gt_fields[self.level_indices[i]].heatmaps\n                for d in batch_data_samples\n            ])\n            loss_i = loss_func(msmu_pred_heatmaps[i], gt_heatmaps,\n                               keypoint_weights[:, self.level_indices[i]])\n\n            if 'loss_kpt' not in losses:\n                losses['loss_kpt'] = loss_i\n            else:\n                losses['loss_kpt'] += loss_i\n\n        # calculate accuracy\n        _, avg_acc, _ = pose_pck_accuracy(\n            output=to_numpy(msmu_pred_heatmaps[-1]),\n            target=to_numpy(gt_heatmaps),\n            mask=to_numpy(keypoint_weights[:, -1]) > 0)\n\n        acc_pose = torch.tensor(avg_acc, device=gt_heatmaps.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n"
  },
  {
    "path": "mmpose/models/heads/heatmap_heads/vipnas_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Union\n\nfrom mmcv.cnn import build_conv_layer, build_upsample_layer\nfrom torch import nn\n\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.typing import ConfigType, OptConfigType\nfrom .heatmap_head import HeatmapHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass ViPNASHead(HeatmapHead):\n    \"\"\"ViPNAS heatmap head introduced in `ViPNAS`_ by Xu et al (2021). The head\n    is composed of a few deconvolutional layers followed by a convolutional\n    layer to generate heatmaps from low-resolution feature maps. Specifically,\n    different from the :class: `HeatmapHead` introduced by `Simple Baselines`_,\n    the group numbers in the deconvolutional layers are elastic and thus can be\n    optimized by neural architecture search (NAS).\n\n    Args:\n        in_channels (int | Sequence[int]): Number of channels in the input\n            feature map\n        out_channels (int): Number of channels in the output heatmap\n        deconv_out_channels (Sequence[int], optional): The output channel\n            number of each deconv layer. Defaults to ``(144, 144, 144)``\n        deconv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.Defaults to\n            ``(4, 4, 4)``\n        deconv_num_groups (Sequence[int], optional): The group number of each\n            deconv layer. Defaults to ``(16, 16, 16)``\n        conv_out_channels (Sequence[int], optional): The output channel number\n            of each intermediate conv layer. ``None`` means no intermediate\n            conv layer between deconv layers and the final conv layer.\n            Defaults to ``None``\n        conv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each intermediate conv layer. Defaults to ``None``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KeypointMSELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`ViPNAS`: https://arxiv.org/abs/2105.10154\n    .. _`Simple Baselines`: https://arxiv.org/abs/1804.06208\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 out_channels: int,\n                 deconv_out_channels: OptIntSeq = (144, 144, 144),\n                 deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n                 deconv_num_groups: OptIntSeq = (16, 16, 16),\n                 conv_out_channels: OptIntSeq = None,\n                 conv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 loss: ConfigType = dict(\n                     type='KeypointMSELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super(HeatmapHead, self).__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        if deconv_out_channels:\n            if deconv_kernel_sizes is None or len(deconv_out_channels) != len(\n                    deconv_kernel_sizes):\n                raise ValueError(\n                    '\"deconv_out_channels\" and \"deconv_kernel_sizes\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {deconv_out_channels} and '\n                    f'{deconv_kernel_sizes}')\n            if deconv_num_groups is None or len(deconv_out_channels) != len(\n                    deconv_num_groups):\n                raise ValueError(\n                    '\"deconv_out_channels\" and \"deconv_num_groups\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {deconv_out_channels} and '\n                    f'{deconv_num_groups}')\n\n            self.deconv_layers = self._make_deconv_layers(\n                in_channels=in_channels,\n                layer_out_channels=deconv_out_channels,\n                layer_kernel_sizes=deconv_kernel_sizes,\n                layer_groups=deconv_num_groups,\n            )\n            in_channels = deconv_out_channels[-1]\n        else:\n            self.deconv_layers = nn.Identity()\n\n        if conv_out_channels:\n            if conv_kernel_sizes is None or len(conv_out_channels) != len(\n                    conv_kernel_sizes):\n                raise ValueError(\n                    '\"conv_out_channels\" and \"conv_kernel_sizes\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {conv_out_channels} and '\n                    f'{conv_kernel_sizes}')\n\n            self.conv_layers = self._make_conv_layers(\n                in_channels=in_channels,\n                layer_out_channels=conv_out_channels,\n                layer_kernel_sizes=conv_kernel_sizes)\n            in_channels = conv_out_channels[-1]\n        else:\n            self.conv_layers = nn.Identity()\n\n        if final_layer is not None:\n            cfg = dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=1)\n            cfg.update(final_layer)\n            self.final_layer = build_conv_layer(cfg)\n        else:\n            self.final_layer = nn.Identity()\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    def _make_deconv_layers(self, in_channels: int,\n                            layer_out_channels: Sequence[int],\n                            layer_kernel_sizes: Sequence[int],\n                            layer_groups: Sequence[int]) -> nn.Module:\n        \"\"\"Create deconvolutional layers by given parameters.\"\"\"\n\n        layers = []\n        for out_channels, kernel_size, groups in zip(layer_out_channels,\n                                                     layer_kernel_sizes,\n                                                     layer_groups):\n            if kernel_size == 4:\n                padding = 1\n                output_padding = 0\n            elif kernel_size == 3:\n                padding = 1\n                output_padding = 1\n            elif kernel_size == 2:\n                padding = 0\n                output_padding = 0\n            else:\n                raise ValueError(f'Unsupported kernel size {kernel_size} for'\n                                 'deconvlutional layers in '\n                                 f'{self.__class__.__name__}')\n            cfg = dict(\n                type='deconv',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=kernel_size,\n                groups=groups,\n                stride=2,\n                padding=padding,\n                output_padding=output_padding,\n                bias=False)\n            layers.append(build_upsample_layer(cfg))\n            layers.append(nn.BatchNorm2d(num_features=out_channels))\n            layers.append(nn.ReLU(inplace=True))\n            in_channels = out_channels\n\n        return nn.Sequential(*layers)\n"
  },
  {
    "path": "mmpose/models/heads/hybrid_heads/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .dekr_head import DEKRHead\nfrom .rtmo_head import RTMOHead\nfrom .vis_head import VisPredictHead\nfrom .yoloxpose_head import YOLOXPoseHead\n\n__all__ = ['DEKRHead', 'VisPredictHead', 'YOLOXPoseHead', 'RTMOHead']\n"
  },
  {
    "path": "mmpose/models/heads/hybrid_heads/dekr_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Sequence, Tuple, Union\n\nimport torch\nfrom mmcv.cnn import (ConvModule, build_activation_layer, build_conv_layer,\n                      build_norm_layer)\nfrom mmengine.model import BaseModule, ModuleDict, Sequential\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import Tensor\n\nfrom mmpose.evaluation.functional.nms import nearby_joints_nms\nfrom mmpose.models.utils.tta import flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, Features, InstanceList,\n                                 OptConfigType, OptSampleList, Predictions)\nfrom ...backbones.resnet import BasicBlock\nfrom ..base_head import BaseHead\n\ntry:\n    from mmcv.ops import DeformConv2d\n    has_mmcv_full = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmcv_full = False\n\n\nclass AdaptiveActivationBlock(BaseModule):\n    \"\"\"Adaptive activation convolution block. \"Bottom-up human pose estimation\n    via disentangled keypoint regression\", CVPR'2021.\n\n    Args:\n        in_channels (int): Number of input channels\n        out_channels (int): Number of output channels\n        groups (int): Number of groups. Generally equal to the\n            number of joints.\n        norm_cfg (dict): Config for normalization layers.\n        act_cfg (dict): Config for activation layers.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 groups=1,\n                 norm_cfg=dict(type='BN'),\n                 act_cfg=dict(type='ReLU'),\n                 init_cfg=None):\n        super(AdaptiveActivationBlock, self).__init__(init_cfg=init_cfg)\n\n        assert in_channels % groups == 0 and out_channels % groups == 0\n        self.groups = groups\n\n        regular_matrix = torch.tensor([[-1, -1, -1, 0, 0, 0, 1, 1, 1],\n                                       [-1, 0, 1, -1, 0, 1, -1, 0, 1],\n                                       [1, 1, 1, 1, 1, 1, 1, 1, 1]])\n        self.register_buffer('regular_matrix', regular_matrix.float())\n\n        self.transform_matrix_conv = build_conv_layer(\n            dict(type='Conv2d'),\n            in_channels=in_channels,\n            out_channels=6 * groups,\n            kernel_size=3,\n            padding=1,\n            groups=groups,\n            bias=True)\n\n        if has_mmcv_full:\n            self.adapt_conv = DeformConv2d(\n                in_channels,\n                out_channels,\n                kernel_size=3,\n                padding=1,\n                bias=False,\n                groups=groups,\n                deform_groups=groups)\n        else:\n            raise ImportError('Please install the full version of mmcv '\n                              'to use `DeformConv2d`.')\n\n        self.norm = build_norm_layer(norm_cfg, out_channels)[1]\n        self.act = build_activation_layer(act_cfg)\n\n    def forward(self, x):\n        B, _, H, W = x.size()\n        residual = x\n\n        affine_matrix = self.transform_matrix_conv(x)\n        affine_matrix = affine_matrix.permute(0, 2, 3, 1).contiguous()\n        affine_matrix = affine_matrix.view(B, H, W, self.groups, 2, 3)\n        offset = torch.matmul(affine_matrix, self.regular_matrix)\n        offset = offset.transpose(4, 5).reshape(B, H, W, self.groups * 18)\n        offset = offset.permute(0, 3, 1, 2).contiguous()\n\n        x = self.adapt_conv(x, offset)\n        x = self.norm(x)\n        x = self.act(x + residual)\n\n        return x\n\n\nclass RescoreNet(BaseModule):\n    \"\"\"Rescore net used to predict the OKS score of predicted pose. We use the\n    off-the-shelf rescore net pretrained by authors of DEKR.\n\n    Args:\n        in_channels (int): Input channels\n        norm_indexes (Tuple(int)): Indices of torso in skeleton\n        init_cfg (dict, optional): Initialization config dict\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels,\n        norm_indexes,\n        init_cfg=None,\n    ):\n        super(RescoreNet, self).__init__(init_cfg=init_cfg)\n\n        self.norm_indexes = norm_indexes\n\n        hidden = 256\n\n        self.l1 = torch.nn.Linear(in_channels, hidden, bias=True)\n        self.l2 = torch.nn.Linear(hidden, hidden, bias=True)\n        self.l3 = torch.nn.Linear(hidden, 1, bias=True)\n        self.relu = torch.nn.ReLU()\n\n    def make_feature(self, keypoints, keypoint_scores, skeleton):\n        \"\"\"Combine original scores, joint distance and relative distance to\n        make feature.\n\n        Args:\n            keypoints (torch.Tensor): predicetd keypoints\n            keypoint_scores (torch.Tensor): predicetd keypoint scores\n            skeleton (list(list(int))): joint links\n\n        Returns:\n            torch.Tensor: feature for each instance\n        \"\"\"\n        joint_1, joint_2 = zip(*skeleton)\n        num_link = len(skeleton)\n\n        joint_relate = (keypoints[:, joint_1] -\n                        keypoints[:, joint_2])[:, :, :2]\n        joint_length = joint_relate.norm(dim=2)\n\n        # To use the torso distance to normalize\n        normalize = (joint_length[:, self.norm_indexes[0]] +\n                     joint_length[:, self.norm_indexes[1]]) / 2\n        normalize = normalize.unsqueeze(1).expand(normalize.size(0), num_link)\n        normalize = normalize.clamp(min=1).contiguous()\n\n        joint_length = joint_length / normalize[:, :]\n        joint_relate = joint_relate / normalize.unsqueeze(-1)\n        joint_relate = joint_relate.flatten(1)\n\n        feature = torch.cat((joint_relate, joint_length, keypoint_scores),\n                            dim=1).float()\n        return feature\n\n    def forward(self, keypoints, keypoint_scores, skeleton):\n        feature = self.make_feature(keypoints, keypoint_scores, skeleton)\n        x = self.relu(self.l1(feature))\n        x = self.relu(self.l2(x))\n        x = self.l3(x)\n        return x.squeeze(1)\n\n\n@MODELS.register_module()\nclass DEKRHead(BaseHead):\n    \"\"\"DisEntangled Keypoint Regression head introduced in `Bottom-up human\n    pose estimation via disentangled keypoint regression`_ by Geng et al\n    (2021). The head is composed of a heatmap branch and a displacement branch.\n\n    Args:\n        in_channels (int | Sequence[int]): Number of channels in the input\n            feature map\n        num_joints (int): Number of joints\n        num_heatmap_filters (int): Number of filters for heatmap branch.\n            Defaults to 32\n        num_offset_filters_per_joint (int): Number of filters for each joint\n            in displacement branch. Defaults to 15\n        heatmap_loss (Config): Config of the heatmap loss. Defaults to use\n            :class:`KeypointMSELoss`\n        displacement_loss (Config): Config of the displacement regression loss.\n            Defaults to use :class:`SoftWeightSmoothL1Loss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        rescore_cfg (Config, optional): The config for rescore net which\n            estimates OKS via predicted keypoints and keypoint scores.\n            Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`Bottom-up human pose estimation via disentangled keypoint regression`:\n        https://arxiv.org/abs/2104.02300\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 num_keypoints: int,\n                 num_heatmap_filters: int = 32,\n                 num_displacement_filters_per_keypoint: int = 15,\n                 heatmap_loss: ConfigType = dict(\n                     type='KeypointMSELoss', use_target_weight=True),\n                 displacement_loss: ConfigType = dict(\n                     type='SoftWeightSmoothL1Loss',\n                     use_target_weight=True,\n                     supervise_empty=False),\n                 decoder: OptConfigType = None,\n                 rescore_cfg: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_keypoints = num_keypoints\n\n        # build heatmap branch\n        self.heatmap_conv_layers = self._make_heatmap_conv_layers(\n            in_channels=in_channels,\n            out_channels=1 + num_keypoints,\n            num_filters=num_heatmap_filters,\n        )\n\n        # build displacement branch\n        self.displacement_conv_layers = self._make_displacement_conv_layers(\n            in_channels=in_channels,\n            out_channels=2 * num_keypoints,\n            num_filters=num_keypoints * num_displacement_filters_per_keypoint,\n            groups=num_keypoints)\n\n        # build losses\n        self.loss_module = ModuleDict(\n            dict(\n                heatmap=MODELS.build(heatmap_loss),\n                displacement=MODELS.build(displacement_loss),\n            ))\n\n        # build decoder\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # build rescore net\n        if rescore_cfg is not None:\n            self.rescore_net = RescoreNet(**rescore_cfg)\n        else:\n            self.rescore_net = None\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(\n                type='Normal', layer=['Conv2d', 'ConvTranspose2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1)\n        ]\n        return init_cfg\n\n    def _make_heatmap_conv_layers(self, in_channels: int, out_channels: int,\n                                  num_filters: int):\n        \"\"\"Create convolutional layers of heatmap branch by given\n        parameters.\"\"\"\n        layers = [\n            ConvModule(\n                in_channels=in_channels,\n                out_channels=num_filters,\n                kernel_size=1,\n                norm_cfg=dict(type='BN')),\n            BasicBlock(num_filters, num_filters),\n            build_conv_layer(\n                dict(type='Conv2d'),\n                in_channels=num_filters,\n                out_channels=out_channels,\n                kernel_size=1),\n        ]\n\n        return Sequential(*layers)\n\n    def _make_displacement_conv_layers(self, in_channels: int,\n                                       out_channels: int, num_filters: int,\n                                       groups: int):\n        \"\"\"Create convolutional layers of displacement branch by given\n        parameters.\"\"\"\n        layers = [\n            ConvModule(\n                in_channels=in_channels,\n                out_channels=num_filters,\n                kernel_size=1,\n                norm_cfg=dict(type='BN')),\n            AdaptiveActivationBlock(num_filters, num_filters, groups=groups),\n            AdaptiveActivationBlock(num_filters, num_filters, groups=groups),\n            build_conv_layer(\n                dict(type='Conv2d'),\n                in_channels=num_filters,\n                out_channels=out_channels,\n                kernel_size=1,\n                groups=groups)\n        ]\n\n        return Sequential(*layers)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is a tuple of heatmap and displacement.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tuple[Tensor]: output heatmap and displacement.\n        \"\"\"\n        x = feats[-1]\n\n        heatmaps = self.heatmap_conv_layers(x)\n        displacements = self.displacement_conv_layers(x)\n\n        return heatmaps, displacements\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        pred_heatmaps, pred_displacements = self.forward(feats)\n        gt_heatmaps = torch.stack(\n            [d.gt_fields.heatmaps for d in batch_data_samples])\n        heatmap_weights = torch.stack(\n            [d.gt_fields.heatmap_weights for d in batch_data_samples])\n        gt_displacements = torch.stack(\n            [d.gt_fields.displacements for d in batch_data_samples])\n        displacement_weights = torch.stack(\n            [d.gt_fields.displacement_weights for d in batch_data_samples])\n\n        if 'heatmap_mask' in batch_data_samples[0].gt_fields.keys():\n            heatmap_mask = torch.stack(\n                [d.gt_fields.heatmap_mask for d in batch_data_samples])\n        else:\n            heatmap_mask = None\n\n        # calculate losses\n        losses = dict()\n        heatmap_loss = self.loss_module['heatmap'](pred_heatmaps, gt_heatmaps,\n                                                   heatmap_weights,\n                                                   heatmap_mask)\n        displacement_loss = self.loss_module['displacement'](\n            pred_displacements, gt_displacements, displacement_weights)\n\n        losses.update({\n            'loss/heatmap': heatmap_loss,\n            'loss/displacement': displacement_loss,\n        })\n\n        return losses\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-scale features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (1, h, w)\n                    or (K+1, h, w) if keypoint heatmaps are predicted\n                - displacements (Tensor): The predicted displacement fields\n                    in shape (K*2, h, w)\n        \"\"\"\n\n        assert len(batch_data_samples) == 1, f'DEKRHead only supports ' \\\n            f'prediction with batch_size 1, but got {len(batch_data_samples)}'\n\n        multiscale_test = test_cfg.get('multiscale_test', False)\n        flip_test = test_cfg.get('flip_test', False)\n        metainfo = batch_data_samples[0].metainfo\n        aug_scales = [1]\n\n        if not multiscale_test:\n            feats = [feats]\n        else:\n            aug_scales = aug_scales + metainfo['aug_scales']\n\n        heatmaps, displacements = [], []\n        for feat, s in zip(feats, aug_scales):\n            if flip_test:\n                assert isinstance(feat, list) and len(feat) == 2\n                flip_indices = metainfo['flip_indices']\n                _feat, _feat_flip = feat\n                _heatmaps, _displacements = self.forward(_feat)\n                _heatmaps_flip, _displacements_flip = self.forward(_feat_flip)\n\n                _heatmaps_flip = flip_heatmaps(\n                    _heatmaps_flip,\n                    flip_mode='heatmap',\n                    flip_indices=flip_indices + [len(flip_indices)],\n                    shift_heatmap=test_cfg.get('shift_heatmap', False))\n                _heatmaps = (_heatmaps + _heatmaps_flip) / 2.0\n\n                _displacements_flip = flip_heatmaps(\n                    _displacements_flip,\n                    flip_mode='offset',\n                    flip_indices=flip_indices,\n                    shift_heatmap=False)\n\n                # this is a coordinate amendment.\n                x_scale_factor = s * (\n                    metainfo['input_size'][0] / _heatmaps.shape[-1])\n                _displacements_flip[:, ::2] += (x_scale_factor - 1) / (\n                    x_scale_factor)\n                _displacements = (_displacements + _displacements_flip) / 2.0\n\n            else:\n                _heatmaps, _displacements = self.forward(feat)\n\n            heatmaps.append(_heatmaps)\n            displacements.append(_displacements)\n\n        preds = self.decode(heatmaps, displacements, test_cfg, metainfo)\n\n        if test_cfg.get('output_heatmaps', False):\n            heatmaps = [hm.detach() for hm in heatmaps]\n            displacements = [dm.detach() for dm in displacements]\n            B = heatmaps[0].shape[0]\n            pred_fields = []\n            for i in range(B):\n                pred_fields.append(\n                    PixelData(\n                        heatmaps=heatmaps[0][i],\n                        displacements=displacements[0][i]))\n            return preds, pred_fields\n        else:\n            return preds\n\n    def decode(self,\n               heatmaps: Tuple[Tensor],\n               displacements: Tuple[Tensor],\n               test_cfg: ConfigType = {},\n               metainfo: dict = {}) -> InstanceList:\n        \"\"\"Decode keypoints from outputs.\n\n        Args:\n            heatmaps (Tuple[Tensor]): The output heatmaps inferred from one\n                image or multi-scale images.\n            displacements (Tuple[Tensor]): The output displacement fields\n                inferred from one image or multi-scale images.\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n            metainfo (dict): The metainfo of test dataset. Defaults to {}\n\n        Returns:\n            List[InstanceData]: A list of InstanceData, each contains the\n                decoded pose information of the instances of one data sample.\n        \"\"\"\n\n        if self.decoder is None:\n            raise RuntimeError(\n                f'The decoder has not been set in {self.__class__.__name__}. '\n                'Please set the decoder configs in the init parameters to '\n                'enable head methods `head.predict()` and `head.decode()`')\n\n        multiscale_test = test_cfg.get('multiscale_test', False)\n        skeleton = metainfo.get('skeleton_links', None)\n\n        preds = []\n        batch_size = heatmaps[0].shape[0]\n\n        for b in range(batch_size):\n            if multiscale_test:\n                raise NotImplementedError\n            else:\n                keypoints, (root_scores,\n                            keypoint_scores) = self.decoder.decode(\n                                heatmaps[0][b], displacements[0][b])\n\n            # rescore each instance\n            if self.rescore_net is not None and skeleton and len(\n                    keypoints) > 0:\n                instance_scores = self.rescore_net(keypoints, keypoint_scores,\n                                                   skeleton)\n                instance_scores[torch.isnan(instance_scores)] = 0\n                root_scores = root_scores * instance_scores\n\n            # nms\n            keypoints, keypoint_scores = to_numpy((keypoints, keypoint_scores))\n            scores = to_numpy(root_scores)[..., None] * keypoint_scores\n            if len(keypoints) > 0 and test_cfg.get('nms_dist_thr', 0) > 0:\n                kpts_db = []\n                for i in range(len(keypoints)):\n                    kpts_db.append(\n                        dict(keypoints=keypoints[i], score=keypoint_scores[i]))\n                keep_instance_inds = nearby_joints_nms(\n                    kpts_db,\n                    test_cfg['nms_dist_thr'],\n                    test_cfg.get('nms_joints_thr', None),\n                    score_per_joint=True,\n                    max_dets=test_cfg.get('max_num_people', 30))\n                keypoints = keypoints[keep_instance_inds]\n                scores = scores[keep_instance_inds]\n\n            # pack outputs\n            preds.append(\n                InstanceData(keypoints=keypoints, keypoint_scores=scores))\n\n        return preds\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to convert old-version state dict of\n        :class:`DEKRHead` (before MMPose v1.0.0) to a compatible format\n        of :class:`DEKRHead`.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n        version = local_meta.get('version', None)\n        if version and version >= self._version:\n            return\n\n        # convert old-version state dict\n        keys = list(state_dict.keys())\n        for k in keys:\n            if 'offset_conv_layer' in k:\n                v = state_dict.pop(k)\n                k = k.replace('offset_conv_layers', 'displacement_conv_layers')\n                if 'displacement_conv_layers.3.' in k:\n                    # the source and target of displacement vectors are\n                    # opposite between two versions.\n                    v = -v\n                state_dict[k] = v\n\n            if 'heatmap_conv_layers.2' in k:\n                # root heatmap is at the first/last channel of the\n                # heatmap tensor in MMPose v0.x/1.x, respectively.\n                v = state_dict.pop(k)\n                state_dict[k] = torch.cat((v[1:], v[:1]))\n\n            if 'rescore_net' in k:\n                v = state_dict.pop(k)\n                k = k.replace('rescore_net', 'head.rescore_net')\n                state_dict[k] = v\n"
  },
  {
    "path": "mmpose/models/heads/hybrid_heads/rtmo_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport types\nfrom typing import Dict, List, Optional, Sequence, Tuple, Union\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, Scale\nfrom mmdet.utils import ConfigType, reduce_mean\nfrom mmengine.model import BaseModule, bias_init_with_prob\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor\n\nfrom mmpose.evaluation.functional import nms_torch\nfrom mmpose.models.utils import (GAUEncoder, SinePositionalEncoding,\n                                 filter_scores_and_topk)\nfrom mmpose.registry import MODELS\nfrom mmpose.structures.bbox import bbox_xyxy2cs\nfrom mmpose.utils.typing import Features, OptSampleList, Predictions\nfrom .yoloxpose_head import YOLOXPoseHead\n\nEPS = 1e-8\n\n\nclass RTMOHeadModule(BaseModule):\n    \"\"\"RTMO head module for one-stage human pose estimation.\n\n    This module predicts classification scores, bounding boxes, keypoint\n    offsets and visibilities from multi-level feature maps.\n\n    Args:\n        num_classes (int): Number of categories excluding the background\n            category.\n        num_keypoints (int): Number of keypoints defined for one instance.\n         in_channels (int): Number of channels in the input feature maps.\n        cls_feat_channels (int): Number of channels in the classification score\n            and objectness prediction branch. Defaults to 256.\n         widen_factor (float): Width multiplier, multiply number of\n             channels in each layer by this amount. Defaults to 1.0.\n        num_groups (int): Group number of group convolution layers in keypoint\n            regression branch. Defaults to 8.\n        channels_per_group (int): Number of channels for each group of group\n            convolution layers in keypoint regression branch. Defaults to 32.\n        featmap_strides (Sequence[int]): Downsample factor of each feature\n            map. Defaults to [8, 16, 32].\n        conv_bias (bool or str): If specified as `auto`, it will be decided\n            by the norm_cfg. Bias of conv will be set as True if `norm_cfg`\n            is None, otherwise False. Defaults to \"auto\".\n        conv_cfg (:obj:`ConfigDict` or dict, optional): Config dict for\n            convolution layer. Defaults to None.\n        norm_cfg (:obj:`ConfigDict` or dict): Config dict for normalization\n            layer. Defaults to dict(type='BN', momentum=0.03, eps=0.001).\n        act_cfg (:obj:`ConfigDict` or dict): Config dict for activation layer.\n            Defaults to None.\n        init_cfg (:obj:`ConfigDict` or list[:obj:`ConfigDict`] or dict or\n            list[dict], optional): Initialization config dict.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(\n        self,\n        num_keypoints: int,\n        in_channels: int,\n        num_classes: int = 1,\n        widen_factor: float = 1.0,\n        cls_feat_channels: int = 256,\n        stacked_convs: int = 2,\n        num_groups=8,\n        channels_per_group=36,\n        pose_vec_channels=-1,\n        featmap_strides: Sequence[int] = [8, 16, 32],\n        conv_bias: Union[bool, str] = 'auto',\n        conv_cfg: Optional[ConfigType] = None,\n        norm_cfg: ConfigType = dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg: ConfigType = dict(type='SiLU', inplace=True),\n        init_cfg: Optional[ConfigType] = None,\n    ):\n        super().__init__(init_cfg=init_cfg)\n        self.num_classes = num_classes\n        self.cls_feat_channels = int(cls_feat_channels * widen_factor)\n        self.stacked_convs = stacked_convs\n        assert conv_bias == 'auto' or isinstance(conv_bias, bool)\n        self.conv_bias = conv_bias\n\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.featmap_strides = featmap_strides\n\n        self.in_channels = int(in_channels * widen_factor)\n        self.num_keypoints = num_keypoints\n\n        self.num_groups = num_groups\n        self.channels_per_group = int(widen_factor * channels_per_group)\n        self.pose_vec_channels = pose_vec_channels\n\n        self._init_layers()\n\n    def _init_layers(self):\n        \"\"\"Initialize heads for all level feature maps.\"\"\"\n        self._init_cls_branch()\n        self._init_pose_branch()\n\n    def _init_cls_branch(self):\n        \"\"\"Initialize classification branch for all level feature maps.\"\"\"\n        self.conv_cls = nn.ModuleList()\n        for _ in self.featmap_strides:\n            stacked_convs = []\n            for i in range(self.stacked_convs):\n                chn = self.in_channels if i == 0 else self.cls_feat_channels\n                stacked_convs.append(\n                    ConvModule(\n                        chn,\n                        self.cls_feat_channels,\n                        3,\n                        stride=1,\n                        padding=1,\n                        conv_cfg=self.conv_cfg,\n                        norm_cfg=self.norm_cfg,\n                        act_cfg=self.act_cfg,\n                        bias=self.conv_bias))\n            self.conv_cls.append(nn.Sequential(*stacked_convs))\n\n        # output layers\n        self.out_cls = nn.ModuleList()\n        for _ in self.featmap_strides:\n            self.out_cls.append(\n                nn.Conv2d(self.cls_feat_channels, self.num_classes, 1))\n\n    def _init_pose_branch(self):\n        \"\"\"Initialize pose prediction branch for all level feature maps.\"\"\"\n        self.conv_pose = nn.ModuleList()\n        out_chn = self.num_groups * self.channels_per_group\n        for _ in self.featmap_strides:\n            stacked_convs = []\n            for i in range(self.stacked_convs * 2):\n                chn = self.in_channels if i == 0 else out_chn\n                groups = 1 if i == 0 else self.num_groups\n                stacked_convs.append(\n                    ConvModule(\n                        chn,\n                        out_chn,\n                        3,\n                        stride=1,\n                        padding=1,\n                        groups=groups,\n                        conv_cfg=self.conv_cfg,\n                        norm_cfg=self.norm_cfg,\n                        act_cfg=self.act_cfg,\n                        bias=self.conv_bias))\n            self.conv_pose.append(nn.Sequential(*stacked_convs))\n\n        # output layers\n        self.out_bbox = nn.ModuleList()\n        self.out_kpt_reg = nn.ModuleList()\n        self.out_kpt_vis = nn.ModuleList()\n        for _ in self.featmap_strides:\n            self.out_bbox.append(nn.Conv2d(out_chn, 4, 1))\n            self.out_kpt_reg.append(\n                nn.Conv2d(out_chn, self.num_keypoints * 2, 1))\n            self.out_kpt_vis.append(nn.Conv2d(out_chn, self.num_keypoints, 1))\n\n        if self.pose_vec_channels > 0:\n            self.out_pose = nn.ModuleList()\n            for _ in self.featmap_strides:\n                self.out_pose.append(\n                    nn.Conv2d(out_chn, self.pose_vec_channels, 1))\n\n    def init_weights(self):\n        \"\"\"Initialize weights of the head.\n\n        Use prior in model initialization to improve stability.\n        \"\"\"\n\n        super().init_weights()\n        bias_init = bias_init_with_prob(0.01)\n        for conv_cls in self.out_cls:\n            conv_cls.bias.data.fill_(bias_init)\n\n    def forward(self, x: Tuple[Tensor]) -> Tuple[List]:\n        \"\"\"Forward features from the upstream network.\n\n        Args:\n            x (Tuple[Tensor]): Features from the upstream network, each is\n                a 4D-tensor.\n\n        Returns:\n            cls_scores (List[Tensor]): Classification scores for each level.\n            bbox_preds (List[Tensor]): Bounding box predictions for each level.\n            kpt_offsets (List[Tensor]): Keypoint offsets for each level.\n            kpt_vis (List[Tensor]): Keypoint visibilities for each level.\n            pose_feats (List[Tensor]): Pose features for each level.\n        \"\"\"\n\n        cls_scores, bbox_preds = [], []\n        kpt_offsets, kpt_vis = [], []\n        pose_feats = []\n\n        for i in range(len(x)):\n\n            cls_feat, reg_feat = x[i].split(x[i].size(1) // 2, 1)\n\n            cls_feat = self.conv_cls[i](cls_feat)\n            reg_feat = self.conv_pose[i](reg_feat)\n\n            cls_scores.append(self.out_cls[i](cls_feat))\n            bbox_preds.append(self.out_bbox[i](reg_feat))\n            if self.training:\n                # `kpt_offsets` generates the proxy poses for positive\n                # sample selection during training\n                kpt_offsets.append(self.out_kpt_reg[i](reg_feat))\n            kpt_vis.append(self.out_kpt_vis[i](reg_feat))\n\n            if self.pose_vec_channels > 0:\n                pose_feats.append(self.out_pose[i](reg_feat))\n            else:\n                pose_feats.append(reg_feat)\n\n        return cls_scores, bbox_preds, kpt_offsets, kpt_vis, pose_feats\n\n\nclass DCC(BaseModule):\n    \"\"\"Dynamic Coordinate Classifier for One-stage Pose Estimation.\n\n    Args:\n        in_channels (int): Number of input feature map channels.\n        num_keypoints (int): Number of keypoints for pose estimation.\n        feat_channels (int): Number of feature channels.\n        num_bins (Tuple[int, int]): Tuple representing the number of bins in\n            x and y directions.\n        spe_channels (int): Number of channels for Sine Positional Encoding.\n            Defaults to 128.\n        spe_temperature (float): Temperature for Sine Positional Encoding.\n            Defaults to 300.0.\n        gau_cfg (dict, optional): Configuration for Gated Attention Unit.\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: int,\n        num_keypoints: int,\n        feat_channels: int,\n        num_bins: Tuple[int, int],\n        spe_channels: int = 128,\n        spe_temperature: float = 300.0,\n        gau_cfg: Optional[dict] = dict(\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.0,\n            drop_path=0.0,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc='add'),\n    ):\n        super().__init__()\n\n        self.in_channels = in_channels\n        self.num_keypoints = num_keypoints\n\n        self.feat_channels = feat_channels\n        self.num_bins = num_bins\n        self.gau_cfg = gau_cfg\n\n        self.spe = SinePositionalEncoding(\n            out_channels=spe_channels,\n            temperature=spe_temperature,\n        )\n        self.spe_feat_channels = spe_channels\n\n        self._build_layers()\n        self._build_basic_bins()\n\n    def _build_layers(self):\n        \"\"\"Builds layers for the model.\"\"\"\n\n        # GAU encoder\n        if self.gau_cfg is not None:\n            gau_cfg = self.gau_cfg.copy()\n            gau_cfg['in_token_dims'] = self.feat_channels\n            gau_cfg['out_token_dims'] = self.feat_channels\n            self.gau = GAUEncoder(**gau_cfg)\n            if gau_cfg.get('pos_enc', 'none') in ('add', 'rope'):\n                self.pos_enc = nn.Parameter(\n                    torch.randn(self.num_keypoints, gau_cfg['s']))\n\n        # fully-connected layers to convert pose feats to keypoint feats\n        pose_to_kpts = [\n            nn.Linear(self.in_channels,\n                      self.feat_channels * self.num_keypoints),\n            nn.BatchNorm1d(self.feat_channels * self.num_keypoints)\n        ]\n        self.pose_to_kpts = nn.Sequential(*pose_to_kpts)\n\n        # adapter layers for dynamic encodings\n        self.x_fc = nn.Linear(self.spe_feat_channels, self.feat_channels)\n        self.y_fc = nn.Linear(self.spe_feat_channels, self.feat_channels)\n\n        # fully-connected layers to predict sigma\n        self.sigma_fc = nn.Sequential(\n            nn.Linear(self.in_channels, self.num_keypoints), nn.Sigmoid(),\n            Scale(0.1))\n\n    def _build_basic_bins(self):\n        \"\"\"Builds basic bin coordinates for x and y.\"\"\"\n        self.register_buffer('y_bins',\n                             torch.linspace(-0.5, 0.5, self.num_bins[1]))\n        self.register_buffer('x_bins',\n                             torch.linspace(-0.5, 0.5, self.num_bins[0]))\n\n    def _apply_softmax(self, x_hms, y_hms):\n        \"\"\"Apply softmax on 1-D heatmaps.\n\n        Args:\n            x_hms (Tensor): 1-D heatmap in x direction.\n            y_hms (Tensor): 1-D heatmap in y direction.\n\n        Returns:\n            tuple: A tuple containing the normalized x and y heatmaps.\n        \"\"\"\n\n        x_hms = x_hms.clamp(min=-5e4, max=5e4)\n        y_hms = y_hms.clamp(min=-5e4, max=5e4)\n        pred_x = x_hms - x_hms.max(dim=-1, keepdims=True).values.detach()\n        pred_y = y_hms - y_hms.max(dim=-1, keepdims=True).values.detach()\n\n        exp_x, exp_y = pred_x.exp(), pred_y.exp()\n        prob_x = exp_x / (exp_x.sum(dim=-1, keepdims=True) + EPS)\n        prob_y = exp_y / (exp_y.sum(dim=-1, keepdims=True) + EPS)\n\n        return prob_x, prob_y\n\n    def _get_bin_enc(self, bbox_cs, grids):\n        \"\"\"Calculate dynamic bin encodings for expanded bounding box.\n\n        This function computes dynamic bin allocations and encodings based\n        on the expanded bounding box center-scale (bbox_cs) and grid values.\n        The process involves adjusting the bins according to the scale and\n        center of the bounding box and then applying a sinusoidal positional\n        encoding (spe) followed by a fully connected layer (fc) to obtain the\n        final x and y bin encodings.\n\n        Args:\n            bbox_cs (Tensor): A tensor representing the center and scale of\n                bounding boxes.\n            grids (Tensor): A tensor representing the grid coordinates.\n\n        Returns:\n            tuple: A tuple containing the encoded x and y bins.\n        \"\"\"\n        center, scale = bbox_cs.split(2, dim=-1)\n        center = center - grids\n\n        x_bins, y_bins = self.x_bins, self.y_bins\n\n        # dynamic bin allocation\n        x_bins = x_bins.view(*((1,) * (scale.ndim-1)), -1) \\\n            * scale[..., 0:1] + center[..., 0:1]\n        y_bins = y_bins.view(*((1,) * (scale.ndim-1)), -1) \\\n            * scale[..., 1:2] + center[..., 1:2]\n\n        # dynamic bin encoding\n        x_bins_enc = self.x_fc(self.spe(position=x_bins))\n        y_bins_enc = self.y_fc(self.spe(position=y_bins))\n\n        return x_bins_enc, y_bins_enc\n\n    def _pose_feats_to_heatmaps(self, pose_feats, x_bins_enc, y_bins_enc):\n        \"\"\"Convert pose features to heatmaps using x and y bin encodings.\n\n        This function transforms the given pose features into keypoint\n        features and then generates x and y heatmaps based on the x and y\n        bin encodings. If Gated attention unit (gau) is used, it applies it\n        to the keypoint features. The heatmaps are generated using matrix\n        multiplication of pose features and bin encodings.\n\n        Args:\n            pose_feats (Tensor): The pose features tensor.\n            x_bins_enc (Tensor): The encoded x bins tensor.\n            y_bins_enc (Tensor): The encoded y bins tensor.\n\n        Returns:\n            tuple: A tuple containing the x and y heatmaps.\n        \"\"\"\n\n        kpt_feats = self.pose_to_kpts(pose_feats)\n\n        kpt_feats = kpt_feats.reshape(*kpt_feats.shape[:-1],\n                                      self.num_keypoints, self.feat_channels)\n\n        if hasattr(self, 'gau'):\n            kpt_feats = self.gau(\n                kpt_feats, pos_enc=getattr(self, 'pos_enc', None))\n\n        x_hms = torch.matmul(kpt_feats,\n                             x_bins_enc.transpose(-1, -2).contiguous())\n        y_hms = torch.matmul(kpt_feats,\n                             y_bins_enc.transpose(-1, -2).contiguous())\n\n        return x_hms, y_hms\n\n    def _decode_xy_heatmaps(self, x_hms, y_hms, bbox_cs):\n        \"\"\"Decode x and y heatmaps to obtain coordinates.\n\n        This function  decodes x and y heatmaps to obtain the corresponding\n        coordinates. It adjusts the x and y bins based on the bounding box\n        center and scale, and then computes the weighted sum of these bins\n        with the heatmaps to derive the x and y coordinates.\n\n        Args:\n            x_hms (Tensor): The normalized x heatmaps tensor.\n            y_hms (Tensor): The normalized y heatmaps tensor.\n            bbox_cs (Tensor): The bounding box center-scale tensor.\n\n        Returns:\n            Tensor: A tensor of decoded x and y coordinates.\n        \"\"\"\n        center, scale = bbox_cs.split(2, dim=-1)\n\n        x_bins, y_bins = self.x_bins, self.y_bins\n\n        x_bins = x_bins.view(*((1,) * (scale.ndim-1)), -1) \\\n            * scale[..., 0:1] + center[..., 0:1]\n        y_bins = y_bins.view(*((1,) * (scale.ndim-1)), -1) \\\n            * scale[..., 1:2] + center[..., 1:2]\n\n        x = (x_hms * x_bins.unsqueeze(1)).sum(dim=-1)\n        y = (y_hms * y_bins.unsqueeze(1)).sum(dim=-1)\n\n        return torch.stack((x, y), dim=-1)\n\n    def generate_target_heatmap(self, kpt_targets, bbox_cs, sigmas, areas):\n        \"\"\"Generate target heatmaps for keypoints based on bounding box.\n\n        This function calculates x and y bins adjusted by bounding box center\n        and scale. It then computes distances from keypoint targets to these\n        bins and normalizes these distances based on the areas and sigmas.\n        Finally, it uses these distances to generate heatmaps for x and y\n        coordinates under assumption of laplacian error.\n\n        Args:\n            kpt_targets (Tensor): Keypoint targets tensor.\n            bbox_cs (Tensor): Bounding box center-scale tensor.\n            sigmas (Tensor): Learned deviation of grids.\n            areas (Tensor): Areas of GT instance assigned to grids.\n\n        Returns:\n            tuple: A tuple containing the x and y heatmaps.\n        \"\"\"\n\n        # calculate the error of each bin from the GT keypoint coordinates\n        center, scale = bbox_cs.split(2, dim=-1)\n        x_bins = self.x_bins.view(*((1,) * (scale.ndim-1)), -1) \\\n            * scale[..., 0:1] + center[..., 0:1]\n        y_bins = self.y_bins.view(*((1,) * (scale.ndim-1)), -1) \\\n            * scale[..., 1:2] + center[..., 1:2]\n\n        dist_x = torch.abs(kpt_targets.narrow(2, 0, 1) - x_bins.unsqueeze(1))\n        dist_y = torch.abs(kpt_targets.narrow(2, 1, 1) - y_bins.unsqueeze(1))\n\n        # normalize\n        areas = areas.pow(0.5).clip(min=1).reshape(-1, 1, 1)\n        sigmas = sigmas.clip(min=1e-3).unsqueeze(2)\n        dist_x = dist_x / areas / sigmas\n        dist_y = dist_y / areas / sigmas\n\n        hm_x = torch.exp(-dist_x / 2) / sigmas\n        hm_y = torch.exp(-dist_y / 2) / sigmas\n\n        return hm_x, hm_y\n\n    def forward_train(self, pose_feats, bbox_cs, grids):\n        \"\"\"Forward pass for training.\n\n        This function processes pose features during training. It computes\n        sigmas using a fully connected layer, generates bin encodings,\n        creates heatmaps from pose features, applies softmax to the heatmaps,\n        and then decodes the heatmaps to get pose predictions.\n\n        Args:\n            pose_feats (Tensor): The pose features tensor.\n            bbox_cs (Tensor): The bounding box in the format of center & scale.\n            grids (Tensor): The grid coordinates.\n\n        Returns:\n            tuple: A tuple containing pose predictions, heatmaps, and sigmas.\n        \"\"\"\n        sigmas = self.sigma_fc(pose_feats)\n        x_bins_enc, y_bins_enc = self._get_bin_enc(bbox_cs, grids)\n        x_hms, y_hms = self._pose_feats_to_heatmaps(pose_feats, x_bins_enc,\n                                                    y_bins_enc)\n        x_hms, y_hms = self._apply_softmax(x_hms, y_hms)\n        pose_preds = self._decode_xy_heatmaps(x_hms, y_hms, bbox_cs)\n        return pose_preds, (x_hms, y_hms), sigmas\n\n    @torch.no_grad()\n    def forward_test(self, pose_feats, bbox_cs, grids):\n        \"\"\"Forward pass for testing.\n\n        This function processes pose features during testing. It generates\n        bin encodings, creates heatmaps from pose features, and then decodes\n        the heatmaps to get pose predictions.\n\n        Args:\n            pose_feats (Tensor): The pose features tensor.\n            bbox_cs (Tensor): The bounding box in the format of center & scale.\n            grids (Tensor): The grid coordinates.\n\n        Returns:\n            Tensor: Pose predictions tensor.\n        \"\"\"\n        x_bins_enc, y_bins_enc = self._get_bin_enc(bbox_cs, grids)\n        x_hms, y_hms = self._pose_feats_to_heatmaps(pose_feats, x_bins_enc,\n                                                    y_bins_enc)\n        x_hms, y_hms = self._apply_softmax(x_hms, y_hms)\n        pose_preds = self._decode_xy_heatmaps(x_hms, y_hms, bbox_cs)\n        return pose_preds\n\n    def switch_to_deploy(self, test_cfg: Optional[Dict] = None):\n        if getattr(self, 'deploy', False):\n            return\n\n        self._convert_pose_to_kpts()\n        if hasattr(self, 'gau'):\n            self._convert_gau()\n        self._convert_forward_test()\n\n        self.deploy = True\n\n    def _convert_pose_to_kpts(self):\n        \"\"\"Merge BatchNorm layer into Fully Connected layer.\n\n        This function merges a BatchNorm layer into the associated Fully\n        Connected layer to avoid dimension mismatch during ONNX exportation. It\n        adjusts the weights and biases of the FC layer to incorporate the BN\n        layer's parameters, and then replaces the original FC layer with the\n        updated one.\n        \"\"\"\n        fc, bn = self.pose_to_kpts\n\n        # Calculate adjusted weights and biases\n        std = (bn.running_var + bn.eps).sqrt()\n        weight = fc.weight * (bn.weight / std).unsqueeze(1)\n        bias = bn.bias + (fc.bias - bn.running_mean) * bn.weight / std\n\n        # Update FC layer with adjusted parameters\n        fc.weight.data = weight.detach()\n        fc.bias.data = bias.detach()\n        self.pose_to_kpts = fc\n\n    def _convert_gau(self):\n        \"\"\"Reshape and merge tensors for Gated Attention Unit (GAU).\n\n        This function pre-processes the gamma and beta tensors of the GAU and\n        handles the position encoding if available. It also redefines the GAU's\n        forward method to incorporate these pre-processed tensors, optimizing\n        the computation process.\n        \"\"\"\n        # Reshape gamma and beta tensors in advance\n        gamma_q = self.gau.gamma[0].view(1, 1, 1, self.gau.gamma.size(-1))\n        gamma_k = self.gau.gamma[1].view(1, 1, 1, self.gau.gamma.size(-1))\n        beta_q = self.gau.beta[0].view(1, 1, 1, self.gau.beta.size(-1))\n        beta_k = self.gau.beta[1].view(1, 1, 1, self.gau.beta.size(-1))\n\n        # Adjust beta tensors with position encoding if available\n        if hasattr(self, 'pos_enc'):\n            pos_enc = self.pos_enc.reshape(1, 1, *self.pos_enc.shape)\n            beta_q = beta_q + pos_enc\n            beta_k = beta_k + pos_enc\n\n        gamma_q = gamma_q.detach().cpu()\n        gamma_k = gamma_k.detach().cpu()\n        beta_q = beta_q.detach().cpu()\n        beta_k = beta_k.detach().cpu()\n\n        @torch.no_grad()\n        def _forward(self, x, *args, **kwargs):\n            norm = torch.linalg.norm(x, dim=-1, keepdim=True) * self.ln.scale\n            x = x / norm.clamp(min=self.ln.eps) * self.ln.g\n\n            uv = self.uv(x)\n            uv = self.act_fn(uv)\n\n            u, v, base = torch.split(uv, [self.e, self.e, self.s], dim=-1)\n            if not torch.onnx.is_in_onnx_export():\n                q = base * gamma_q.to(base) + beta_q.to(base)\n                k = base * gamma_k.to(base) + beta_k.to(base)\n            else:\n                q = base * gamma_q + beta_q\n                k = base * gamma_k + beta_k\n            qk = torch.matmul(q, k.transpose(-1, -2))\n\n            kernel = torch.square(torch.nn.functional.relu(qk / self.sqrt_s))\n            x = u * torch.matmul(kernel, v)\n            x = self.o(x)\n            return x\n\n        self.gau._forward = types.MethodType(_forward, self.gau)\n\n    def _convert_forward_test(self):\n        \"\"\"Simplify the forward test process.\n\n        This function precomputes certain tensors and redefines the\n        forward_test method for the model. It includes steps for converting\n        pose features to keypoint features, performing dynamic bin encoding,\n        calculating 1-D heatmaps, and decoding these heatmaps to produce final\n        pose predictions.\n        \"\"\"\n        x_bins_ = self.x_bins.view(1, 1, -1).detach().cpu()\n        y_bins_ = self.y_bins.view(1, 1, -1).detach().cpu()\n        dim_t = self.spe.dim_t.view(1, 1, 1, -1).detach().cpu()\n\n        @torch.no_grad()\n        def _forward_test(self, pose_feats, bbox_cs, grids):\n\n            # step 1: pose features -> keypoint features\n            kpt_feats = self.pose_to_kpts(pose_feats)\n            kpt_feats = kpt_feats.reshape(*kpt_feats.shape[:-1],\n                                          self.num_keypoints,\n                                          self.feat_channels)\n            kpt_feats = self.gau(kpt_feats)\n\n            # step 2: dynamic bin encoding\n            center, scale = bbox_cs.split(2, dim=-1)\n            center = center - grids\n\n            if not torch.onnx.is_in_onnx_export():\n                x_bins = x_bins_.to(scale) * scale[..., 0:1] + center[..., 0:1]\n                y_bins = y_bins_.to(scale) * scale[..., 1:2] + center[..., 1:2]\n                freq_x = x_bins.unsqueeze(-1) / dim_t.to(scale)\n                freq_y = y_bins.unsqueeze(-1) / dim_t.to(scale)\n            else:\n                x_bins = x_bins_ * scale[..., 0:1] + center[..., 0:1]\n                y_bins = y_bins_ * scale[..., 1:2] + center[..., 1:2]\n                freq_x = x_bins.unsqueeze(-1) / dim_t\n                freq_y = y_bins.unsqueeze(-1) / dim_t\n\n            spe_x = torch.cat((freq_x.cos(), freq_x.sin()), dim=-1)\n            spe_y = torch.cat((freq_y.cos(), freq_y.sin()), dim=-1)\n\n            x_bins_enc = self.x_fc(spe_x).transpose(-1, -2).contiguous()\n            y_bins_enc = self.y_fc(spe_y).transpose(-1, -2).contiguous()\n\n            # step 3: calculate 1-D heatmaps\n            x_hms = torch.matmul(kpt_feats, x_bins_enc)\n            y_hms = torch.matmul(kpt_feats, y_bins_enc)\n            x_hms, y_hms = self._apply_softmax(x_hms, y_hms)\n\n            # step 4: decode 1-D heatmaps through integral\n            x = (x_hms * x_bins.unsqueeze(-2)).sum(dim=-1) + grids[..., 0:1]\n            y = (y_hms * y_bins.unsqueeze(-2)).sum(dim=-1) + grids[..., 1:2]\n\n            keypoints = torch.stack((x, y), dim=-1)\n\n            if not torch.onnx.is_in_onnx_export():\n                keypoints = keypoints.squeeze(0)\n            return keypoints\n\n        self.forward_test = types.MethodType(_forward_test, self)\n\n\n@MODELS.register_module()\nclass RTMOHead(YOLOXPoseHead):\n    \"\"\"One-stage coordinate classification head introduced in RTMO (2023). This\n    head incorporates dynamic coordinate classification and YOLO structure for\n    precise keypoint localization.\n\n    Args:\n        num_keypoints (int): Number of keypoints to detect.\n        head_module_cfg (ConfigType): Configuration for the head module.\n        featmap_strides (Sequence[int]): Strides of feature maps.\n            Defaults to [16, 32].\n        num_classes (int): Number of object classes, defaults to 1.\n        use_aux_loss (bool): Indicates whether to use auxiliary loss,\n            defaults to False.\n        proxy_target_cc (bool): Indicates whether to use keypoints predicted\n            by coordinate classification as the targets for proxy regression\n            branch. Defaults to False.\n        assigner (ConfigType): Configuration for positive sample assigning\n            module.\n        prior_generator (ConfigType): Configuration for prior generation.\n        bbox_padding (float): Padding for bounding boxes, defaults to 1.25.\n        overlaps_power (float): Power factor adopted by overlaps before they\n            are assigned as targets in classification loss. Defaults to 1.0.\n        dcc_cfg (Optional[ConfigType]): Configuration for dynamic coordinate\n            classification module.\n        loss_cls (Optional[ConfigType]): Configuration for classification loss.\n        loss_bbox (Optional[ConfigType]): Configuration for bounding box loss.\n        loss_oks (Optional[ConfigType]): Configuration for OKS loss.\n        loss_vis (Optional[ConfigType]): Configuration for visibility loss.\n        loss_mle (Optional[ConfigType]): Configuration for MLE loss.\n        loss_bbox_aux (Optional[ConfigType]): Configuration for auxiliary\n            bounding box loss.\n    \"\"\"\n\n    def __init__(\n        self,\n        num_keypoints: int,\n        head_module_cfg: ConfigType,\n        featmap_strides: Sequence[int] = [16, 32],\n        num_classes: int = 1,\n        use_aux_loss: bool = False,\n        proxy_target_cc: bool = False,\n        assigner: ConfigType = None,\n        prior_generator: ConfigType = None,\n        bbox_padding: float = 1.25,\n        overlaps_power: float = 1.0,\n        dcc_cfg: Optional[ConfigType] = None,\n        loss_cls: Optional[ConfigType] = None,\n        loss_bbox: Optional[ConfigType] = None,\n        loss_oks: Optional[ConfigType] = None,\n        loss_vis: Optional[ConfigType] = None,\n        loss_mle: Optional[ConfigType] = None,\n        loss_bbox_aux: Optional[ConfigType] = None,\n    ):\n        super().__init__(\n            num_keypoints=num_keypoints,\n            head_module_cfg=None,\n            featmap_strides=featmap_strides,\n            num_classes=num_classes,\n            use_aux_loss=use_aux_loss,\n            assigner=assigner,\n            prior_generator=prior_generator,\n            loss_cls=loss_cls,\n            loss_bbox=loss_bbox,\n            loss_oks=loss_oks,\n            loss_vis=loss_vis,\n            loss_bbox_aux=loss_bbox_aux,\n            overlaps_power=overlaps_power)\n\n        self.bbox_padding = bbox_padding\n\n        # override to ensure consistency\n        head_module_cfg['featmap_strides'] = featmap_strides\n        head_module_cfg['num_keypoints'] = num_keypoints\n\n        # build modules\n        self.head_module = RTMOHeadModule(**head_module_cfg)\n\n        self.proxy_target_cc = proxy_target_cc\n        if dcc_cfg is not None:\n            dcc_cfg['num_keypoints'] = num_keypoints\n            self.dcc = DCC(**dcc_cfg)\n\n        # build losses\n        if loss_mle is not None:\n            self.loss_mle = MODELS.build(loss_mle)\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n\n        # 1. collect & reform predictions\n        cls_scores, bbox_preds, kpt_offsets, kpt_vis, pose_vecs = self.forward(\n            feats)\n\n        featmap_sizes = [cls_score.shape[2:] for cls_score in cls_scores]\n        mlvl_priors = self.prior_generator.grid_priors(\n            featmap_sizes,\n            dtype=cls_scores[0].dtype,\n            device=cls_scores[0].device,\n            with_stride=True)\n        flatten_priors = torch.cat(mlvl_priors)\n\n        # flatten cls_scores, bbox_preds and objectness\n        flatten_cls_scores = self._flatten_predictions(cls_scores)\n        flatten_bbox_preds = self._flatten_predictions(bbox_preds)\n        flatten_objectness = torch.ones_like(\n            flatten_cls_scores).detach().narrow(-1, 0, 1) * 1e4\n        flatten_kpt_offsets = self._flatten_predictions(kpt_offsets)\n        flatten_kpt_vis = self._flatten_predictions(kpt_vis)\n        flatten_pose_vecs = self._flatten_predictions(pose_vecs)\n        flatten_bbox_decoded = self.decode_bbox(flatten_bbox_preds,\n                                                flatten_priors[..., :2],\n                                                flatten_priors[..., -1])\n        flatten_kpt_decoded = self.decode_kpt_reg(flatten_kpt_offsets,\n                                                  flatten_priors[..., :2],\n                                                  flatten_priors[..., -1])\n\n        # 2. generate targets\n        targets = self._get_targets(flatten_priors,\n                                    flatten_cls_scores.detach(),\n                                    flatten_objectness.detach(),\n                                    flatten_bbox_decoded.detach(),\n                                    flatten_kpt_decoded.detach(),\n                                    flatten_kpt_vis.detach(),\n                                    batch_data_samples)\n        pos_masks, cls_targets, obj_targets, obj_weights, \\\n            bbox_targets, bbox_aux_targets, kpt_targets, kpt_aux_targets, \\\n            vis_targets, vis_weights, pos_areas, pos_priors, group_indices, \\\n            num_fg_imgs = targets\n\n        num_pos = torch.tensor(\n            sum(num_fg_imgs),\n            dtype=torch.float,\n            device=flatten_cls_scores.device)\n        num_total_samples = max(reduce_mean(num_pos), 1.0)\n\n        # 3. calculate loss\n        extra_info = dict(num_samples=num_total_samples)\n        losses = dict()\n        cls_preds_all = flatten_cls_scores.view(-1, self.num_classes)\n\n        if num_pos > 0:\n\n            # 3.1 bbox loss\n            bbox_preds = flatten_bbox_decoded.view(-1, 4)[pos_masks]\n            losses['loss_bbox'] = self.loss_bbox(\n                bbox_preds, bbox_targets) / num_total_samples\n\n            if self.use_aux_loss:\n                if hasattr(self, 'loss_bbox_aux'):\n                    bbox_preds_raw = flatten_bbox_preds.view(-1, 4)[pos_masks]\n                    losses['loss_bbox_aux'] = self.loss_bbox_aux(\n                        bbox_preds_raw, bbox_aux_targets) / num_total_samples\n\n            # 3.2 keypoint visibility loss\n            kpt_vis_preds = flatten_kpt_vis.view(-1,\n                                                 self.num_keypoints)[pos_masks]\n            losses['loss_vis'] = self.loss_vis(kpt_vis_preds, vis_targets,\n                                               vis_weights)\n\n            # 3.3 keypoint loss\n            kpt_reg_preds = flatten_kpt_decoded.view(-1, self.num_keypoints,\n                                                     2)[pos_masks]\n\n            if hasattr(self, 'loss_mle') and self.loss_mle.loss_weight > 0:\n                pose_vecs = flatten_pose_vecs.view(\n                    -1, flatten_pose_vecs.size(-1))[pos_masks]\n                bbox_cs = torch.cat(\n                    bbox_xyxy2cs(bbox_preds, self.bbox_padding), dim=1)\n                # 'cc' refers to 'cordinate classification'\n                kpt_cc_preds, pred_hms, sigmas = \\\n                    self.dcc.forward_train(pose_vecs,\n                                           bbox_cs,\n                                           pos_priors[..., :2])\n                target_hms = self.dcc.generate_target_heatmap(\n                    kpt_targets, bbox_cs, sigmas, pos_areas)\n                losses['loss_mle'] = self.loss_mle(pred_hms, target_hms,\n                                                   vis_targets)\n\n            if self.proxy_target_cc:\n                # form the regression target using the coordinate\n                # classification predictions\n                with torch.no_grad():\n                    diff_cc = torch.norm(kpt_cc_preds - kpt_targets, dim=-1)\n                    diff_reg = torch.norm(kpt_reg_preds - kpt_targets, dim=-1)\n                    mask = (diff_reg > diff_cc).float()\n                    kpt_weights_reg = vis_targets * mask\n                    oks = self.assigner.oks_calculator(kpt_cc_preds,\n                                                       kpt_targets,\n                                                       vis_targets, pos_areas)\n                    cls_targets = oks.unsqueeze(1)\n\n                losses['loss_oks'] = self.loss_oks(kpt_reg_preds,\n                                                   kpt_cc_preds.detach(),\n                                                   kpt_weights_reg, pos_areas)\n\n            else:\n                losses['loss_oks'] = self.loss_oks(kpt_reg_preds, kpt_targets,\n                                                   vis_targets, pos_areas)\n\n            # update the target for classification loss\n            # the target for the positive grids are set to the oks calculated\n            # using predictions and assigned ground truth instances\n            extra_info['overlaps'] = cls_targets\n            cls_targets = cls_targets.pow(self.overlaps_power).detach()\n            obj_targets[pos_masks] = cls_targets.to(obj_targets)\n\n        # 3.4 classification loss\n        losses['loss_cls'] = self.loss_cls(cls_preds_all, obj_targets,\n                                           obj_weights) / num_total_samples\n        losses.update(extra_info)\n\n        return losses\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-scale features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (1, h, w)\n                    or (K+1, h, w) if keypoint heatmaps are predicted\n                - displacements (Tensor): The predicted displacement fields\n                    in shape (K*2, h, w)\n        \"\"\"\n\n        cls_scores, bbox_preds, _, kpt_vis, pose_vecs = self.forward(feats)\n\n        cfg = copy.deepcopy(test_cfg)\n\n        batch_img_metas = [d.metainfo for d in batch_data_samples]\n        featmap_sizes = [cls_score.shape[2:] for cls_score in cls_scores]\n\n        # If the shape does not change, use the previous mlvl_priors\n        if featmap_sizes != self.featmap_sizes:\n            self.mlvl_priors = self.prior_generator.grid_priors(\n                featmap_sizes,\n                dtype=cls_scores[0].dtype,\n                device=cls_scores[0].device)\n            self.featmap_sizes = featmap_sizes\n        flatten_priors = torch.cat(self.mlvl_priors)\n\n        mlvl_strides = [\n            flatten_priors.new_full((featmap_size.numel(), ),\n                                    stride) for featmap_size, stride in zip(\n                                        featmap_sizes, self.featmap_strides)\n        ]\n        flatten_stride = torch.cat(mlvl_strides)\n\n        # flatten predictions\n        flatten_cls_scores = self._flatten_predictions(cls_scores).sigmoid()\n        flatten_bbox_preds = self._flatten_predictions(bbox_preds)\n        flatten_kpt_vis = self._flatten_predictions(kpt_vis).sigmoid()\n        flatten_pose_vecs = self._flatten_predictions(pose_vecs)\n        if flatten_pose_vecs is None:\n            flatten_pose_vecs = [None] * len(batch_img_metas)\n        flatten_bbox_preds = self.decode_bbox(flatten_bbox_preds,\n                                              flatten_priors, flatten_stride)\n\n        results_list = []\n        for (bboxes, scores, kpt_vis, pose_vecs,\n             img_meta) in zip(flatten_bbox_preds, flatten_cls_scores,\n                              flatten_kpt_vis, flatten_pose_vecs,\n                              batch_img_metas):\n\n            score_thr = cfg.get('score_thr', 0.01)\n\n            nms_pre = cfg.get('nms_pre', 100000)\n            scores, labels = scores.max(1, keepdim=True)\n            scores, _, keep_idxs_score, results = filter_scores_and_topk(\n                scores, score_thr, nms_pre, results=dict(labels=labels[:, 0]))\n            labels = results['labels']\n\n            bboxes = bboxes[keep_idxs_score]\n            kpt_vis = kpt_vis[keep_idxs_score]\n            grids = flatten_priors[keep_idxs_score]\n            stride = flatten_stride[keep_idxs_score]\n\n            if bboxes.numel() > 0:\n                nms_thr = cfg.get('nms_thr', 1.0)\n                if nms_thr < 1.0:\n\n                    keep_idxs_nms = nms_torch(bboxes, scores, nms_thr)\n                    bboxes = bboxes[keep_idxs_nms]\n                    stride = stride[keep_idxs_nms]\n                    labels = labels[keep_idxs_nms]\n                    kpt_vis = kpt_vis[keep_idxs_nms]\n                    scores = scores[keep_idxs_nms]\n\n                pose_vecs = pose_vecs[keep_idxs_score][keep_idxs_nms]\n                bbox_cs = torch.cat(\n                    bbox_xyxy2cs(bboxes, self.bbox_padding), dim=1)\n                grids = grids[keep_idxs_nms]\n                keypoints = self.dcc.forward_test(pose_vecs, bbox_cs, grids)\n\n            else:\n                # empty prediction\n                keypoints = bboxes.new_zeros((0, self.num_keypoints, 2))\n\n            results = InstanceData(\n                scores=scores,\n                labels=labels,\n                bboxes=bboxes,\n                bbox_scores=scores,\n                keypoints=keypoints,\n                keypoint_scores=kpt_vis,\n                keypoints_visible=kpt_vis)\n\n            input_size = img_meta['input_size']\n            results.bboxes[:, 0::2].clamp_(0, input_size[0])\n            results.bboxes[:, 1::2].clamp_(0, input_size[1])\n\n            results_list.append(results.numpy())\n\n        return results_list\n\n    def switch_to_deploy(self, test_cfg: Optional[Dict]):\n        \"\"\"Precompute and save the grid coordinates and strides.\"\"\"\n\n        if getattr(self, 'deploy', False):\n            return\n\n        self.deploy = True\n\n        # grid generator\n        input_size = test_cfg.get('input_size', (640, 640))\n        featmaps = []\n        for s in self.featmap_strides:\n            featmaps.append(\n                torch.rand(1, 1, input_size[0] // s, input_size[1] // s))\n        featmap_sizes = [fmap.shape[2:] for fmap in featmaps]\n\n        self.mlvl_priors = self.prior_generator.grid_priors(\n            featmap_sizes, dtype=torch.float32, device='cpu')\n        self.flatten_priors = torch.cat(self.mlvl_priors)\n\n        mlvl_strides = [\n            self.flatten_priors.new_full((featmap_size.numel(), ), stride) for\n            featmap_size, stride in zip(featmap_sizes, self.featmap_strides)\n        ]\n        self.flatten_stride = torch.cat(mlvl_strides)\n"
  },
  {
    "path": "mmpose/models/heads/hybrid_heads/vis_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Tuple, Union\n\nimport torch\nfrom torch import Tensor, nn\n\nfrom mmpose.models.utils.tta import flip_visibility\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptSampleList, Predictions)\nfrom ..base_head import BaseHead\n\n\n@MODELS.register_module()\nclass VisPredictHead(BaseHead):\n    \"\"\"VisPredictHead must be used together with other heads. It can predict\n    keypoints coordinates of and their visibility simultaneously. In the\n    current version, it only supports top-down approaches.\n\n    Args:\n        pose_cfg (Config): Config to construct keypoints prediction head\n        loss (Config): Config for visibility loss. Defaults to use\n            :class:`BCELoss`\n        use_sigmoid (bool): Whether to use sigmoid activation function\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(self,\n                 pose_cfg: ConfigType,\n                 loss: ConfigType = dict(\n                     type='BCELoss', use_target_weight=False,\n                     use_sigmoid=True),\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = pose_cfg['in_channels']\n        if pose_cfg.get('num_joints', None) is not None:\n            self.out_channels = pose_cfg['num_joints']\n        elif pose_cfg.get('out_channels', None) is not None:\n            self.out_channels = pose_cfg['out_channels']\n        else:\n            raise ValueError('VisPredictHead requires \\'num_joints\\' or'\n                             ' \\'out_channels\\' in the pose_cfg.')\n\n        self.loss_module = MODELS.build(loss)\n\n        self.pose_head = MODELS.build(pose_cfg)\n        self.pose_cfg = pose_cfg\n\n        self.use_sigmoid = loss.get('use_sigmoid', False)\n\n        modules = [\n            nn.AdaptiveAvgPool2d(1),\n            nn.Flatten(),\n            nn.Linear(self.in_channels, self.out_channels)\n        ]\n        if self.use_sigmoid:\n            modules.append(nn.Sigmoid())\n\n        self.vis_head = nn.Sequential(*modules)\n\n    def vis_forward(self, feats: Tuple[Tensor]):\n        \"\"\"Forward the vis_head. The input is multi scale feature maps and the\n        output is coordinates visibility.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output coordinates visibility.\n        \"\"\"\n        x = feats[-1]\n        while len(x.shape) < 4:\n            x.unsqueeze_(-1)\n        x = self.vis_head(x)\n        return x.reshape(-1, self.out_channels)\n\n    def forward(self, feats: Tuple[Tensor]):\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is coordinates and coordinates visibility.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tuple[Tensor]: output coordinates and coordinates visibility.\n        \"\"\"\n        x_pose = self.pose_head.forward(feats)\n        x_vis = self.vis_forward(feats)\n\n        return x_pose, x_vis\n\n    def integrate(self, batch_vis: Tensor,\n                  pose_preds: Union[Tuple, Predictions]) -> InstanceList:\n        \"\"\"Add keypoints visibility prediction to pose prediction.\n\n        Overwrite the original keypoint_scores.\n        \"\"\"\n        if isinstance(pose_preds, tuple):\n            pose_pred_instances, pose_pred_fields = pose_preds\n        else:\n            pose_pred_instances = pose_preds\n            pose_pred_fields = None\n\n        batch_vis_np = to_numpy(batch_vis, unzip=True)\n\n        assert len(pose_pred_instances) == len(batch_vis_np)\n        for index, _ in enumerate(pose_pred_instances):\n            pose_pred_instances[index].keypoints_visible = batch_vis_np[index]\n\n        return pose_pred_instances, pose_pred_fields\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            posehead's ``test_cfg['output_heatmap']==True``, return both\n            pose and heatmap prediction; otherwise only return the pose\n            prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n                - keypoint_visibility (np.ndarray): predicted keypoints\n                    visibility in shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n\n            _batch_vis = self.vis_forward(_feats)\n            _batch_vis_flip = flip_visibility(\n                self.vis_forward(_feats_flip), flip_indices=flip_indices)\n            batch_vis = (_batch_vis + _batch_vis_flip) * 0.5\n        else:\n            batch_vis = self.vis_forward(feats)  # (B, K, D)\n\n        batch_vis.unsqueeze_(dim=1)  # (B, N, K, D)\n\n        if not self.use_sigmoid:\n            batch_vis = torch.sigmoid(batch_vis)\n\n        batch_pose = self.pose_head.predict(feats, batch_data_samples,\n                                            test_cfg)\n\n        return self.integrate(batch_vis, batch_pose)\n\n    @torch.no_grad()\n    def vis_accuracy(self, vis_pred_outputs, vis_labels, vis_weights=None):\n        \"\"\"Calculate visibility prediction accuracy.\"\"\"\n        if not self.use_sigmoid:\n            vis_pred_outputs = torch.sigmoid(vis_pred_outputs)\n        threshold = 0.5\n        predictions = (vis_pred_outputs >= threshold).float()\n        correct = (predictions == vis_labels).float()\n        if vis_weights is not None:\n            accuracy = (correct * vis_weights).sum(dim=1) / (\n                vis_weights.sum(dim=1) + 1e-6)\n        else:\n            accuracy = correct.mean(dim=1)\n        return accuracy.mean()\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: OptConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        vis_pred_outputs = self.vis_forward(feats)\n        vis_labels = []\n        vis_weights = [] if self.loss_module.use_target_weight else None\n        for d in batch_data_samples:\n            vis_label = d.gt_instance_labels.keypoint_weights.float()\n            vis_labels.append(vis_label)\n            if vis_weights is not None:\n                vis_weights.append(\n                    getattr(d.gt_instance_labels, 'keypoints_visible_weights',\n                            vis_label.new_ones(vis_label.shape)))\n        vis_labels = torch.cat(vis_labels)\n        vis_weights = torch.cat(vis_weights) if vis_weights else None\n\n        # calculate vis losses\n        losses = dict()\n        loss_vis = self.loss_module(vis_pred_outputs, vis_labels, vis_weights)\n\n        losses.update(loss_vis=loss_vis)\n\n        # calculate vis accuracy\n        acc_vis = self.vis_accuracy(vis_pred_outputs, vis_labels, vis_weights)\n        losses.update(acc_vis=acc_vis)\n\n        # calculate keypoints losses\n        loss_kpt = self.pose_head.loss(feats, batch_data_samples)\n        losses.update(loss_kpt)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/hybrid_heads/yoloxpose_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nfrom typing import List, Optional, Sequence, Tuple, Union\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule, bias_init_with_prob\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor\n\nfrom mmpose.evaluation.functional import nms_torch\nfrom mmpose.models.utils import filter_scores_and_topk\nfrom mmpose.registry import MODELS, TASK_UTILS\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.utils import reduce_mean\nfrom mmpose.utils.typing import (ConfigType, Features, OptSampleList,\n                                 Predictions, SampleList)\n\n\nclass YOLOXPoseHeadModule(BaseModule):\n    \"\"\"YOLOXPose head module for one-stage human pose estimation.\n\n    This module predicts classification scores, bounding boxes, keypoint\n    offsets and visibilities from multi-level feature maps.\n\n    Args:\n        num_classes (int): Number of categories excluding the background\n            category.\n        num_keypoints (int): Number of keypoints defined for one instance.\n         in_channels (Union[int, Sequence]): Number of channels in the input\n             feature map.\n        feat_channels (int): Number of channels in the classification score\n            and objectness prediction branch. Defaults to 256.\n         widen_factor (float): Width multiplier, multiply number of\n             channels in each layer by this amount. Defaults to 1.0.\n        num_groups (int): Group number of group convolution layers in keypoint\n            regression branch. Defaults to 8.\n        channels_per_group (int): Number of channels for each group of group\n            convolution layers in keypoint regression branch. Defaults to 32.\n        featmap_strides (Sequence[int]): Downsample factor of each feature\n            map. Defaults to [8, 16, 32].\n        conv_bias (bool or str): If specified as `auto`, it will be decided\n            by the norm_cfg. Bias of conv will be set as True if `norm_cfg`\n            is None, otherwise False. Defaults to \"auto\".\n        conv_cfg (:obj:`ConfigDict` or dict, optional): Config dict for\n            convolution layer. Defaults to None.\n        norm_cfg (:obj:`ConfigDict` or dict): Config dict for normalization\n            layer. Defaults to dict(type='BN', momentum=0.03, eps=0.001).\n        act_cfg (:obj:`ConfigDict` or dict): Config dict for activation layer.\n            Defaults to None.\n        init_cfg (:obj:`ConfigDict` or list[:obj:`ConfigDict`] or dict or\n            list[dict], optional): Initialization config dict.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(\n        self,\n        num_keypoints: int,\n        in_channels: Union[int, Sequence],\n        num_classes: int = 1,\n        widen_factor: float = 1.0,\n        feat_channels: int = 256,\n        stacked_convs: int = 2,\n        featmap_strides: Sequence[int] = [8, 16, 32],\n        conv_bias: Union[bool, str] = 'auto',\n        conv_cfg: Optional[ConfigType] = None,\n        norm_cfg: ConfigType = dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg: ConfigType = dict(type='SiLU', inplace=True),\n        init_cfg: Optional[ConfigType] = None,\n    ):\n        super().__init__(init_cfg=init_cfg)\n        self.num_classes = num_classes\n        self.feat_channels = int(feat_channels * widen_factor)\n        self.stacked_convs = stacked_convs\n        assert conv_bias == 'auto' or isinstance(conv_bias, bool)\n        self.conv_bias = conv_bias\n\n        self.conv_cfg = conv_cfg\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n        self.featmap_strides = featmap_strides\n\n        if isinstance(in_channels, int):\n            in_channels = int(in_channels * widen_factor)\n        self.in_channels = in_channels\n        self.num_keypoints = num_keypoints\n\n        self._init_layers()\n\n    def _init_layers(self):\n        \"\"\"Initialize heads for all level feature maps.\"\"\"\n        self._init_cls_branch()\n        self._init_reg_branch()\n        self._init_pose_branch()\n\n    def _init_cls_branch(self):\n        \"\"\"Initialize classification branch for all level feature maps.\"\"\"\n        self.conv_cls = nn.ModuleList()\n        for _ in self.featmap_strides:\n            stacked_convs = []\n            for i in range(self.stacked_convs):\n                chn = self.in_channels if i == 0 else self.feat_channels\n                stacked_convs.append(\n                    ConvModule(\n                        chn,\n                        self.feat_channels,\n                        3,\n                        stride=1,\n                        padding=1,\n                        conv_cfg=self.conv_cfg,\n                        norm_cfg=self.norm_cfg,\n                        act_cfg=self.act_cfg,\n                        bias=self.conv_bias))\n            self.conv_cls.append(nn.Sequential(*stacked_convs))\n\n        # output layers\n        self.out_cls = nn.ModuleList()\n        self.out_obj = nn.ModuleList()\n        for _ in self.featmap_strides:\n            self.out_cls.append(\n                nn.Conv2d(self.feat_channels, self.num_classes, 1))\n\n    def _init_reg_branch(self):\n        \"\"\"Initialize classification branch for all level feature maps.\"\"\"\n        self.conv_reg = nn.ModuleList()\n        for _ in self.featmap_strides:\n            stacked_convs = []\n            for i in range(self.stacked_convs):\n                chn = self.in_channels if i == 0 else self.feat_channels\n                stacked_convs.append(\n                    ConvModule(\n                        chn,\n                        self.feat_channels,\n                        3,\n                        stride=1,\n                        padding=1,\n                        conv_cfg=self.conv_cfg,\n                        norm_cfg=self.norm_cfg,\n                        act_cfg=self.act_cfg,\n                        bias=self.conv_bias))\n            self.conv_reg.append(nn.Sequential(*stacked_convs))\n\n        # output layers\n        self.out_bbox = nn.ModuleList()\n        self.out_obj = nn.ModuleList()\n        for _ in self.featmap_strides:\n            self.out_bbox.append(nn.Conv2d(self.feat_channels, 4, 1))\n            self.out_obj.append(nn.Conv2d(self.feat_channels, 1, 1))\n\n    def _init_pose_branch(self):\n        self.conv_pose = nn.ModuleList()\n\n        for _ in self.featmap_strides:\n            stacked_convs = []\n            for i in range(self.stacked_convs * 2):\n                in_chn = self.in_channels if i == 0 else self.feat_channels\n                stacked_convs.append(\n                    ConvModule(\n                        in_chn,\n                        self.feat_channels,\n                        3,\n                        stride=1,\n                        padding=1,\n                        conv_cfg=self.conv_cfg,\n                        norm_cfg=self.norm_cfg,\n                        act_cfg=self.act_cfg,\n                        bias=self.conv_bias))\n            self.conv_pose.append(nn.Sequential(*stacked_convs))\n\n        # output layers\n        self.out_kpt = nn.ModuleList()\n        self.out_kpt_vis = nn.ModuleList()\n        for _ in self.featmap_strides:\n            self.out_kpt.append(\n                nn.Conv2d(self.feat_channels, self.num_keypoints * 2, 1))\n            self.out_kpt_vis.append(\n                nn.Conv2d(self.feat_channels, self.num_keypoints, 1))\n\n    def init_weights(self):\n        \"\"\"Initialize weights of the head.\"\"\"\n        # Use prior in model initialization to improve stability\n        super().init_weights()\n        bias_init = bias_init_with_prob(0.01)\n        for conv_cls, conv_obj in zip(self.out_cls, self.out_obj):\n            conv_cls.bias.data.fill_(bias_init)\n            conv_obj.bias.data.fill_(bias_init)\n\n    def forward(self, x: Tuple[Tensor]) -> Tuple[List]:\n        \"\"\"Forward features from the upstream network.\n\n        Args:\n            x (Tuple[Tensor]): Features from the upstream network, each is\n                a 4D-tensor.\n\n        Returns:\n            cls_scores (List[Tensor]): Classification scores for each level.\n            objectnesses (List[Tensor]): Objectness scores for each level.\n            bbox_preds (List[Tensor]): Bounding box predictions for each level.\n            kpt_offsets (List[Tensor]): Keypoint offsets for each level.\n            kpt_vis (List[Tensor]): Keypoint visibilities for each level.\n        \"\"\"\n\n        cls_scores, bbox_preds, objectnesses = [], [], []\n        kpt_offsets, kpt_vis = [], []\n\n        for i in range(len(x)):\n\n            cls_feat = self.conv_cls[i](x[i])\n            reg_feat = self.conv_reg[i](x[i])\n            pose_feat = self.conv_pose[i](x[i])\n\n            cls_scores.append(self.out_cls[i](cls_feat))\n            objectnesses.append(self.out_obj[i](reg_feat))\n            bbox_preds.append(self.out_bbox[i](reg_feat))\n            kpt_offsets.append(self.out_kpt[i](pose_feat))\n            kpt_vis.append(self.out_kpt_vis[i](pose_feat))\n\n        return cls_scores, objectnesses, bbox_preds, kpt_offsets, kpt_vis\n\n\n@MODELS.register_module()\nclass YOLOXPoseHead(BaseModule):\n\n    def __init__(\n        self,\n        num_keypoints: int,\n        head_module_cfg: Optional[ConfigType] = None,\n        featmap_strides: Sequence[int] = [8, 16, 32],\n        num_classes: int = 1,\n        use_aux_loss: bool = False,\n        assigner: ConfigType = None,\n        prior_generator: ConfigType = None,\n        loss_cls: Optional[ConfigType] = None,\n        loss_obj: Optional[ConfigType] = None,\n        loss_bbox: Optional[ConfigType] = None,\n        loss_oks: Optional[ConfigType] = None,\n        loss_vis: Optional[ConfigType] = None,\n        loss_bbox_aux: Optional[ConfigType] = None,\n        loss_kpt_aux: Optional[ConfigType] = None,\n        overlaps_power: float = 1.0,\n    ):\n        super().__init__()\n\n        self.featmap_sizes = None\n        self.num_classes = num_classes\n        self.featmap_strides = featmap_strides\n        self.use_aux_loss = use_aux_loss\n        self.num_keypoints = num_keypoints\n        self.overlaps_power = overlaps_power\n\n        self.prior_generator = TASK_UTILS.build(prior_generator)\n        if head_module_cfg is not None:\n            head_module_cfg['featmap_strides'] = featmap_strides\n            head_module_cfg['num_keypoints'] = num_keypoints\n            self.head_module = YOLOXPoseHeadModule(**head_module_cfg)\n        self.assigner = TASK_UTILS.build(assigner)\n\n        # build losses\n        self.loss_cls = MODELS.build(loss_cls)\n        if loss_obj is not None:\n            self.loss_obj = MODELS.build(loss_obj)\n        self.loss_bbox = MODELS.build(loss_bbox)\n        self.loss_oks = MODELS.build(loss_oks)\n        self.loss_vis = MODELS.build(loss_vis)\n        if loss_bbox_aux is not None:\n            self.loss_bbox_aux = MODELS.build(loss_bbox_aux)\n        if loss_kpt_aux is not None:\n            self.loss_kpt_aux = MODELS.build(loss_kpt_aux)\n\n    def forward(self, feats: Features):\n        assert isinstance(feats, (tuple, list))\n        return self.head_module(feats)\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n\n        # 1. collect & reform predictions\n        cls_scores, objectnesses, bbox_preds, kpt_offsets, \\\n            kpt_vis = self.forward(feats)\n\n        featmap_sizes = [cls_score.shape[2:] for cls_score in cls_scores]\n        mlvl_priors = self.prior_generator.grid_priors(\n            featmap_sizes,\n            dtype=cls_scores[0].dtype,\n            device=cls_scores[0].device,\n            with_stride=True)\n        flatten_priors = torch.cat(mlvl_priors)\n\n        # flatten cls_scores, bbox_preds and objectness\n        flatten_cls_scores = self._flatten_predictions(cls_scores)\n        flatten_bbox_preds = self._flatten_predictions(bbox_preds)\n        flatten_objectness = self._flatten_predictions(objectnesses)\n        flatten_kpt_offsets = self._flatten_predictions(kpt_offsets)\n        flatten_kpt_vis = self._flatten_predictions(kpt_vis)\n        flatten_bbox_decoded = self.decode_bbox(flatten_bbox_preds,\n                                                flatten_priors[..., :2],\n                                                flatten_priors[..., -1])\n        flatten_kpt_decoded = self.decode_kpt_reg(flatten_kpt_offsets,\n                                                  flatten_priors[..., :2],\n                                                  flatten_priors[..., -1])\n\n        # 2. generate targets\n        targets = self._get_targets(flatten_priors,\n                                    flatten_cls_scores.detach(),\n                                    flatten_objectness.detach(),\n                                    flatten_bbox_decoded.detach(),\n                                    flatten_kpt_decoded.detach(),\n                                    flatten_kpt_vis.detach(),\n                                    batch_data_samples)\n        pos_masks, cls_targets, obj_targets, obj_weights, \\\n            bbox_targets, bbox_aux_targets, kpt_targets, kpt_aux_targets, \\\n            vis_targets, vis_weights, pos_areas, pos_priors, group_indices, \\\n            num_fg_imgs = targets\n\n        num_pos = torch.tensor(\n            sum(num_fg_imgs),\n            dtype=torch.float,\n            device=flatten_cls_scores.device)\n        num_total_samples = max(reduce_mean(num_pos), 1.0)\n\n        # 3. calculate loss\n        # 3.1 objectness loss\n        losses = dict()\n\n        obj_preds = flatten_objectness.view(-1, 1)\n        losses['loss_obj'] = self.loss_obj(obj_preds, obj_targets,\n                                           obj_weights) / num_total_samples\n\n        if num_pos > 0:\n            # 3.2 bbox loss\n            bbox_preds = flatten_bbox_decoded.view(-1, 4)[pos_masks]\n            losses['loss_bbox'] = self.loss_bbox(\n                bbox_preds, bbox_targets) / num_total_samples\n\n            # 3.3 keypoint loss\n            kpt_preds = flatten_kpt_decoded.view(-1, self.num_keypoints,\n                                                 2)[pos_masks]\n            losses['loss_kpt'] = self.loss_oks(kpt_preds, kpt_targets,\n                                               vis_targets, pos_areas)\n\n            # 3.4 keypoint visibility loss\n            kpt_vis_preds = flatten_kpt_vis.view(-1,\n                                                 self.num_keypoints)[pos_masks]\n            losses['loss_vis'] = self.loss_vis(kpt_vis_preds, vis_targets,\n                                               vis_weights)\n\n            # 3.5 classification loss\n            cls_preds = flatten_cls_scores.view(-1,\n                                                self.num_classes)[pos_masks]\n            losses['overlaps'] = cls_targets\n            cls_targets = cls_targets.pow(self.overlaps_power).detach()\n            losses['loss_cls'] = self.loss_cls(cls_preds,\n                                               cls_targets) / num_total_samples\n\n            if self.use_aux_loss:\n                if hasattr(self, 'loss_bbox_aux'):\n                    # 3.6 auxiliary bbox regression loss\n                    bbox_preds_raw = flatten_bbox_preds.view(-1, 4)[pos_masks]\n                    losses['loss_bbox_aux'] = self.loss_bbox_aux(\n                        bbox_preds_raw, bbox_aux_targets) / num_total_samples\n\n                if hasattr(self, 'loss_kpt_aux'):\n                    # 3.7 auxiliary keypoint regression loss\n                    kpt_preds_raw = flatten_kpt_offsets.view(\n                        -1, self.num_keypoints, 2)[pos_masks]\n                    kpt_weights = vis_targets / vis_targets.size(-1)\n                    losses['loss_kpt_aux'] = self.loss_kpt_aux(\n                        kpt_preds_raw, kpt_aux_targets, kpt_weights)\n\n        return losses\n\n    @torch.no_grad()\n    def _get_targets(\n        self,\n        priors: Tensor,\n        batch_cls_scores: Tensor,\n        batch_objectness: Tensor,\n        batch_decoded_bboxes: Tensor,\n        batch_decoded_kpts: Tensor,\n        batch_kpt_vis: Tensor,\n        batch_data_samples: SampleList,\n    ):\n        num_imgs = len(batch_data_samples)\n\n        # use clip to avoid nan\n        batch_cls_scores = batch_cls_scores.clip(min=-1e4, max=1e4).sigmoid()\n        batch_objectness = batch_objectness.clip(min=-1e4, max=1e4).sigmoid()\n        batch_kpt_vis = batch_kpt_vis.clip(min=-1e4, max=1e4).sigmoid()\n        batch_cls_scores[torch.isnan(batch_cls_scores)] = 0\n        batch_objectness[torch.isnan(batch_objectness)] = 0\n\n        targets_each = []\n        for i in range(num_imgs):\n            target = self._get_targets_single(priors, batch_cls_scores[i],\n                                              batch_objectness[i],\n                                              batch_decoded_bboxes[i],\n                                              batch_decoded_kpts[i],\n                                              batch_kpt_vis[i],\n                                              batch_data_samples[i])\n            targets_each.append(target)\n\n        targets = list(zip(*targets_each))\n        for i, target in enumerate(targets):\n            if torch.is_tensor(target[0]):\n                target = tuple(filter(lambda x: x.size(0) > 0, target))\n                if len(target) > 0:\n                    targets[i] = torch.cat(target)\n\n        foreground_masks, cls_targets, obj_targets, obj_weights, \\\n            bbox_targets, kpt_targets, vis_targets, vis_weights, pos_areas, \\\n            pos_priors, group_indices, num_pos_per_img = targets\n\n        # post-processing for targets\n        if self.use_aux_loss:\n            bbox_cxcy = (bbox_targets[:, :2] + bbox_targets[:, 2:]) / 2.0\n            bbox_wh = bbox_targets[:, 2:] - bbox_targets[:, :2]\n            bbox_aux_targets = torch.cat([\n                (bbox_cxcy - pos_priors[:, :2]) / pos_priors[:, 2:],\n                torch.log(bbox_wh / pos_priors[:, 2:] + 1e-8)\n            ],\n                                         dim=-1)\n\n            kpt_aux_targets = (kpt_targets - pos_priors[:, None, :2]) \\\n                / pos_priors[:, None, 2:]\n        else:\n            bbox_aux_targets, kpt_aux_targets = None, None\n\n        return (foreground_masks, cls_targets, obj_targets, obj_weights,\n                bbox_targets, bbox_aux_targets, kpt_targets, kpt_aux_targets,\n                vis_targets, vis_weights, pos_areas, pos_priors, group_indices,\n                num_pos_per_img)\n\n    @torch.no_grad()\n    def _get_targets_single(\n        self,\n        priors: Tensor,\n        cls_scores: Tensor,\n        objectness: Tensor,\n        decoded_bboxes: Tensor,\n        decoded_kpts: Tensor,\n        kpt_vis: Tensor,\n        data_sample: PoseDataSample,\n    ) -> tuple:\n        \"\"\"Compute classification, bbox, keypoints and objectness targets for\n        priors in a single image.\n\n        Args:\n            priors (Tensor): All priors of one image, a 2D-Tensor with shape\n                [num_priors, 4] in [cx, xy, stride_w, stride_y] format.\n            cls_scores (Tensor): Classification predictions of one image,\n                a 2D-Tensor with shape [num_priors, num_classes]\n            objectness (Tensor): Objectness predictions of one image,\n                a 1D-Tensor with shape [num_priors]\n            decoded_bboxes (Tensor): Decoded bboxes predictions of one image,\n                a 2D-Tensor with shape [num_priors, 4] in xyxy format.\n            decoded_kpts (Tensor): Decoded keypoints predictions of one image,\n                a 3D-Tensor with shape [num_priors, num_keypoints, 2].\n            kpt_vis (Tensor): Keypoints visibility predictions of one image,\n                a 2D-Tensor with shape [num_priors, num_keypoints].\n            gt_instances (:obj:`InstanceData`): Ground truth of instance\n                annotations. It should includes ``bboxes`` and ``labels``\n                attributes.\n            data_sample (PoseDataSample): Data sample that contains the ground\n                truth annotations for current image.\n\n        Returns:\n            tuple: A tuple containing various target tensors for training:\n                - foreground_mask (Tensor): Binary mask indicating foreground\n                    priors.\n                - cls_target (Tensor): Classification targets.\n                - obj_target (Tensor): Objectness targets.\n                - obj_weight (Tensor): Weights for objectness targets.\n                - bbox_target (Tensor): BBox targets.\n                - kpt_target (Tensor): Keypoints targets.\n                - vis_target (Tensor): Visibility targets for keypoints.\n                - vis_weight (Tensor): Weights for keypoints visibility\n                    targets.\n                - pos_areas (Tensor): Areas of positive samples.\n                - pos_priors (Tensor): Priors corresponding to positive\n                    samples.\n                - group_index (List[Tensor]): Indices of groups for positive\n                    samples.\n                - num_pos_per_img (int): Number of positive samples.\n        \"\"\"\n        # TODO: change the shape of objectness to [num_priors]\n        num_priors = priors.size(0)\n        gt_instances = data_sample.gt_instance_labels\n        gt_fields = data_sample.get('gt_fields', dict())\n        num_gts = len(gt_instances)\n\n        # No target\n        if num_gts == 0:\n            cls_target = cls_scores.new_zeros((0, self.num_classes))\n            bbox_target = cls_scores.new_zeros((0, 4))\n            obj_target = cls_scores.new_zeros((num_priors, 1))\n            obj_weight = cls_scores.new_ones((num_priors, 1))\n            kpt_target = cls_scores.new_zeros((0, self.num_keypoints, 2))\n            vis_target = cls_scores.new_zeros((0, self.num_keypoints))\n            vis_weight = cls_scores.new_zeros((0, self.num_keypoints))\n            pos_areas = cls_scores.new_zeros((0, ))\n            pos_priors = priors[:0]\n            foreground_mask = cls_scores.new_zeros(num_priors).bool()\n            return (foreground_mask, cls_target, obj_target, obj_weight,\n                    bbox_target, kpt_target, vis_target, vis_weight, pos_areas,\n                    pos_priors, [], 0)\n\n        # assign positive samples\n        scores = cls_scores * objectness\n        pred_instances = InstanceData(\n            bboxes=decoded_bboxes,\n            scores=scores.sqrt_(),\n            priors=priors,\n            keypoints=decoded_kpts,\n            keypoints_visible=kpt_vis,\n        )\n        assign_result = self.assigner.assign(\n            pred_instances=pred_instances, gt_instances=gt_instances)\n\n        # sampling\n        pos_inds = torch.nonzero(\n            assign_result['gt_inds'] > 0, as_tuple=False).squeeze(-1).unique()\n        num_pos_per_img = pos_inds.size(0)\n        pos_gt_labels = assign_result['labels'][pos_inds]\n        pos_assigned_gt_inds = assign_result['gt_inds'][pos_inds] - 1\n\n        # bbox target\n        bbox_target = gt_instances.bboxes[pos_assigned_gt_inds.long()]\n\n        # cls target\n        max_overlaps = assign_result['max_overlaps'][pos_inds]\n        cls_target = F.one_hot(pos_gt_labels,\n                               self.num_classes) * max_overlaps.unsqueeze(-1)\n\n        # pose targets\n        kpt_target = gt_instances.keypoints[pos_assigned_gt_inds]\n        vis_target = gt_instances.keypoints_visible[pos_assigned_gt_inds]\n        if 'keypoints_visible_weights' in gt_instances:\n            vis_weight = gt_instances.keypoints_visible_weights[\n                pos_assigned_gt_inds]\n        else:\n            vis_weight = vis_target.new_ones(vis_target.shape)\n        pos_areas = gt_instances.areas[pos_assigned_gt_inds]\n\n        # obj target\n        obj_target = torch.zeros_like(objectness)\n        obj_target[pos_inds] = 1\n\n        invalid_mask = gt_fields.get('heatmap_mask', None)\n        if invalid_mask is not None and (invalid_mask != 0.0).any():\n            # ignore the tokens that predict the unlabled instances\n            pred_vis = (kpt_vis.unsqueeze(-1) > 0.3).float()\n            mean_kpts = (decoded_kpts * pred_vis).sum(dim=1) / pred_vis.sum(\n                dim=1).clamp(min=1e-8)\n            mean_kpts = mean_kpts.reshape(1, -1, 1, 2)\n            wh = invalid_mask.shape[-1]\n            grids = mean_kpts / (wh - 1) * 2 - 1\n            mask = invalid_mask.unsqueeze(0).float()\n            weight = F.grid_sample(\n                mask, grids, mode='bilinear', padding_mode='zeros')\n            obj_weight = 1.0 - weight.reshape(num_priors, 1)\n        else:\n            obj_weight = obj_target.new_ones(obj_target.shape)\n\n        # misc\n        foreground_mask = torch.zeros_like(objectness.squeeze()).to(torch.bool)\n        foreground_mask[pos_inds] = 1\n        pos_priors = priors[pos_inds]\n        group_index = [\n            torch.where(pos_assigned_gt_inds == num)[0]\n            for num in torch.unique(pos_assigned_gt_inds)\n        ]\n\n        return (foreground_mask, cls_target, obj_target, obj_weight,\n                bbox_target, kpt_target, vis_target, vis_weight, pos_areas,\n                pos_priors, group_index, num_pos_per_img)\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-scale features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (1, h, w)\n                    or (K+1, h, w) if keypoint heatmaps are predicted\n                - displacements (Tensor): The predicted displacement fields\n                    in shape (K*2, h, w)\n        \"\"\"\n\n        cls_scores, objectnesses, bbox_preds, kpt_offsets, \\\n            kpt_vis = self.forward(feats)\n\n        cfg = copy.deepcopy(test_cfg)\n\n        batch_img_metas = [d.metainfo for d in batch_data_samples]\n        featmap_sizes = [cls_score.shape[2:] for cls_score in cls_scores]\n\n        # If the shape does not change, use the previous mlvl_priors\n        if featmap_sizes != self.featmap_sizes:\n            self.mlvl_priors = self.prior_generator.grid_priors(\n                featmap_sizes,\n                dtype=cls_scores[0].dtype,\n                device=cls_scores[0].device)\n            self.featmap_sizes = featmap_sizes\n        flatten_priors = torch.cat(self.mlvl_priors)\n\n        mlvl_strides = [\n            flatten_priors.new_full((featmap_size.numel(), ),\n                                    stride) for featmap_size, stride in zip(\n                                        featmap_sizes, self.featmap_strides)\n        ]\n        flatten_stride = torch.cat(mlvl_strides)\n\n        # flatten cls_scores, bbox_preds and objectness\n        flatten_cls_scores = self._flatten_predictions(cls_scores).sigmoid()\n        flatten_bbox_preds = self._flatten_predictions(bbox_preds)\n        flatten_objectness = self._flatten_predictions(objectnesses).sigmoid()\n        flatten_kpt_offsets = self._flatten_predictions(kpt_offsets)\n        flatten_kpt_vis = self._flatten_predictions(kpt_vis).sigmoid()\n        flatten_bbox_preds = self.decode_bbox(flatten_bbox_preds,\n                                              flatten_priors, flatten_stride)\n        flatten_kpt_reg = self.decode_kpt_reg(flatten_kpt_offsets,\n                                              flatten_priors, flatten_stride)\n\n        results_list = []\n        for (bboxes, scores, objectness, kpt_reg, kpt_vis,\n             img_meta) in zip(flatten_bbox_preds, flatten_cls_scores,\n                              flatten_objectness, flatten_kpt_reg,\n                              flatten_kpt_vis, batch_img_metas):\n\n            score_thr = cfg.get('score_thr', 0.01)\n            scores *= objectness\n\n            nms_pre = cfg.get('nms_pre', 100000)\n            scores, labels = scores.max(1, keepdim=True)\n            scores, _, keep_idxs_score, results = filter_scores_and_topk(\n                scores, score_thr, nms_pre, results=dict(labels=labels[:, 0]))\n            labels = results['labels']\n\n            bboxes = bboxes[keep_idxs_score]\n            kpt_vis = kpt_vis[keep_idxs_score]\n            stride = flatten_stride[keep_idxs_score]\n            keypoints = kpt_reg[keep_idxs_score]\n\n            if bboxes.numel() > 0:\n                nms_thr = cfg.get('nms_thr', 1.0)\n                if nms_thr < 1.0:\n                    keep_idxs_nms = nms_torch(bboxes, scores, nms_thr)\n                    bboxes = bboxes[keep_idxs_nms]\n                    stride = stride[keep_idxs_nms]\n                    labels = labels[keep_idxs_nms]\n                    kpt_vis = kpt_vis[keep_idxs_nms]\n                    keypoints = keypoints[keep_idxs_nms]\n                    scores = scores[keep_idxs_nms]\n\n            results = InstanceData(\n                scores=scores,\n                labels=labels,\n                bboxes=bboxes,\n                bbox_scores=scores,\n                keypoints=keypoints,\n                keypoint_scores=kpt_vis,\n                keypoints_visible=kpt_vis)\n\n            input_size = img_meta['input_size']\n            results.bboxes[:, 0::2].clamp_(0, input_size[0])\n            results.bboxes[:, 1::2].clamp_(0, input_size[1])\n\n            results_list.append(results.numpy())\n\n        return results_list\n\n    def decode_bbox(self, pred_bboxes: torch.Tensor, priors: torch.Tensor,\n                    stride: Union[torch.Tensor, int]) -> torch.Tensor:\n        \"\"\"Decode regression results (delta_x, delta_y, log_w, log_h) to\n        bounding boxes (tl_x, tl_y, br_x, br_y).\n\n        Note:\n            - batch size: B\n            - token number: N\n\n        Args:\n            pred_bboxes (torch.Tensor): Encoded boxes with shape (B, N, 4),\n                representing (delta_x, delta_y, log_w, log_h) for each box.\n            priors (torch.Tensor): Anchors coordinates, with shape (N, 2).\n            stride (torch.Tensor | int): Strides of the bboxes. It can be a\n                single value if the same stride applies to all boxes, or it\n                can be a tensor of shape (N, ) if different strides are used\n                for each box.\n\n        Returns:\n            torch.Tensor: Decoded bounding boxes with shape (N, 4),\n                representing (tl_x, tl_y, br_x, br_y) for each box.\n        \"\"\"\n        stride = stride.view(1, stride.size(0), 1)\n        priors = priors.view(1, priors.size(0), 2)\n\n        xys = (pred_bboxes[..., :2] * stride) + priors\n        whs = pred_bboxes[..., 2:].exp() * stride\n\n        # Calculate bounding box corners\n        tl_x = xys[..., 0] - whs[..., 0] / 2\n        tl_y = xys[..., 1] - whs[..., 1] / 2\n        br_x = xys[..., 0] + whs[..., 0] / 2\n        br_y = xys[..., 1] + whs[..., 1] / 2\n\n        decoded_bboxes = torch.stack([tl_x, tl_y, br_x, br_y], -1)\n        return decoded_bboxes\n\n    def decode_kpt_reg(self, pred_kpt_offsets: torch.Tensor,\n                       priors: torch.Tensor,\n                       stride: torch.Tensor) -> torch.Tensor:\n        \"\"\"Decode regression results (delta_x, delta_y) to keypoints\n        coordinates (x, y).\n\n        Args:\n            pred_kpt_offsets (torch.Tensor): Encoded keypoints offsets with\n                shape (batch_size, num_anchors, num_keypoints, 2).\n            priors (torch.Tensor): Anchors coordinates with shape\n                (num_anchors, 2).\n            stride (torch.Tensor): Strides of the anchors.\n\n        Returns:\n            torch.Tensor: Decoded keypoints coordinates with shape\n                (batch_size, num_boxes, num_keypoints, 2).\n        \"\"\"\n        stride = stride.view(1, stride.size(0), 1, 1)\n        priors = priors.view(1, priors.size(0), 1, 2)\n        pred_kpt_offsets = pred_kpt_offsets.reshape(\n            *pred_kpt_offsets.shape[:-1], self.num_keypoints, 2)\n\n        decoded_kpts = pred_kpt_offsets * stride + priors\n        return decoded_kpts\n\n    def _flatten_predictions(self, preds: List[Tensor]):\n        \"\"\"Flattens the predictions from a list of tensors to a single\n        tensor.\"\"\"\n        if len(preds) == 0:\n            return None\n\n        preds = [x.permute(0, 2, 3, 1).flatten(1, 2) for x in preds]\n        return torch.cat(preds, dim=1)\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .dsnt_head import DSNTHead\nfrom .integral_regression_head import IntegralRegressionHead\nfrom .motion_regression_head import MotionRegressionHead\nfrom .regression_head import RegressionHead\nfrom .rle_head import RLEHead\nfrom .temporal_regression_head import TemporalRegressionHead\nfrom .trajectory_regression_head import TrajectoryRegressionHead\n\n__all__ = [\n    'RegressionHead', 'IntegralRegressionHead', 'DSNTHead', 'RLEHead',\n    'TemporalRegressionHead', 'TrajectoryRegressionHead',\n    'MotionRegressionHead'\n]\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/dsnt_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport numpy as np\nimport torch\nfrom mmengine.logging import MessageHub\nfrom torch import Tensor\n\nfrom mmpose.evaluation.functional import keypoint_pck_accuracy\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import ConfigType, OptConfigType, OptSampleList\nfrom .integral_regression_head import IntegralRegressionHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass DSNTHead(IntegralRegressionHead):\n    \"\"\"Top-down integral regression head introduced in `DSNT`_ by Nibali et\n    al(2018). The head contains a differentiable spatial to numerical transform\n    (DSNT) layer that do soft-argmax operation on the predicted heatmaps to\n    regress the coordinates.\n\n    This head is used for algorithms that require supervision of heatmaps\n    in `DSNT` approach.\n\n    Args:\n        in_channels (int | sequence[int]): Number of input channels\n        in_featuremap_size (int | sequence[int]): Size of input feature map\n        num_joints (int): Number of joints\n        lambda_t (int): Discard heatmap-based loss when current\n            epoch > lambda_t. Defaults to -1.\n        debias (bool): Whether to remove the bias of Integral Pose Regression.\n            see `Removing the Bias of Integral Pose Regression`_ by Gu et al\n            (2021). Defaults to ``False``.\n        beta (float): A smoothing parameter in softmax. Defaults to ``1.0``.\n        deconv_out_channels (sequence[int]): The output channel number of each\n            deconv layer. Defaults to ``(256, 256, 256)``\n        deconv_kernel_sizes (sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.Defaults to\n            ``(4, 4, 4)``\n        conv_out_channels (sequence[int], optional): The output channel number\n            of each intermediate conv layer. ``None`` means no intermediate\n            conv layer between deconv layers and the final conv layer.\n            Defaults to ``None``\n        conv_kernel_sizes (sequence[int | tuple], optional): The kernel size\n            of each intermediate conv layer. Defaults to ``None``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config): Config for keypoint loss. Defaults to use\n            :class:`DSNTLoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`DSNT`: https://arxiv.org/abs/1801.07372\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 in_featuremap_size: Tuple[int, int],\n                 num_joints: int,\n                 lambda_t: int = -1,\n                 debias: bool = False,\n                 beta: float = 1.0,\n                 deconv_out_channels: OptIntSeq = (256, 256, 256),\n                 deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n                 conv_out_channels: OptIntSeq = None,\n                 conv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 loss: ConfigType = dict(\n                     type='MultipleLossWrapper',\n                     losses=[\n                         dict(type='SmoothL1Loss', use_target_weight=True),\n                         dict(type='JSDiscretLoss', use_target_weight=True)\n                     ]),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        super().__init__(\n            in_channels=in_channels,\n            in_featuremap_size=in_featuremap_size,\n            num_joints=num_joints,\n            debias=debias,\n            beta=beta,\n            deconv_out_channels=deconv_out_channels,\n            deconv_kernel_sizes=deconv_kernel_sizes,\n            conv_out_channels=conv_out_channels,\n            conv_kernel_sizes=conv_kernel_sizes,\n            final_layer=final_layer,\n            loss=loss,\n            decoder=decoder,\n            init_cfg=init_cfg)\n\n        self.lambda_t = lambda_t\n\n    def loss(self,\n             inputs: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_coords, pred_heatmaps = self.forward(inputs)\n        keypoint_labels = torch.cat(\n            [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n        gt_heatmaps = torch.stack(\n            [d.gt_fields.heatmaps for d in batch_data_samples])\n\n        input_list = [pred_coords, pred_heatmaps]\n        target_list = [keypoint_labels, gt_heatmaps]\n        # calculate losses\n        losses = dict()\n\n        loss_list = self.loss_module(input_list, target_list, keypoint_weights)\n\n        loss = loss_list[0] + loss_list[1]\n\n        if self.lambda_t > 0:\n            mh = MessageHub.get_current_instance()\n            cur_epoch = mh.get_info('epoch')\n            if cur_epoch >= self.lambda_t:\n                loss = loss_list[0]\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = keypoint_pck_accuracy(\n            pred=to_numpy(pred_coords),\n            gt=to_numpy(keypoint_labels),\n            mask=to_numpy(keypoint_weights) > 0,\n            thr=0.05,\n            norm_factor=np.ones((pred_coords.size(0), 2), dtype=np.float32))\n\n        acc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/integral_regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nfrom mmcv.cnn import build_conv_layer\nfrom mmengine.structures import PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import keypoint_pck_accuracy\nfrom mmpose.models.utils.tta import flip_coordinates, flip_heatmaps\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, OptConfigType, OptSampleList,\n                                 Predictions)\nfrom .. import HeatmapHead\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass IntegralRegressionHead(BaseHead):\n    \"\"\"Top-down integral regression head introduced in `IPR`_ by Xiao et\n    al(2018). The head contains a differentiable spatial to numerical transform\n    (DSNT) layer that do soft-argmax operation on the predicted heatmaps to\n    regress the coordinates.\n\n    This head is used for algorithms that only supervise the coordinates.\n\n    Args:\n        in_channels (int | sequence[int]): Number of input channels\n        in_featuremap_size (int | sequence[int]): Size of input feature map\n        num_joints (int): Number of joints\n        debias (bool): Whether to remove the bias of Integral Pose Regression.\n            see `Removing the Bias of Integral Pose Regression`_ by Gu et al\n            (2021). Defaults to ``False``.\n        beta (float): A smoothing parameter in softmax. Defaults to ``1.0``.\n        deconv_out_channels (sequence[int]): The output channel number of each\n            deconv layer. Defaults to ``(256, 256, 256)``\n        deconv_kernel_sizes (sequence[int | tuple], optional): The kernel size\n            of each deconv layer. Each element should be either an integer for\n            both height and width dimensions, or a tuple of two integers for\n            the height and the width dimension respectively.Defaults to\n            ``(4, 4, 4)``\n        conv_out_channels (sequence[int], optional): The output channel number\n            of each intermediate conv layer. ``None`` means no intermediate\n            conv layer between deconv layers and the final conv layer.\n            Defaults to ``None``\n        conv_kernel_sizes (sequence[int | tuple], optional): The kernel size\n            of each intermediate conv layer. Defaults to ``None``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config): Config for keypoint loss. Defaults to use\n            :class:`SmoothL1Loss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`IPR`: https://arxiv.org/abs/1711.08229\n    .. _`Debias`:\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 in_featuremap_size: Tuple[int, int],\n                 num_joints: int,\n                 debias: bool = False,\n                 beta: float = 1.0,\n                 deconv_out_channels: OptIntSeq = (256, 256, 256),\n                 deconv_kernel_sizes: OptIntSeq = (4, 4, 4),\n                 conv_out_channels: OptIntSeq = None,\n                 conv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 loss: ConfigType = dict(\n                     type='SmoothL1Loss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_joints = num_joints\n        self.debias = debias\n        self.beta = beta\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        num_deconv = len(deconv_out_channels) if deconv_out_channels else 0\n        if num_deconv != 0:\n\n            self.heatmap_size = tuple(\n                [s * (2**num_deconv) for s in in_featuremap_size])\n\n            # deconv layers + 1x1 conv\n            self.simplebaseline_head = HeatmapHead(\n                in_channels=in_channels,\n                out_channels=num_joints,\n                deconv_out_channels=deconv_out_channels,\n                deconv_kernel_sizes=deconv_kernel_sizes,\n                conv_out_channels=conv_out_channels,\n                conv_kernel_sizes=conv_kernel_sizes,\n                final_layer=final_layer)\n\n            if final_layer is not None:\n                in_channels = num_joints\n            else:\n                in_channels = deconv_out_channels[-1]\n\n        else:\n            self.simplebaseline_head = None\n\n            if final_layer is not None:\n                cfg = dict(\n                    type='Conv2d',\n                    in_channels=in_channels,\n                    out_channels=num_joints,\n                    kernel_size=1)\n                cfg.update(final_layer)\n                self.final_layer = build_conv_layer(cfg)\n            else:\n                self.final_layer = None\n\n            self.heatmap_size = in_featuremap_size\n\n        if isinstance(in_channels, list):\n            raise ValueError(\n                f'{self.__class__.__name__} does not support selecting '\n                'multiple input features.')\n\n        W, H = self.heatmap_size\n        self.linspace_x = torch.arange(0.0, 1.0 * W, 1).reshape(1, 1, 1, W) / W\n        self.linspace_y = torch.arange(0.0, 1.0 * H, 1).reshape(1, 1, H, 1) / H\n\n        self.linspace_x = nn.Parameter(self.linspace_x, requires_grad=False)\n        self.linspace_y = nn.Parameter(self.linspace_y, requires_grad=False)\n\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    def _linear_expectation(self, heatmaps: Tensor,\n                            linspace: Tensor) -> Tensor:\n        \"\"\"Calculate linear expectation.\"\"\"\n\n        B, N, _, _ = heatmaps.shape\n        heatmaps = heatmaps.mul(linspace).reshape(B, N, -1)\n        expectation = torch.sum(heatmaps, dim=2, keepdim=True)\n\n        return expectation\n\n    def _flat_softmax(self, featmaps: Tensor) -> Tensor:\n        \"\"\"Use Softmax to normalize the featmaps in depthwise.\"\"\"\n\n        _, N, H, W = featmaps.shape\n\n        featmaps = featmaps.reshape(-1, N, H * W)\n        heatmaps = F.softmax(featmaps, dim=2)\n\n        return heatmaps.reshape(-1, N, H, W)\n\n    def forward(self, feats: Tuple[Tensor]) -> Union[Tensor, Tuple[Tensor]]:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output coordinates(and sigmas[optional]).\n        \"\"\"\n        if self.simplebaseline_head is None:\n            feats = feats[-1]\n            if self.final_layer is not None:\n                feats = self.final_layer(feats)\n        else:\n            feats = self.simplebaseline_head(feats)\n\n        heatmaps = self._flat_softmax(feats * self.beta)\n\n        pred_x = self._linear_expectation(heatmaps, self.linspace_x)\n        pred_y = self._linear_expectation(heatmaps, self.linspace_y)\n\n        if self.debias:\n            B, N, H, W = feats.shape\n            C = feats.reshape(B, N, H * W).exp().sum(dim=2).reshape(B, N, 1)\n            pred_x = C / (C - 1) * (pred_x - 1 / (2 * C))\n            pred_y = C / (C - 1) * (pred_y - 1 / (2 * C))\n\n        coords = torch.cat([pred_x, pred_y], dim=-1)\n        return coords, heatmaps\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            input_size = batch_data_samples[0].metainfo['input_size']\n            _feats, _feats_flip = feats\n\n            _batch_coords, _batch_heatmaps = self.forward(_feats)\n\n            _batch_coords_flip, _batch_heatmaps_flip = self.forward(\n                _feats_flip)\n            _batch_coords_flip = flip_coordinates(\n                _batch_coords_flip,\n                flip_indices=flip_indices,\n                shift_coords=test_cfg.get('shift_coords', True),\n                input_size=input_size)\n            _batch_heatmaps_flip = flip_heatmaps(\n                _batch_heatmaps_flip,\n                flip_mode='heatmap',\n                flip_indices=flip_indices,\n                shift_heatmap=test_cfg.get('shift_heatmap', False))\n\n            batch_coords = (_batch_coords + _batch_coords_flip) * 0.5\n            batch_heatmaps = (_batch_heatmaps + _batch_heatmaps_flip) * 0.5\n        else:\n            batch_coords, batch_heatmaps = self.forward(feats)  # (B, K, D)\n\n        batch_coords.unsqueeze_(dim=1)  # (B, N, K, D)\n        preds = self.decode(batch_coords)\n\n        if test_cfg.get('output_heatmaps', False):\n            pred_fields = [\n                PixelData(heatmaps=hm) for hm in batch_heatmaps.detach()\n            ]\n            return preds, pred_fields\n        else:\n            return preds\n\n    def loss(self,\n             inputs: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_coords, _ = self.forward(inputs)\n        keypoint_labels = torch.cat(\n            [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n\n        # TODO: multi-loss calculation\n        loss = self.loss_module(pred_coords, keypoint_labels, keypoint_weights)\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = keypoint_pck_accuracy(\n            pred=to_numpy(pred_coords),\n            gt=to_numpy(keypoint_labels),\n            mask=to_numpy(keypoint_weights) > 0,\n            thr=0.05,\n            norm_factor=np.ones((pred_coords.size(0), 2), dtype=np.float32))\n\n        acc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to load weights of deconv layers from\n        :class:`HeatmapHead` into `simplebaseline_head`.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n\n        # convert old-version state dict\n        keys = list(state_dict.keys())\n        for _k in keys:\n            if not _k.startswith(prefix):\n                continue\n            v = state_dict.pop(_k)\n            k = _k.lstrip(prefix)\n\n            k_new = _k\n            k_parts = k.split('.')\n            if self.simplebaseline_head is not None:\n                if k_parts[0] == 'conv_layers':\n                    k_new = (\n                        prefix + 'simplebaseline_head.deconv_layers.' +\n                        '.'.join(k_parts[1:]))\n                elif k_parts[0] == 'final_layer':\n                    k_new = prefix + 'simplebaseline_head.' + k\n\n            state_dict[k_new] = v\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/motion_regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import OrderedDict\nfrom typing import Tuple\n\nimport numpy as np\nimport torch\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import keypoint_mpjpe\nfrom mmpose.models.utils.tta import flip_coordinates\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, OptConfigType, OptSampleList,\n                                 Predictions)\nfrom ..base_head import BaseHead\n\n\n@MODELS.register_module()\nclass MotionRegressionHead(BaseHead):\n    \"\"\"Regression head of `MotionBERT`_ by Zhu et al (2022).\n\n    Args:\n        in_channels (int): Number of input channels. Default: 256.\n        out_channels (int): Number of output channels. Default: 3.\n        embedding_size (int): Number of embedding channels. Default: 512.\n        loss (Config): Config for keypoint loss. Defaults to use\n            :class:`MSELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`MotionBERT`: https://arxiv.org/abs/2210.06551\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: int = 256,\n                 out_channels: int = 3,\n                 embedding_size: int = 512,\n                 loss: ConfigType = dict(\n                     type='MSELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Define fully-connected layers\n        self.pre_logits = nn.Sequential(\n            OrderedDict([('fc', nn.Linear(in_channels, embedding_size)),\n                         ('act', nn.Tanh())]))\n        self.fc = nn.Linear(\n            embedding_size,\n            out_channels) if embedding_size > 0 else nn.Identity()\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: Output coordinates (and sigmas[optional]).\n        \"\"\"\n        x = feats  # (B, F, K, in_channels)\n        x = self.pre_logits(x)  # (B, F, K, embedding_size)\n        x = self.fc(x)  # (B, F, K, out_channels)\n\n        return x\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from outputs.\n\n        Returns:\n            preds (sequence[InstanceData]): Prediction results.\n                Each contains the following fields:\n\n                - keypoints: Predicted keypoints of shape (B, N, K, D).\n                - keypoint_scores: Scores of predicted keypoints of shape\n                  (B, N, K).\n        \"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            _feats, _feats_flip = feats\n            _batch_coords = self.forward(_feats)\n            _batch_coords_flip = torch.stack([\n                flip_coordinates(\n                    _batch_coord_flip,\n                    flip_indices=flip_indices,\n                    shift_coords=test_cfg.get('shift_coords', True),\n                    input_size=(1, 1))\n                for _batch_coord_flip in self.forward(_feats_flip)\n            ],\n                                             dim=0)\n            batch_coords = (_batch_coords + _batch_coords_flip) * 0.5\n        else:\n            batch_coords = self.forward(feats)\n\n        # Restore global position with camera_param and factor\n        camera_param = batch_data_samples[0].metainfo.get('camera_param', None)\n        if camera_param is not None:\n            w = torch.stack([\n                torch.from_numpy(np.array([b.metainfo['camera_param']['w']]))\n                for b in batch_data_samples\n            ])\n            h = torch.stack([\n                torch.from_numpy(np.array([b.metainfo['camera_param']['h']]))\n                for b in batch_data_samples\n            ])\n        else:\n            w = torch.stack([\n                torch.empty((0), dtype=torch.float32)\n                for _ in batch_data_samples\n            ])\n            h = torch.stack([\n                torch.empty((0), dtype=torch.float32)\n                for _ in batch_data_samples\n            ])\n\n        factor = batch_data_samples[0].metainfo.get('factor', None)\n        if factor is not None:\n            factor = torch.stack([\n                torch.from_numpy(b.metainfo['factor'])\n                for b in batch_data_samples\n            ])\n        else:\n            factor = torch.stack([\n                torch.empty((0), dtype=torch.float32)\n                for _ in batch_data_samples\n            ])\n\n        preds = self.decode((batch_coords, w, h, factor))\n\n        return preds\n\n    def loss(self,\n             inputs: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_outputs = self.forward(inputs)\n\n        lifting_target_label = torch.stack([\n            d.gt_instance_labels.lifting_target_label\n            for d in batch_data_samples\n        ])\n        lifting_target_weight = torch.stack([\n            d.gt_instance_labels.lifting_target_weight\n            for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_outputs, lifting_target_label,\n                                lifting_target_weight.unsqueeze(-1))\n\n        losses.update(loss_pose3d=loss)\n\n        # calculate accuracy\n        mpjpe_err = keypoint_mpjpe(\n            pred=to_numpy(pred_outputs),\n            gt=to_numpy(lifting_target_label),\n            mask=to_numpy(lifting_target_weight) > 0)\n\n        mpjpe_pose = torch.tensor(\n            mpjpe_err, device=lifting_target_label.device)\n        losses.update(mpjpe=mpjpe_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='TruncNormal', layer=['Linear'], std=0.02)]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport numpy as np\nimport torch\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import keypoint_pck_accuracy\nfrom mmpose.models.utils.tta import flip_coordinates\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, OptConfigType, OptSampleList,\n                                 Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass RegressionHead(BaseHead):\n    \"\"\"Top-down regression head introduced in `Deeppose`_ by Toshev et al\n    (2014). The head is composed of fully-connected layers to predict the\n    coordinates directly.\n\n    Args:\n        in_channels (int | sequence[int]): Number of input channels\n        num_joints (int): Number of joints\n        loss (Config): Config for keypoint loss. Defaults to use\n            :class:`SmoothL1Loss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`Deeppose`: https://arxiv.org/abs/1312.4659\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 num_joints: int,\n                 loss: ConfigType = dict(\n                     type='SmoothL1Loss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_joints = num_joints\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Define fully-connected layers\n        self.fc = nn.Linear(in_channels, self.num_joints * 2)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output coordinates(and sigmas[optional]).\n        \"\"\"\n        x = feats[-1]\n\n        x = torch.flatten(x, 1)\n        x = self.fc(x)\n\n        return x.reshape(-1, self.num_joints, 2)\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from outputs.\"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            input_size = batch_data_samples[0].metainfo['input_size']\n            _feats, _feats_flip = feats\n\n            _batch_coords = self.forward(_feats)\n            _batch_coords_flip = flip_coordinates(\n                self.forward(_feats_flip),\n                flip_indices=flip_indices,\n                shift_coords=test_cfg.get('shift_coords', True),\n                input_size=input_size)\n            batch_coords = (_batch_coords + _batch_coords_flip) * 0.5\n        else:\n            batch_coords = self.forward(feats)  # (B, K, D)\n\n        batch_coords.unsqueeze_(dim=1)  # (B, N, K, D)\n        preds = self.decode(batch_coords)\n\n        return preds\n\n    def loss(self,\n             inputs: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_outputs = self.forward(inputs)\n\n        keypoint_labels = torch.cat(\n            [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_outputs, keypoint_labels,\n                                keypoint_weights.unsqueeze(-1))\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = keypoint_pck_accuracy(\n            pred=to_numpy(pred_outputs),\n            gt=to_numpy(keypoint_labels),\n            mask=to_numpy(keypoint_weights) > 0,\n            thr=0.05,\n            norm_factor=np.ones((pred_outputs.size(0), 2), dtype=np.float32))\n\n        acc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/rle_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport numpy as np\nimport torch\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import keypoint_pck_accuracy\nfrom mmpose.models.utils.tta import flip_coordinates\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, OptConfigType, OptSampleList,\n                                 Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass RLEHead(BaseHead):\n    \"\"\"Top-down regression head introduced in `RLE`_ by Li et al(2021). The\n    head is composed of fully-connected layers to predict the coordinates and\n    sigma(the variance of the coordinates) together.\n\n    Args:\n        in_channels (int | sequence[int]): Number of input channels\n        num_joints (int): Number of joints\n        loss (Config): Config for keypoint loss. Defaults to use\n            :class:`RLELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`RLE`: https://arxiv.org/abs/2107.11291\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 num_joints: int,\n                 loss: ConfigType = dict(\n                     type='RLELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_joints = num_joints\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Define fully-connected layers\n        self.fc = nn.Linear(in_channels, self.num_joints * 4)\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output coordinates(and sigmas[optional]).\n        \"\"\"\n        x = feats[-1]\n\n        x = torch.flatten(x, 1)\n        x = self.fc(x)\n\n        return x.reshape(-1, self.num_joints, 4)\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from outputs.\"\"\"\n\n        if test_cfg.get('flip_test', False):\n            # TTA: flip test -> feats = [orig, flipped]\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = batch_data_samples[0].metainfo['flip_indices']\n            input_size = batch_data_samples[0].metainfo['input_size']\n\n            _feats, _feats_flip = feats\n\n            _batch_coords = self.forward(_feats)\n            _batch_coords[..., 2:] = _batch_coords[..., 2:].sigmoid()\n\n            _batch_coords_flip = flip_coordinates(\n                self.forward(_feats_flip),\n                flip_indices=flip_indices,\n                shift_coords=test_cfg.get('shift_coords', True),\n                input_size=input_size)\n            _batch_coords_flip[..., 2:] = _batch_coords_flip[..., 2:].sigmoid()\n\n            batch_coords = (_batch_coords + _batch_coords_flip) * 0.5\n        else:\n            batch_coords = self.forward(feats)  # (B, K, D)\n            batch_coords[..., 2:] = batch_coords[..., 2:].sigmoid()\n\n        batch_coords.unsqueeze_(dim=1)  # (B, N, K, D)\n        preds = self.decode(batch_coords)\n\n        return preds\n\n    def loss(self,\n             inputs: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_outputs = self.forward(inputs)\n\n        keypoint_labels = torch.cat(\n            [d.gt_instance_labels.keypoint_labels for d in batch_data_samples])\n        keypoint_weights = torch.cat([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n\n        pred_coords = pred_outputs[:, :, :2]\n        pred_sigma = pred_outputs[:, :, 2:4]\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_coords, pred_sigma, keypoint_labels,\n                                keypoint_weights.unsqueeze(-1))\n\n        losses.update(loss_kpt=loss)\n\n        # calculate accuracy\n        _, avg_acc, _ = keypoint_pck_accuracy(\n            pred=to_numpy(pred_coords),\n            gt=to_numpy(keypoint_labels),\n            mask=to_numpy(keypoint_weights) > 0,\n            thr=0.05,\n            norm_factor=np.ones((pred_coords.size(0), 2), dtype=np.float32))\n\n        acc_pose = torch.tensor(avg_acc, device=keypoint_labels.device)\n        losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to convert old-version state dict of\n        :class:`DeepposeRegressionHead` (before MMPose v1.0.0) to a\n        compatible format of :class:`RegressionHead`.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n\n        version = local_meta.get('version', None)\n        if version and version >= self._version:\n            return\n\n        # convert old-version state dict\n        keys = list(state_dict.keys())\n        for _k in keys:\n            v = state_dict.pop(_k)\n            k = _k.lstrip(prefix)\n            # In old version, \"loss\" includes the instances of loss,\n            # now it should be renamed \"loss_module\"\n            k_parts = k.split('.')\n            if k_parts[0] == 'loss':\n                # loss.xxx -> loss_module.xxx\n                k_new = prefix + 'loss_module.' + '.'.join(k_parts[1:])\n            else:\n                k_new = _k\n\n            state_dict[k_new] = v\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/temporal_regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import keypoint_mpjpe\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, OptConfigType, OptSampleList,\n                                 Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass TemporalRegressionHead(BaseHead):\n    \"\"\"Temporal Regression head of `VideoPose3D`_ by Dario et al (CVPR'2019).\n\n    Args:\n        in_channels (int | sequence[int]): Number of input channels\n        num_joints (int): Number of joints\n        loss (Config): Config for keypoint loss. Defaults to use\n            :class:`SmoothL1Loss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`VideoPose3D`: https://arxiv.org/abs/1811.11742\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 num_joints: int,\n                 loss: ConfigType = dict(\n                     type='MSELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_joints = num_joints\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Define fully-connected layers\n        self.conv = nn.Conv1d(in_channels, self.num_joints * 3, 1)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: Output coordinates (and sigmas[optional]).\n        \"\"\"\n        x = feats[-1]\n\n        x = self.conv(x)\n\n        return x.reshape(-1, self.num_joints, 3)\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from outputs.\n\n        Returns:\n            preds (sequence[InstanceData]): Prediction results.\n                Each contains the following fields:\n\n                - keypoints: Predicted keypoints of shape (B, N, K, D).\n                - keypoint_scores: Scores of predicted keypoints of shape\n                  (B, N, K).\n        \"\"\"\n\n        batch_coords = self.forward(feats)  # (B, K, D)\n\n        # Restore global position with target_root\n        target_root = batch_data_samples[0].metainfo.get('target_root', None)\n        if target_root is not None:\n            target_root = torch.stack([\n                torch.from_numpy(b.metainfo['target_root'])\n                for b in batch_data_samples\n            ])\n        else:\n            target_root = torch.stack([\n                torch.empty((0), dtype=torch.float32)\n                for _ in batch_data_samples\n            ])\n\n        preds = self.decode((batch_coords, target_root))\n\n        return preds\n\n    def loss(self,\n             inputs: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_outputs = self.forward(inputs)\n\n        lifting_target_label = torch.cat([\n            d.gt_instance_labels.lifting_target_label\n            for d in batch_data_samples\n        ])\n        lifting_target_weight = torch.cat([\n            d.gt_instance_labels.lifting_target_weight\n            for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_outputs, lifting_target_label,\n                                lifting_target_weight.unsqueeze(-1))\n\n        losses.update(loss_pose3d=loss)\n\n        # calculate accuracy\n        mpjpe_err = keypoint_mpjpe(\n            pred=to_numpy(pred_outputs),\n            gt=to_numpy(lifting_target_label),\n            mask=to_numpy(lifting_target_weight) > 0)\n\n        mpjpe_pose = torch.tensor(\n            mpjpe_err, device=lifting_target_label.device)\n        losses.update(mpjpe=mpjpe_pose)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/regression_heads/trajectory_regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nfrom torch import Tensor, nn\n\nfrom mmpose.evaluation.functional import keypoint_mpjpe\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, OptConfigType, OptSampleList,\n                                 Predictions)\nfrom ..base_head import BaseHead\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass TrajectoryRegressionHead(BaseHead):\n    \"\"\"Trajectory Regression head of `VideoPose3D`_ by Dario et al (CVPR'2019).\n\n    Args:\n        in_channels (int | sequence[int]): Number of input channels\n        num_joints (int): Number of joints\n        loss (Config): Config for trajectory loss. Defaults to use\n            :class:`MPJPELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n    .. _`VideoPose3D`: https://arxiv.org/abs/1811.11742\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 num_joints: int,\n                 loss: ConfigType = dict(\n                     type='MPJPELoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.num_joints = num_joints\n        self.loss_module = MODELS.build(loss)\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Define fully-connected layers\n        self.conv = nn.Conv1d(in_channels, self.num_joints * 3, 1)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output coordinates(and sigmas[optional]).\n        \"\"\"\n        x = feats[-1]\n\n        x = self.conv(x)\n\n        return x.reshape(-1, self.num_joints, 3)\n\n    def predict(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from outputs.\n\n        Returns:\n            preds (sequence[InstanceData]): Prediction results.\n                Each contains the following fields:\n\n                - keypoints: Predicted keypoints of shape (B, N, K, D).\n                - keypoint_scores: Scores of predicted keypoints of shape\n                  (B, N, K).\n        \"\"\"\n\n        batch_coords = self.forward(feats)  # (B, K, D)\n\n        # Restore global position with target_root\n        target_root = batch_data_samples[0].metainfo.get('target_root', None)\n        if target_root is not None:\n            target_root = torch.stack([\n                torch.from_numpy(b.metainfo['target_root'])\n                for b in batch_data_samples\n            ])\n        else:\n            target_root = torch.stack([\n                torch.empty((0), dtype=torch.float32)\n                for _ in batch_data_samples\n            ])\n\n        preds = self.decode((batch_coords, target_root))\n\n        return preds\n\n    def loss(self,\n             inputs: Union[Tensor, Tuple[Tensor]],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_outputs = self.forward(inputs)\n\n        lifting_target_label = torch.cat([\n            d.gt_instance_labels.lifting_target_label\n            for d in batch_data_samples\n        ])\n        trajectory_weights = torch.cat([\n            d.gt_instance_labels.trajectory_weights for d in batch_data_samples\n        ])\n\n        # calculate losses\n        losses = dict()\n        loss = self.loss_module(pred_outputs, lifting_target_label,\n                                trajectory_weights.unsqueeze(-1))\n\n        losses.update(loss_traj=loss)\n\n        # calculate accuracy\n        mpjpe_err = keypoint_mpjpe(\n            pred=to_numpy(pred_outputs),\n            gt=to_numpy(lifting_target_label),\n            mask=to_numpy(trajectory_weights) > 0)\n\n        mpjpe_traj = torch.tensor(\n            mpjpe_err, device=lifting_target_label.device)\n        losses.update(mpjpe_traj=mpjpe_traj)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .edpose_head import EDPoseHead\nfrom .transformers import (FFN, DeformableDetrTransformerDecoder,\n                           DeformableDetrTransformerDecoderLayer,\n                           DeformableDetrTransformerEncoder,\n                           DeformableDetrTransformerEncoderLayer,\n                           DetrTransformerDecoder, DetrTransformerDecoderLayer,\n                           DetrTransformerEncoder, DetrTransformerEncoderLayer,\n                           PositionEmbeddingSineHW)\n\n__all__ = [\n    'EDPoseHead', 'DetrTransformerEncoder', 'DetrTransformerDecoder',\n    'DetrTransformerEncoderLayer', 'DetrTransformerDecoderLayer',\n    'DeformableDetrTransformerEncoder', 'DeformableDetrTransformerDecoder',\n    'DeformableDetrTransformerEncoderLayer',\n    'DeformableDetrTransformerDecoderLayer', 'PositionEmbeddingSineHW', 'FFN'\n]\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/base_transformer_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import abstractmethod\nfrom typing import Dict, Tuple\n\nimport torch\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import (Features, OptConfigType, OptMultiConfig,\n                                 OptSampleList, Predictions)\nfrom ..base_head import BaseHead\n\n\n@MODELS.register_module()\nclass TransformerHead(BaseHead):\n    r\"\"\"Implementation of `Deformable DETR: Deformable Transformers for\n    End-to-End Object Detection <https://arxiv.org/abs/2010.04159>`_\n\n    Code is modified from the `official github repo\n    <https://github.com/fundamentalvision/Deformable-DETR>`_.\n\n    Args:\n        encoder (ConfigDict, optional): Config of the\n            Transformer encoder. Defaults to None.\n        decoder (ConfigDict, optional): Config of the\n            Transformer decoder. Defaults to None.\n        out_head (ConfigDict, optional): Config for the\n            bounding final out head module. Defaults to None.\n        positional_encoding (ConfigDict, optional): Config for\n            transformer position encoding. Defaults to None.\n        num_queries (int): Number of query in Transformer.\n        loss (ConfigDict, optional): Config for loss functions.\n            Defaults to None.\n        init_cfg (ConfigDict, optional): Config to control the initialization.\n    \"\"\"\n\n    def __init__(self,\n                 encoder: OptConfigType = None,\n                 decoder: OptConfigType = None,\n                 out_head: OptConfigType = None,\n                 positional_encoding: OptConfigType = None,\n                 num_queries: int = 100,\n                 loss: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.encoder_cfg = encoder\n        self.decoder_cfg = decoder\n        self.out_head_cfg = out_head\n        self.positional_encoding_cfg = positional_encoding\n        self.num_queries = num_queries\n\n    def forward(self,\n                feats: Tuple[Tensor],\n                batch_data_samples: OptSampleList = None) -> Dict:\n        \"\"\"Forward the network.\"\"\"\n        encoder_outputs_dict = self.forward_encoder(feats, batch_data_samples)\n\n        decoder_outputs_dict = self.forward_decoder(**encoder_outputs_dict)\n\n        head_outputs_dict = self.forward_out_head(batch_data_samples,\n                                                  **decoder_outputs_dict)\n        return head_outputs_dict\n\n    @abstractmethod\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: OptConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\"\"\"\n        pass\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: OptConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n        pass\n\n    @abstractmethod\n    def forward_encoder(self, feat: Tensor, feat_mask: Tensor,\n                        feat_pos: Tensor, **kwargs) -> Dict:\n        pass\n\n    @abstractmethod\n    def forward_decoder(self, query: Tensor, query_pos: Tensor, memory: Tensor,\n                        **kwargs) -> Dict:\n        pass\n\n    @abstractmethod\n    def forward_out_head(self, query: Tensor, query_pos: Tensor,\n                         memory: Tensor, **kwargs) -> Dict:\n        pass\n\n    @staticmethod\n    def get_valid_ratio(mask: Tensor) -> Tensor:\n        \"\"\"Get the valid radios of feature map in a level.\n\n        .. code:: text\n\n                    |---> valid_W <---|\n                 ---+-----------------+-----+---\n                  A |                 |     | A\n                  | |                 |     | |\n                  | |                 |     | |\n            valid_H |                 |     | |\n                  | |                 |     | H\n                  | |                 |     | |\n                  V |                 |     | |\n                 ---+-----------------+     | |\n                    |                       | V\n                    +-----------------------+---\n                    |---------> W <---------|\n\n          The valid_ratios are defined as:\n                r_h = valid_H / H,  r_w = valid_W / W\n          They are the factors to re-normalize the relative coordinates of the\n          image to the relative coordinates of the current level feature map.\n\n        Args:\n            mask (Tensor): Binary mask of a feature map, has shape (bs, H, W).\n\n        Returns:\n            Tensor: valid ratios [r_w, r_h] of a feature map, has shape (1, 2).\n        \"\"\"\n        _, H, W = mask.shape\n        valid_H = torch.sum(~mask[:, :, 0], 1)\n        valid_W = torch.sum(~mask[:, 0, :], 1)\n        valid_ratio_h = valid_H.float() / H\n        valid_ratio_w = valid_W.float() / W\n        valid_ratio = torch.stack([valid_ratio_w, valid_ratio_h], -1)\n        return valid_ratio\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/edpose_head.py",
    "content": "# ----------------------------------------------------------------------------\n# Adapted from https://github.com/IDEA-Research/ED-Pose/ \\\n#              tree/master/models/edpose\n# Original licence: IDEA License 1.0\n# ----------------------------------------------------------------------------\n\nimport copy\nimport math\nfrom typing import Dict, List, Tuple\n\nimport numpy as np\nimport torch\nimport torch.nn.functional as F\nfrom mmcv.ops import MultiScaleDeformableAttention\nfrom mmengine.model import BaseModule, ModuleList, constant_init\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor, nn\n\nfrom mmpose.models.utils import inverse_sigmoid\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, Features, OptConfigType,\n                                 OptSampleList, Predictions)\nfrom .base_transformer_head import TransformerHead\nfrom .transformers.deformable_detr_layers import (\n    DeformableDetrTransformerDecoderLayer, DeformableDetrTransformerEncoder)\nfrom .transformers.utils import FFN, PositionEmbeddingSineHW\n\n\nclass EDPoseDecoder(BaseModule):\n    \"\"\"Transformer decoder of EDPose: `Explicit Box Detection Unifies End-to-\n    End Multi-Person Pose Estimation.\n\n    Args:\n        layer_cfg (ConfigDict): the config of each encoder\n            layer. All the layers will share the same config.\n        num_layers (int): Number of decoder layers.\n        return_intermediate (bool, optional): Whether to return outputs of\n            intermediate layers. Defaults to `True`.\n        embed_dims (int): Dims of embed.\n        query_dim (int): Dims of queries.\n        num_feature_levels (int): Number of feature levels.\n        num_box_decoder_layers (int): Number of box decoder layers.\n        num_keypoints (int): Number of datasets' body keypoints.\n        num_dn (int): Number of denosing points.\n        num_group (int): Number of decoder layers.\n    \"\"\"\n\n    def __init__(self,\n                 layer_cfg,\n                 num_layers,\n                 return_intermediate,\n                 embed_dims: int = 256,\n                 query_dim=4,\n                 num_feature_levels=1,\n                 num_box_decoder_layers=2,\n                 num_keypoints=17,\n                 num_dn=100,\n                 num_group=100):\n        super().__init__()\n\n        self.layer_cfg = layer_cfg\n        self.num_layers = num_layers\n        self.embed_dims = embed_dims\n\n        assert return_intermediate, 'support return_intermediate only'\n        self.return_intermediate = return_intermediate\n\n        assert query_dim in [\n            2, 4\n        ], 'query_dim should be 2/4 but {}'.format(query_dim)\n        self.query_dim = query_dim\n\n        self.num_feature_levels = num_feature_levels\n\n        self.layers = ModuleList([\n            DeformableDetrTransformerDecoderLayer(**self.layer_cfg)\n            for _ in range(self.num_layers)\n        ])\n        self.norm = nn.LayerNorm(self.embed_dims)\n\n        self.ref_point_head = FFN(self.query_dim // 2 * self.embed_dims,\n                                  self.embed_dims, self.embed_dims, 2)\n\n        self.num_keypoints = num_keypoints\n        self.query_scale = None\n        self.bbox_embed = None\n        self.class_embed = None\n        self.pose_embed = None\n        self.pose_hw_embed = None\n        self.num_box_decoder_layers = num_box_decoder_layers\n        self.box_pred_damping = None\n        self.num_group = num_group\n        self.rm_detach = None\n        self.num_dn = num_dn\n        self.hw = nn.Embedding(self.num_keypoints, 2)\n        self.keypoint_embed = nn.Embedding(self.num_keypoints, embed_dims)\n        self.kpt_index = [\n            x for x in range(self.num_group * (self.num_keypoints + 1))\n            if x % (self.num_keypoints + 1) != 0\n        ]\n\n    def forward(self, query: Tensor, value: Tensor, key_padding_mask: Tensor,\n                reference_points: Tensor, spatial_shapes: Tensor,\n                level_start_index: Tensor, valid_ratios: Tensor,\n                humandet_attn_mask: Tensor, human2pose_attn_mask: Tensor,\n                **kwargs) -> Tuple[Tensor]:\n        \"\"\"Forward function of decoder\n        Args:\n            query (Tensor): The input queries, has shape (bs, num_queries,\n                dim).\n            value (Tensor): The input values, has shape (bs, num_value, dim).\n            key_padding_mask (Tensor): The `key_padding_mask` of `cross_attn`\n                input. ByteTensor, has shape (bs, num_value).\n            reference_points (Tensor): The initial reference, has shape\n                (bs, num_queries, 4) with the last dimension arranged as\n                (cx, cy, w, h) when `as_two_stage` is `True`, otherwise has\n                shape (bs, num_queries, 2) with the last dimension arranged\n                as (cx, cy).\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n            level_start_index (Tensor): The start index of each level.\n                A tensor has shape (num_levels, ) and can be represented\n                as [0, h_0*w_0, h_0*w_0+h_1*w_1, ...].\n            valid_ratios (Tensor): The ratios of the valid width and the valid\n                height relative to the width and the height of features in all\n                levels, has shape (bs, num_levels, 2).\n            reg_branches: (obj:`nn.ModuleList`, optional): Used for refining\n                the regression results.\n\n        Returns:\n            Tuple[Tuple[Tensor]]: Outputs of Deformable Transformer Decoder.\n\n            - output (Tuple[Tensor]): Output embeddings of the last decoder,\n              each has shape (num_decoder_layers, num_queries, bs, embed_dims)\n            - reference_points (Tensor): The reference of the last decoder\n              layer, each has shape (num_decoder_layers, bs, num_queries, 4).\n              The coordinates are arranged as (cx, cy, w, h)\n        \"\"\"\n        output = query\n        attn_mask = humandet_attn_mask\n        intermediate = []\n        intermediate_reference_points = [reference_points]\n        effect_num_dn = self.num_dn if self.training else 0\n        inter_select_number = self.num_group\n        for layer_id, layer in enumerate(self.layers):\n            if reference_points.shape[-1] == 4:\n                reference_points_input = \\\n                    reference_points[:, :, None] * \\\n                    torch.cat([valid_ratios, valid_ratios], -1)[None, :]\n            else:\n                assert reference_points.shape[-1] == 2\n                reference_points_input = \\\n                    reference_points[:, :, None] * \\\n                    valid_ratios[None, :]\n\n            query_sine_embed = self.get_proposal_pos_embed(\n                reference_points_input[:, :, 0, :])  # nq, bs, 256*2\n            query_pos = self.ref_point_head(query_sine_embed)  # nq, bs, 256\n\n            output = layer(\n                output.transpose(0, 1),\n                query_pos=query_pos.transpose(0, 1),\n                value=value.transpose(0, 1),\n                key_padding_mask=key_padding_mask,\n                spatial_shapes=spatial_shapes,\n                level_start_index=level_start_index,\n                valid_ratios=valid_ratios,\n                reference_points=reference_points_input.transpose(\n                    0, 1).contiguous(),\n                self_attn_mask=attn_mask,\n                **kwargs)\n            output = output.transpose(0, 1)\n            intermediate.append(self.norm(output))\n\n            # human update\n            if layer_id < self.num_box_decoder_layers:\n                delta_unsig = self.bbox_embed[layer_id](output)\n                new_reference_points = delta_unsig + inverse_sigmoid(\n                    reference_points)\n                new_reference_points = new_reference_points.sigmoid()\n\n            # query expansion\n            if layer_id == self.num_box_decoder_layers - 1:\n                dn_output = output[:effect_num_dn]\n                dn_new_reference_points = new_reference_points[:effect_num_dn]\n                class_unselected = self.class_embed[layer_id](\n                    output)[effect_num_dn:]\n                topk_proposals = torch.topk(\n                    class_unselected.max(-1)[0], inter_select_number, dim=0)[1]\n                new_reference_points_for_box = torch.gather(\n                    new_reference_points[effect_num_dn:], 0,\n                    topk_proposals.unsqueeze(-1).repeat(1, 1, 4))\n                new_output_for_box = torch.gather(\n                    output[effect_num_dn:], 0,\n                    topk_proposals.unsqueeze(-1).repeat(1, 1, self.embed_dims))\n                bs = new_output_for_box.shape[1]\n                new_output_for_keypoint = new_output_for_box[:, None, :, :] \\\n                    + self.keypoint_embed.weight[None, :, None, :]\n                if self.num_keypoints == 17:\n                    delta_xy = self.pose_embed[-1](new_output_for_keypoint)[\n                        ..., :2]\n                else:\n                    delta_xy = self.pose_embed[0](new_output_for_keypoint)[\n                        ..., :2]\n                keypoint_xy = (inverse_sigmoid(\n                    new_reference_points_for_box[..., :2][:, None]) +\n                               delta_xy).sigmoid()\n                num_queries, _, bs, _ = keypoint_xy.shape\n                keypoint_wh_weight = self.hw.weight.unsqueeze(0).unsqueeze(\n                    -2).repeat(num_queries, 1, bs, 1).sigmoid()\n                keypoint_wh = keypoint_wh_weight * \\\n                    new_reference_points_for_box[..., 2:][:, None]\n                new_reference_points_for_keypoint = torch.cat(\n                    (keypoint_xy, keypoint_wh), dim=-1)\n                new_reference_points = torch.cat(\n                    (new_reference_points_for_box.unsqueeze(1),\n                     new_reference_points_for_keypoint),\n                    dim=1).flatten(0, 1)\n                output = torch.cat(\n                    (new_output_for_box.unsqueeze(1), new_output_for_keypoint),\n                    dim=1).flatten(0, 1)\n                new_reference_points = torch.cat(\n                    (dn_new_reference_points, new_reference_points), dim=0)\n                output = torch.cat((dn_output, output), dim=0)\n                attn_mask = human2pose_attn_mask\n\n            # human-to-keypoints update\n            if layer_id >= self.num_box_decoder_layers:\n                effect_num_dn = self.num_dn if self.training else 0\n                inter_select_number = self.num_group\n                ref_before_sigmoid = inverse_sigmoid(reference_points)\n                output_bbox_dn = output[:effect_num_dn]\n                output_bbox_norm = output[effect_num_dn:][0::(\n                    self.num_keypoints + 1)]\n                ref_before_sigmoid_bbox_dn = \\\n                    ref_before_sigmoid[:effect_num_dn]\n                ref_before_sigmoid_bbox_norm = \\\n                    ref_before_sigmoid[effect_num_dn:][0::(\n                        self.num_keypoints + 1)]\n                delta_unsig_dn = self.bbox_embed[layer_id](output_bbox_dn)\n                delta_unsig_norm = self.bbox_embed[layer_id](output_bbox_norm)\n                outputs_unsig_dn = delta_unsig_dn + ref_before_sigmoid_bbox_dn\n                outputs_unsig_norm = delta_unsig_norm + \\\n                    ref_before_sigmoid_bbox_norm\n                new_reference_points_for_box_dn = outputs_unsig_dn.sigmoid()\n                new_reference_points_for_box_norm = outputs_unsig_norm.sigmoid(\n                )\n                output_kpt = output[effect_num_dn:].index_select(\n                    0, torch.tensor(self.kpt_index, device=output.device))\n                delta_xy_unsig = self.pose_embed[layer_id -\n                                                 self.num_box_decoder_layers](\n                                                     output_kpt)\n                outputs_unsig = ref_before_sigmoid[\n                    effect_num_dn:].index_select(\n                        0, torch.tensor(self.kpt_index,\n                                        device=output.device)).clone()\n                delta_hw_unsig = self.pose_hw_embed[\n                    layer_id - self.num_box_decoder_layers](\n                        output_kpt)\n                outputs_unsig[..., :2] += delta_xy_unsig[..., :2]\n                outputs_unsig[..., 2:] += delta_hw_unsig\n                new_reference_points_for_keypoint = outputs_unsig.sigmoid()\n                bs = new_reference_points_for_box_norm.shape[1]\n                new_reference_points_norm = torch.cat(\n                    (new_reference_points_for_box_norm.unsqueeze(1),\n                     new_reference_points_for_keypoint.view(\n                         -1, self.num_keypoints, bs, 4)),\n                    dim=1).flatten(0, 1)\n                new_reference_points = torch.cat(\n                    (new_reference_points_for_box_dn,\n                     new_reference_points_norm),\n                    dim=0)\n\n            reference_points = new_reference_points.detach()\n            intermediate_reference_points.append(reference_points)\n\n        decoder_outputs = [itm_out.transpose(0, 1) for itm_out in intermediate]\n        reference_points = [\n            itm_refpoint.transpose(0, 1)\n            for itm_refpoint in intermediate_reference_points\n        ]\n\n        return decoder_outputs, reference_points\n\n    @staticmethod\n    def get_proposal_pos_embed(pos_tensor: Tensor,\n                               temperature: int = 10000,\n                               num_pos_feats: int = 128) -> Tensor:\n        \"\"\"Get the position embedding of the proposal.\n\n        Args:\n            pos_tensor (Tensor): Not normalized proposals, has shape\n                (bs, num_queries, 4) with the last dimension arranged as\n                (cx, cy, w, h).\n            temperature (int, optional): The temperature used for scaling the\n                position embedding. Defaults to 10000.\n            num_pos_feats (int, optional): The feature dimension for each\n                position along x, y, w, and h-axis. Note the final returned\n                dimension for each position is 4 times of num_pos_feats.\n                Default to 128.\n\n        Returns:\n            Tensor: The position embedding of proposal, has shape\n            (bs, num_queries, num_pos_feats * 4), with the last dimension\n            arranged as (cx, cy, w, h)\n        \"\"\"\n\n        scale = 2 * math.pi\n        dim_t = torch.arange(\n            num_pos_feats, dtype=torch.float32, device=pos_tensor.device)\n        dim_t = temperature**(2 * (dim_t // 2) / num_pos_feats)\n        x_embed = pos_tensor[:, :, 0] * scale\n        y_embed = pos_tensor[:, :, 1] * scale\n        pos_x = x_embed[:, :, None] / dim_t\n        pos_y = y_embed[:, :, None] / dim_t\n        pos_x = torch.stack((pos_x[:, :, 0::2].sin(), pos_x[:, :, 1::2].cos()),\n                            dim=3).flatten(2)\n        pos_y = torch.stack((pos_y[:, :, 0::2].sin(), pos_y[:, :, 1::2].cos()),\n                            dim=3).flatten(2)\n        if pos_tensor.size(-1) == 2:\n            pos = torch.cat((pos_y, pos_x), dim=2)\n        elif pos_tensor.size(-1) == 4:\n            w_embed = pos_tensor[:, :, 2] * scale\n            pos_w = w_embed[:, :, None] / dim_t\n            pos_w = torch.stack(\n                (pos_w[:, :, 0::2].sin(), pos_w[:, :, 1::2].cos()),\n                dim=3).flatten(2)\n\n            h_embed = pos_tensor[:, :, 3] * scale\n            pos_h = h_embed[:, :, None] / dim_t\n            pos_h = torch.stack(\n                (pos_h[:, :, 0::2].sin(), pos_h[:, :, 1::2].cos()),\n                dim=3).flatten(2)\n\n            pos = torch.cat((pos_y, pos_x, pos_w, pos_h), dim=2)\n        else:\n            raise ValueError('Unknown pos_tensor shape(-1):{}'.format(\n                pos_tensor.size(-1)))\n        return pos\n\n\nclass EDPoseOutHead(BaseModule):\n    \"\"\"Final Head of EDPose: `Explicit Box Detection Unifies End-to-End Multi-\n    Person Pose Estimation.\n\n    Args:\n        num_classes (int): The number of classes.\n        num_keypoints (int): The number of datasets' body keypoints.\n        num_queries (int): The number of queries.\n        cls_no_bias (bool): Weather add the bias to class embed.\n        embed_dims (int): The dims of embed.\n        as_two_stage (bool, optional): Whether to generate the proposal\n            from the outputs of encoder. Defaults to `False`.\n        refine_queries_num (int): The number of refines queries after\n            decoders.\n        num_box_decoder_layers (int): The number of bbox decoder layer.\n        num_group (int): The number of groups.\n        num_pred_layer (int): The number of the prediction layers.\n            Defaults to 6.\n        dec_pred_class_embed_share (bool): Whether to share parameters\n            for all the class prediction layers. Defaults to `False`.\n        dec_pred_bbox_embed_share (bool): Whether to share parameters\n            for all the bbox prediction layers. Defaults to `False`.\n        dec_pred_pose_embed_share (bool): Whether to share parameters\n            for all the pose prediction layers. Defaults to `False`.\n    \"\"\"\n\n    def __init__(self,\n                 num_classes,\n                 num_keypoints: int = 17,\n                 num_queries: int = 900,\n                 cls_no_bias: bool = False,\n                 embed_dims: int = 256,\n                 as_two_stage: bool = False,\n                 refine_queries_num: int = 100,\n                 num_box_decoder_layers: int = 2,\n                 num_group: int = 100,\n                 num_pred_layer: int = 6,\n                 dec_pred_class_embed_share: bool = False,\n                 dec_pred_bbox_embed_share: bool = False,\n                 dec_pred_pose_embed_share: bool = False,\n                 **kwargs):\n        super().__init__()\n        self.embed_dims = embed_dims\n        self.as_two_stage = as_two_stage\n        self.num_classes = num_classes\n        self.refine_queries_num = refine_queries_num\n        self.num_box_decoder_layers = num_box_decoder_layers\n        self.num_keypoints = num_keypoints\n        self.num_queries = num_queries\n\n        # prepare pred layers\n        self.dec_pred_class_embed_share = dec_pred_class_embed_share\n        self.dec_pred_bbox_embed_share = dec_pred_bbox_embed_share\n        self.dec_pred_pose_embed_share = dec_pred_pose_embed_share\n        # prepare class & box embed\n        _class_embed = nn.Linear(\n            self.embed_dims, self.num_classes, bias=(not cls_no_bias))\n        if not cls_no_bias:\n            prior_prob = 0.01\n            bias_value = -math.log((1 - prior_prob) / prior_prob)\n            _class_embed.bias.data = torch.ones(self.num_classes) * bias_value\n\n        _bbox_embed = FFN(self.embed_dims, self.embed_dims, 4, 3)\n        _pose_embed = FFN(self.embed_dims, self.embed_dims, 2, 3)\n        _pose_hw_embed = FFN(self.embed_dims, self.embed_dims, 2, 3)\n\n        self.num_group = num_group\n        if dec_pred_bbox_embed_share:\n            box_embed_layerlist = [_bbox_embed for i in range(num_pred_layer)]\n        else:\n            box_embed_layerlist = [\n                copy.deepcopy(_bbox_embed) for i in range(num_pred_layer)\n            ]\n        if dec_pred_class_embed_share:\n            class_embed_layerlist = [\n                _class_embed for i in range(num_pred_layer)\n            ]\n        else:\n            class_embed_layerlist = [\n                copy.deepcopy(_class_embed) for i in range(num_pred_layer)\n            ]\n\n        if num_keypoints == 17:\n            if dec_pred_pose_embed_share:\n                pose_embed_layerlist = [\n                    _pose_embed\n                    for i in range(num_pred_layer - num_box_decoder_layers + 1)\n                ]\n            else:\n                pose_embed_layerlist = [\n                    copy.deepcopy(_pose_embed)\n                    for i in range(num_pred_layer - num_box_decoder_layers + 1)\n                ]\n        else:\n            if dec_pred_pose_embed_share:\n                pose_embed_layerlist = [\n                    _pose_embed\n                    for i in range(num_pred_layer - num_box_decoder_layers)\n                ]\n            else:\n                pose_embed_layerlist = [\n                    copy.deepcopy(_pose_embed)\n                    for i in range(num_pred_layer - num_box_decoder_layers)\n                ]\n\n        pose_hw_embed_layerlist = [\n            _pose_hw_embed\n            for i in range(num_pred_layer - num_box_decoder_layers)\n        ]\n        self.bbox_embed = nn.ModuleList(box_embed_layerlist)\n        self.class_embed = nn.ModuleList(class_embed_layerlist)\n        self.pose_embed = nn.ModuleList(pose_embed_layerlist)\n        self.pose_hw_embed = nn.ModuleList(pose_hw_embed_layerlist)\n\n    def init_weights(self) -> None:\n        \"\"\"Initialize weights of the Deformable DETR head.\"\"\"\n\n        for m in self.bbox_embed:\n            constant_init(m[-1], 0, bias=0)\n        for m in self.pose_embed:\n            constant_init(m[-1], 0, bias=0)\n\n    def forward(self, hidden_states: List[Tensor], references: List[Tensor],\n                mask_dict: Dict, hidden_states_enc: Tensor,\n                referens_enc: Tensor, batch_data_samples) -> Dict:\n        \"\"\"Forward function.\n\n        Args:\n            hidden_states (Tensor): Hidden states output from each decoder\n                layer, has shape (num_decoder_layers, bs, num_queries, dim).\n            references (list[Tensor]): List of the reference from the decoder.\n\n        Returns:\n            tuple[Tensor]: results of head containing the following tensor.\n\n            - pred_logits (Tensor): Outputs from the\n              classification head, the socres of every bboxes.\n            - pred_boxes (Tensor): The output boxes.\n            - pred_keypoints (Tensor): The output keypoints.\n        \"\"\"\n        # update human boxes\n        effec_dn_num = self.refine_queries_num if self.training else 0\n        outputs_coord_list = []\n        outputs_class = []\n        for dec_lid, (layer_ref_sig, layer_bbox_embed, layer_cls_embed,\n                      layer_hs) in enumerate(\n                          zip(references[:-1], self.bbox_embed,\n                              self.class_embed, hidden_states)):\n            if dec_lid < self.num_box_decoder_layers:\n                layer_delta_unsig = layer_bbox_embed(layer_hs)\n                layer_outputs_unsig = layer_delta_unsig + inverse_sigmoid(\n                    layer_ref_sig)\n                layer_outputs_unsig = layer_outputs_unsig.sigmoid()\n                layer_cls = layer_cls_embed(layer_hs)\n                outputs_coord_list.append(layer_outputs_unsig)\n                outputs_class.append(layer_cls)\n            else:\n                layer_hs_bbox_dn = layer_hs[:, :effec_dn_num, :]\n                layer_hs_bbox_norm = \\\n                    layer_hs[:, effec_dn_num:, :][:, 0::(\n                        self.num_keypoints + 1), :]\n                bs = layer_ref_sig.shape[0]\n                ref_before_sigmoid_bbox_dn = \\\n                    layer_ref_sig[:, : effec_dn_num, :]\n                ref_before_sigmoid_bbox_norm = \\\n                    layer_ref_sig[:, effec_dn_num:, :][:, 0::(\n                        self.num_keypoints + 1), :]\n                layer_delta_unsig_dn = layer_bbox_embed(layer_hs_bbox_dn)\n                layer_delta_unsig_norm = layer_bbox_embed(layer_hs_bbox_norm)\n                layer_outputs_unsig_dn = layer_delta_unsig_dn + \\\n                    inverse_sigmoid(ref_before_sigmoid_bbox_dn)\n                layer_outputs_unsig_dn = layer_outputs_unsig_dn.sigmoid()\n                layer_outputs_unsig_norm = layer_delta_unsig_norm + \\\n                    inverse_sigmoid(ref_before_sigmoid_bbox_norm)\n                layer_outputs_unsig_norm = layer_outputs_unsig_norm.sigmoid()\n                layer_outputs_unsig = torch.cat(\n                    (layer_outputs_unsig_dn, layer_outputs_unsig_norm), dim=1)\n                layer_cls_dn = layer_cls_embed(layer_hs_bbox_dn)\n                layer_cls_norm = layer_cls_embed(layer_hs_bbox_norm)\n                layer_cls = torch.cat((layer_cls_dn, layer_cls_norm), dim=1)\n                outputs_class.append(layer_cls)\n                outputs_coord_list.append(layer_outputs_unsig)\n\n        # update keypoints boxes\n        outputs_keypoints_list = []\n        kpt_index = [\n            x for x in range(self.num_group * (self.num_keypoints + 1))\n            if x % (self.num_keypoints + 1) != 0\n        ]\n        for dec_lid, (layer_ref_sig, layer_hs) in enumerate(\n                zip(references[:-1], hidden_states)):\n            if dec_lid < self.num_box_decoder_layers:\n                assert isinstance(layer_hs, torch.Tensor)\n                bs = layer_hs.shape[0]\n                layer_res = layer_hs.new_zeros(\n                    (bs, self.num_queries, self.num_keypoints * 3))\n                outputs_keypoints_list.append(layer_res)\n            else:\n                bs = layer_ref_sig.shape[0]\n                layer_hs_kpt = \\\n                    layer_hs[:, effec_dn_num:, :].index_select(\n                        1, torch.tensor(kpt_index, device=layer_hs.device))\n                delta_xy_unsig = self.pose_embed[dec_lid -\n                                                 self.num_box_decoder_layers](\n                                                     layer_hs_kpt)\n                layer_ref_sig_kpt = \\\n                    layer_ref_sig[:, effec_dn_num:, :].index_select(\n                        1, torch.tensor(kpt_index, device=layer_hs.device))\n                layer_outputs_unsig_keypoints = delta_xy_unsig + \\\n                    inverse_sigmoid(layer_ref_sig_kpt[..., :2])\n                vis_xy_unsig = torch.ones_like(\n                    layer_outputs_unsig_keypoints,\n                    device=layer_outputs_unsig_keypoints.device)\n                xyv = torch.cat((layer_outputs_unsig_keypoints,\n                                 vis_xy_unsig[:, :, 0].unsqueeze(-1)),\n                                dim=-1)\n                xyv = xyv.sigmoid()\n                layer_res = xyv.reshape(\n                    (bs, self.num_group, self.num_keypoints, 3)).flatten(2, 3)\n                layer_res = self.keypoint_xyzxyz_to_xyxyzz(layer_res)\n                outputs_keypoints_list.append(layer_res)\n\n        dn_mask_dict = mask_dict\n        if self.refine_queries_num > 0 and dn_mask_dict is not None:\n            outputs_class, outputs_coord_list, outputs_keypoints_list = \\\n                self.dn_post_process2(\n                    outputs_class, outputs_coord_list,\n                    outputs_keypoints_list, dn_mask_dict\n                )\n\n        for _out_class, _out_bbox, _out_keypoint in zip(\n                outputs_class, outputs_coord_list, outputs_keypoints_list):\n            assert _out_class.shape[1] == \\\n                _out_bbox.shape[1] == _out_keypoint.shape[1]\n\n        return outputs_class[-1], outputs_coord_list[\n            -1], outputs_keypoints_list[-1]\n\n    def keypoint_xyzxyz_to_xyxyzz(self, keypoints: torch.Tensor):\n        \"\"\"\n        Args:\n            keypoints (torch.Tensor): ..., 51\n        \"\"\"\n        res = torch.zeros_like(keypoints)\n        num_points = keypoints.shape[-1] // 3\n        res[..., 0:2 * num_points:2] = keypoints[..., 0::3]\n        res[..., 1:2 * num_points:2] = keypoints[..., 1::3]\n        res[..., 2 * num_points:] = keypoints[..., 2::3]\n        return res\n\n\n@MODELS.register_module()\nclass EDPoseHead(TransformerHead):\n    \"\"\"Head introduced in `Explicit Box Detection Unifies End-to-End Multi-\n    Person Pose Estimation`_ by J Yang1 et al (2023). The head is composed of\n    Encoder, Decoder and Out_head.\n\n    Code is modified from the `official github repo\n    <https://github.com/IDEA-Research/ED-Pose>`_.\n\n    More details can be found in the `paper\n    <https://arxiv.org/pdf/2302.01593.pdf>`_ .\n\n    Args:\n        num_queries (int): Number of query in Transformer.\n        num_feature_levels (int): Number of feature levels. Defaults to 4.\n        num_keypoints (int): Number of keypoints. Defaults to 4.\n        as_two_stage (bool, optional): Whether to generate the proposal\n            from the outputs of encoder. Defaults to `False`.\n        encoder (:obj:`ConfigDict` or dict, optional): Config of the\n            Transformer encoder. Defaults to None.\n        decoder (:obj:`ConfigDict` or dict, optional): Config of the\n            Transformer decoder. Defaults to None.\n        out_head (:obj:`ConfigDict` or dict, optional): Config for the\n            bounding final out head module. Defaults to None.\n        positional_encoding (:obj:`ConfigDict` or dict): Config for\n            transformer position encoding. Defaults None.\n        denosing_cfg (:obj:`ConfigDict` or dict, optional): Config of the\n            human query denoising training strategy.\n        data_decoder (:obj:`ConfigDict` or dict, optional): Config of the\n            data decoder which transform the results from output space to\n            input space.\n        dec_pred_class_embed_share (bool): Whether to share the class embed\n            layer. Default False.\n        dec_pred_bbox_embed_share (bool): Whether to share the bbox embed\n            layer. Default False.\n        refine_queries_num (int): Number of refined human content queries\n            and their position queries .\n        two_stage_keep_all_tokens (bool): Whether to keep all tokens.\n    \"\"\"\n\n    def __init__(self,\n                 num_queries: int = 100,\n                 num_feature_levels: int = 4,\n                 num_keypoints: int = 17,\n                 as_two_stage: bool = False,\n                 encoder: OptConfigType = None,\n                 decoder: OptConfigType = None,\n                 out_head: OptConfigType = None,\n                 positional_encoding: OptConfigType = None,\n                 data_decoder: OptConfigType = None,\n                 denosing_cfg: OptConfigType = None,\n                 dec_pred_class_embed_share: bool = False,\n                 dec_pred_bbox_embed_share: bool = False,\n                 refine_queries_num: int = 100,\n                 two_stage_keep_all_tokens: bool = False) -> None:\n\n        self.as_two_stage = as_two_stage\n        self.num_feature_levels = num_feature_levels\n        self.refine_queries_num = refine_queries_num\n        self.dec_pred_class_embed_share = dec_pred_class_embed_share\n        self.dec_pred_bbox_embed_share = dec_pred_bbox_embed_share\n        self.two_stage_keep_all_tokens = two_stage_keep_all_tokens\n        self.num_heads = decoder['layer_cfg']['self_attn_cfg']['num_heads']\n        self.num_group = decoder['num_group']\n        self.num_keypoints = num_keypoints\n        self.denosing_cfg = denosing_cfg\n        if data_decoder is not None:\n            self.data_decoder = KEYPOINT_CODECS.build(data_decoder)\n        else:\n            self.data_decoder = None\n\n        super().__init__(\n            encoder=encoder,\n            decoder=decoder,\n            out_head=out_head,\n            positional_encoding=positional_encoding,\n            num_queries=num_queries)\n\n        self.positional_encoding = PositionEmbeddingSineHW(\n            **self.positional_encoding_cfg)\n        self.encoder = DeformableDetrTransformerEncoder(**self.encoder_cfg)\n        self.decoder = EDPoseDecoder(\n            num_keypoints=num_keypoints, **self.decoder_cfg)\n        self.out_head = EDPoseOutHead(\n            num_keypoints=num_keypoints,\n            as_two_stage=as_two_stage,\n            refine_queries_num=refine_queries_num,\n            **self.out_head_cfg,\n            **self.decoder_cfg)\n\n        self.embed_dims = self.encoder.embed_dims\n        self.label_enc = nn.Embedding(\n            self.denosing_cfg['dn_labelbook_size'] + 1, self.embed_dims)\n\n        if not self.as_two_stage:\n            self.query_embedding = nn.Embedding(self.num_queries,\n                                                self.embed_dims)\n            self.refpoint_embedding = nn.Embedding(self.num_queries, 4)\n\n        self.level_embed = nn.Parameter(\n            torch.Tensor(self.num_feature_levels, self.embed_dims))\n\n        self.decoder.bbox_embed = self.out_head.bbox_embed\n        self.decoder.pose_embed = self.out_head.pose_embed\n        self.decoder.pose_hw_embed = self.out_head.pose_hw_embed\n        self.decoder.class_embed = self.out_head.class_embed\n\n        if self.as_two_stage:\n            self.memory_trans_fc = nn.Linear(self.embed_dims, self.embed_dims)\n            self.memory_trans_norm = nn.LayerNorm(self.embed_dims)\n            if dec_pred_class_embed_share and dec_pred_bbox_embed_share:\n                self.enc_out_bbox_embed = self.out_head.bbox_embed[0]\n            else:\n                self.enc_out_bbox_embed = copy.deepcopy(\n                    self.out_head.bbox_embed[0])\n\n            if dec_pred_class_embed_share and dec_pred_bbox_embed_share:\n                self.enc_out_class_embed = self.out_head.class_embed[0]\n            else:\n                self.enc_out_class_embed = copy.deepcopy(\n                    self.out_head.class_embed[0])\n\n    def init_weights(self) -> None:\n        \"\"\"Initialize weights for Transformer and other components.\"\"\"\n        super().init_weights()\n        for coder in self.encoder, self.decoder:\n            for p in coder.parameters():\n                if p.dim() > 1:\n                    nn.init.xavier_uniform_(p)\n        for m in self.modules():\n            if isinstance(m, MultiScaleDeformableAttention):\n                m.init_weights()\n        if self.as_two_stage:\n            nn.init.xavier_uniform_(self.memory_trans_fc.weight)\n\n        nn.init.normal_(self.level_embed)\n\n    def pre_transformer(self,\n                        img_feats: Tuple[Tensor],\n                        batch_data_samples: OptSampleList = None\n                        ) -> Tuple[Dict]:\n        \"\"\"Process image features before feeding them to the transformer.\n\n        Args:\n            img_feats (tuple[Tensor]): Multi-level features that may have\n                different resolutions, output from neck. Each feature has\n                shape (bs, dim, h_lvl, w_lvl), where 'lvl' means 'layer'.\n            batch_data_samples (list[:obj:`DetDataSample`], optional): The\n                batch data samples. It usually includes information such\n                as `gt_instance` or `gt_panoptic_seg` or `gt_sem_seg`.\n                Defaults to None.\n\n        Returns:\n            tuple[dict]: The first dict contains the inputs of encoder and the\n            second dict contains the inputs of decoder.\n\n            - encoder_inputs_dict (dict): The keyword args dictionary of\n              `self.encoder()`.\n            - decoder_inputs_dict (dict): The keyword args dictionary of\n              `self.forward_decoder()`, which includes 'memory_mask'.\n        \"\"\"\n        batch_size = img_feats[0].size(0)\n        # construct binary masks for the transformer.\n        assert batch_data_samples is not None\n        batch_input_shape = batch_data_samples[0].batch_input_shape\n        img_shape_list = [sample.img_shape for sample in batch_data_samples]\n        input_img_h, input_img_w = batch_input_shape\n        masks = img_feats[0].new_ones((batch_size, input_img_h, input_img_w))\n        for img_id in range(batch_size):\n            img_h, img_w = img_shape_list[img_id]\n            masks[img_id, :img_h, :img_w] = 0\n        # NOTE following the official DETR repo, non-zero values representing\n        # ignored positions, while zero values means valid positions.\n\n        mlvl_masks = []\n        mlvl_pos_embeds = []\n        for feat in img_feats:\n            mlvl_masks.append(\n                F.interpolate(masks[None],\n                              size=feat.shape[-2:]).to(torch.bool).squeeze(0))\n            mlvl_pos_embeds.append(self.positional_encoding(mlvl_masks[-1]))\n\n        feat_flatten = []\n        lvl_pos_embed_flatten = []\n        mask_flatten = []\n        spatial_shapes = []\n        for lvl, (feat, mask, pos_embed) in enumerate(\n                zip(img_feats, mlvl_masks, mlvl_pos_embeds)):\n            batch_size, c, h, w = feat.shape\n            # [bs, c, h_lvl, w_lvl] -> [bs, h_lvl*w_lvl, c]\n            feat = feat.view(batch_size, c, -1).permute(0, 2, 1)\n            pos_embed = pos_embed.view(batch_size, c, -1).permute(0, 2, 1)\n            lvl_pos_embed = pos_embed + self.level_embed[lvl].view(1, 1, -1)\n            # [bs, h_lvl, w_lvl] -> [bs, h_lvl*w_lvl]\n            mask = mask.flatten(1)\n            spatial_shape = (h, w)\n\n            feat_flatten.append(feat)\n            lvl_pos_embed_flatten.append(lvl_pos_embed)\n            mask_flatten.append(mask)\n            spatial_shapes.append(spatial_shape)\n\n        # (bs, num_feat_points, dim)\n        feat_flatten = torch.cat(feat_flatten, 1)\n        lvl_pos_embed_flatten = torch.cat(lvl_pos_embed_flatten, 1)\n        # (bs, num_feat_points), where num_feat_points = sum_lvl(h_lvl*w_lvl)\n        mask_flatten = torch.cat(mask_flatten, 1)\n\n        spatial_shapes = torch.as_tensor(  # (num_level, 2)\n            spatial_shapes,\n            dtype=torch.long,\n            device=feat_flatten.device)\n        level_start_index = torch.cat((\n            spatial_shapes.new_zeros((1, )),  # (num_level)\n            spatial_shapes.prod(1).cumsum(0)[:-1]))\n        valid_ratios = torch.stack(  # (bs, num_level, 2)\n            [self.get_valid_ratio(m) for m in mlvl_masks], 1)\n\n        if self.refine_queries_num > 0 or batch_data_samples is not None:\n            input_query_label, input_query_bbox, humandet_attn_mask, \\\n                human2pose_attn_mask, mask_dict =\\\n                self.prepare_for_denosing(\n                    batch_data_samples,\n                    device=img_feats[0].device)\n        else:\n            assert batch_data_samples is None\n            input_query_bbox = input_query_label = \\\n                humandet_attn_mask = human2pose_attn_mask = mask_dict = None\n\n        encoder_inputs_dict = dict(\n            query=feat_flatten,\n            query_pos=lvl_pos_embed_flatten,\n            key_padding_mask=mask_flatten,\n            spatial_shapes=spatial_shapes,\n            level_start_index=level_start_index,\n            valid_ratios=valid_ratios)\n        decoder_inputs_dict = dict(\n            memory_mask=mask_flatten,\n            spatial_shapes=spatial_shapes,\n            level_start_index=level_start_index,\n            valid_ratios=valid_ratios,\n            humandet_attn_mask=humandet_attn_mask,\n            human2pose_attn_mask=human2pose_attn_mask,\n            input_query_bbox=input_query_bbox,\n            input_query_label=input_query_label,\n            mask_dict=mask_dict)\n        return encoder_inputs_dict, decoder_inputs_dict\n\n    def forward_encoder(self,\n                        img_feats: Tuple[Tensor],\n                        batch_data_samples: OptSampleList = None) -> Dict:\n        \"\"\"Forward with Transformer encoder.\n\n        The forward procedure is defined as:\n        'pre_transformer' -> 'encoder'\n\n        Args:\n            img_feats (tuple[Tensor]): Multi-level features that may have\n                different resolutions, output from neck. Each feature has\n                shape (bs, dim, h_lvl, w_lvl), where 'lvl' means 'layer'.\n            batch_data_samples (list[:obj:`DetDataSample`], optional): The\n                batch data samples. It usually includes information such\n                as `gt_instance` or `gt_panoptic_seg` or `gt_sem_seg`.\n                Defaults to None.\n\n        Returns:\n            dict: The dictionary of encoder outputs, which includes the\n            `memory` of the encoder output.\n        \"\"\"\n        encoder_inputs_dict, decoder_inputs_dict = self.pre_transformer(\n            img_feats, batch_data_samples)\n\n        memory = self.encoder(**encoder_inputs_dict)\n        encoder_outputs_dict = dict(memory=memory, **decoder_inputs_dict)\n        return encoder_outputs_dict\n\n    def pre_decoder(self, memory: Tensor, memory_mask: Tensor,\n                    spatial_shapes: Tensor, input_query_bbox: Tensor,\n                    input_query_label: Tensor) -> Tuple[Dict, Dict]:\n        \"\"\"Prepare intermediate variables before entering Transformer decoder,\n        such as `query` and `reference_points`.\n\n        Args:\n            memory (Tensor): The output embeddings of the Transformer encoder,\n                has shape (bs, num_feat_points, dim).\n            memory_mask (Tensor): ByteTensor, the padding mask of the memory,\n                has shape (bs, num_feat_points). It will only be used when\n                `as_two_stage` is `True`.\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n                It will only be used when `as_two_stage` is `True`.\n            input_query_bbox (Tensor): Denosing bbox query for training.\n            input_query_label (Tensor): Denosing label query for training.\n\n        Returns:\n            tuple[dict, dict]: The decoder_inputs_dict and head_inputs_dict.\n\n            - decoder_inputs_dict (dict): The keyword dictionary args of\n              `self.decoder()`.\n            - head_inputs_dict (dict): The keyword dictionary args of the\n              bbox_head functions.\n        \"\"\"\n        bs, _, c = memory.shape\n        if self.as_two_stage:\n            output_memory, output_proposals = \\\n                self.gen_encoder_output_proposals(\n                    memory, memory_mask, spatial_shapes)\n            enc_outputs_class = self.enc_out_class_embed(output_memory)\n            enc_outputs_coord_unact = self.enc_out_bbox_embed(\n                output_memory) + output_proposals\n\n            topk_proposals = torch.topk(\n                enc_outputs_class.max(-1)[0], self.num_queries, dim=1)[1]\n            topk_coords_undetach = torch.gather(\n                enc_outputs_coord_unact, 1,\n                topk_proposals.unsqueeze(-1).repeat(1, 1, 4))\n            topk_coords_unact = topk_coords_undetach.detach()\n            reference_points = topk_coords_unact.sigmoid()\n\n            query_undetach = torch.gather(\n                output_memory, 1,\n                topk_proposals.unsqueeze(-1).repeat(1, 1, self.embed_dims))\n            query = query_undetach.detach()\n\n            if input_query_bbox is not None:\n                reference_points = torch.cat(\n                    [input_query_bbox, topk_coords_unact], dim=1).sigmoid()\n                query = torch.cat([input_query_label, query], dim=1)\n            if self.two_stage_keep_all_tokens:\n                hidden_states_enc = output_memory.unsqueeze(0)\n                referens_enc = enc_outputs_coord_unact.unsqueeze(0)\n            else:\n                hidden_states_enc = query_undetach.unsqueeze(0)\n                referens_enc = topk_coords_undetach.sigmoid().unsqueeze(0)\n        else:\n            hidden_states_enc, referens_enc = None, None\n            query = self.query_embedding.weight[:, None, :].repeat(\n                1, bs, 1).transpose(0, 1)\n            reference_points = \\\n                self.refpoint_embedding.weight[:, None, :].repeat(1, bs, 1)\n\n            if input_query_bbox is not None:\n                reference_points = torch.cat(\n                    [input_query_bbox, reference_points], dim=1)\n                query = torch.cat([input_query_label, query], dim=1)\n            reference_points = reference_points.sigmoid()\n\n        decoder_inputs_dict = dict(\n            query=query, reference_points=reference_points)\n        head_inputs_dict = dict(\n            hidden_states_enc=hidden_states_enc, referens_enc=referens_enc)\n        return decoder_inputs_dict, head_inputs_dict\n\n    def forward_decoder(self, memory: Tensor, memory_mask: Tensor,\n                        spatial_shapes: Tensor, level_start_index: Tensor,\n                        valid_ratios: Tensor, humandet_attn_mask: Tensor,\n                        human2pose_attn_mask: Tensor, input_query_bbox: Tensor,\n                        input_query_label: Tensor, mask_dict: Dict) -> Dict:\n        \"\"\"Forward with Transformer decoder.\n\n        The forward procedure is defined as:\n        'pre_decoder' -> 'decoder'\n\n        Args:\n            memory (Tensor): The output embeddings of the Transformer encoder,\n                has shape (bs, num_feat_points, dim).\n            memory_mask (Tensor): ByteTensor, the padding mask of the memory,\n                has shape (bs, num_feat_points).\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n            level_start_index (Tensor): The start index of each level.\n                A tensor has shape (num_levels, ) and can be represented\n                as [0, h_0*w_0, h_0*w_0+h_1*w_1, ...].\n            valid_ratios (Tensor): The ratios of the valid width and the valid\n                height relative to the width and the height of features in all\n                levels, has shape (bs, num_levels, 2).\n            humandet_attn_mask (Tensor): Human attention mask.\n            human2pose_attn_mask (Tensor): Human to pose attention mask.\n            input_query_bbox (Tensor): Denosing bbox query for training.\n            input_query_label (Tensor): Denosing label query for training.\n\n        Returns:\n            dict: The dictionary of decoder outputs, which includes the\n            `hidden_states` of the decoder output and `references` including\n            the initial and intermediate reference_points.\n        \"\"\"\n        decoder_in, head_in = self.pre_decoder(memory, memory_mask,\n                                               spatial_shapes,\n                                               input_query_bbox,\n                                               input_query_label)\n\n        inter_states, inter_references = self.decoder(\n            query=decoder_in['query'].transpose(0, 1),\n            value=memory.transpose(0, 1),\n            key_padding_mask=memory_mask,  # for cross_attn\n            reference_points=decoder_in['reference_points'].transpose(0, 1),\n            spatial_shapes=spatial_shapes,\n            level_start_index=level_start_index,\n            valid_ratios=valid_ratios,\n            humandet_attn_mask=humandet_attn_mask,\n            human2pose_attn_mask=human2pose_attn_mask)\n        references = inter_references\n        decoder_outputs_dict = dict(\n            hidden_states=inter_states,\n            references=references,\n            mask_dict=mask_dict)\n        decoder_outputs_dict.update(head_in)\n        return decoder_outputs_dict\n\n    def forward_out_head(self, batch_data_samples: OptSampleList,\n                         hidden_states: List[Tensor], references: List[Tensor],\n                         mask_dict: Dict, hidden_states_enc: Tensor,\n                         referens_enc: Tensor) -> Tuple[Tensor]:\n        \"\"\"Forward function.\"\"\"\n        out = self.out_head(hidden_states, references, mask_dict,\n                            hidden_states_enc, referens_enc,\n                            batch_data_samples)\n        return out\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\"\"\"\n        input_shapes = np.array(\n            [d.metainfo['input_size'] for d in batch_data_samples])\n\n        if test_cfg.get('flip_test', False):\n            assert NotImplementedError(\n                'flip_test is currently not supported '\n                'for EDPose. Please set `model.test_cfg.flip_test=False`')\n        else:\n            pred_logits, pred_boxes, pred_keypoints = self.forward(\n                feats, batch_data_samples)  # (B, K, D)\n\n            pred = self.decode(\n                input_shapes,\n                pred_logits=pred_logits,\n                pred_boxes=pred_boxes,\n                pred_keypoints=pred_keypoints)\n        return pred\n\n    def decode(self, input_shapes: np.ndarray, pred_logits: Tensor,\n               pred_boxes: Tensor, pred_keypoints: Tensor):\n        \"\"\"Select the final top-k keypoints, and decode the results from\n        normalize size to origin input size.\n\n        Args:\n            input_shapes (Tensor): The size of input image.\n            pred_logits (Tensor): The result of score.\n            pred_boxes (Tensor): The result of bbox.\n            pred_keypoints (Tensor): The result of keypoints.\n\n        Returns:\n        \"\"\"\n\n        if self.data_decoder is None:\n            raise RuntimeError(f'The data decoder has not been set in \\\n                {self.__class__.__name__}. '\n                               'Please set the data decoder configs in \\\n                    the init parameters to '\n                               'enable head methods `head.predict()` and \\\n                     `head.decode()`')\n\n        preds = []\n\n        pred_logits = pred_logits.sigmoid()\n        pred_logits, pred_boxes, pred_keypoints = to_numpy(\n            [pred_logits, pred_boxes, pred_keypoints])\n\n        for input_shape, pred_logit, pred_bbox, pred_kpts in zip(\n                input_shapes, pred_logits, pred_boxes, pred_keypoints):\n\n            bboxes, keypoints, keypoint_scores = self.data_decoder.decode(\n                input_shape, pred_logit, pred_bbox, pred_kpts)\n\n            # pack outputs\n            preds.append(\n                InstanceData(\n                    keypoints=keypoints,\n                    keypoint_scores=keypoint_scores,\n                    bboxes=bboxes))\n\n        return preds\n\n    def gen_encoder_output_proposals(self, memory: Tensor, memory_mask: Tensor,\n                                     spatial_shapes: Tensor\n                                     ) -> Tuple[Tensor, Tensor]:\n        \"\"\"Generate proposals from encoded memory. The function will only be\n        used when `as_two_stage` is `True`.\n\n        Args:\n            memory (Tensor): The output embeddings of the Transformer encoder,\n                has shape (bs, num_feat_points, dim).\n            memory_mask (Tensor): ByteTensor, the padding mask of the memory,\n                has shape (bs, num_feat_points).\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n\n        Returns:\n            tuple: A tuple of transformed memory and proposals.\n\n            - output_memory (Tensor): The transformed memory for obtaining\n              top-k proposals, has shape (bs, num_feat_points, dim).\n            - output_proposals (Tensor): The inverse-normalized proposal, has\n              shape (batch_size, num_keys, 4) with the last dimension arranged\n              as (cx, cy, w, h).\n        \"\"\"\n        bs = memory.size(0)\n        proposals = []\n        _cur = 0  # start index in the sequence of the current level\n        for lvl, (H, W) in enumerate(spatial_shapes):\n            mask_flatten_ = memory_mask[:,\n                                        _cur:(_cur + H * W)].view(bs, H, W, 1)\n            valid_H = torch.sum(~mask_flatten_[:, :, 0, 0], 1).unsqueeze(-1)\n            valid_W = torch.sum(~mask_flatten_[:, 0, :, 0], 1).unsqueeze(-1)\n\n            grid_y, grid_x = torch.meshgrid(\n                torch.linspace(\n                    0, H - 1, H, dtype=torch.float32, device=memory.device),\n                torch.linspace(\n                    0, W - 1, W, dtype=torch.float32, device=memory.device))\n            grid = torch.cat([grid_x.unsqueeze(-1), grid_y.unsqueeze(-1)], -1)\n\n            scale = torch.cat([valid_W, valid_H], 1).view(bs, 1, 1, 2)\n            grid = (grid.unsqueeze(0).expand(bs, -1, -1, -1) + 0.5) / scale\n            wh = torch.ones_like(grid) * 0.05 * (2.0**lvl)\n            proposal = torch.cat((grid, wh), -1).view(bs, -1, 4)\n            proposals.append(proposal)\n            _cur += (H * W)\n        output_proposals = torch.cat(proposals, 1)\n        output_proposals_valid = ((output_proposals > 0.01) &\n                                  (output_proposals < 0.99)).all(\n                                      -1, keepdim=True)\n\n        output_proposals = inverse_sigmoid(output_proposals)\n        output_proposals = output_proposals.masked_fill(\n            memory_mask.unsqueeze(-1), float('inf'))\n        output_proposals = output_proposals.masked_fill(\n            ~output_proposals_valid, float('inf'))\n\n        output_memory = memory\n        output_memory = output_memory.masked_fill(\n            memory_mask.unsqueeze(-1), float(0))\n        output_memory = output_memory.masked_fill(~output_proposals_valid,\n                                                  float(0))\n        output_memory = self.memory_trans_fc(output_memory)\n        output_memory = self.memory_trans_norm(output_memory)\n        # [bs, sum(hw), 2]\n        return output_memory, output_proposals\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [dict(type='Normal', layer=['Linear'], std=0.01, bias=0)]\n        return init_cfg\n\n    def prepare_for_denosing(self, targets: OptSampleList, device):\n        \"\"\"prepare for dn components in forward function.\"\"\"\n        if not self.training:\n            bs = len(targets)\n            attn_mask_infere = torch.zeros(\n                bs,\n                self.num_heads,\n                self.num_group * (self.num_keypoints + 1),\n                self.num_group * (self.num_keypoints + 1),\n                device=device,\n                dtype=torch.bool)\n            group_bbox_kpt = (self.num_keypoints + 1)\n            kpt_index = [\n                x for x in range(self.num_group * (self.num_keypoints + 1))\n                if x % (self.num_keypoints + 1) == 0\n            ]\n            for matchj in range(self.num_group * (self.num_keypoints + 1)):\n                sj = (matchj // group_bbox_kpt) * group_bbox_kpt\n                ej = (matchj // group_bbox_kpt + 1) * group_bbox_kpt\n                if sj > 0:\n                    attn_mask_infere[:, :, matchj, :sj] = True\n                if ej < self.num_group * (self.num_keypoints + 1):\n                    attn_mask_infere[:, :, matchj, ej:] = True\n            for match_x in range(self.num_group * (self.num_keypoints + 1)):\n                if match_x % group_bbox_kpt == 0:\n                    attn_mask_infere[:, :, match_x, kpt_index] = False\n\n            attn_mask_infere = attn_mask_infere.flatten(0, 1)\n            return None, None, None, attn_mask_infere, None\n\n        # targets, dn_scalar, noise_scale = dn_args\n        device = targets[0]['boxes'].device\n        bs = len(targets)\n        refine_queries_num = self.refine_queries_num\n\n        # gather gt boxes and labels\n        gt_boxes = [t['boxes'] for t in targets]\n        gt_labels = [t['labels'] for t in targets]\n        gt_keypoints = [t['keypoints'] for t in targets]\n\n        # repeat them\n        def get_indices_for_repeat(now_num, target_num, device='cuda'):\n            \"\"\"\n            Input:\n                - now_num: int\n                - target_num: int\n            Output:\n                - indices: tensor[target_num]\n            \"\"\"\n            out_indice = []\n            base_indice = torch.arange(now_num).to(device)\n            multiplier = target_num // now_num\n            out_indice.append(base_indice.repeat(multiplier))\n            residue = target_num % now_num\n            out_indice.append(base_indice[torch.randint(\n                0, now_num, (residue, ), device=device)])\n            return torch.cat(out_indice)\n\n        gt_boxes_expand = []\n        gt_labels_expand = []\n        gt_keypoints_expand = []\n        for idx, (gt_boxes_i, gt_labels_i, gt_keypoint_i) in enumerate(\n                zip(gt_boxes, gt_labels, gt_keypoints)):\n            num_gt_i = gt_boxes_i.shape[0]\n            if num_gt_i > 0:\n                indices = get_indices_for_repeat(num_gt_i, refine_queries_num,\n                                                 device)\n                gt_boxes_expand_i = gt_boxes_i[indices]  # num_dn, 4\n                gt_labels_expand_i = gt_labels_i[indices]\n                gt_keypoints_expand_i = gt_keypoint_i[indices]\n            else:\n                # all negative samples when no gt boxes\n                gt_boxes_expand_i = torch.rand(\n                    refine_queries_num, 4, device=device)\n                gt_labels_expand_i = torch.ones(\n                    refine_queries_num, dtype=torch.int64,\n                    device=device) * int(self.num_classes)\n                gt_keypoints_expand_i = torch.rand(\n                    refine_queries_num, self.num_keypoints * 3, device=device)\n            gt_boxes_expand.append(gt_boxes_expand_i)\n            gt_labels_expand.append(gt_labels_expand_i)\n            gt_keypoints_expand.append(gt_keypoints_expand_i)\n        gt_boxes_expand = torch.stack(gt_boxes_expand)\n        gt_labels_expand = torch.stack(gt_labels_expand)\n        gt_keypoints_expand = torch.stack(gt_keypoints_expand)\n        knwon_boxes_expand = gt_boxes_expand.clone()\n        knwon_labels_expand = gt_labels_expand.clone()\n\n        # add noise\n        if self.denosing_cfg['dn_label_noise_ratio'] > 0:\n            prob = torch.rand_like(knwon_labels_expand.float())\n            chosen_indice = prob < self.denosing_cfg['dn_label_noise_ratio']\n            new_label = torch.randint_like(\n                knwon_labels_expand[chosen_indice], 0,\n                self.dn_labelbook_size)  # randomly put a new one here\n            knwon_labels_expand[chosen_indice] = new_label\n\n        if self.denosing_cfg['dn_box_noise_scale'] > 0:\n            diff = torch.zeros_like(knwon_boxes_expand)\n            diff[..., :2] = knwon_boxes_expand[..., 2:] / 2\n            diff[..., 2:] = knwon_boxes_expand[..., 2:]\n            knwon_boxes_expand += torch.mul(\n                (torch.rand_like(knwon_boxes_expand) * 2 - 1.0),\n                diff) * self.denosing_cfg['dn_box_noise_scale']\n            knwon_boxes_expand = knwon_boxes_expand.clamp(min=0.0, max=1.0)\n\n        input_query_label = self.label_enc(knwon_labels_expand)\n        input_query_bbox = inverse_sigmoid(knwon_boxes_expand)\n\n        # prepare mask\n        if 'group2group' in self.denosing_cfg['dn_attn_mask_type_list']:\n            attn_mask = torch.zeros(\n                bs,\n                self.num_heads,\n                refine_queries_num + self.num_queries,\n                refine_queries_num + self.num_queries,\n                device=device,\n                dtype=torch.bool)\n            attn_mask[:, :, refine_queries_num:, :refine_queries_num] = True\n            for idx, (gt_boxes_i,\n                      gt_labels_i) in enumerate(zip(gt_boxes, gt_labels)):\n                num_gt_i = gt_boxes_i.shape[0]\n                if num_gt_i == 0:\n                    continue\n                for matchi in range(refine_queries_num):\n                    si = (matchi // num_gt_i) * num_gt_i\n                    ei = (matchi // num_gt_i + 1) * num_gt_i\n                    if si > 0:\n                        attn_mask[idx, :, matchi, :si] = True\n                    if ei < refine_queries_num:\n                        attn_mask[idx, :, matchi, ei:refine_queries_num] = True\n            attn_mask = attn_mask.flatten(0, 1)\n\n        if 'group2group' in self.denosing_cfg['dn_attn_mask_type_list']:\n            attn_mask2 = torch.zeros(\n                bs,\n                self.num_heads,\n                refine_queries_num + self.num_group * (self.num_keypoints + 1),\n                refine_queries_num + self.num_group * (self.num_keypoints + 1),\n                device=device,\n                dtype=torch.bool)\n            attn_mask2[:, :, refine_queries_num:, :refine_queries_num] = True\n            group_bbox_kpt = (self.num_keypoints + 1)\n            kpt_index = [\n                x for x in range(self.num_group * (self.num_keypoints + 1))\n                if x % (self.num_keypoints + 1) == 0\n            ]\n            for matchj in range(self.num_group * (self.num_keypoints + 1)):\n                sj = (matchj // group_bbox_kpt) * group_bbox_kpt\n                ej = (matchj // group_bbox_kpt + 1) * group_bbox_kpt\n                if sj > 0:\n                    attn_mask2[:, :, refine_queries_num:,\n                               refine_queries_num:][:, :, matchj, :sj] = True\n                if ej < self.num_group * (self.num_keypoints + 1):\n                    attn_mask2[:, :, refine_queries_num:,\n                               refine_queries_num:][:, :, matchj, ej:] = True\n\n            for match_x in range(self.num_group * (self.num_keypoints + 1)):\n                if match_x % group_bbox_kpt == 0:\n                    attn_mask2[:, :, refine_queries_num:,\n                               refine_queries_num:][:, :, match_x,\n                                                    kpt_index] = False\n\n            for idx, (gt_boxes_i,\n                      gt_labels_i) in enumerate(zip(gt_boxes, gt_labels)):\n                num_gt_i = gt_boxes_i.shape[0]\n                if num_gt_i == 0:\n                    continue\n                for matchi in range(refine_queries_num):\n                    si = (matchi // num_gt_i) * num_gt_i\n                    ei = (matchi // num_gt_i + 1) * num_gt_i\n                    if si > 0:\n                        attn_mask2[idx, :, matchi, :si] = True\n                    if ei < refine_queries_num:\n                        attn_mask2[idx, :, matchi,\n                                   ei:refine_queries_num] = True\n            attn_mask2 = attn_mask2.flatten(0, 1)\n\n        mask_dict = {\n            'pad_size': refine_queries_num,\n            'known_bboxs': gt_boxes_expand,\n            'known_labels': gt_labels_expand,\n            'known_keypoints': gt_keypoints_expand\n        }\n\n        return input_query_label, input_query_bbox, \\\n            attn_mask, attn_mask2, mask_dict\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: OptConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        assert NotImplementedError(\n            'the training of EDPose has not been '\n            'supported. Please stay tuned for further update.')\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/transformers/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .deformable_detr_layers import (DeformableDetrTransformerDecoder,\n                                     DeformableDetrTransformerDecoderLayer,\n                                     DeformableDetrTransformerEncoder,\n                                     DeformableDetrTransformerEncoderLayer)\nfrom .detr_layers import (DetrTransformerDecoder, DetrTransformerDecoderLayer,\n                          DetrTransformerEncoder, DetrTransformerEncoderLayer)\nfrom .utils import FFN, PositionEmbeddingSineHW\n\n__all__ = [\n    'DetrTransformerEncoder', 'DetrTransformerDecoder',\n    'DetrTransformerEncoderLayer', 'DetrTransformerDecoderLayer',\n    'DeformableDetrTransformerEncoder', 'DeformableDetrTransformerDecoder',\n    'DeformableDetrTransformerEncoderLayer',\n    'DeformableDetrTransformerDecoderLayer', 'PositionEmbeddingSineHW', 'FFN'\n]\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/transformers/deformable_detr_layers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple, Union\n\nimport torch\nfrom mmcv.cnn import build_norm_layer\nfrom mmcv.cnn.bricks.transformer import FFN, MultiheadAttention\nfrom mmcv.ops import MultiScaleDeformableAttention\nfrom mmengine.model import ModuleList\nfrom torch import Tensor, nn\n\nfrom mmpose.models.utils import inverse_sigmoid\nfrom .detr_layers import (DetrTransformerDecoder, DetrTransformerDecoderLayer,\n                          DetrTransformerEncoder, DetrTransformerEncoderLayer)\n\n\nclass DeformableDetrTransformerEncoder(DetrTransformerEncoder):\n    \"\"\"Transformer encoder of Deformable DETR.\"\"\"\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize encoder layers.\"\"\"\n        self.layers = ModuleList([\n            DeformableDetrTransformerEncoderLayer(**self.layer_cfg)\n            for _ in range(self.num_layers)\n        ])\n        self.embed_dims = self.layers[0].embed_dims\n\n    def forward(self, query: Tensor, query_pos: Tensor,\n                key_padding_mask: Tensor, spatial_shapes: Tensor,\n                level_start_index: Tensor, valid_ratios: Tensor,\n                **kwargs) -> Tensor:\n        \"\"\"Forward function of Transformer encoder.\n\n        Args:\n            query (Tensor): The input query, has shape (bs, num_queries, dim).\n            query_pos (Tensor): The positional encoding for query, has shape\n                (bs, num_queries, dim).\n            key_padding_mask (Tensor): The `key_padding_mask` of `self_attn`\n                input. ByteTensor, has shape (bs, num_queries).\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n            level_start_index (Tensor): The start index of each level.\n                A tensor has shape (num_levels, ) and can be represented\n                as [0, h_0*w_0, h_0*w_0+h_1*w_1, ...].\n            valid_ratios (Tensor): The ratios of the valid width and the valid\n                height relative to the width and the height of features in all\n                levels, has shape (bs, num_levels, 2).\n\n        Returns:\n            Tensor: Output queries of Transformer encoder, which is also\n            called 'encoder output embeddings' or 'memory', has shape\n            (bs, num_queries, dim)\n        \"\"\"\n        reference_points = self.get_encoder_reference_points(\n            spatial_shapes, valid_ratios, device=query.device)\n        for layer in self.layers:\n            query = layer(\n                query=query,\n                query_pos=query_pos,\n                key_padding_mask=key_padding_mask,\n                spatial_shapes=spatial_shapes,\n                level_start_index=level_start_index,\n                valid_ratios=valid_ratios,\n                reference_points=reference_points,\n                **kwargs)\n        return query\n\n    @staticmethod\n    def get_encoder_reference_points(spatial_shapes: Tensor,\n                                     valid_ratios: Tensor,\n                                     device: Union[torch.device,\n                                                   str]) -> Tensor:\n        \"\"\"Get the reference points used in encoder.\n\n        Args:\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n            valid_ratios (Tensor): The ratios of the valid width and the valid\n                height relative to the width and the height of features in all\n                levels, has shape (bs, num_levels, 2).\n            device (obj:`device` or str): The device acquired by the\n                `reference_points`.\n\n        Returns:\n            Tensor: Reference points used in decoder, has shape (bs, length,\n            num_levels, 2).\n        \"\"\"\n\n        reference_points_list = []\n        for lvl, (H, W) in enumerate(spatial_shapes):\n            ref_y, ref_x = torch.meshgrid(\n                torch.linspace(\n                    0.5, H - 0.5, H, dtype=torch.float32, device=device),\n                torch.linspace(\n                    0.5, W - 0.5, W, dtype=torch.float32, device=device))\n            ref_y = ref_y.reshape(-1)[None] / (\n                valid_ratios[:, None, lvl, 1] * H)\n            ref_x = ref_x.reshape(-1)[None] / (\n                valid_ratios[:, None, lvl, 0] * W)\n            ref = torch.stack((ref_x, ref_y), -1)\n            reference_points_list.append(ref)\n        reference_points = torch.cat(reference_points_list, 1)\n        # [bs, sum(hw), num_level, 2]\n        reference_points = reference_points[:, :, None] * valid_ratios[:, None]\n        return reference_points\n\n\nclass DeformableDetrTransformerDecoder(DetrTransformerDecoder):\n    \"\"\"Transformer Decoder of Deformable DETR.\"\"\"\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize decoder layers.\"\"\"\n        self.layers = ModuleList([\n            DeformableDetrTransformerDecoderLayer(**self.layer_cfg)\n            for _ in range(self.num_layers)\n        ])\n        self.embed_dims = self.layers[0].embed_dims\n        if self.post_norm_cfg is not None:\n            raise ValueError('There is not post_norm in '\n                             f'{self._get_name()}')\n\n    def forward(self,\n                query: Tensor,\n                query_pos: Tensor,\n                value: Tensor,\n                key_padding_mask: Tensor,\n                reference_points: Tensor,\n                spatial_shapes: Tensor,\n                level_start_index: Tensor,\n                valid_ratios: Tensor,\n                reg_branches: Optional[nn.Module] = None,\n                **kwargs) -> Tuple[Tensor]:\n        \"\"\"Forward function of Transformer decoder.\n\n        Args:\n            query (Tensor): The input queries, has shape (bs, num_queries,\n                dim).\n            query_pos (Tensor): The input positional query, has shape\n                (bs, num_queries, dim). It will be added to `query` before\n                forward function.\n            value (Tensor): The input values, has shape (bs, num_value, dim).\n            key_padding_mask (Tensor): The `key_padding_mask` of `cross_attn`\n                input. ByteTensor, has shape (bs, num_value).\n            reference_points (Tensor): The initial reference, has shape\n                (bs, num_queries, 4) with the last dimension arranged as\n                (cx, cy, w, h) when `as_two_stage` is `True`, otherwise has\n                shape (bs, num_queries, 2) with the last dimension arranged\n                as (cx, cy).\n            spatial_shapes (Tensor): Spatial shapes of features in all levels,\n                has shape (num_levels, 2), last dimension represents (h, w).\n            level_start_index (Tensor): The start index of each level.\n                A tensor has shape (num_levels, ) and can be represented\n                as [0, h_0*w_0, h_0*w_0+h_1*w_1, ...].\n            valid_ratios (Tensor): The ratios of the valid width and the valid\n                height relative to the width and the height of features in all\n                levels, has shape (bs, num_levels, 2).\n            reg_branches: (obj:`nn.ModuleList`, optional): Used for refining\n                the regression results. Only would be passed when\n                `with_box_refine` is `True`, otherwise would be `None`.\n\n        Returns:\n            tuple[Tensor]: Outputs of Deformable Transformer Decoder.\n\n            - output (Tensor): Output embeddings of the last decoder, has\n              shape (num_queries, bs, embed_dims) when `return_intermediate`\n              is `False`. Otherwise, Intermediate output embeddings of all\n              decoder layers, has shape (num_decoder_layers, num_queries, bs,\n              embed_dims).\n            - reference_points (Tensor): The reference of the last decoder\n              layer, has shape (bs, num_queries, 4)  when `return_intermediate`\n              is `False`. Otherwise, Intermediate references of all decoder\n              layers, has shape (num_decoder_layers, bs, num_queries, 4). The\n              coordinates are arranged as (cx, cy, w, h)\n        \"\"\"\n        output = query\n        intermediate = []\n        intermediate_reference_points = []\n        for layer_id, layer in enumerate(self.layers):\n            if reference_points.shape[-1] == 4:\n                reference_points_input = \\\n                    reference_points[:, :, None] * \\\n                    torch.cat([valid_ratios, valid_ratios], -1)[:, None]\n            else:\n                assert reference_points.shape[-1] == 2\n                reference_points_input = \\\n                    reference_points[:, :, None] * \\\n                    valid_ratios[:, None]\n            output = layer(\n                output,\n                query_pos=query_pos,\n                value=value,\n                key_padding_mask=key_padding_mask,\n                spatial_shapes=spatial_shapes,\n                level_start_index=level_start_index,\n                valid_ratios=valid_ratios,\n                reference_points=reference_points_input,\n                **kwargs)\n\n            if reg_branches is not None:\n                tmp_reg_preds = reg_branches[layer_id](output)\n                if reference_points.shape[-1] == 4:\n                    new_reference_points = tmp_reg_preds + inverse_sigmoid(\n                        reference_points)\n                    new_reference_points = new_reference_points.sigmoid()\n                else:\n                    assert reference_points.shape[-1] == 2\n                    new_reference_points = tmp_reg_preds\n                    new_reference_points[..., :2] = tmp_reg_preds[\n                        ..., :2] + inverse_sigmoid(reference_points)\n                    new_reference_points = new_reference_points.sigmoid()\n                reference_points = new_reference_points.detach()\n\n            if self.return_intermediate:\n                intermediate.append(output)\n                intermediate_reference_points.append(reference_points)\n\n        if self.return_intermediate:\n            return torch.stack(intermediate), torch.stack(\n                intermediate_reference_points)\n\n        return output, reference_points\n\n\nclass DeformableDetrTransformerEncoderLayer(DetrTransformerEncoderLayer):\n    \"\"\"Encoder layer of Deformable DETR.\"\"\"\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize self_attn, ffn, and norms.\"\"\"\n        self.self_attn = MultiScaleDeformableAttention(**self.self_attn_cfg)\n        self.embed_dims = self.self_attn.embed_dims\n        self.ffn = FFN(**self.ffn_cfg)\n        norms_list = [\n            build_norm_layer(self.norm_cfg, self.embed_dims)[1]\n            for _ in range(2)\n        ]\n        self.norms = ModuleList(norms_list)\n\n\nclass DeformableDetrTransformerDecoderLayer(DetrTransformerDecoderLayer):\n    \"\"\"Decoder layer of Deformable DETR.\"\"\"\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize self_attn, cross-attn, ffn, and norms.\"\"\"\n        self.self_attn = MultiheadAttention(**self.self_attn_cfg)\n        self.cross_attn = MultiScaleDeformableAttention(**self.cross_attn_cfg)\n        self.embed_dims = self.self_attn.embed_dims\n        self.ffn = FFN(**self.ffn_cfg)\n        norms_list = [\n            build_norm_layer(self.norm_cfg, self.embed_dims)[1]\n            for _ in range(3)\n        ]\n        self.norms = ModuleList(norms_list)\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/transformers/detr_layers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Union\n\nimport torch\nfrom mmcv.cnn import build_norm_layer\nfrom mmcv.cnn.bricks.transformer import FFN, MultiheadAttention\nfrom mmengine import ConfigDict\nfrom mmengine.model import BaseModule, ModuleList\nfrom torch import Tensor\n\nfrom mmpose.utils.typing import ConfigType, OptConfigType\n\n\nclass DetrTransformerEncoder(BaseModule):\n    \"\"\"Encoder of DETR.\n\n    Args:\n        num_layers (int): Number of encoder layers.\n        layer_cfg (:obj:`ConfigDict` or dict): the config of each encoder\n            layer. All the layers will share the same config.\n        init_cfg (:obj:`ConfigDict` or dict, optional): the config to control\n            the initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 num_layers: int,\n                 layer_cfg: ConfigType,\n                 init_cfg: OptConfigType = None) -> None:\n\n        super().__init__(init_cfg=init_cfg)\n        self.num_layers = num_layers\n        self.layer_cfg = layer_cfg\n        self._init_layers()\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize encoder layers.\"\"\"\n        self.layers = ModuleList([\n            DetrTransformerEncoderLayer(**self.layer_cfg)\n            for _ in range(self.num_layers)\n        ])\n        self.embed_dims = self.layers[0].embed_dims\n\n    def forward(self, query: Tensor, query_pos: Tensor,\n                key_padding_mask: Tensor, **kwargs) -> Tensor:\n        \"\"\"Forward function of encoder.\n\n        Args:\n            query (Tensor): Input queries of encoder, has shape\n                (bs, num_queries, dim).\n            query_pos (Tensor): The positional embeddings of the queries, has\n                shape (bs, num_queries, dim).\n            key_padding_mask (Tensor): The `key_padding_mask` of `self_attn`\n                input. ByteTensor, has shape (bs, num_queries).\n\n        Returns:\n            Tensor: Has shape (bs, num_queries, dim) if `batch_first` is\n            `True`, otherwise (num_queries, bs, dim).\n        \"\"\"\n        for layer in self.layers:\n            query = layer(query, query_pos, key_padding_mask, **kwargs)\n        return query\n\n\nclass DetrTransformerDecoder(BaseModule):\n    \"\"\"Decoder of DETR.\n\n    Args:\n        num_layers (int): Number of decoder layers.\n        layer_cfg (:obj:`ConfigDict` or dict): the config of each encoder\n            layer. All the layers will share the same config.\n        post_norm_cfg (:obj:`ConfigDict` or dict, optional): Config of the\n            post normalization layer. Defaults to `LN`.\n        return_intermediate (bool, optional): Whether to return outputs of\n            intermediate layers. Defaults to `True`,\n        init_cfg (:obj:`ConfigDict` or dict, optional): the config to control\n            the initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 num_layers: int,\n                 layer_cfg: ConfigType,\n                 post_norm_cfg: OptConfigType = dict(type='LN'),\n                 return_intermediate: bool = True,\n                 init_cfg: Union[dict, ConfigDict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        self.layer_cfg = layer_cfg\n        self.num_layers = num_layers\n        self.post_norm_cfg = post_norm_cfg\n        self.return_intermediate = return_intermediate\n        self._init_layers()\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize decoder layers.\"\"\"\n        self.layers = ModuleList([\n            DetrTransformerDecoderLayer(**self.layer_cfg)\n            for _ in range(self.num_layers)\n        ])\n        self.embed_dims = self.layers[0].embed_dims\n        self.post_norm = build_norm_layer(self.post_norm_cfg,\n                                          self.embed_dims)[1]\n\n    def forward(self, query: Tensor, key: Tensor, value: Tensor,\n                query_pos: Tensor, key_pos: Tensor, key_padding_mask: Tensor,\n                **kwargs) -> Tensor:\n        \"\"\"Forward function of decoder\n        Args:\n            query (Tensor): The input query, has shape (bs, num_queries, dim).\n            key (Tensor): The input key, has shape (bs, num_keys, dim).\n            value (Tensor): The input value with the same shape as `key`.\n            query_pos (Tensor): The positional encoding for `query`, with the\n                same shape as `query`.\n            key_pos (Tensor): The positional encoding for `key`, with the\n                same shape as `key`.\n            key_padding_mask (Tensor): The `key_padding_mask` of `cross_attn`\n                input. ByteTensor, has shape (bs, num_value).\n\n        Returns:\n            Tensor: The forwarded results will have shape\n            (num_decoder_layers, bs, num_queries, dim) if\n            `return_intermediate` is `True` else (1, bs, num_queries, dim).\n        \"\"\"\n        intermediate = []\n        for layer in self.layers:\n            query = layer(\n                query,\n                key=key,\n                value=value,\n                query_pos=query_pos,\n                key_pos=key_pos,\n                key_padding_mask=key_padding_mask,\n                **kwargs)\n            if self.return_intermediate:\n                intermediate.append(self.post_norm(query))\n        query = self.post_norm(query)\n\n        if self.return_intermediate:\n            return torch.stack(intermediate)\n\n        return query.unsqueeze(0)\n\n\nclass DetrTransformerEncoderLayer(BaseModule):\n    \"\"\"Implements encoder layer in DETR transformer.\n\n    Args:\n        self_attn_cfg (:obj:`ConfigDict` or dict, optional): Config for self\n            attention.\n        ffn_cfg (:obj:`ConfigDict` or dict, optional): Config for FFN.\n        norm_cfg (:obj:`ConfigDict` or dict, optional): Config for\n            normalization layers. All the layers will share the same\n            config. Defaults to `LN`.\n        init_cfg (:obj:`ConfigDict` or dict, optional): Config to control\n            the initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 self_attn_cfg: OptConfigType = dict(\n                     embed_dims=256, num_heads=8, dropout=0.0),\n                 ffn_cfg: OptConfigType = dict(\n                     embed_dims=256,\n                     feedforward_channels=1024,\n                     num_fcs=2,\n                     ffn_drop=0.,\n                     act_cfg=dict(type='ReLU', inplace=True)),\n                 norm_cfg: OptConfigType = dict(type='LN'),\n                 init_cfg: OptConfigType = None) -> None:\n\n        super().__init__(init_cfg=init_cfg)\n\n        self.self_attn_cfg = self_attn_cfg\n        if 'batch_first' not in self.self_attn_cfg:\n            self.self_attn_cfg['batch_first'] = True\n        else:\n            assert self.self_attn_cfg['batch_first'] is True, 'First \\\n            dimension of all DETRs in mmdet is `batch`, \\\n            please set `batch_first` flag.'\n\n        self.ffn_cfg = ffn_cfg\n        self.norm_cfg = norm_cfg\n        self._init_layers()\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize self-attention, FFN, and normalization.\"\"\"\n        self.self_attn = MultiheadAttention(**self.self_attn_cfg)\n        self.embed_dims = self.self_attn.embed_dims\n        self.ffn = FFN(**self.ffn_cfg)\n        norms_list = [\n            build_norm_layer(self.norm_cfg, self.embed_dims)[1]\n            for _ in range(2)\n        ]\n        self.norms = ModuleList(norms_list)\n\n    def forward(self, query: Tensor, query_pos: Tensor,\n                key_padding_mask: Tensor, **kwargs) -> Tensor:\n        \"\"\"Forward function of an encoder layer.\n\n        Args:\n            query (Tensor): The input query, has shape (bs, num_queries, dim).\n            query_pos (Tensor): The positional encoding for query, with\n                the same shape as `query`.\n            key_padding_mask (Tensor): The `key_padding_mask` of `self_attn`\n                input. ByteTensor. has shape (bs, num_queries).\n        Returns:\n            Tensor: forwarded results, has shape (bs, num_queries, dim).\n        \"\"\"\n        query = self.self_attn(\n            query=query,\n            key=query,\n            value=query,\n            query_pos=query_pos,\n            key_pos=query_pos,\n            key_padding_mask=key_padding_mask,\n            **kwargs)\n        query = self.norms[0](query)\n        query = self.ffn(query)\n        query = self.norms[1](query)\n\n        return query\n\n\nclass DetrTransformerDecoderLayer(BaseModule):\n    \"\"\"Implements decoder layer in DETR transformer.\n\n    Args:\n        self_attn_cfg (:obj:`ConfigDict` or dict, optional): Config for self\n            attention.\n        cross_attn_cfg (:obj:`ConfigDict` or dict, optional): Config for cross\n            attention.\n        ffn_cfg (:obj:`ConfigDict` or dict, optional): Config for FFN.\n        norm_cfg (:obj:`ConfigDict` or dict, optional): Config for\n            normalization layers. All the layers will share the same\n            config. Defaults to `LN`.\n        init_cfg (:obj:`ConfigDict` or dict, optional): Config to control\n            the initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 self_attn_cfg: OptConfigType = dict(\n                     embed_dims=256,\n                     num_heads=8,\n                     dropout=0.0,\n                     batch_first=True),\n                 cross_attn_cfg: OptConfigType = dict(\n                     embed_dims=256,\n                     num_heads=8,\n                     dropout=0.0,\n                     batch_first=True),\n                 ffn_cfg: OptConfigType = dict(\n                     embed_dims=256,\n                     feedforward_channels=1024,\n                     num_fcs=2,\n                     ffn_drop=0.,\n                     act_cfg=dict(type='ReLU', inplace=True),\n                 ),\n                 norm_cfg: OptConfigType = dict(type='LN'),\n                 init_cfg: OptConfigType = None) -> None:\n\n        super().__init__(init_cfg=init_cfg)\n\n        self.self_attn_cfg = self_attn_cfg\n        self.cross_attn_cfg = cross_attn_cfg\n        if 'batch_first' not in self.self_attn_cfg:\n            self.self_attn_cfg['batch_first'] = True\n        else:\n            assert self.self_attn_cfg['batch_first'] is True, 'First \\\n            dimension of all DETRs in mmdet is `batch`, \\\n            please set `batch_first` flag.'\n\n        if 'batch_first' not in self.cross_attn_cfg:\n            self.cross_attn_cfg['batch_first'] = True\n        else:\n            assert self.cross_attn_cfg['batch_first'] is True, 'First \\\n            dimension of all DETRs in mmdet is `batch`, \\\n            please set `batch_first` flag.'\n\n        self.ffn_cfg = ffn_cfg\n        self.norm_cfg = norm_cfg\n        self._init_layers()\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize self-attention, FFN, and normalization.\"\"\"\n        self.self_attn = MultiheadAttention(**self.self_attn_cfg)\n        self.cross_attn = MultiheadAttention(**self.cross_attn_cfg)\n        self.embed_dims = self.self_attn.embed_dims\n        self.ffn = FFN(**self.ffn_cfg)\n        norms_list = [\n            build_norm_layer(self.norm_cfg, self.embed_dims)[1]\n            for _ in range(3)\n        ]\n        self.norms = ModuleList(norms_list)\n\n    def forward(self,\n                query: Tensor,\n                key: Tensor = None,\n                value: Tensor = None,\n                query_pos: Tensor = None,\n                key_pos: Tensor = None,\n                self_attn_mask: Tensor = None,\n                cross_attn_mask: Tensor = None,\n                key_padding_mask: Tensor = None,\n                **kwargs) -> Tensor:\n        \"\"\"\n        Args:\n            query (Tensor): The input query, has shape (bs, num_queries, dim).\n            key (Tensor, optional): The input key, has shape (bs, num_keys,\n                dim). If `None`, the `query` will be used. Defaults to `None`.\n            value (Tensor, optional): The input value, has the same shape as\n                `key`, as in `nn.MultiheadAttention.forward`. If `None`, the\n                `key` will be used. Defaults to `None`.\n            query_pos (Tensor, optional): The positional encoding for `query`,\n                has the same shape as `query`. If not `None`, it will be added\n                to `query` before forward function. Defaults to `None`.\n            key_pos (Tensor, optional): The positional encoding for `key`, has\n                the same shape as `key`. If not `None`, it will be added to\n                `key` before forward function. If None, and `query_pos` has the\n                same shape as `key`, then `query_pos` will be used for\n                `key_pos`. Defaults to None.\n            self_attn_mask (Tensor, optional): ByteTensor mask, has shape\n                (num_queries, num_keys), as in `nn.MultiheadAttention.forward`.\n                Defaults to None.\n            cross_attn_mask (Tensor, optional): ByteTensor mask, has shape\n                (num_queries, num_keys), as in `nn.MultiheadAttention.forward`.\n                Defaults to None.\n            key_padding_mask (Tensor, optional): The `key_padding_mask` of\n                `self_attn` input. ByteTensor, has shape (bs, num_value).\n                Defaults to None.\n\n        Returns:\n            Tensor: forwarded results, has shape (bs, num_queries, dim).\n        \"\"\"\n\n        query = self.self_attn(\n            query=query,\n            key=query,\n            value=query,\n            query_pos=query_pos,\n            key_pos=query_pos,\n            attn_mask=self_attn_mask,\n            **kwargs)\n        query = self.norms[0](query)\n        query = self.cross_attn(\n            query=query,\n            key=key,\n            value=value,\n            query_pos=query_pos,\n            key_pos=key_pos,\n            attn_mask=cross_attn_mask,\n            key_padding_mask=key_padding_mask,\n            **kwargs)\n        query = self.norms[1](query)\n        query = self.ffn(query)\n        query = self.norms[2](query)\n\n        return query\n"
  },
  {
    "path": "mmpose/models/heads/transformer_heads/transformers/utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\n\nimport torch\nimport torch.nn.functional as F\nfrom mmcv.cnn import Linear\nfrom mmengine.model import BaseModule, ModuleList\nfrom torch import Tensor\n\n\nclass FFN(BaseModule):\n    \"\"\"Very simple multi-layer perceptron with relu. Mostly used in DETR series\n    detectors.\n\n    Args:\n        input_dim (int): Feature dim of the input tensor.\n        hidden_dim (int): Feature dim of the hidden layer.\n        output_dim (int): Feature dim of the output tensor.\n        num_layers (int): Number of FFN layers..\n    \"\"\"\n\n    def __init__(self, input_dim: int, hidden_dim: int, output_dim: int,\n                 num_layers: int) -> None:\n        super().__init__()\n\n        self.num_layers = num_layers\n\n        self.layers = ModuleList()\n        self.layers.append(Linear(input_dim, hidden_dim))\n        for _ in range(num_layers - 2):\n            self.layers.append(Linear(hidden_dim, hidden_dim))\n        self.layers.append(Linear(hidden_dim, output_dim))\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward function of FFN.\n\n        Args:\n            x (Tensor): The input feature, has shape\n                (num_queries, bs, input_dim).\n        Returns:\n            Tensor: The output feature, has shape\n                (num_queries, bs, output_dim).\n        \"\"\"\n        for i, layer in enumerate(self.layers):\n            x = layer(x)\n            if i < self.num_layers - 1:\n                x = F.relu(x)\n        return x\n\n\nclass PositionEmbeddingSineHW(BaseModule):\n    \"\"\"This is a more standard version of the position embedding, very similar\n    to the one used by the Attention is all you need paper, generalized to work\n    on images.\"\"\"\n\n    def __init__(self,\n                 num_pos_feats=64,\n                 temperatureH=10000,\n                 temperatureW=10000,\n                 normalize=False,\n                 scale=None):\n        super().__init__()\n        self.num_pos_feats = num_pos_feats\n        self.temperatureH = temperatureH\n        self.temperatureW = temperatureW\n        self.normalize = normalize\n        if scale is not None and normalize is False:\n            raise ValueError('normalize should be True if scale is passed')\n        if scale is None:\n            scale = 2 * math.pi\n        self.scale = scale\n\n    def forward(self, mask: Tensor):\n\n        assert mask is not None\n        not_mask = ~mask\n        y_embed = not_mask.cumsum(1, dtype=torch.float32)\n        x_embed = not_mask.cumsum(2, dtype=torch.float32)\n\n        if self.normalize:\n            eps = 1e-6\n            y_embed = y_embed / (y_embed[:, -1:, :] + eps) * self.scale\n            x_embed = x_embed / (x_embed[:, :, -1:] + eps) * self.scale\n\n        dim_tx = torch.arange(\n            self.num_pos_feats, dtype=torch.float32, device=mask.device)\n        dim_tx = self.temperatureW**(2 * (dim_tx // 2) / self.num_pos_feats)\n        pos_x = x_embed[:, :, :, None] / dim_tx\n\n        dim_ty = torch.arange(\n            self.num_pos_feats, dtype=torch.float32, device=mask.device)\n        dim_ty = self.temperatureH**(2 * (dim_ty // 2) / self.num_pos_feats)\n        pos_y = y_embed[:, :, :, None] / dim_ty\n\n        pos_x = torch.stack(\n            (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()),\n            dim=4).flatten(3)\n        pos_y = torch.stack(\n            (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()),\n            dim=4).flatten(3)\n        pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2)\n\n        return pos\n"
  },
  {
    "path": "mmpose/models/losses/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .ae_loss import AssociativeEmbeddingLoss\nfrom .bbox_loss import IoULoss\nfrom .classification_loss import (BCELoss, JSDiscretLoss, KLDiscretLoss,\n                                  VariFocalLoss)\nfrom .fea_dis_loss import FeaLoss\nfrom .heatmap_loss import (AdaptiveWingLoss, KeypointMSELoss,\n                           KeypointOHKMMSELoss, MLECCLoss)\nfrom .logit_dis_loss import KDLoss\nfrom .loss_wrappers import CombinedLoss, MultipleLossWrapper\nfrom .regression_loss import (BoneLoss, L1Loss, MPJPELoss,\n                              MPJPEVelocityJointLoss, MSELoss, OKSLoss,\n                              RLELoss, SemiSupervisionLoss, SmoothL1Loss,\n                              SoftWeightSmoothL1Loss, SoftWingLoss, WingLoss)\n\n__all__ = [\n    'KeypointMSELoss', 'KeypointOHKMMSELoss', 'SmoothL1Loss', 'WingLoss',\n    'MPJPELoss', 'MSELoss', 'L1Loss', 'BCELoss', 'BoneLoss',\n    'SemiSupervisionLoss', 'SoftWingLoss', 'AdaptiveWingLoss', 'RLELoss',\n    'KLDiscretLoss', 'MultipleLossWrapper', 'JSDiscretLoss', 'CombinedLoss',\n    'AssociativeEmbeddingLoss', 'SoftWeightSmoothL1Loss',\n    'MPJPEVelocityJointLoss', 'FeaLoss', 'KDLoss', 'OKSLoss', 'IoULoss',\n    'VariFocalLoss', 'MLECCLoss'\n]\n"
  },
  {
    "path": "mmpose/models/losses/ae_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom typing import List, Union\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass AssociativeEmbeddingLoss(nn.Module):\n    \"\"\"Associative Embedding loss.\n\n    Details can be found in\n    `Associative Embedding <https://arxiv.org/abs/1611.05424>`_\n\n    Note:\n\n        - batch size: B\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - embedding tag dimension: L\n        - heatmap size: [W, H]\n\n    Args:\n        loss_weight (float): Weight of the loss. Defaults to 1.0\n        push_loss_factor (float): A factor that controls the weight between\n            the push loss and the pull loss. Defaults to 0.5\n    \"\"\"\n\n    def __init__(self,\n                 loss_weight: float = 1.0,\n                 push_loss_factor: float = 0.5) -> None:\n        super().__init__()\n        self.loss_weight = loss_weight\n        self.push_loss_factor = push_loss_factor\n\n    def _ae_loss_per_image(self, tags: Tensor, keypoint_indices: Tensor):\n        \"\"\"Compute associative embedding loss for one image.\n\n        Args:\n            tags (Tensor): Tagging heatmaps in shape (K*L, H, W)\n            keypoint_indices (Tensor): Ground-truth keypint position indices\n                in shape (N, K, 2)\n        \"\"\"\n        K = keypoint_indices.shape[1]\n        C, H, W = tags.shape\n        L = C // K\n\n        tags = tags.view(L, K, H * W)\n        instance_tags = []\n        instance_kpt_tags = []\n\n        for keypoint_indices_n in keypoint_indices:\n            _kpt_tags = []\n            for k in range(K):\n                if keypoint_indices_n[k, 1]:\n                    _kpt_tags.append(tags[:, k, keypoint_indices_n[k, 0]])\n\n            if _kpt_tags:\n                kpt_tags = torch.stack(_kpt_tags)\n                instance_kpt_tags.append(kpt_tags)\n                instance_tags.append(kpt_tags.mean(dim=0))\n\n        N = len(instance_kpt_tags)  # number of instances with valid keypoints\n\n        if N == 0:\n            pull_loss = tags.new_zeros(size=(), requires_grad=True)\n            push_loss = tags.new_zeros(size=(), requires_grad=True)\n        else:\n            pull_loss = sum(\n                F.mse_loss(_kpt_tags, _tag.expand_as(_kpt_tags))\n                for (_kpt_tags, _tag) in zip(instance_kpt_tags, instance_tags))\n\n            if N == 1:\n                push_loss = tags.new_zeros(size=(), requires_grad=True)\n            else:\n                tag_mat = torch.stack(instance_tags)  # (N, L)\n                diff = tag_mat[None] - tag_mat[:, None]  # (N, N, L)\n                push_loss = torch.sum(torch.exp(-diff.pow(2)))\n\n            # normalization\n            eps = 1e-6\n            pull_loss = pull_loss / (N + eps)\n            push_loss = push_loss / ((N - 1) * N + eps)\n\n        return pull_loss, push_loss\n\n    def forward(self, tags: Tensor, keypoint_indices: Union[List[Tensor],\n                                                            Tensor]):\n        \"\"\"Compute associative embedding loss on a batch of data.\n\n        Args:\n            tags (Tensor): Tagging heatmaps in shape (B, L*K, H, W)\n            keypoint_indices (Tensor|List[Tensor]): Ground-truth keypint\n                position indices represented by a Tensor in shape\n                (B, N, K, 2), or a list of B Tensors in shape (N_i, K, 2)\n                Each keypoint's index is represented as [i, v], where i is the\n                position index in the heatmap (:math:`i=y*w+x`) and v is the\n                visibility\n\n        Returns:\n            tuple:\n            - pull_loss (Tensor)\n            - push_loss (Tensor)\n        \"\"\"\n\n        assert tags.shape[0] == len(keypoint_indices)\n\n        pull_loss = 0.\n        push_loss = 0.\n\n        for i in range(tags.shape[0]):\n            _pull, _push = self._ae_loss_per_image(tags[i],\n                                                   keypoint_indices[i])\n            pull_loss += _pull * self.loss_weight\n            push_loss += _push * self.loss_weight * self.push_loss_factor\n\n        return pull_loss, push_loss\n"
  },
  {
    "path": "mmpose/models/losses/bbox_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom functools import partial\n\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom mmpose.registry import MODELS\nfrom mmpose.structures.bbox import bbox_overlaps\n\n\n@MODELS.register_module()\nclass IoULoss(nn.Module):\n    \"\"\"Binary Cross Entropy loss.\n\n    Args:\n        reduction (str): Options are \"none\", \"mean\" and \"sum\".\n        eps (float): Epsilon to avoid log(0).\n        loss_weight (float): Weight of the loss. Default: 1.0.\n        mode (str): Loss scaling mode, including \"linear\", \"square\", and \"log\".\n            Default: 'log'\n    \"\"\"\n\n    def __init__(self,\n                 reduction='mean',\n                 mode='log',\n                 eps: float = 1e-16,\n                 loss_weight=1.):\n        super().__init__()\n\n        assert reduction in ('mean', 'sum', 'none'), f'the argument ' \\\n            f'`reduction` should be either \\'mean\\', \\'sum\\' or \\'none\\', ' \\\n            f'but got {reduction}'\n\n        assert mode in ('linear', 'square', 'log'), f'the argument ' \\\n            f'`reduction` should be either \\'linear\\', \\'square\\' or ' \\\n            f'\\'log\\', but got {mode}'\n\n        self.reduction = reduction\n        self.criterion = partial(F.cross_entropy, reduction='none')\n        self.loss_weight = loss_weight\n        self.mode = mode\n        self.eps = eps\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_labels: K\n\n        Args:\n            output (torch.Tensor[N, K]): Output classification.\n            target (torch.Tensor[N, K]): Target classification.\n        \"\"\"\n        ious = bbox_overlaps(\n            output, target, is_aligned=True).clamp(min=self.eps)\n\n        if self.mode == 'linear':\n            loss = 1 - ious\n        elif self.mode == 'square':\n            loss = 1 - ious.pow(2)\n        elif self.mode == 'log':\n            loss = -ious.log()\n        else:\n            raise NotImplementedError\n\n        if target_weight is not None:\n            for i in range(loss.ndim - target_weight.ndim):\n                target_weight = target_weight.unsqueeze(-1)\n            loss = loss * target_weight\n\n        if self.reduction == 'sum':\n            loss = loss.sum()\n        elif self.reduction == 'mean':\n            loss = loss.mean()\n\n        return loss * self.loss_weight\n"
  },
  {
    "path": "mmpose/models/losses/classification_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom functools import partial\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass BCELoss(nn.Module):\n    \"\"\"Binary Cross Entropy loss.\n\n    Args:\n        use_target_weight (bool): Option to use weighted loss.\n            Different joint types may have different target weights.\n        reduction (str): Options are \"none\", \"mean\" and \"sum\".\n        loss_weight (float): Weight of the loss. Default: 1.0.\n        use_sigmoid (bool, optional): Whether the prediction uses sigmoid\n            before output. Defaults to False.\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight=False,\n                 loss_weight=1.,\n                 reduction='mean',\n                 use_sigmoid=False):\n        super().__init__()\n\n        assert reduction in ('mean', 'sum', 'none'), f'the argument ' \\\n            f'`reduction` should be either \\'mean\\', \\'sum\\' or \\'none\\', ' \\\n            f'but got {reduction}'\n\n        self.reduction = reduction\n        self.use_sigmoid = use_sigmoid\n        criterion = F.binary_cross_entropy if use_sigmoid \\\n            else F.binary_cross_entropy_with_logits\n        self.criterion = partial(criterion, reduction='none')\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_labels: K\n\n        Args:\n            output (torch.Tensor[N, K]): Output classification.\n            target (torch.Tensor[N, K]): Target classification.\n            target_weight (torch.Tensor[N, K] or torch.Tensor[N]):\n                Weights across different labels.\n        \"\"\"\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss = self.criterion(output, target)\n            if target_weight.dim() == 1:\n                target_weight = target_weight[:, None]\n            loss = (loss * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        if self.reduction == 'sum':\n            loss = loss.sum()\n        elif self.reduction == 'mean':\n            loss = loss.mean()\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass JSDiscretLoss(nn.Module):\n    \"\"\"Discrete JS Divergence loss for DSNT with Gaussian Heatmap.\n\n    Modified from `the official implementation\n    <https://github.com/anibali/dsntnn/blob/master/dsntnn/__init__.py>`_.\n\n    Args:\n        use_target_weight (bool): Option to use weighted loss.\n            Different joint types may have different target weights.\n        size_average (bool): Option to average the loss by the batch_size.\n    \"\"\"\n\n    def __init__(\n        self,\n        use_target_weight=True,\n        size_average: bool = True,\n    ):\n        super(JSDiscretLoss, self).__init__()\n        self.use_target_weight = use_target_weight\n        self.size_average = size_average\n        self.kl_loss = nn.KLDivLoss(reduction='none')\n\n    def kl(self, p, q):\n        \"\"\"Kullback-Leibler Divergence.\"\"\"\n\n        eps = 1e-24\n        kl_values = self.kl_loss((q + eps).log(), p)\n        return kl_values\n\n    def js(self, pred_hm, gt_hm):\n        \"\"\"Jensen-Shannon Divergence.\"\"\"\n\n        m = 0.5 * (pred_hm + gt_hm)\n        js_values = 0.5 * (self.kl(pred_hm, m) + self.kl(gt_hm, m))\n        return js_values\n\n    def forward(self, pred_hm, gt_hm, target_weight=None):\n        \"\"\"Forward function.\n\n        Args:\n            pred_hm (torch.Tensor[N, K, H, W]): Predicted heatmaps.\n            gt_hm (torch.Tensor[N, K, H, W]): Target heatmaps.\n            target_weight (torch.Tensor[N, K] or torch.Tensor[N]):\n                Weights across different labels.\n\n        Returns:\n            torch.Tensor: Loss value.\n        \"\"\"\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            assert pred_hm.ndim >= target_weight.ndim\n\n            for i in range(pred_hm.ndim - target_weight.ndim):\n                target_weight = target_weight.unsqueeze(-1)\n\n            loss = self.js(pred_hm * target_weight, gt_hm * target_weight)\n        else:\n            loss = self.js(pred_hm, gt_hm)\n\n        if self.size_average:\n            loss /= len(gt_hm)\n\n        return loss.sum()\n\n\n@MODELS.register_module()\nclass KLDiscretLoss(nn.Module):\n    \"\"\"Discrete KL Divergence loss for SimCC with Gaussian Label Smoothing.\n    Modified from `the official implementation.\n\n    <https://github.com/leeyegy/SimCC>`_.\n    Args:\n        beta (float): Temperature factor of Softmax. Default: 1.0.\n        label_softmax (bool): Whether to use Softmax on labels.\n            Default: False.\n        label_beta (float): Temperature factor of Softmax on labels.\n            Default: 1.0.\n        use_target_weight (bool): Option to use weighted loss.\n            Different joint types may have different target weights.\n        mask (list[int]): Index of masked keypoints.\n        mask_weight (float): Weight of masked keypoints. Default: 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 beta=1.0,\n                 label_softmax=False,\n                 label_beta=10.0,\n                 use_target_weight=True,\n                 mask=None,\n                 mask_weight=1.0):\n        super(KLDiscretLoss, self).__init__()\n        self.beta = beta\n        self.label_softmax = label_softmax\n        self.label_beta = label_beta\n        self.use_target_weight = use_target_weight\n        self.mask = mask\n        self.mask_weight = mask_weight\n\n        self.log_softmax = nn.LogSoftmax(dim=1)\n        self.kl_loss = nn.KLDivLoss(reduction='none')\n\n    def criterion(self, dec_outs, labels):\n        \"\"\"Criterion function.\"\"\"\n        log_pt = self.log_softmax(dec_outs * self.beta)\n        if self.label_softmax:\n            labels = F.softmax(labels * self.label_beta, dim=1)\n        loss = torch.mean(self.kl_loss(log_pt, labels), dim=1)\n        return loss\n\n    def forward(self, pred_simcc, gt_simcc, target_weight):\n        \"\"\"Forward function.\n\n        Args:\n            pred_simcc (Tuple[Tensor, Tensor]): Predicted SimCC vectors of\n                x-axis and y-axis.\n            gt_simcc (Tuple[Tensor, Tensor]): Target representations.\n            target_weight (torch.Tensor[N, K] or torch.Tensor[N]):\n                Weights across different labels.\n        \"\"\"\n        N, K, _ = pred_simcc[0].shape\n        loss = 0\n\n        if self.use_target_weight:\n            weight = target_weight.reshape(-1)\n        else:\n            weight = 1.\n\n        for pred, target in zip(pred_simcc, gt_simcc):\n            pred = pred.reshape(-1, pred.size(-1))\n            target = target.reshape(-1, target.size(-1))\n\n            t_loss = self.criterion(pred, target).mul(weight)\n\n            if self.mask is not None:\n                t_loss = t_loss.reshape(N, K)\n                t_loss[:, self.mask] = t_loss[:, self.mask] * self.mask_weight\n\n            loss = loss + t_loss.sum()\n\n        return loss / K\n\n\n@MODELS.register_module()\nclass InfoNCELoss(nn.Module):\n    \"\"\"InfoNCE loss for training a discriminative representation space with a\n    contrastive manner.\n\n    `Representation Learning with Contrastive Predictive Coding\n    arXiv: <https://arxiv.org/abs/1611.05424>`_.\n\n    Args:\n        temperature (float, optional): The temperature to use in the softmax\n            function. Higher temperatures lead to softer probability\n            distributions. Defaults to 1.0.\n        loss_weight (float, optional): The weight to apply to the loss.\n            Defaults to 1.0.\n    \"\"\"\n\n    def __init__(self, temperature: float = 1.0, loss_weight=1.0) -> None:\n        super(InfoNCELoss, self).__init__()\n        assert temperature > 0, f'the argument `temperature` must be ' \\\n                                f'positive, but got {temperature}'\n        self.temp = temperature\n        self.loss_weight = loss_weight\n\n    def forward(self, features: torch.Tensor) -> torch.Tensor:\n        \"\"\"Computes the InfoNCE loss.\n\n        Args:\n            features (Tensor): A tensor containing the feature\n                representations of different samples.\n\n        Returns:\n            Tensor: A tensor of shape (1,) containing the InfoNCE loss.\n        \"\"\"\n        n = features.size(0)\n        features_norm = F.normalize(features, dim=1)\n        logits = features_norm.mm(features_norm.t()) / self.temp\n        targets = torch.arange(n, dtype=torch.long, device=features.device)\n        loss = F.cross_entropy(logits, targets, reduction='sum')\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass VariFocalLoss(nn.Module):\n    \"\"\"Varifocal loss.\n\n    Args:\n        use_target_weight (bool): Option to use weighted loss.\n            Different joint types may have different target weights.\n        reduction (str): Options are \"none\", \"mean\" and \"sum\".\n        loss_weight (float): Weight of the loss. Default: 1.0.\n        alpha (float): A balancing factor for the negative part of\n            Varifocal Loss. Defaults to 0.75.\n        gamma (float): Gamma parameter for the modulating factor.\n            Defaults to 2.0.\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight=False,\n                 loss_weight=1.,\n                 reduction='mean',\n                 alpha=0.75,\n                 gamma=2.0):\n        super().__init__()\n\n        assert reduction in ('mean', 'sum', 'none'), f'the argument ' \\\n            f'`reduction` should be either \\'mean\\', \\'sum\\' or \\'none\\', ' \\\n            f'but got {reduction}'\n\n        self.reduction = reduction\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n        self.alpha = alpha\n        self.gamma = gamma\n\n    def criterion(self, output, target):\n        label = (target > 1e-4).to(target)\n        weight = self.alpha * output.sigmoid().pow(\n            self.gamma) * (1 - label) + target\n        output = output.clip(min=-10, max=10)\n        vfl = (\n            F.binary_cross_entropy_with_logits(\n                output, target, reduction='none') * weight)\n        return vfl\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_labels: K\n\n        Args:\n            output (torch.Tensor[N, K]): Output classification.\n            target (torch.Tensor[N, K]): Target classification.\n            target_weight (torch.Tensor[N, K] or torch.Tensor[N]):\n                Weights across different labels.\n        \"\"\"\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss = self.criterion(output, target)\n            if target_weight.dim() == 1:\n                target_weight = target_weight.unsqueeze(1)\n            loss = (loss * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        loss[torch.isinf(loss)] = 0.0\n        loss[torch.isnan(loss)] = 0.0\n\n        if self.reduction == 'sum':\n            loss = loss.sum()\n        elif self.reduction == 'mean':\n            loss = loss.mean()\n\n        return loss * self.loss_weight\n"
  },
  {
    "path": "mmpose/models/losses/fea_dis_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.nn as nn\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass FeaLoss(nn.Module):\n    \"\"\"PyTorch version of feature-based distillation from DWPose Modified from\n    the official implementation.\n\n    <https://github.com/IDEA-Research/DWPose>\n    Args:\n        student_channels(int): Number of channels in the student's feature map.\n        teacher_channels(int): Number of channels in the teacher's feature map.\n        alpha_fea (float, optional): Weight of dis_loss. Defaults to 0.00007\n    \"\"\"\n\n    def __init__(\n        self,\n        name,\n        use_this,\n        student_channels,\n        teacher_channels,\n        alpha_fea=0.00007,\n    ):\n        super(FeaLoss, self).__init__()\n        self.alpha_fea = alpha_fea\n\n        if teacher_channels != student_channels:\n            self.align = nn.Conv2d(\n                student_channels,\n                teacher_channels,\n                kernel_size=1,\n                stride=1,\n                padding=0)\n        else:\n            self.align = None\n\n    def forward(self, preds_S, preds_T):\n        \"\"\"Forward function.\n\n        Args:\n            preds_S(Tensor): Bs*C*H*W, student's feature map\n            preds_T(Tensor): Bs*C*H*W, teacher's feature map\n        \"\"\"\n\n        if self.align is not None:\n            outs = self.align(preds_S)\n        else:\n            outs = preds_S\n\n        loss = self.get_dis_loss(outs, preds_T)\n\n        return loss\n\n    def get_dis_loss(self, preds_S, preds_T):\n        loss_mse = nn.MSELoss(reduction='sum')\n        N, C, H, W = preds_T.shape\n\n        dis_loss = loss_mse(preds_S, preds_T) / N * self.alpha_fea\n\n        return dis_loss\n"
  },
  {
    "path": "mmpose/models/losses/heatmap_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass KeypointMSELoss(nn.Module):\n    \"\"\"MSE loss for heatmaps.\n\n    Args:\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n            Defaults to ``False``\n        skip_empty_channel (bool): If ``True``, heatmap channels with no\n            non-zero value (which means no visible ground-truth keypoint\n            in the image) will not be used to calculate the loss. Defaults to\n            ``False``\n        loss_weight (float): Weight of the loss. Defaults to 1.0\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight: bool = False,\n                 skip_empty_channel: bool = False,\n                 loss_weight: float = 1.):\n        super().__init__()\n        self.use_target_weight = use_target_weight\n        self.skip_empty_channel = skip_empty_channel\n        self.loss_weight = loss_weight\n\n    def forward(self,\n                output: Tensor,\n                target: Tensor,\n                target_weights: Optional[Tensor] = None,\n                mask: Optional[Tensor] = None) -> Tensor:\n        \"\"\"Forward function of loss.\n\n        Note:\n            - batch_size: B\n            - num_keypoints: K\n            - heatmaps height: H\n            - heatmaps weight: W\n\n        Args:\n            output (Tensor): The output heatmaps with shape [B, K, H, W]\n            target (Tensor): The target heatmaps with shape [B, K, H, W]\n            target_weights (Tensor, optional): The target weights of differet\n                keypoints, with shape [B, K] (keypoint-wise) or\n                [B, K, H, W] (pixel-wise).\n            mask (Tensor, optional): The masks of valid heatmap pixels in\n                shape [B, K, H, W] or [B, 1, H, W]. If ``None``, no mask will\n                be applied. Defaults to ``None``\n\n        Returns:\n            Tensor: The calculated loss.\n        \"\"\"\n\n        _mask = self._get_mask(target, target_weights, mask)\n        if _mask is None:\n            loss = F.mse_loss(output, target)\n        else:\n            _loss = F.mse_loss(output, target, reduction='none')\n            loss = (_loss * _mask).mean()\n\n        return loss * self.loss_weight\n\n    def _get_mask(self, target: Tensor, target_weights: Optional[Tensor],\n                  mask: Optional[Tensor]) -> Optional[Tensor]:\n        \"\"\"Generate the heatmap mask w.r.t. the given mask, target weight and\n        `skip_empty_channel` setting.\n\n        Returns:\n            Tensor: The mask in shape (B, K, *) or ``None`` if no mask is\n            needed.\n        \"\"\"\n        # Given spatial mask\n        if mask is not None:\n            # check mask has matching type with target\n            assert (mask.ndim == target.ndim and all(\n                d_m == d_t or d_m == 1\n                for d_m, d_t in zip(mask.shape, target.shape))), (\n                    f'mask and target have mismatched shapes {mask.shape} v.s.'\n                    f'{target.shape}')\n\n        # Mask by target weights (keypoint-wise mask)\n        if target_weights is not None:\n            # check target weight has matching shape with target\n            assert (target_weights.ndim in (2, 4) and target_weights.shape\n                    == target.shape[:target_weights.ndim]), (\n                        'target_weights and target have mismatched shapes '\n                        f'{target_weights.shape} v.s. {target.shape}')\n\n            ndim_pad = target.ndim - target_weights.ndim\n            _mask = target_weights.view(target_weights.shape +\n                                        (1, ) * ndim_pad)\n\n            if mask is None:\n                mask = _mask\n            else:\n                mask = mask * _mask\n\n        # Mask by ``skip_empty_channel``\n        if self.skip_empty_channel:\n            _mask = (target != 0).flatten(2).any(dim=2)\n            ndim_pad = target.ndim - _mask.ndim\n            _mask = _mask.view(_mask.shape + (1, ) * ndim_pad)\n\n            if mask is None:\n                mask = _mask\n            else:\n                mask = mask * _mask\n\n        return mask\n\n\n@MODELS.register_module()\nclass CombinedTargetMSELoss(nn.Module):\n    \"\"\"MSE loss for combined target.\n\n    CombinedTarget: The combination of classification target\n    (response map) and regression target (offset map).\n    Paper ref: Huang et al. The Devil is in the Details: Delving into\n    Unbiased Data Processing for Human Pose Estimation (CVPR 2020).\n\n    Args:\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n            Defaults to ``False``\n        loss_weight (float): Weight of the loss. Defaults to 1.0\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight: bool = False,\n                 loss_weight: float = 1.):\n        super().__init__()\n        self.criterion = nn.MSELoss(reduction='mean')\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, output: Tensor, target: Tensor,\n                target_weights: Tensor) -> Tensor:\n        \"\"\"Forward function of loss.\n\n        Note:\n            - batch_size: B\n            - num_channels: C\n            - heatmaps height: H\n            - heatmaps weight: W\n            - num_keypoints: K\n            Here, C = 3 * K\n\n        Args:\n            output (Tensor): The output feature maps with shape [B, C, H, W].\n            target (Tensor): The target feature maps with shape [B, C, H, W].\n            target_weights (Tensor): The target weights of differet keypoints,\n                with shape [B, K].\n\n        Returns:\n            Tensor: The calculated loss.\n        \"\"\"\n        batch_size = output.size(0)\n        num_channels = output.size(1)\n        heatmaps_pred = output.reshape(\n            (batch_size, num_channels, -1)).split(1, 1)\n        heatmaps_gt = target.reshape(\n            (batch_size, num_channels, -1)).split(1, 1)\n        loss = 0.\n        num_joints = num_channels // 3\n        for idx in range(num_joints):\n            heatmap_pred = heatmaps_pred[idx * 3].squeeze()\n            heatmap_gt = heatmaps_gt[idx * 3].squeeze()\n            offset_x_pred = heatmaps_pred[idx * 3 + 1].squeeze()\n            offset_x_gt = heatmaps_gt[idx * 3 + 1].squeeze()\n            offset_y_pred = heatmaps_pred[idx * 3 + 2].squeeze()\n            offset_y_gt = heatmaps_gt[idx * 3 + 2].squeeze()\n            if self.use_target_weight:\n                target_weight = target_weights[:, idx, None]\n                heatmap_pred = heatmap_pred * target_weight\n                heatmap_gt = heatmap_gt * target_weight\n            # classification loss\n            loss += 0.5 * self.criterion(heatmap_pred, heatmap_gt)\n            # regression loss\n            loss += 0.5 * self.criterion(heatmap_gt * offset_x_pred,\n                                         heatmap_gt * offset_x_gt)\n            loss += 0.5 * self.criterion(heatmap_gt * offset_y_pred,\n                                         heatmap_gt * offset_y_gt)\n        return loss / num_joints * self.loss_weight\n\n\n@MODELS.register_module()\nclass KeypointOHKMMSELoss(nn.Module):\n    \"\"\"MSE loss with online hard keypoint mining.\n\n    Args:\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n            Defaults to ``False``\n        topk (int): Only top k joint losses are kept. Defaults to 8\n        loss_weight (float): Weight of the loss. Defaults to 1.0\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight: bool = False,\n                 topk: int = 8,\n                 loss_weight: float = 1.):\n        super().__init__()\n        assert topk > 0\n        self.criterion = nn.MSELoss(reduction='none')\n        self.use_target_weight = use_target_weight\n        self.topk = topk\n        self.loss_weight = loss_weight\n\n    def _ohkm(self, losses: Tensor) -> Tensor:\n        \"\"\"Online hard keypoint mining.\n\n        Note:\n            - batch_size: B\n            - num_keypoints: K\n\n        Args:\n            loss (Tensor): The losses with shape [B, K]\n\n        Returns:\n            Tensor: The calculated loss.\n        \"\"\"\n        ohkm_loss = 0.\n        B = losses.shape[0]\n        for i in range(B):\n            sub_loss = losses[i]\n            _, topk_idx = torch.topk(\n                sub_loss, k=self.topk, dim=0, sorted=False)\n            tmp_loss = torch.gather(sub_loss, 0, topk_idx)\n            ohkm_loss += torch.sum(tmp_loss) / self.topk\n        ohkm_loss /= B\n        return ohkm_loss\n\n    def forward(self, output: Tensor, target: Tensor,\n                target_weights: Tensor) -> Tensor:\n        \"\"\"Forward function of loss.\n\n        Note:\n            - batch_size: B\n            - num_keypoints: K\n            - heatmaps height: H\n            - heatmaps weight: W\n\n        Args:\n            output (Tensor): The output heatmaps with shape [B, K, H, W].\n            target (Tensor): The target heatmaps with shape [B, K, H, W].\n            target_weights (Tensor): The target weights of differet keypoints,\n                with shape [B, K].\n\n        Returns:\n            Tensor: The calculated loss.\n        \"\"\"\n        num_keypoints = output.size(1)\n        if num_keypoints < self.topk:\n            raise ValueError(f'topk ({self.topk}) should not be '\n                             f'larger than num_keypoints ({num_keypoints}).')\n\n        losses = []\n        for idx in range(num_keypoints):\n            if self.use_target_weight:\n                target_weight = target_weights[:, idx, None, None]\n                losses.append(\n                    self.criterion(output[:, idx] * target_weight,\n                                   target[:, idx] * target_weight))\n            else:\n                losses.append(self.criterion(output[:, idx], target[:, idx]))\n\n        losses = [loss.mean(dim=(1, 2)).unsqueeze(dim=1) for loss in losses]\n        losses = torch.cat(losses, dim=1)\n\n        return self._ohkm(losses) * self.loss_weight\n\n\n@MODELS.register_module()\nclass AdaptiveWingLoss(nn.Module):\n    \"\"\"Adaptive wing loss. paper ref: 'Adaptive Wing Loss for Robust Face\n    Alignment via Heatmap Regression' Wang et al. ICCV'2019.\n\n    Args:\n        alpha (float), omega (float), epsilon (float), theta (float)\n            are hyper-parameters.\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 alpha=2.1,\n                 omega=14,\n                 epsilon=1,\n                 theta=0.5,\n                 use_target_weight=False,\n                 loss_weight=1.):\n        super().__init__()\n        self.alpha = float(alpha)\n        self.omega = float(omega)\n        self.epsilon = float(epsilon)\n        self.theta = float(theta)\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def criterion(self, pred, target):\n        \"\"\"Criterion of wingloss.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n\n        Args:\n            pred (torch.Tensor[NxKxHxW]): Predicted heatmaps.\n            target (torch.Tensor[NxKxHxW]): Target heatmaps.\n        \"\"\"\n        H, W = pred.shape[2:4]\n        delta = (target - pred).abs()\n\n        A = self.omega * (\n            1 / (1 + torch.pow(self.theta / self.epsilon, self.alpha - target))\n        ) * (self.alpha - target) * (torch.pow(\n            self.theta / self.epsilon,\n            self.alpha - target - 1)) * (1 / self.epsilon)\n        C = self.theta * A - self.omega * torch.log(\n            1 + torch.pow(self.theta / self.epsilon, self.alpha - target))\n\n        losses = torch.where(\n            delta < self.theta,\n            self.omega *\n            torch.log(1 +\n                      torch.pow(delta / self.epsilon, self.alpha - target)),\n            A * delta - C)\n\n        return torch.mean(losses)\n\n    def forward(self,\n                output: Tensor,\n                target: Tensor,\n                target_weights: Optional[Tensor] = None):\n        \"\"\"Forward function.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n\n        Args:\n            output (torch.Tensor[N, K, H, W]): Output heatmaps.\n            target (torch.Tensor[N, K, H, W]): Target heatmaps.\n            target_weight (torch.Tensor[N, K]):\n                Weights across different joint types.\n        \"\"\"\n        if self.use_target_weight:\n            assert (target_weights.ndim in (2, 4) and target_weights.shape\n                    == target.shape[:target_weights.ndim]), (\n                        'target_weights and target have mismatched shapes '\n                        f'{target_weights.shape} v.s. {target.shape}')\n\n            ndim_pad = target.ndim - target_weights.ndim\n            target_weights = target_weights.view(target_weights.shape +\n                                                 (1, ) * ndim_pad)\n            loss = self.criterion(output * target_weights,\n                                  target * target_weights)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass FocalHeatmapLoss(KeypointMSELoss):\n    \"\"\"A class for calculating the modified focal loss for heatmap prediction.\n\n    This loss function is exactly the same as the one used in CornerNet. It\n    runs faster and costs a little bit more memory.\n\n    `CornerNet: Detecting Objects as Paired Keypoints\n    arXiv: <https://arxiv.org/abs/1808.01244>`_.\n\n    Arguments:\n        alpha (int): The alpha parameter in the focal loss equation.\n        beta (int): The beta parameter in the focal loss equation.\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n            Defaults to ``False``\n        skip_empty_channel (bool): If ``True``, heatmap channels with no\n            non-zero value (which means no visible ground-truth keypoint\n            in the image) will not be used to calculate the loss. Defaults to\n            ``False``\n        loss_weight (float): Weight of the loss. Defaults to 1.0\n    \"\"\"\n\n    def __init__(self,\n                 alpha: int = 2,\n                 beta: int = 4,\n                 use_target_weight: bool = False,\n                 skip_empty_channel: bool = False,\n                 loss_weight: float = 1.0):\n        super(FocalHeatmapLoss, self).__init__(use_target_weight,\n                                               skip_empty_channel, loss_weight)\n        self.alpha = alpha\n        self.beta = beta\n\n    def forward(self,\n                output: Tensor,\n                target: Tensor,\n                target_weights: Optional[Tensor] = None,\n                mask: Optional[Tensor] = None) -> Tensor:\n        \"\"\"Calculate the modified focal loss for heatmap prediction.\n\n        Note:\n            - batch_size: B\n            - num_keypoints: K\n            - heatmaps height: H\n            - heatmaps weight: W\n\n        Args:\n            output (Tensor): The output heatmaps with shape [B, K, H, W]\n            target (Tensor): The target heatmaps with shape [B, K, H, W]\n            target_weights (Tensor, optional): The target weights of differet\n                keypoints, with shape [B, K] (keypoint-wise) or\n                [B, K, H, W] (pixel-wise).\n            mask (Tensor, optional): The masks of valid heatmap pixels in\n                shape [B, K, H, W] or [B, 1, H, W]. If ``None``, no mask will\n                be applied. Defaults to ``None``\n\n        Returns:\n            Tensor: The calculated loss.\n        \"\"\"\n        _mask = self._get_mask(target, target_weights, mask)\n\n        pos_inds = target.eq(1).float()\n        neg_inds = target.lt(1).float()\n\n        if _mask is not None:\n            pos_inds = pos_inds * _mask\n            neg_inds = neg_inds * _mask\n\n        neg_weights = torch.pow(1 - target, self.beta)\n\n        pos_loss = torch.log(output) * torch.pow(1 - output,\n                                                 self.alpha) * pos_inds\n        neg_loss = torch.log(1 - output) * torch.pow(\n            output, self.alpha) * neg_weights * neg_inds\n\n        num_pos = pos_inds.float().sum()\n        if num_pos == 0:\n            loss = -neg_loss.sum()\n        else:\n            loss = -(pos_loss.sum() + neg_loss.sum()) / num_pos\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass MLECCLoss(nn.Module):\n    \"\"\"Maximum Likelihood Estimation loss for Coordinate Classification.\n\n    This loss function is designed to work with coordinate classification\n    problems where the likelihood of each target coordinate is maximized.\n\n    Args:\n        reduction (str): Specifies the reduction to apply to the output:\n            'none' | 'mean' | 'sum'. Default: 'mean'.\n        mode (str): Specifies the mode of calculating loss:\n            'linear' | 'square' | 'log'. Default: 'log'.\n        use_target_weight (bool): If True, uses weighted loss. Different\n            joint types may have different target weights. Defaults to False.\n        loss_weight (float): Weight of the loss. Defaults to 1.0.\n\n    Raises:\n        AssertionError: If the `reduction` or `mode` arguments are not in the\n                        expected choices.\n        NotImplementedError: If the selected mode is not implemented.\n    \"\"\"\n\n    def __init__(self,\n                 reduction: str = 'mean',\n                 mode: str = 'log',\n                 use_target_weight: bool = False,\n                 loss_weight: float = 1.0):\n        super().__init__()\n        assert reduction in ('mean', 'sum', 'none'), \\\n            f\"`reduction` should be either 'mean', 'sum', or 'none', \" \\\n            f'but got {reduction}'\n        assert mode in ('linear', 'square', 'log'), \\\n            f\"`mode` should be either 'linear', 'square', or 'log', \" \\\n            f'but got {mode}'\n\n        self.reduction = reduction\n        self.mode = mode\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, outputs, targets, target_weight=None):\n        \"\"\"Forward pass for the MLECCLoss.\n\n        Args:\n            outputs (torch.Tensor): The predicted outputs.\n            targets (torch.Tensor): The ground truth targets.\n            target_weight (torch.Tensor, optional): Optional tensor of weights\n                for each target.\n\n        Returns:\n            torch.Tensor: Calculated loss based on the specified mode and\n                reduction.\n        \"\"\"\n\n        assert len(outputs) == len(targets), \\\n            'Outputs and targets must have the same length'\n\n        prob = 1.0\n        for o, t in zip(outputs, targets):\n            prob *= (o * t).sum(dim=-1)\n\n        if self.mode == 'linear':\n            loss = 1.0 - prob\n        elif self.mode == 'square':\n            loss = 1.0 - prob.pow(2)\n        elif self.mode == 'log':\n            loss = -torch.log(prob + 1e-4)\n\n        loss[torch.isnan(loss)] = 0.0\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            for i in range(loss.ndim - target_weight.ndim):\n                target_weight = target_weight.unsqueeze(-1)\n            loss = loss * target_weight\n\n        if self.reduction == 'sum':\n            loss = loss.flatten(1).sum(dim=1)\n        elif self.reduction == 'mean':\n            loss = loss.flatten(1).mean(dim=1)\n\n        return loss * self.loss_weight\n"
  },
  {
    "path": "mmpose/models/losses/logit_dis_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass KDLoss(nn.Module):\n    \"\"\"PyTorch version of logit-based distillation from DWPose Modified from\n    the official implementation.\n\n    <https://github.com/IDEA-Research/DWPose>\n    Args:\n        weight (float, optional): Weight of dis_loss. Defaults to 1.0\n    \"\"\"\n\n    def __init__(\n        self,\n        name,\n        use_this,\n        weight=1.0,\n    ):\n        super(KDLoss, self).__init__()\n\n        self.log_softmax = nn.LogSoftmax(dim=1)\n        self.kl_loss = nn.KLDivLoss(reduction='none')\n        self.weight = weight\n\n    def forward(self, pred, pred_t, beta, target_weight):\n        ls_x, ls_y = pred\n        lt_x, lt_y = pred_t\n\n        lt_x = lt_x.detach()\n        lt_y = lt_y.detach()\n\n        num_joints = ls_x.size(1)\n        loss = 0\n\n        loss += (self.loss(ls_x, lt_x, beta, target_weight))\n        loss += (self.loss(ls_y, lt_y, beta, target_weight))\n\n        return loss / num_joints\n\n    def loss(self, logit_s, logit_t, beta, weight):\n\n        N = logit_s.shape[0]\n\n        if len(logit_s.shape) == 3:\n            K = logit_s.shape[1]\n            logit_s = logit_s.reshape(N * K, -1)\n            logit_t = logit_t.reshape(N * K, -1)\n\n        # N*W(H)\n        s_i = self.log_softmax(logit_s * beta)\n        t_i = F.softmax(logit_t * beta, dim=1)\n\n        # kd\n        loss_all = torch.sum(self.kl_loss(s_i, t_i), dim=1)\n        loss_all = loss_all.reshape(N, K).sum(dim=1).mean()\n        loss_all = self.weight * loss_all\n\n        return loss_all\n"
  },
  {
    "path": "mmpose/models/losses/loss_wrappers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict\n\nimport torch.nn as nn\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import ConfigType\n\n\n@MODELS.register_module()\nclass MultipleLossWrapper(nn.Module):\n    \"\"\"A wrapper to collect multiple loss functions together and return a list\n    of losses in the same order.\n\n    Args:\n        losses (list): List of Loss Config\n    \"\"\"\n\n    def __init__(self, losses: list):\n        super().__init__()\n        self.num_losses = len(losses)\n\n        loss_modules = []\n        for loss_cfg in losses:\n            t_loss = MODELS.build(loss_cfg)\n            loss_modules.append(t_loss)\n        self.loss_modules = nn.ModuleList(loss_modules)\n\n    def forward(self, input_list, target_list, keypoint_weights=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            input_list (List[Tensor]): List of inputs.\n            target_list (List[Tensor]): List of targets.\n            keypoint_weights (Tensor[N, K, D]):\n                Weights across different joint types.\n        \"\"\"\n        assert isinstance(input_list, list), ''\n        assert isinstance(target_list, list), ''\n        assert len(input_list) == len(target_list), ''\n\n        losses = []\n        for i in range(self.num_losses):\n            input_i = input_list[i]\n            target_i = target_list[i]\n\n            loss_i = self.loss_modules[i](input_i, target_i, keypoint_weights)\n            losses.append(loss_i)\n\n        return losses\n\n\n@MODELS.register_module()\nclass CombinedLoss(nn.ModuleDict):\n    \"\"\"A wrapper to combine multiple loss functions. These loss functions can\n    have different input type (e.g. heatmaps or regression values), and can\n    only be involed individually and explixitly.\n\n    Args:\n        losses (Dict[str, ConfigType]): The names and configs of loss\n            functions to be wrapped\n\n    Example::\n        >>> heatmap_loss_cfg = dict(type='KeypointMSELoss')\n        >>> ae_loss_cfg = dict(type='AssociativeEmbeddingLoss')\n        >>> loss_module = CombinedLoss(\n        ...     losses=dict(\n        ...         heatmap_loss=heatmap_loss_cfg,\n        ...         ae_loss=ae_loss_cfg))\n        >>> loss_hm = loss_module.heatmap_loss(pred_heatmap, gt_heatmap)\n        >>> loss_ae = loss_module.ae_loss(pred_tags, keypoint_indices)\n    \"\"\"\n\n    def __init__(self, losses: Dict[str, ConfigType]):\n        super().__init__()\n        for loss_name, loss_cfg in losses.items():\n            self.add_module(loss_name, MODELS.build(loss_cfg))\n"
  },
  {
    "path": "mmpose/models/losses/regression_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom functools import partial\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.registry import MODELS\nfrom ..utils.realnvp import RealNVP\n\n\n@MODELS.register_module()\nclass RLELoss(nn.Module):\n    \"\"\"RLE Loss.\n\n    `Human Pose Regression With Residual Log-Likelihood Estimation\n    arXiv: <https://arxiv.org/abs/2107.11291>`_.\n\n    Code is modified from `the official implementation\n    <https://github.com/Jeff-sjtu/res-loglikelihood-regression>`_.\n\n    Args:\n        use_target_weight (bool): Option to use weighted loss.\n            Different joint types may have different target weights.\n        size_average (bool): Option to average the loss by the batch_size.\n        residual (bool): Option to add L1 loss and let the flow\n            learn the residual error distribution.\n        q_dis (string): Option for the identity Q(error) distribution,\n            Options: \"laplace\" or \"gaussian\"\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight=False,\n                 size_average=True,\n                 residual=True,\n                 q_distribution='laplace'):\n        super(RLELoss, self).__init__()\n        self.size_average = size_average\n        self.use_target_weight = use_target_weight\n        self.residual = residual\n        self.q_distribution = q_distribution\n\n        self.flow_model = RealNVP()\n\n    def forward(self, pred, sigma, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            pred (Tensor[N, K, D]): Output regression.\n            sigma (Tensor[N, K, D]): Output sigma.\n            target (Tensor[N, K, D]): Target regression.\n            target_weight (Tensor[N, K, D]):\n                Weights across different joint types.\n        \"\"\"\n        sigma = sigma.sigmoid()\n\n        error = (pred - target) / (sigma + 1e-9)\n        # (B, K, 2)\n        log_phi = self.flow_model.log_prob(error.reshape(-1, 2))\n        log_phi = log_phi.reshape(target.shape[0], target.shape[1], 1)\n        log_sigma = torch.log(sigma).reshape(target.shape[0], target.shape[1],\n                                             2)\n        nf_loss = log_sigma - log_phi\n\n        if self.residual:\n            assert self.q_distribution in ['laplace', 'gaussian']\n            if self.q_distribution == 'laplace':\n                loss_q = torch.log(sigma * 2) + torch.abs(error)\n            else:\n                loss_q = torch.log(\n                    sigma * math.sqrt(2 * math.pi)) + 0.5 * error**2\n\n            loss = nf_loss + loss_q\n        else:\n            loss = nf_loss\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss *= target_weight\n\n        if self.size_average:\n            loss /= len(loss)\n\n        return loss.sum()\n\n\n@MODELS.register_module()\nclass SmoothL1Loss(nn.Module):\n    \"\"\"SmoothL1Loss loss.\n\n    Args:\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self, use_target_weight=False, loss_weight=1.):\n        super().__init__()\n        self.criterion = F.smooth_l1_loss\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N, K, D]):\n                Weights across different joint types.\n        \"\"\"\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            assert output.ndim >= target_weight.ndim\n\n            for i in range(output.ndim - target_weight.ndim):\n                target_weight = target_weight.unsqueeze(-1)\n\n            loss = self.criterion(output * target_weight,\n                                  target * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass SoftWeightSmoothL1Loss(nn.Module):\n    \"\"\"Smooth L1 loss with soft weight for regression.\n\n    Args:\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n        supervise_empty (bool): Whether to supervise the output with zero\n            weight.\n        beta (float):  Specifies the threshold at which to change between\n            L1 and L2 loss.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight=False,\n                 supervise_empty=True,\n                 beta=1.0,\n                 loss_weight=1.):\n        super().__init__()\n\n        reduction = 'none' if use_target_weight else 'mean'\n        self.criterion = partial(\n            self.smooth_l1_loss, reduction=reduction, beta=beta)\n\n        self.supervise_empty = supervise_empty\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    @staticmethod\n    def smooth_l1_loss(input, target, reduction='none', beta=1.0):\n        \"\"\"Re-implement torch.nn.functional.smooth_l1_loss with beta to support\n        pytorch <= 1.6.\"\"\"\n        delta = input - target\n        mask = delta.abs() < beta\n        delta[mask] = (delta[mask]).pow(2) / (2 * beta)\n        delta[~mask] = delta[~mask].abs() - beta / 2\n\n        if reduction == 'mean':\n            return delta.mean()\n        elif reduction == 'sum':\n            return delta.sum()\n        elif reduction == 'none':\n            return delta\n        else:\n            raise ValueError(f'reduction must be \\'mean\\', \\'sum\\' or '\n                             f'\\'none\\', but got \\'{reduction}\\'')\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N, K, D]):\n                Weights across different joint types.\n        \"\"\"\n        if self.use_target_weight:\n            assert target_weight is not None\n            assert output.ndim >= target_weight.ndim\n\n            for i in range(output.ndim - target_weight.ndim):\n                target_weight = target_weight.unsqueeze(-1)\n\n            loss = self.criterion(output, target) * target_weight\n            if self.supervise_empty:\n                loss = loss.mean()\n            else:\n                num_elements = torch.nonzero(target_weight > 0).size()[0]\n                loss = loss.sum() / max(num_elements, 1.0)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass WingLoss(nn.Module):\n    \"\"\"Wing Loss. paper ref: 'Wing Loss for Robust Facial Landmark Localisation\n    with Convolutional Neural Networks' Feng et al. CVPR'2018.\n\n    Args:\n        omega (float): Also referred to as width.\n        epsilon (float): Also referred to as curvature.\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 omega=10.0,\n                 epsilon=2.0,\n                 use_target_weight=False,\n                 loss_weight=1.):\n        super().__init__()\n        self.omega = omega\n        self.epsilon = epsilon\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n        # constant that smoothly links the piecewise-defined linear\n        # and nonlinear parts\n        self.C = self.omega * (1.0 - math.log(1.0 + self.omega / self.epsilon))\n\n    def criterion(self, pred, target):\n        \"\"\"Criterion of wingloss.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            pred (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n        \"\"\"\n        delta = (target - pred).abs()\n        losses = torch.where(\n            delta < self.omega,\n            self.omega * torch.log(1.0 + delta / self.epsilon), delta - self.C)\n        return torch.mean(torch.sum(losses, dim=[1, 2]), dim=0)\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N,K,D]):\n                Weights across different joint types.\n        \"\"\"\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss = self.criterion(output * target_weight,\n                                  target * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass SoftWingLoss(nn.Module):\n    \"\"\"Soft Wing Loss 'Structure-Coherent Deep Feature Learning for Robust Face\n    Alignment' Lin et al. TIP'2021.\n\n    loss =\n        1. |x|                           , if |x| < omega1\n        2. omega2*ln(1+|x|/epsilon) + B, if |x| >= omega1\n\n    Args:\n        omega1 (float): The first threshold.\n        omega2 (float): The second threshold.\n        epsilon (float): Also referred to as curvature.\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 omega1=2.0,\n                 omega2=20.0,\n                 epsilon=0.5,\n                 use_target_weight=False,\n                 loss_weight=1.):\n        super().__init__()\n        self.omega1 = omega1\n        self.omega2 = omega2\n        self.epsilon = epsilon\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n        # constant that smoothly links the piecewise-defined linear\n        # and nonlinear parts\n        self.B = self.omega1 - self.omega2 * math.log(1.0 + self.omega1 /\n                                                      self.epsilon)\n\n    def criterion(self, pred, target):\n        \"\"\"Criterion of wingloss.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n            dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            pred (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n        \"\"\"\n        delta = (target - pred).abs()\n        losses = torch.where(\n            delta < self.omega1, delta,\n            self.omega2 * torch.log(1.0 + delta / self.epsilon) + self.B)\n        return torch.mean(torch.sum(losses, dim=[1, 2]), dim=0)\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n            dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N, K, D]):\n                Weights across different joint types.\n        \"\"\"\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss = self.criterion(output * target_weight,\n                                  target * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass MPJPEVelocityJointLoss(nn.Module):\n    \"\"\"MPJPE (Mean Per Joint Position Error) loss.\n\n    Args:\n        loss_weight (float): Weight of the loss. Default: 1.0.\n        lambda_scale (float): Factor of the N-MPJPE loss. Default: 0.5.\n        lambda_3d_velocity (float): Factor of the velocity loss. Default: 20.0.\n    \"\"\"\n\n    def __init__(self,\n                 use_target_weight=False,\n                 loss_weight=1.,\n                 lambda_scale=0.5,\n                 lambda_3d_velocity=20.0):\n        super().__init__()\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n        self.lambda_scale = lambda_scale\n        self.lambda_3d_velocity = lambda_3d_velocity\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N,K,D]):\n                Weights across different joint types.\n        \"\"\"\n        norm_output = torch.mean(\n            torch.sum(torch.square(output), dim=-1, keepdim=True),\n            dim=-2,\n            keepdim=True)\n        norm_target = torch.mean(\n            torch.sum(target * output, dim=-1, keepdim=True),\n            dim=-2,\n            keepdim=True)\n\n        velocity_output = output[..., 1:, :, :] - output[..., :-1, :, :]\n        velocity_target = target[..., 1:, :, :] - target[..., :-1, :, :]\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            mpjpe = torch.mean(\n                torch.norm((output - target) * target_weight, dim=-1))\n\n            nmpjpe = torch.mean(\n                torch.norm(\n                    (norm_target / norm_output * output - target) *\n                    target_weight,\n                    dim=-1))\n\n            loss_3d_velocity = torch.mean(\n                torch.norm(\n                    (velocity_output - velocity_target) * target_weight,\n                    dim=-1))\n        else:\n            mpjpe = torch.mean(torch.norm(output - target, dim=-1))\n\n            nmpjpe = torch.mean(\n                torch.norm(\n                    norm_target / norm_output * output - target, dim=-1))\n\n            loss_3d_velocity = torch.mean(\n                torch.norm(velocity_output - velocity_target, dim=-1))\n\n        loss = mpjpe + nmpjpe * self.lambda_scale + \\\n            loss_3d_velocity * self.lambda_3d_velocity\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass MPJPELoss(nn.Module):\n    \"\"\"MPJPE (Mean Per Joint Position Error) loss.\n\n    Args:\n        use_target_weight (bool): Option to use weighted MSE loss.\n            Different joint types may have different target weights.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self, use_target_weight=False, loss_weight=1.):\n        super().__init__()\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N,K,D]):\n                Weights across different joint types.\n        \"\"\"\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss = torch.mean(\n                torch.norm((output - target) * target_weight, dim=-1))\n        else:\n            loss = torch.mean(torch.norm(output - target, dim=-1))\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass L1Loss(nn.Module):\n    \"\"\"L1Loss loss.\"\"\"\n\n    def __init__(self,\n                 reduction='mean',\n                 use_target_weight=False,\n                 loss_weight=1.):\n        super().__init__()\n\n        assert reduction in ('mean', 'sum', 'none'), f'the argument ' \\\n            f'`reduction` should be either \\'mean\\', \\'sum\\' or \\'none\\', ' \\\n            f'but got {reduction}'\n\n        self.criterion = partial(F.l1_loss, reduction=reduction)\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n\n        Args:\n            output (torch.Tensor[N, K, 2]): Output regression.\n            target (torch.Tensor[N, K, 2]): Target regression.\n            target_weight (torch.Tensor[N, K, 2]):\n                Weights across different joint types.\n        \"\"\"\n        if self.use_target_weight:\n            assert target_weight is not None\n            for _ in range(target.ndim - target_weight.ndim):\n                target_weight = target_weight.unsqueeze(-1)\n            loss = self.criterion(output * target_weight,\n                                  target * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass MSELoss(nn.Module):\n    \"\"\"MSE loss for coordinate regression.\"\"\"\n\n    def __init__(self, use_target_weight=False, loss_weight=1.):\n        super().__init__()\n        self.criterion = F.mse_loss\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n\n        Args:\n            output (torch.Tensor[N, K, 2]): Output regression.\n            target (torch.Tensor[N, K, 2]): Target regression.\n            target_weight (torch.Tensor[N, K, 2]):\n                Weights across different joint types.\n        \"\"\"\n\n        if self.use_target_weight:\n            assert target_weight is not None\n            loss = self.criterion(output * target_weight,\n                                  target * target_weight)\n        else:\n            loss = self.criterion(output, target)\n\n        return loss * self.loss_weight\n\n\n@MODELS.register_module()\nclass BoneLoss(nn.Module):\n    \"\"\"Bone length loss.\n\n    Args:\n        joint_parents (list): Indices of each joint's parent joint.\n        use_target_weight (bool): Option to use weighted bone loss.\n            Different bone types may have different target weights.\n        loss_weight (float): Weight of the loss. Default: 1.0.\n    \"\"\"\n\n    def __init__(self,\n                 joint_parents,\n                 use_target_weight: bool = False,\n                 loss_weight: float = 1.,\n                 loss_name: str = 'loss_bone'):\n        super().__init__()\n        self.joint_parents = joint_parents\n        self.use_target_weight = use_target_weight\n        self.loss_weight = loss_weight\n\n        self.non_root_indices = []\n        for i in range(len(self.joint_parents)):\n            if i != self.joint_parents[i]:\n                self.non_root_indices.append(i)\n\n        self._loss_name = loss_name\n\n    def forward(self, output, target, target_weight=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_keypoints: K\n            - dimension of keypoints: D (D=2 or D=3)\n\n        Args:\n            output (torch.Tensor[N, K, D]): Output regression.\n            target (torch.Tensor[N, K, D]): Target regression.\n            target_weight (torch.Tensor[N, K-1]):\n                Weights across different bone types.\n        \"\"\"\n        output_bone = torch.norm(\n            output - output[:, self.joint_parents, :],\n            dim=-1)[:, self.non_root_indices]\n        target_bone = torch.norm(\n            target - target[:, self.joint_parents, :],\n            dim=-1)[:, self.non_root_indices]\n        if self.use_target_weight:\n            assert target_weight is not None\n            target_weight = target_weight[:, self.non_root_indices]\n            loss = torch.mean(\n                torch.abs((output_bone * target_weight).mean(dim=0) -\n                          (target_bone * target_weight).mean(dim=0)))\n        else:\n            loss = torch.mean(\n                torch.abs(output_bone.mean(dim=0) - target_bone.mean(dim=0)))\n\n        return loss * self.loss_weight\n\n    @property\n    def loss_name(self):\n        \"\"\"Loss Name.\n\n        Returns:\n            str: The name of this loss item.\n        \"\"\"\n        return self._loss_name\n\n\n@MODELS.register_module()\nclass SemiSupervisionLoss(nn.Module):\n    \"\"\"Semi-supervision loss for unlabeled data. It is composed of projection\n    loss and bone loss.\n\n    Paper ref: `3D human pose estimation in video with temporal convolutions\n    and semi-supervised training` Dario Pavllo et al. CVPR'2019.\n\n    Args:\n        joint_parents (list): Indices of each joint's parent joint.\n        projection_loss_weight (float): Weight for projection loss.\n        bone_loss_weight (float): Weight for bone loss.\n        warmup_iterations (int): Number of warmup iterations. In the first\n            `warmup_iterations` iterations, the model is trained only on\n            labeled data, and semi-supervision loss will be 0.\n            This is a workaround since currently we cannot access\n            epoch number in loss functions. Note that the iteration number in\n            an epoch can be changed due to different GPU numbers in multi-GPU\n            settings. So please set this parameter carefully.\n            warmup_iterations = dataset_size // samples_per_gpu // gpu_num\n            * warmup_epochs\n    \"\"\"\n\n    def __init__(self,\n                 joint_parents,\n                 projection_loss_weight=1.,\n                 bone_loss_weight=1.,\n                 warmup_iterations=0):\n        super().__init__()\n        self.criterion_projection = MPJPELoss(\n            loss_weight=projection_loss_weight)\n        self.criterion_bone = BoneLoss(\n            joint_parents, loss_weight=bone_loss_weight)\n        self.warmup_iterations = warmup_iterations\n        self.num_iterations = 0\n\n    @staticmethod\n    def project_joints(x, intrinsics):\n        \"\"\"Project 3D joint coordinates to 2D image plane using camera\n        intrinsic parameters.\n\n        Args:\n            x (torch.Tensor[N, K, 3]): 3D joint coordinates.\n            intrinsics (torch.Tensor[N, 4] | torch.Tensor[N, 9]): Camera\n                intrinsics: f (2), c (2), k (3), p (2).\n        \"\"\"\n        while intrinsics.dim() < x.dim():\n            intrinsics.unsqueeze_(1)\n        f = intrinsics[..., :2]\n        c = intrinsics[..., 2:4]\n        _x = torch.clamp(x[:, :, :2] / x[:, :, 2:], -1, 1)\n        if intrinsics.shape[-1] == 9:\n            k = intrinsics[..., 4:7]\n            p = intrinsics[..., 7:9]\n\n            r2 = torch.sum(_x[:, :, :2]**2, dim=-1, keepdim=True)\n            radial = 1 + torch.sum(\n                k * torch.cat((r2, r2**2, r2**3), dim=-1),\n                dim=-1,\n                keepdim=True)\n            tan = torch.sum(p * _x, dim=-1, keepdim=True)\n            _x = _x * (radial + tan) + p * r2\n        _x = f * _x + c\n        return _x\n\n    def forward(self, output, target):\n        losses = dict()\n\n        self.num_iterations += 1\n        if self.num_iterations <= self.warmup_iterations:\n            return losses\n\n        labeled_pose = output['labeled_pose']\n        unlabeled_pose = output['unlabeled_pose']\n        unlabeled_traj = output['unlabeled_traj']\n        unlabeled_target_2d = target['unlabeled_target_2d']\n        intrinsics = target['intrinsics']\n\n        # projection loss\n        unlabeled_output = unlabeled_pose + unlabeled_traj\n        unlabeled_output_2d = self.project_joints(unlabeled_output, intrinsics)\n        loss_proj = self.criterion_projection(unlabeled_output_2d,\n                                              unlabeled_target_2d, None)\n        losses['proj_loss'] = loss_proj\n\n        # bone loss\n        loss_bone = self.criterion_bone(unlabeled_pose, labeled_pose, None)\n        losses['bone_loss'] = loss_bone\n\n        return losses\n\n\n@MODELS.register_module()\nclass OKSLoss(nn.Module):\n    \"\"\"A PyTorch implementation of the Object Keypoint Similarity (OKS) loss as\n    described in the paper \"YOLO-Pose: Enhancing YOLO for Multi Person Pose\n    Estimation Using Object Keypoint Similarity Loss\" by Debapriya et al.\n    (2022).\n\n    The OKS loss is used for keypoint-based object recognition and consists\n    of a measure of the similarity between predicted and ground truth\n    keypoint locations, adjusted by the size of the object in the image.\n\n    The loss function takes as input the predicted keypoint locations, the\n    ground truth keypoint locations, a mask indicating which keypoints are\n    valid, and bounding boxes for the objects.\n\n    Args:\n        metainfo (Optional[str]): Path to a JSON file containing information\n            about the dataset's annotations.\n        reduction (str): Options are \"none\", \"mean\" and \"sum\".\n        eps (float): Epsilon to avoid log(0).\n        loss_weight (float): Weight of the loss. Default: 1.0.\n        mode (str): Loss scaling mode, including \"linear\", \"square\", and \"log\".\n            Default: 'linear'\n        norm_target_weight (bool): whether to normalize the target weight\n            with number of visible keypoints. Defaults to False.\n    \"\"\"\n\n    def __init__(self,\n                 metainfo: Optional[str] = None,\n                 reduction='mean',\n                 mode='linear',\n                 eps=1e-8,\n                 norm_target_weight=False,\n                 loss_weight=1.):\n        super().__init__()\n\n        assert reduction in ('mean', 'sum', 'none'), f'the argument ' \\\n            f'`reduction` should be either \\'mean\\', \\'sum\\' or \\'none\\', ' \\\n            f'but got {reduction}'\n\n        assert mode in ('linear', 'square', 'log'), f'the argument ' \\\n            f'`reduction` should be either \\'linear\\', \\'square\\' or ' \\\n            f'\\'log\\', but got {mode}'\n\n        self.reduction = reduction\n        self.loss_weight = loss_weight\n        self.mode = mode\n        self.norm_target_weight = norm_target_weight\n        self.eps = eps\n\n        if metainfo is not None:\n            metainfo = parse_pose_metainfo(dict(from_file=metainfo))\n            sigmas = metainfo.get('sigmas', None)\n            if sigmas is not None:\n                self.register_buffer('sigmas', torch.as_tensor(sigmas))\n\n    def forward(self, output, target, target_weight=None, areas=None):\n        \"\"\"Forward function.\n\n        Note:\n            - batch_size: N\n            - num_labels: K\n\n        Args:\n            output (torch.Tensor[N, K, 2]): Output keypoints coordinates.\n            target (torch.Tensor[N, K, 2]): Target keypoints coordinates..\n            target_weight (torch.Tensor[N, K]): Loss weight for each keypoint.\n            areas (torch.Tensor[N]): Instance size which is adopted as\n                normalization factor.\n        \"\"\"\n        dist = torch.norm(output - target, dim=-1)\n        if areas is not None:\n            dist = dist / areas.pow(0.5).clip(min=self.eps).unsqueeze(-1)\n        if hasattr(self, 'sigmas'):\n            sigmas = self.sigmas.reshape(*((1, ) * (dist.ndim - 1)), -1)\n            dist = dist / (sigmas * 2)\n\n        oks = torch.exp(-dist.pow(2) / 2)\n\n        if target_weight is not None:\n            if self.norm_target_weight:\n                target_weight = target_weight / target_weight.sum(\n                    dim=-1, keepdims=True).clip(min=self.eps)\n            else:\n                target_weight = target_weight / target_weight.size(-1)\n            oks = oks * target_weight\n        oks = oks.sum(dim=-1)\n\n        if self.mode == 'linear':\n            loss = 1 - oks\n        elif self.mode == 'square':\n            loss = 1 - oks.pow(2)\n        elif self.mode == 'log':\n            loss = -oks.log()\n        else:\n            raise NotImplementedError()\n\n        if self.reduction == 'sum':\n            loss = loss.sum()\n        elif self.reduction == 'mean':\n            loss = loss.mean()\n\n        return loss * self.loss_weight\n"
  },
  {
    "path": "mmpose/models/necks/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .channel_mapper import ChannelMapper\nfrom .cspnext_pafpn import CSPNeXtPAFPN\nfrom .fmap_proc_neck import FeatureMapProcessor\nfrom .fpn import FPN\nfrom .gap_neck import GlobalAveragePooling\nfrom .hybrid_encoder import HybridEncoder\nfrom .posewarper_neck import PoseWarperNeck\nfrom .yolox_pafpn import YOLOXPAFPN\n\n__all__ = [\n    'GlobalAveragePooling', 'PoseWarperNeck', 'FPN', 'FeatureMapProcessor',\n    'ChannelMapper', 'YOLOXPAFPN', 'CSPNeXtPAFPN', 'HybridEncoder'\n]\n"
  },
  {
    "path": "mmpose/models/necks/channel_mapper.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple, Union\n\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import OptConfigType, OptMultiConfig\n\n\n@MODELS.register_module()\nclass ChannelMapper(BaseModule):\n    \"\"\"Channel Mapper to reduce/increase channels of backbone features.\n\n    This is used to reduce/increase channels of backbone features.\n\n    Args:\n        in_channels (List[int]): Number of input channels per scale.\n        out_channels (int): Number of output channels (used at each scale).\n        kernel_size (int, optional): kernel_size for reducing channels (used\n            at each scale). Default: 3.\n        conv_cfg (:obj:`ConfigDict` or dict, optional): Config dict for\n            convolution layer. Default: None.\n        norm_cfg (:obj:`ConfigDict` or dict, optional): Config dict for\n            normalization layer. Default: None.\n        act_cfg (:obj:`ConfigDict` or dict, optional): Config dict for\n            activation layer in ConvModule. Default: dict(type='ReLU').\n        num_outs (int, optional): Number of output feature maps. There would\n            be extra_convs when num_outs larger than the length of in_channels.\n        init_cfg (:obj:`ConfigDict` or dict or list[:obj:`ConfigDict` or dict],\n            optional): Initialization config dict.\n    Example:\n        >>> import torch\n        >>> in_channels = [2, 3, 5, 7]\n        >>> scales = [340, 170, 84, 43]\n        >>> inputs = [torch.rand(1, c, s, s)\n        ...           for c, s in zip(in_channels, scales)]\n        >>> self = ChannelMapper(in_channels, 11, 3).eval()\n        >>> outputs = self.forward(inputs)\n        >>> for i in range(len(outputs)):\n        ...     print(f'outputs[{i}].shape = {outputs[i].shape}')\n        outputs[0].shape = torch.Size([1, 11, 340, 340])\n        outputs[1].shape = torch.Size([1, 11, 170, 170])\n        outputs[2].shape = torch.Size([1, 11, 84, 84])\n        outputs[3].shape = torch.Size([1, 11, 43, 43])\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: List[int],\n        out_channels: int,\n        kernel_size: int = 3,\n        conv_cfg: OptConfigType = None,\n        norm_cfg: OptConfigType = None,\n        act_cfg: OptConfigType = dict(type='ReLU'),\n        num_outs: int = None,\n        bias: Union[bool, str] = 'auto',\n        init_cfg: OptMultiConfig = dict(\n            type='Xavier', layer='Conv2d', distribution='uniform')\n    ) -> None:\n        super().__init__(init_cfg=init_cfg)\n        assert isinstance(in_channels, list)\n        self.extra_convs = None\n        if num_outs is None:\n            num_outs = len(in_channels)\n        self.convs = nn.ModuleList()\n        for in_channel in in_channels:\n            self.convs.append(\n                ConvModule(\n                    in_channel,\n                    out_channels,\n                    kernel_size,\n                    bias=bias,\n                    padding=(kernel_size - 1) // 2,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n        if num_outs > len(in_channels):\n            self.extra_convs = nn.ModuleList()\n            for i in range(len(in_channels), num_outs):\n                if i == len(in_channels):\n                    in_channel = in_channels[-1]\n                else:\n                    in_channel = out_channels\n                self.extra_convs.append(\n                    ConvModule(\n                        in_channel,\n                        out_channels,\n                        3,\n                        stride=2,\n                        padding=1,\n                        bias=bias,\n                        conv_cfg=conv_cfg,\n                        norm_cfg=norm_cfg,\n                        act_cfg=act_cfg))\n\n    def forward(self, inputs: Tuple[Tensor]) -> Tuple[Tensor]:\n        \"\"\"Forward function.\"\"\"\n        assert len(inputs) == len(self.convs)\n        outs = [self.convs[i](inputs[i]) for i in range(len(inputs))]\n        if self.extra_convs:\n            for i in range(len(self.extra_convs)):\n                if i == 0:\n                    outs.append(self.extra_convs[0](inputs[-1]))\n                else:\n                    outs.append(self.extra_convs[i](outs[-1]))\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/necks/cspnext_pafpn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Sequence, Tuple\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, DepthwiseSeparableConvModule\nfrom mmengine.model import BaseModule\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import ConfigType, OptMultiConfig\nfrom ..utils import CSPLayer\n\n\n@MODELS.register_module()\nclass CSPNeXtPAFPN(BaseModule):\n    \"\"\"Path Aggregation Network with CSPNeXt blocks. Modified from RTMDet.\n\n    Args:\n        in_channels (Sequence[int]): Number of input channels per scale.\n        out_channels (int): Number of output channels (used at each scale)\n        out_indices (Sequence[int]): Output from which stages.\n        num_csp_blocks (int): Number of bottlenecks in CSPLayer.\n            Defaults to 3.\n        use_depthwise (bool): Whether to use depthwise separable convolution in\n            blocks. Defaults to False.\n        expand_ratio (float): Ratio to adjust the number of channels of the\n            hidden layer. Default: 0.5\n        upsample_cfg (dict): Config dict for interpolate layer.\n            Default: `dict(scale_factor=2, mode='nearest')`\n        conv_cfg (dict, optional): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN')\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='Swish')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: Sequence[int],\n        out_channels: int,\n        out_indices=(\n            0,\n            1,\n            2,\n        ),\n        num_csp_blocks: int = 3,\n        use_depthwise: bool = False,\n        expand_ratio: float = 0.5,\n        upsample_cfg: ConfigType = dict(scale_factor=2, mode='nearest'),\n        conv_cfg: bool = None,\n        norm_cfg: ConfigType = dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg: ConfigType = dict(type='Swish'),\n        init_cfg: OptMultiConfig = dict(\n            type='Kaiming',\n            layer='Conv2d',\n            a=math.sqrt(5),\n            distribution='uniform',\n            mode='fan_in',\n            nonlinearity='leaky_relu')\n    ) -> None:\n        super().__init__(init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.out_indices = out_indices\n\n        conv = DepthwiseSeparableConvModule if use_depthwise else ConvModule\n\n        # build top-down blocks\n        self.upsample = nn.Upsample(**upsample_cfg)\n        self.reduce_layers = nn.ModuleList()\n        self.top_down_blocks = nn.ModuleList()\n        for idx in range(len(in_channels) - 1, 0, -1):\n            self.reduce_layers.append(\n                ConvModule(\n                    in_channels[idx],\n                    in_channels[idx - 1],\n                    1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n            self.top_down_blocks.append(\n                CSPLayer(\n                    in_channels[idx - 1] * 2,\n                    in_channels[idx - 1],\n                    num_blocks=num_csp_blocks,\n                    add_identity=False,\n                    use_depthwise=use_depthwise,\n                    use_cspnext_block=True,\n                    expand_ratio=expand_ratio,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n\n        # build bottom-up blocks\n        self.downsamples = nn.ModuleList()\n        self.bottom_up_blocks = nn.ModuleList()\n        for idx in range(len(in_channels) - 1):\n            self.downsamples.append(\n                conv(\n                    in_channels[idx],\n                    in_channels[idx],\n                    3,\n                    stride=2,\n                    padding=1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n            self.bottom_up_blocks.append(\n                CSPLayer(\n                    in_channels[idx] * 2,\n                    in_channels[idx + 1],\n                    num_blocks=num_csp_blocks,\n                    add_identity=False,\n                    use_depthwise=use_depthwise,\n                    use_cspnext_block=True,\n                    expand_ratio=expand_ratio,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n\n        if self.out_channels is not None:\n            self.out_convs = nn.ModuleList()\n            for i in range(len(in_channels)):\n                self.out_convs.append(\n                    conv(\n                        in_channels[i],\n                        out_channels,\n                        3,\n                        padding=1,\n                        conv_cfg=conv_cfg,\n                        norm_cfg=norm_cfg,\n                        act_cfg=act_cfg))\n            self.out_convs = conv(\n                in_channels[-1],\n                out_channels,\n                3,\n                padding=1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n\n    def forward(self, inputs: Tuple[Tensor, ...]) -> Tuple[Tensor, ...]:\n        \"\"\"\n        Args:\n            inputs (tuple[Tensor]): input features.\n\n        Returns:\n            tuple[Tensor]: YOLOXPAFPN features.\n        \"\"\"\n        assert len(inputs) == len(self.in_channels)\n\n        # top-down path\n        inner_outs = [inputs[-1]]\n        for idx in range(len(self.in_channels) - 1, 0, -1):\n            feat_high = inner_outs[0]\n            feat_low = inputs[idx - 1]\n            feat_high = self.reduce_layers[len(self.in_channels) - 1 - idx](\n                feat_high)\n            inner_outs[0] = feat_high\n\n            upsample_feat = self.upsample(feat_high)\n\n            inner_out = self.top_down_blocks[len(self.in_channels) - 1 - idx](\n                torch.cat([upsample_feat, feat_low], 1))\n            inner_outs.insert(0, inner_out)\n\n        # bottom-up path\n        outs = [inner_outs[0]]\n        for idx in range(len(self.in_channels) - 1):\n            feat_low = outs[-1]\n            feat_high = inner_outs[idx + 1]\n            downsample_feat = self.downsamples[idx](feat_low)\n            out = self.bottom_up_blocks[idx](\n                torch.cat([downsample_feat, feat_high], 1))\n            outs.append(out)\n\n        if self.out_channels is not None:\n            # out convs\n            for idx, conv in enumerate(self.out_convs):\n                outs[idx] = conv(outs[idx])\n\n        return tuple([outs[i] for i in self.out_indices])\n"
  },
  {
    "path": "mmpose/models/necks/fmap_proc_neck.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Sequence, Tuple, Union\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom torch import Tensor\n\nfrom mmpose.models.utils.ops import resize\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass FeatureMapProcessor(nn.Module):\n    \"\"\"A PyTorch module for selecting, concatenating, and rescaling feature\n    maps.\n\n    Args:\n        select_index (Optional[Union[int, Tuple[int]]], optional): Index or\n            indices of feature maps to select. Defaults to None, which means\n            all feature maps are used.\n        concat (bool, optional): Whether to concatenate the selected feature\n            maps. Defaults to False.\n        scale_factor (float, optional): The scaling factor to apply to the\n            feature maps. Defaults to 1.0.\n        apply_relu (bool, optional): Whether to apply ReLU on input feature\n            maps. Defaults to False.\n        align_corners (bool, optional): Whether to align corners when resizing\n            the feature maps. Defaults to False.\n    \"\"\"\n\n    def __init__(\n        self,\n        select_index: Optional[Union[int, Tuple[int]]] = None,\n        concat: bool = False,\n        scale_factor: float = 1.0,\n        apply_relu: bool = False,\n        align_corners: bool = False,\n    ):\n        super().__init__()\n\n        if isinstance(select_index, int):\n            select_index = (select_index, )\n        self.select_index = select_index\n        self.concat = concat\n\n        assert (\n            scale_factor > 0\n        ), f'the argument `scale_factor` must be positive, ' \\\n           f'but got {scale_factor}'\n        self.scale_factor = scale_factor\n        self.apply_relu = apply_relu\n        self.align_corners = align_corners\n\n    def forward(self, inputs: Union[Tensor, Sequence[Tensor]]\n                ) -> Union[Tensor, List[Tensor]]:\n\n        if not isinstance(inputs, (tuple, list)):\n            sequential_input = False\n            inputs = [inputs]\n        else:\n            sequential_input = True\n\n            if self.select_index is not None:\n                inputs = [inputs[i] for i in self.select_index]\n\n            if self.concat:\n                inputs = self._concat(inputs)\n\n        if self.apply_relu:\n            inputs = [F.relu(x) for x in inputs]\n\n        if self.scale_factor != 1.0:\n            inputs = self._rescale(inputs)\n\n        if not sequential_input:\n            inputs = inputs[0]\n\n        return inputs\n\n    def _concat(self, inputs: Sequence[Tensor]) -> List[Tensor]:\n        size = inputs[0].shape[-2:]\n        resized_inputs = [\n            resize(\n                x,\n                size=size,\n                mode='bilinear',\n                align_corners=self.align_corners) for x in inputs\n        ]\n        return [torch.cat(resized_inputs, dim=1)]\n\n    def _rescale(self, inputs: Sequence[Tensor]) -> List[Tensor]:\n        rescaled_inputs = [\n            resize(\n                x,\n                scale_factor=self.scale_factor,\n                mode='bilinear',\n                align_corners=self.align_corners,\n            ) for x in inputs\n        ]\n        return rescaled_inputs\n"
  },
  {
    "path": "mmpose/models/necks/fpn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import xavier_init\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass FPN(nn.Module):\n    r\"\"\"Feature Pyramid Network.\n\n    This is an implementation of paper `Feature Pyramid Networks for Object\n    Detection <https://arxiv.org/abs/1612.03144>`_.\n\n    Args:\n        in_channels (list[int]): Number of input channels per scale.\n        out_channels (int): Number of output channels (used at each scale).\n        num_outs (int): Number of output scales.\n        start_level (int): Index of the start input backbone level used to\n            build the feature pyramid. Default: 0.\n        end_level (int): Index of the end input backbone level (exclusive) to\n            build the feature pyramid. Default: -1, which means the last level.\n        add_extra_convs (bool | str): If bool, it decides whether to add conv\n            layers on top of the original feature maps. Default to False.\n            If True, it is equivalent to `add_extra_convs='on_input'`.\n            If str, it specifies the source feature map of the extra convs.\n            Only the following options are allowed\n\n            - 'on_input': Last feat map of neck inputs (i.e. backbone feature).\n            - 'on_lateral': Last feature map after lateral convs.\n            - 'on_output': The last output feature map after fpn convs.\n        relu_before_extra_convs (bool): Whether to apply relu before the extra\n            conv. Default: False.\n        no_norm_on_lateral (bool): Whether to apply norm on lateral.\n            Default: False.\n        conv_cfg (dict): Config dict for convolution layer. Default: None.\n        norm_cfg (dict): Config dict for normalization layer. Default: None.\n        act_cfg (dict): Config dict for activation layer in ConvModule.\n            Default: None.\n        upsample_cfg (dict): Config dict for interpolate layer.\n            Default: dict(mode='nearest').\n\n    Example:\n        >>> import torch\n        >>> in_channels = [2, 3, 5, 7]\n        >>> scales = [340, 170, 84, 43]\n        >>> inputs = [torch.rand(1, c, s, s)\n        ...           for c, s in zip(in_channels, scales)]\n        >>> self = FPN(in_channels, 11, len(in_channels)).eval()\n        >>> outputs = self.forward(inputs)\n        >>> for i in range(len(outputs)):\n        ...     print(f'outputs[{i}].shape = {outputs[i].shape}')\n        outputs[0].shape = torch.Size([1, 11, 340, 340])\n        outputs[1].shape = torch.Size([1, 11, 170, 170])\n        outputs[2].shape = torch.Size([1, 11, 84, 84])\n        outputs[3].shape = torch.Size([1, 11, 43, 43])\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 num_outs,\n                 start_level=0,\n                 end_level=-1,\n                 add_extra_convs=False,\n                 relu_before_extra_convs=False,\n                 no_norm_on_lateral=False,\n                 conv_cfg=None,\n                 norm_cfg=None,\n                 act_cfg=None,\n                 upsample_cfg=dict(mode='nearest')):\n        super().__init__()\n        assert isinstance(in_channels, list)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.num_ins = len(in_channels)\n        self.num_outs = num_outs\n        self.relu_before_extra_convs = relu_before_extra_convs\n        self.no_norm_on_lateral = no_norm_on_lateral\n        self.fp16_enabled = False\n        self.upsample_cfg = upsample_cfg.copy()\n\n        if end_level == -1 or end_level == self.num_ins - 1:\n            self.backbone_end_level = self.num_ins\n            assert num_outs >= self.num_ins - start_level\n        else:\n            # if end_level is not the last level, no extra level is allowed\n            self.backbone_end_level = end_level + 1\n            assert end_level < self.num_ins\n            assert num_outs == end_level - start_level + 1\n        self.start_level = start_level\n        self.end_level = end_level\n        self.add_extra_convs = add_extra_convs\n        assert isinstance(add_extra_convs, (str, bool))\n        if isinstance(add_extra_convs, str):\n            # Extra_convs_source choices: 'on_input', 'on_lateral', 'on_output'\n            assert add_extra_convs in ('on_input', 'on_lateral', 'on_output')\n        elif add_extra_convs:  # True\n            self.add_extra_convs = 'on_input'\n\n        self.lateral_convs = nn.ModuleList()\n        self.fpn_convs = nn.ModuleList()\n\n        for i in range(self.start_level, self.backbone_end_level):\n            l_conv = ConvModule(\n                in_channels[i],\n                out_channels,\n                1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg if not self.no_norm_on_lateral else None,\n                act_cfg=act_cfg,\n                inplace=False)\n            fpn_conv = ConvModule(\n                out_channels,\n                out_channels,\n                3,\n                padding=1,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg,\n                inplace=False)\n\n            self.lateral_convs.append(l_conv)\n            self.fpn_convs.append(fpn_conv)\n\n        # add extra conv layers (e.g., RetinaNet)\n        extra_levels = num_outs - self.backbone_end_level + self.start_level\n        if self.add_extra_convs and extra_levels >= 1:\n            for i in range(extra_levels):\n                if i == 0 and self.add_extra_convs == 'on_input':\n                    in_channels = self.in_channels[self.backbone_end_level - 1]\n                else:\n                    in_channels = out_channels\n                extra_fpn_conv = ConvModule(\n                    in_channels,\n                    out_channels,\n                    3,\n                    stride=2,\n                    padding=1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg,\n                    inplace=False)\n                self.fpn_convs.append(extra_fpn_conv)\n\n    def init_weights(self):\n        \"\"\"Initialize model weights.\"\"\"\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                xavier_init(m, distribution='uniform')\n\n    def forward(self, inputs):\n        \"\"\"Forward function.\"\"\"\n        assert len(inputs) == len(self.in_channels)\n\n        # build laterals\n        laterals = [\n            lateral_conv(inputs[i + self.start_level])\n            for i, lateral_conv in enumerate(self.lateral_convs)\n        ]\n\n        # build top-down path\n        used_backbone_levels = len(laterals)\n        for i in range(used_backbone_levels - 1, 0, -1):\n            # In some cases, fixing `scale factor` (e.g. 2) is preferred, but\n            #  it cannot co-exist with `size` in `F.interpolate`.\n            if 'scale_factor' in self.upsample_cfg:\n                # fix runtime error of \"+=\" inplace operation in PyTorch 1.10\n                laterals[i - 1] = laterals[i - 1] + F.interpolate(\n                    laterals[i], **self.upsample_cfg)\n            else:\n                prev_shape = laterals[i - 1].shape[2:]\n                laterals[i - 1] = laterals[i - 1] + F.interpolate(\n                    laterals[i], size=prev_shape, **self.upsample_cfg)\n\n        # build outputs\n        # part 1: from original levels\n        outs = [\n            self.fpn_convs[i](laterals[i]) for i in range(used_backbone_levels)\n        ]\n        # part 2: add extra levels\n        if self.num_outs > len(outs):\n            # use max pool to get more levels on top of outputs\n            # (e.g., Faster R-CNN, Mask R-CNN)\n            if not self.add_extra_convs:\n                for i in range(self.num_outs - used_backbone_levels):\n                    outs.append(F.max_pool2d(outs[-1], 1, stride=2))\n            # add conv layers on top of original feature maps (RetinaNet)\n            else:\n                if self.add_extra_convs == 'on_input':\n                    extra_source = inputs[self.backbone_end_level - 1]\n                elif self.add_extra_convs == 'on_lateral':\n                    extra_source = laterals[-1]\n                elif self.add_extra_convs == 'on_output':\n                    extra_source = outs[-1]\n                else:\n                    raise NotImplementedError\n                outs.append(self.fpn_convs[used_backbone_levels](extra_source))\n                for i in range(used_backbone_levels + 1, self.num_outs):\n                    if self.relu_before_extra_convs:\n                        outs.append(self.fpn_convs[i](F.relu(outs[-1])))\n                    else:\n                        outs.append(self.fpn_convs[i](outs[-1]))\n        return outs\n"
  },
  {
    "path": "mmpose/models/necks/gap_neck.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn as nn\n\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass GlobalAveragePooling(nn.Module):\n    \"\"\"Global Average Pooling neck.\n\n    Note that we use `view` to remove extra channel after pooling. We do not\n    use `squeeze` as it will also remove the batch dimension when the tensor\n    has a batch dimension of size 1, which can lead to unexpected errors.\n    \"\"\"\n\n    def __init__(self):\n        super().__init__()\n        self.gap = nn.AdaptiveAvgPool2d((1, 1))\n\n    def init_weights(self):\n        pass\n\n    def forward(self, inputs):\n        \"\"\"Forward function.\"\"\"\n\n        if isinstance(inputs, tuple):\n            outs = tuple([self.gap(x) for x in inputs])\n            outs = tuple(\n                [out.view(x.size(0), -1) for out, x in zip(outs, inputs)])\n        elif isinstance(inputs, list):\n            outs = [self.gap(x) for x in inputs]\n            outs = [out.view(x.size(0), -1) for out, x in zip(outs, inputs)]\n        elif isinstance(inputs, torch.Tensor):\n            outs = self.gap(inputs)\n            outs = outs.view(inputs.size(0), -1)\n        else:\n            raise TypeError('neck inputs should be tuple or torch.tensor')\n        return outs\n"
  },
  {
    "path": "mmpose/models/necks/hybrid_encoder.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Tuple\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import ConvModule\nfrom mmengine.model import BaseModule, ModuleList\nfrom torch import Tensor\n\nfrom mmpose.models.utils import (DetrTransformerEncoder, RepVGGBlock,\n                                 SinePositionalEncoding)\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import ConfigType, OptConfigType\n\n\nclass CSPRepLayer(BaseModule):\n    \"\"\"CSPRepLayer, a layer that combines Cross Stage Partial Networks with\n    RepVGG Blocks.\n\n    Args:\n        in_channels (int): Number of input channels to the layer.\n        out_channels (int): Number of output channels from the layer.\n        num_blocks (int): The number of RepVGG blocks to be used in the layer.\n            Defaults to 3.\n        widen_factor (float): Expansion factor for intermediate channels.\n            Determines the hidden channel size based on out_channels.\n            Defaults to 1.0.\n        norm_cfg (dict): Configuration for normalization layers.\n            Defaults to Batch Normalization with trainable parameters.\n        act_cfg (dict): Configuration for activation layers.\n            Defaults to SiLU (Swish) with in-place operation.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int,\n                 out_channels: int,\n                 num_blocks: int = 3,\n                 widen_factor: float = 1.0,\n                 norm_cfg: OptConfigType = dict(type='BN', requires_grad=True),\n                 act_cfg: OptConfigType = dict(type='SiLU', inplace=True)):\n        super(CSPRepLayer, self).__init__()\n        hidden_channels = int(out_channels * widen_factor)\n        self.conv1 = ConvModule(\n            in_channels,\n            hidden_channels,\n            kernel_size=1,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.conv2 = ConvModule(\n            in_channels,\n            hidden_channels,\n            kernel_size=1,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n\n        self.bottlenecks = nn.Sequential(*[\n            RepVGGBlock(hidden_channels, hidden_channels, act_cfg=act_cfg)\n            for _ in range(num_blocks)\n        ])\n        if hidden_channels != out_channels:\n            self.conv3 = ConvModule(\n                hidden_channels,\n                out_channels,\n                kernel_size=1,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg)\n        else:\n            self.conv3 = nn.Identity()\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward function.\n\n        Args:\n            x (Tensor): The input tensor.\n\n        Returns:\n            Tensor: The output tensor.\n        \"\"\"\n        x_1 = self.conv1(x)\n        x_1 = self.bottlenecks(x_1)\n        x_2 = self.conv2(x)\n        return self.conv3(x_1 + x_2)\n\n\n@MODELS.register_module()\nclass HybridEncoder(BaseModule):\n    \"\"\"Hybrid encoder neck introduced in `RT-DETR` by Lyu et al (2023),\n    combining transformer encoders with a Feature Pyramid Network (FPN) and a\n    Path Aggregation Network (PAN).\n\n    Args:\n        encoder_cfg (ConfigType): Configuration for the transformer encoder.\n        projector (OptConfigType, optional): Configuration for an optional\n            projector module. Defaults to None.\n        num_encoder_layers (int, optional): Number of encoder layers.\n            Defaults to 1.\n        in_channels (List[int], optional): Input channels of feature maps.\n            Defaults to [512, 1024, 2048].\n        feat_strides (List[int], optional): Strides of feature maps.\n            Defaults to [8, 16, 32].\n        hidden_dim (int, optional): Hidden dimension of the MLP.\n            Defaults to 256.\n        use_encoder_idx (List[int], optional): Indices of encoder layers to\n            use. Defaults to [2].\n        pe_temperature (int, optional): Positional encoding temperature.\n            Defaults to 10000.\n        widen_factor (float, optional): Expansion factor for CSPRepLayer.\n            Defaults to 1.0.\n        deepen_factor (float, optional): Depth multiplier for CSPRepLayer.\n            Defaults to 1.0.\n        spe_learnable (bool, optional): Whether positional encoding is\n            learnable. Defaults to False.\n        output_indices (Optional[List[int]], optional): Indices of output\n            layers. Defaults to None.\n        norm_cfg (OptConfigType, optional): Configuration for normalization\n            layers. Defaults to Batch Normalization.\n        act_cfg (OptConfigType, optional): Configuration for activation\n            layers. Defaults to SiLU (Swish) with in-place operation.\n\n    .. _`RT-DETR`: https://arxiv.org/abs/2304.08069\n    \"\"\"\n\n    def __init__(self,\n                 encoder_cfg: ConfigType = dict(),\n                 projector: OptConfigType = None,\n                 num_encoder_layers: int = 1,\n                 in_channels: List[int] = [512, 1024, 2048],\n                 feat_strides: List[int] = [8, 16, 32],\n                 hidden_dim: int = 256,\n                 use_encoder_idx: List[int] = [2],\n                 pe_temperature: int = 10000,\n                 widen_factor: float = 1.0,\n                 deepen_factor: float = 1.0,\n                 spe_learnable: bool = False,\n                 output_indices: Optional[List[int]] = None,\n                 norm_cfg: OptConfigType = dict(type='BN', requires_grad=True),\n                 act_cfg: OptConfigType = dict(type='SiLU', inplace=True)):\n        super(HybridEncoder, self).__init__()\n        self.in_channels = in_channels\n        self.feat_strides = feat_strides\n        self.hidden_dim = hidden_dim\n        self.use_encoder_idx = use_encoder_idx\n        self.num_encoder_layers = num_encoder_layers\n        self.pe_temperature = pe_temperature\n        self.output_indices = output_indices\n\n        # channel projection\n        self.input_proj = ModuleList()\n        for in_channel in in_channels:\n            self.input_proj.append(\n                ConvModule(\n                    in_channel,\n                    hidden_dim,\n                    kernel_size=1,\n                    padding=0,\n                    norm_cfg=norm_cfg,\n                    act_cfg=None))\n\n        # encoder transformer\n        if len(use_encoder_idx) > 0:\n            pos_enc_dim = self.hidden_dim // 2\n            self.encoder = ModuleList([\n                DetrTransformerEncoder(num_encoder_layers, encoder_cfg)\n                for _ in range(len(use_encoder_idx))\n            ])\n\n        self.sincos_pos_enc = SinePositionalEncoding(\n            pos_enc_dim,\n            learnable=spe_learnable,\n            temperature=self.pe_temperature,\n            spatial_dim=2)\n\n        # top-down fpn\n        lateral_convs = list()\n        fpn_blocks = list()\n        for idx in range(len(in_channels) - 1, 0, -1):\n            lateral_convs.append(\n                ConvModule(\n                    hidden_dim,\n                    hidden_dim,\n                    1,\n                    1,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n            fpn_blocks.append(\n                CSPRepLayer(\n                    hidden_dim * 2,\n                    hidden_dim,\n                    round(3 * deepen_factor),\n                    act_cfg=act_cfg,\n                    widen_factor=widen_factor))\n        self.lateral_convs = ModuleList(lateral_convs)\n        self.fpn_blocks = ModuleList(fpn_blocks)\n\n        # bottom-up pan\n        downsample_convs = list()\n        pan_blocks = list()\n        for idx in range(len(in_channels) - 1):\n            downsample_convs.append(\n                ConvModule(\n                    hidden_dim,\n                    hidden_dim,\n                    3,\n                    stride=2,\n                    padding=1,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n            pan_blocks.append(\n                CSPRepLayer(\n                    hidden_dim * 2,\n                    hidden_dim,\n                    round(3 * deepen_factor),\n                    act_cfg=act_cfg,\n                    widen_factor=widen_factor))\n        self.downsample_convs = ModuleList(downsample_convs)\n        self.pan_blocks = ModuleList(pan_blocks)\n\n        if projector is not None:\n            self.projector = MODELS.build(projector)\n        else:\n            self.projector = None\n\n    def forward(self, inputs: Tuple[Tensor]) -> Tuple[Tensor]:\n        \"\"\"Forward function.\"\"\"\n        assert len(inputs) == len(self.in_channels)\n\n        proj_feats = [\n            self.input_proj[i](inputs[i]) for i in range(len(inputs))\n        ]\n        # encoder\n        if self.num_encoder_layers > 0:\n            for i, enc_ind in enumerate(self.use_encoder_idx):\n                h, w = proj_feats[enc_ind].shape[2:]\n                # flatten [B, C, H, W] to [B, HxW, C]\n                src_flatten = proj_feats[enc_ind].flatten(2).permute(\n                    0, 2, 1).contiguous()\n\n                if torch.onnx.is_in_onnx_export():\n                    pos_enc = getattr(self, f'pos_enc_{i}')\n                else:\n                    pos_enc = self.sincos_pos_enc(size=(h, w))\n                    pos_enc = pos_enc.transpose(-1, -2).reshape(1, h * w, -1)\n                memory = self.encoder[i](\n                    src_flatten, query_pos=pos_enc, key_padding_mask=None)\n\n                proj_feats[enc_ind] = memory.permute(\n                    0, 2, 1).contiguous().view([-1, self.hidden_dim, h, w])\n\n        # top-down fpn\n        inner_outs = [proj_feats[-1]]\n        for idx in range(len(self.in_channels) - 1, 0, -1):\n            feat_high = inner_outs[0]\n            feat_low = proj_feats[idx - 1]\n            feat_high = self.lateral_convs[len(self.in_channels) - 1 - idx](\n                feat_high)\n            inner_outs[0] = feat_high\n\n            upsample_feat = F.interpolate(\n                feat_high, scale_factor=2., mode='nearest')\n            inner_out = self.fpn_blocks[len(self.in_channels) - 1 - idx](\n                torch.cat([upsample_feat, feat_low], axis=1))\n            inner_outs.insert(0, inner_out)\n\n        # bottom-up pan\n        outs = [inner_outs[0]]\n        for idx in range(len(self.in_channels) - 1):\n            feat_low = outs[-1]\n            feat_high = inner_outs[idx + 1]\n            downsample_feat = self.downsample_convs[idx](feat_low)  # Conv\n            out = self.pan_blocks[idx](  # CSPRepLayer\n                torch.cat([downsample_feat, feat_high], axis=1))\n            outs.append(out)\n\n        if self.output_indices is not None:\n            outs = [outs[i] for i in self.output_indices]\n\n        if self.projector is not None:\n            outs = self.projector(outs)\n\n        return tuple(outs)\n\n    def switch_to_deploy(self, test_cfg):\n        \"\"\"Switch to deploy mode.\"\"\"\n\n        if getattr(self, 'deploy', False):\n            return\n\n        if self.num_encoder_layers > 0:\n            for i, enc_ind in enumerate(self.use_encoder_idx):\n                h, w = test_cfg['input_size']\n                h = int(h / 2**(3 + enc_ind))\n                w = int(w / 2**(3 + enc_ind))\n                pos_enc = self.sincos_pos_enc(size=(h, w))\n                pos_enc = pos_enc.transpose(-1, -2).reshape(1, h * w, -1)\n                self.register_buffer(f'pos_enc_{i}', pos_enc)\n\n        self.deploy = True\n"
  },
  {
    "path": "mmpose/models/necks/posewarper_neck.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport mmcv\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\nfrom mmengine.model import constant_init, normal_init\nfrom mmengine.utils import digit_version\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.utils.ops import resize\nfrom mmpose.registry import MODELS\nfrom ..backbones.resnet import BasicBlock, Bottleneck\n\ntry:\n    from mmcv.ops import DeformConv2d\n    has_mmcv_full = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmcv_full = False\n\n\n@MODELS.register_module()\nclass PoseWarperNeck(nn.Module):\n    \"\"\"PoseWarper neck.\n\n    `\"Learning temporal pose estimation from sparsely-labeled videos\"\n    <https://arxiv.org/abs/1906.04016>`_.\n\n    Args:\n        in_channels (int): Number of input channels from backbone\n        out_channels (int): Number of output channels\n        inner_channels (int): Number of intermediate channels of the res block\n        deform_groups (int): Number of groups in the deformable conv\n        dilations (list|tuple): different dilations of the offset conv layers\n        trans_conv_kernel (int): the kernel of the trans conv layer, which is\n            used to get heatmap from the output of backbone. Default: 1\n        res_blocks_cfg (dict|None): config of residual blocks. If None,\n            use the default values. If not None, it should contain the\n            following keys:\n\n            - block (str): the type of residual block, Default: 'BASIC'.\n            - num_blocks (int):  the number of blocks, Default: 20.\n\n        offsets_kernel (int): the kernel of offset conv layer.\n        deform_conv_kernel (int): the kernel of defomrable conv layer.\n        in_index (int|Sequence[int]): Input feature index. Default: 0\n        input_transform (str|None): Transformation type of input features.\n            Options: 'resize_concat', 'multiple_select', None.\n            Default: None.\n\n            - 'resize_concat': Multiple feature maps will be resize to \\\n                the same size as first one and than concat together. \\\n                Usually used in FCN head of HRNet.\n            - 'multiple_select': Multiple feature maps will be bundle into \\\n                a list and passed into decode head.\n            - None: Only one select feature map is allowed.\n\n        freeze_trans_layer (bool): Whether to freeze the transition layer\n            (stop grad and set eval mode). Default: True.\n        norm_eval (bool): Whether to set norm layers to eval mode, namely,\n            freeze running stats (mean and var). Note: Effect on Batch Norm\n            and its variants only. Default: False.\n        im2col_step (int): the argument `im2col_step` in deformable conv,\n            Default: 80.\n    \"\"\"\n    blocks_dict = {'BASIC': BasicBlock, 'BOTTLENECK': Bottleneck}\n    minimum_mmcv_version = '1.3.17'\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 inner_channels,\n                 deform_groups=17,\n                 dilations=(3, 6, 12, 18, 24),\n                 trans_conv_kernel=1,\n                 res_blocks_cfg=None,\n                 offsets_kernel=3,\n                 deform_conv_kernel=3,\n                 in_index=0,\n                 input_transform=None,\n                 freeze_trans_layer=True,\n                 norm_eval=False,\n                 im2col_step=80):\n        super().__init__()\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.inner_channels = inner_channels\n        self.deform_groups = deform_groups\n        self.dilations = dilations\n        self.trans_conv_kernel = trans_conv_kernel\n        self.res_blocks_cfg = res_blocks_cfg\n        self.offsets_kernel = offsets_kernel\n        self.deform_conv_kernel = deform_conv_kernel\n        self.in_index = in_index\n        self.input_transform = input_transform\n        self.freeze_trans_layer = freeze_trans_layer\n        self.norm_eval = norm_eval\n        self.im2col_step = im2col_step\n\n        identity_trans_layer = False\n\n        assert trans_conv_kernel in [0, 1, 3]\n        kernel_size = trans_conv_kernel\n        if kernel_size == 3:\n            padding = 1\n        elif kernel_size == 1:\n            padding = 0\n        else:\n            # 0 for Identity mapping.\n            identity_trans_layer = True\n\n        if identity_trans_layer:\n            self.trans_layer = nn.Identity()\n        else:\n            self.trans_layer = build_conv_layer(\n                cfg=dict(type='Conv2d'),\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=kernel_size,\n                stride=1,\n                padding=padding)\n\n        # build chain of residual blocks\n        if res_blocks_cfg is not None and not isinstance(res_blocks_cfg, dict):\n            raise TypeError('res_blocks_cfg should be dict or None.')\n\n        if res_blocks_cfg is None:\n            block_type = 'BASIC'\n            num_blocks = 20\n        else:\n            block_type = res_blocks_cfg.get('block', 'BASIC')\n            num_blocks = res_blocks_cfg.get('num_blocks', 20)\n\n        block = self.blocks_dict[block_type]\n\n        res_layers = []\n        downsample = nn.Sequential(\n            build_conv_layer(\n                cfg=dict(type='Conv2d'),\n                in_channels=out_channels,\n                out_channels=inner_channels,\n                kernel_size=1,\n                stride=1,\n                bias=False),\n            build_norm_layer(dict(type='BN'), inner_channels)[1])\n        res_layers.append(\n            block(\n                in_channels=out_channels,\n                out_channels=inner_channels,\n                downsample=downsample))\n\n        for _ in range(1, num_blocks):\n            res_layers.append(block(inner_channels, inner_channels))\n        self.offset_feats = nn.Sequential(*res_layers)\n\n        # build offset layers\n        self.num_offset_layers = len(dilations)\n        assert self.num_offset_layers > 0, 'Number of offset layers ' \\\n            'should be larger than 0.'\n\n        target_offset_channels = 2 * offsets_kernel**2 * deform_groups\n\n        offset_layers = [\n            build_conv_layer(\n                cfg=dict(type='Conv2d'),\n                in_channels=inner_channels,\n                out_channels=target_offset_channels,\n                kernel_size=offsets_kernel,\n                stride=1,\n                dilation=dilations[i],\n                padding=dilations[i],\n                bias=False,\n            ) for i in range(self.num_offset_layers)\n        ]\n        self.offset_layers = nn.ModuleList(offset_layers)\n\n        # build deformable conv layers\n        assert digit_version(mmcv.__version__) >= \\\n            digit_version(self.minimum_mmcv_version), \\\n            f'Current MMCV version: {mmcv.__version__}, ' \\\n            f'but MMCV >= {self.minimum_mmcv_version} is required, see ' \\\n            f'https://github.com/open-mmlab/mmcv/issues/1440, ' \\\n            f'Please install the latest MMCV.'\n\n        if has_mmcv_full:\n            deform_conv_layers = [\n                DeformConv2d(\n                    in_channels=out_channels,\n                    out_channels=out_channels,\n                    kernel_size=deform_conv_kernel,\n                    stride=1,\n                    padding=int(deform_conv_kernel / 2) * dilations[i],\n                    dilation=dilations[i],\n                    deform_groups=deform_groups,\n                    im2col_step=self.im2col_step,\n                ) for i in range(self.num_offset_layers)\n            ]\n        else:\n            raise ImportError('Please install the full version of mmcv '\n                              'to use `DeformConv2d`.')\n\n        self.deform_conv_layers = nn.ModuleList(deform_conv_layers)\n\n        self.freeze_layers()\n\n    def freeze_layers(self):\n        if self.freeze_trans_layer:\n            self.trans_layer.eval()\n\n            for param in self.trans_layer.parameters():\n                param.requires_grad = False\n\n    def init_weights(self):\n        for m in self.modules():\n            if isinstance(m, nn.Conv2d):\n                normal_init(m, std=0.001)\n            elif isinstance(m, (_BatchNorm, nn.GroupNorm)):\n                constant_init(m, 1)\n            elif isinstance(m, DeformConv2d):\n                filler = torch.zeros([\n                    m.weight.size(0),\n                    m.weight.size(1),\n                    m.weight.size(2),\n                    m.weight.size(3)\n                ],\n                                     dtype=torch.float32,\n                                     device=m.weight.device)\n                for k in range(m.weight.size(0)):\n                    filler[k, k,\n                           int(m.weight.size(2) / 2),\n                           int(m.weight.size(3) / 2)] = 1.0\n                m.weight = torch.nn.Parameter(filler)\n                m.weight.requires_grad = True\n\n        # posewarper offset layer weight initialization\n        for m in self.offset_layers.modules():\n            constant_init(m, 0)\n\n    def _transform_inputs(self, inputs):\n        \"\"\"Transform inputs for decoder.\n\n        Args:\n            inputs (list[Tensor] | Tensor): multi-level img features.\n\n        Returns:\n            Tensor: The transformed inputs\n        \"\"\"\n        if not isinstance(inputs, list):\n            return inputs\n\n        if self.input_transform == 'resize_concat':\n            inputs = [inputs[i] for i in self.in_index]\n            upsampled_inputs = [\n                resize(\n                    input=x,\n                    size=inputs[0].shape[2:],\n                    mode='bilinear',\n                    align_corners=self.align_corners) for x in inputs\n            ]\n            inputs = torch.cat(upsampled_inputs, dim=1)\n        elif self.input_transform == 'multiple_select':\n            inputs = [inputs[i] for i in self.in_index]\n        else:\n            inputs = inputs[self.in_index]\n\n        return inputs\n\n    def forward(self, inputs, frame_weight):\n        assert isinstance(inputs, (list, tuple)), 'PoseWarperNeck inputs ' \\\n            'should be list or tuple, even though the length is 1, ' \\\n            'for unified processing.'\n\n        output_heatmap = 0\n        if len(inputs) > 1:\n            inputs = [self._transform_inputs(input) for input in inputs]\n            inputs = [self.trans_layer(input) for input in inputs]\n\n            # calculate difference features\n            diff_features = [\n                self.offset_feats(inputs[0] - input) for input in inputs\n            ]\n\n            for i in range(len(inputs)):\n                if frame_weight[i] == 0:\n                    continue\n                warped_heatmap = 0\n                for j in range(self.num_offset_layers):\n                    offset = (self.offset_layers[j](diff_features[i]))\n                    warped_heatmap_tmp = self.deform_conv_layers[j](inputs[i],\n                                                                    offset)\n                    warped_heatmap += warped_heatmap_tmp / \\\n                        self.num_offset_layers\n\n                output_heatmap += warped_heatmap * frame_weight[i]\n\n        else:\n            inputs = inputs[0]\n            inputs = self._transform_inputs(inputs)\n            inputs = self.trans_layer(inputs)\n\n            num_frames = len(frame_weight)\n            batch_size = inputs.size(0) // num_frames\n            ref_x = inputs[:batch_size]\n            ref_x_tiled = ref_x.repeat(num_frames, 1, 1, 1)\n\n            offset_features = self.offset_feats(ref_x_tiled - inputs)\n\n            warped_heatmap = 0\n            for j in range(self.num_offset_layers):\n                offset = self.offset_layers[j](offset_features)\n\n                warped_heatmap_tmp = self.deform_conv_layers[j](inputs, offset)\n                warped_heatmap += warped_heatmap_tmp / self.num_offset_layers\n\n            for i in range(num_frames):\n                if frame_weight[i] == 0:\n                    continue\n                output_heatmap += warped_heatmap[i * batch_size:(i + 1) *\n                                                 batch_size] * frame_weight[i]\n\n        return output_heatmap\n\n    def train(self, mode=True):\n        \"\"\"Convert the model into training mode.\"\"\"\n        super().train(mode)\n        self.freeze_layers()\n        if mode and self.norm_eval:\n            for m in self.modules():\n                if isinstance(m, _BatchNorm):\n                    m.eval()\n"
  },
  {
    "path": "mmpose/models/necks/yolox_pafpn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, DepthwiseSeparableConvModule\nfrom mmengine.model import BaseModule\n\nfrom mmpose.registry import MODELS\nfrom ..utils import CSPLayer\n\n\n@MODELS.register_module()\nclass YOLOXPAFPN(BaseModule):\n    \"\"\"Path Aggregation Network used in YOLOX.\n\n    Args:\n        in_channels (List[int]): Number of input channels per scale.\n        out_channels (int): Number of output channels (used at each scale)\n        num_csp_blocks (int): Number of bottlenecks in CSPLayer. Default: 3\n        use_depthwise (bool): Whether to depthwise separable convolution in\n            blocks. Default: False\n        upsample_cfg (dict): Config dict for interpolate layer.\n            Default: `dict(scale_factor=2, mode='nearest')`\n        conv_cfg (dict, optional): Config dict for convolution layer.\n            Default: None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: dict(type='BN')\n        act_cfg (dict): Config dict for activation layer.\n            Default: dict(type='Swish')\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 num_csp_blocks=3,\n                 use_depthwise=False,\n                 upsample_cfg=dict(scale_factor=2, mode='nearest'),\n                 conv_cfg=None,\n                 norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n                 act_cfg=dict(type='Swish'),\n                 init_cfg=dict(\n                     type='Kaiming',\n                     layer='Conv2d',\n                     a=math.sqrt(5),\n                     distribution='uniform',\n                     mode='fan_in',\n                     nonlinearity='leaky_relu')):\n        super(YOLOXPAFPN, self).__init__(init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n\n        conv = DepthwiseSeparableConvModule if use_depthwise else ConvModule\n\n        # build top-down blocks\n        self.upsample = nn.Upsample(**upsample_cfg)\n        self.reduce_layers = nn.ModuleList()\n        self.top_down_blocks = nn.ModuleList()\n        for idx in range(len(in_channels) - 1, 0, -1):\n            self.reduce_layers.append(\n                ConvModule(\n                    in_channels[idx],\n                    in_channels[idx - 1],\n                    1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n            self.top_down_blocks.append(\n                CSPLayer(\n                    in_channels[idx - 1] * 2,\n                    in_channels[idx - 1],\n                    num_blocks=num_csp_blocks,\n                    add_identity=False,\n                    use_depthwise=use_depthwise,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n\n        # build bottom-up blocks\n        self.downsamples = nn.ModuleList()\n        self.bottom_up_blocks = nn.ModuleList()\n        for idx in range(len(in_channels) - 1):\n            self.downsamples.append(\n                conv(\n                    in_channels[idx],\n                    in_channels[idx],\n                    3,\n                    stride=2,\n                    padding=1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n            self.bottom_up_blocks.append(\n                CSPLayer(\n                    in_channels[idx] * 2,\n                    in_channels[idx + 1],\n                    num_blocks=num_csp_blocks,\n                    add_identity=False,\n                    use_depthwise=use_depthwise,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n\n        self.out_convs = nn.ModuleList()\n        for i in range(len(in_channels)):\n            self.out_convs.append(\n                ConvModule(\n                    in_channels[i],\n                    out_channels,\n                    1,\n                    conv_cfg=conv_cfg,\n                    norm_cfg=norm_cfg,\n                    act_cfg=act_cfg))\n\n    def forward(self, inputs):\n        \"\"\"\n        Args:\n            inputs (tuple[Tensor]): input features.\n\n        Returns:\n            tuple[Tensor]: YOLOXPAFPN features.\n        \"\"\"\n        assert len(inputs) == len(self.in_channels)\n\n        # top-down path\n        inner_outs = [inputs[-1]]\n        for idx in range(len(self.in_channels) - 1, 0, -1):\n            feat_heigh = inner_outs[0]\n            feat_low = inputs[idx - 1]\n            feat_heigh = self.reduce_layers[len(self.in_channels) - 1 - idx](\n                feat_heigh)\n            inner_outs[0] = feat_heigh\n\n            upsample_feat = self.upsample(feat_heigh)\n\n            inner_out = self.top_down_blocks[len(self.in_channels) - 1 - idx](\n                torch.cat([upsample_feat, feat_low], 1))\n            inner_outs.insert(0, inner_out)\n\n        # bottom-up path\n        outs = [inner_outs[0]]\n        for idx in range(len(self.in_channels) - 1):\n            feat_low = outs[-1]\n            feat_height = inner_outs[idx + 1]\n            downsample_feat = self.downsamples[idx](feat_low)\n            out = self.bottom_up_blocks[idx](\n                torch.cat([downsample_feat, feat_height], 1))\n            outs.append(out)\n\n        # out convs\n        for idx, conv in enumerate(self.out_convs):\n            outs[idx] = conv(outs[idx])\n\n        return tuple(outs)\n"
  },
  {
    "path": "mmpose/models/pose_estimators/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .bottomup import BottomupPoseEstimator\nfrom .pose_lifter import PoseLifter\nfrom .topdown import TopdownPoseEstimator\n\n__all__ = ['TopdownPoseEstimator', 'BottomupPoseEstimator', 'PoseLifter']\n"
  },
  {
    "path": "mmpose/models/pose_estimators/base.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta, abstractmethod\nfrom typing import Tuple, Union\n\nimport torch\nfrom mmengine.dist import get_world_size\nfrom mmengine.logging import print_log\nfrom mmengine.model import BaseModel\nfrom torch import Tensor\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.models.utils import check_and_update_config\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import (ConfigType, ForwardResults, OptConfigType,\n                                 Optional, OptMultiConfig, OptSampleList,\n                                 SampleList)\n\n\nclass BasePoseEstimator(BaseModel, metaclass=ABCMeta):\n    \"\"\"Base class for pose estimators.\n\n    Args:\n        data_preprocessor (dict | ConfigDict, optional): The pre-processing\n            config of :class:`BaseDataPreprocessor`. Defaults to ``None``\n        init_cfg (dict | ConfigDict): The model initialization config.\n            Defaults to ``None``\n        use_syncbn (bool): whether to use SyncBatchNorm. Defaults to False.\n        metainfo (dict): Meta information for dataset, such as keypoints\n            definition and properties. If set, the metainfo of the input data\n            batch will be overridden. For more details, please refer to\n            https://mmpose.readthedocs.io/en/latest/user_guides/\n            prepare_datasets.html#create-a-custom-dataset-info-\n            config-file-for-the-dataset. Defaults to ``None``\n    \"\"\"\n    _version = 2\n\n    def __init__(self,\n                 backbone: ConfigType,\n                 neck: OptConfigType = None,\n                 head: OptConfigType = None,\n                 train_cfg: OptConfigType = None,\n                 test_cfg: OptConfigType = None,\n                 data_preprocessor: OptConfigType = None,\n                 use_syncbn: bool = False,\n                 init_cfg: OptMultiConfig = None,\n                 metainfo: Optional[dict] = None):\n        super().__init__(\n            data_preprocessor=data_preprocessor, init_cfg=init_cfg)\n        self.metainfo = self._load_metainfo(metainfo)\n        self.train_cfg = train_cfg if train_cfg else {}\n        self.test_cfg = test_cfg if test_cfg else {}\n\n        self.backbone = MODELS.build(backbone)\n\n        # the PR #2108 and #2126 modified the interface of neck and head.\n        # The following function automatically detects outdated\n        # configurations and updates them accordingly, while also providing\n        # clear and concise information on the changes made.\n        neck, head = check_and_update_config(neck, head)\n\n        if neck is not None:\n            self.neck = MODELS.build(neck)\n\n        if head is not None:\n            self.head = MODELS.build(head)\n            self.head.test_cfg = self.test_cfg.copy()\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n        # TODO： Waiting for mmengine support\n        if use_syncbn and get_world_size() > 1:\n            torch.nn.SyncBatchNorm.convert_sync_batchnorm(self)\n            print_log('Using SyncBatchNorm()', 'current')\n\n    def switch_to_deploy(self):\n        \"\"\"Switch the sub-modules to deploy mode.\"\"\"\n        for name, layer in self.named_modules():\n            if layer == self:\n                continue\n            if callable(getattr(layer, 'switch_to_deploy', None)):\n                print_log(f'module {name} has been switched to deploy mode',\n                          'current')\n                layer.switch_to_deploy(self.test_cfg)\n\n    @property\n    def with_neck(self) -> bool:\n        \"\"\"bool: whether the pose estimator has a neck.\"\"\"\n        return hasattr(self, 'neck') and self.neck is not None\n\n    @property\n    def with_head(self) -> bool:\n        \"\"\"bool: whether the pose estimator has a head.\"\"\"\n        return hasattr(self, 'head') and self.head is not None\n\n    @staticmethod\n    def _load_metainfo(metainfo: dict = None) -> dict:\n        \"\"\"Collect meta information from the dictionary of meta.\n\n        Args:\n            metainfo (dict): Raw data of pose meta information.\n\n        Returns:\n            dict: Parsed meta information.\n        \"\"\"\n\n        if metainfo is None:\n            return None\n\n        if not isinstance(metainfo, dict):\n            raise TypeError(\n                f'metainfo should be a dict, but got {type(metainfo)}')\n\n        metainfo = parse_pose_metainfo(metainfo)\n        return metainfo\n\n    def forward(self,\n                inputs: torch.Tensor,\n                data_samples: OptSampleList,\n                mode: str = 'tensor') -> ForwardResults:\n        \"\"\"The unified entry for a forward process in both training and test.\n\n        The method should accept three modes: 'tensor', 'predict' and 'loss':\n\n        - 'tensor': Forward the whole network and return tensor or tuple of\n        tensor without any post-processing, same as a common nn.Module.\n        - 'predict': Forward and return the predictions, which are fully\n        processed to a list of :obj:`PoseDataSample`.\n        - 'loss': Forward and return a dict of losses according to the given\n        inputs and data samples.\n\n        Note that this method doesn't handle neither back propagation nor\n        optimizer updating, which are done in the :meth:`train_step`.\n\n        Args:\n            inputs (torch.Tensor): The input tensor with shape\n                (N, C, ...) in general\n            data_samples (list[:obj:`PoseDataSample`], optional): The\n                annotation of every sample. Defaults to ``None``\n            mode (str): Set the forward mode and return value type. Defaults\n                to ``'tensor'``\n\n        Returns:\n            The return type depends on ``mode``.\n\n            - If ``mode='tensor'``, return a tensor or a tuple of tensors\n            - If ``mode='predict'``, return a list of :obj:``PoseDataSample``\n                that contains the pose predictions\n            - If ``mode='loss'``, return a dict of tensor(s) which is the loss\n                function value\n        \"\"\"\n        if isinstance(inputs, list):\n            inputs = torch.stack(inputs)\n        if mode == 'loss':\n            return self.loss(inputs, data_samples)\n        elif mode == 'predict':\n            # use customed metainfo to override the default metainfo\n            if self.metainfo is not None:\n                for data_sample in data_samples:\n                    data_sample.set_metainfo(self.metainfo)\n            return self.predict(inputs, data_samples)\n        elif mode == 'tensor':\n            return self._forward(inputs)\n        else:\n            raise RuntimeError(f'Invalid mode \"{mode}\". '\n                               'Only supports loss, predict and tensor mode.')\n\n    @abstractmethod\n    def loss(self, inputs: Tensor, data_samples: SampleList) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n    @abstractmethod\n    def predict(self, inputs: Tensor, data_samples: SampleList) -> SampleList:\n        \"\"\"Predict results from a batch of inputs and data samples with post-\n        processing.\"\"\"\n\n    def _forward(self,\n                 inputs: Tensor,\n                 data_samples: OptSampleList = None\n                 ) -> Union[Tensor, Tuple[Tensor]]:\n        \"\"\"Network forward process. Usually includes backbone, neck and head\n        forward without any post-processing.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W).\n\n        Returns:\n            Union[Tensor | Tuple[Tensor]]: forward output of the network.\n        \"\"\"\n\n        x = self.extract_feat(inputs)\n        if self.with_head:\n            x = self.head.forward(x)\n\n        return x\n\n    def extract_feat(self, inputs: Tensor) -> Tuple[Tensor]:\n        \"\"\"Extract features.\n\n        Args:\n            inputs (Tensor): Image tensor with shape (N, C, H ,W).\n\n        Returns:\n            tuple[Tensor]: Multi-level features that may have various\n            resolutions.\n        \"\"\"\n        x = self.backbone(inputs)\n        if self.with_neck:\n            x = self.neck(x)\n\n        return x\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to.\n\n        1) convert old-version state dict of\n        :class:`TopdownHeatmapSimpleHead` (before MMPose v1.0.0) to a\n        compatible format of :class:`HeatmapHead`.\n\n        2) remove the weights in data_preprocessor to avoid warning\n        `unexpected key in source state_dict: ...`. These weights are\n        initialized with given arguments and remain same during training\n        and inference.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n\n        keys = list(state_dict.keys())\n\n        # remove the keys in data_preprocessor to avoid warning\n        for k in keys:\n            if k in ('data_preprocessor.mean', 'data_preprocessor.std'):\n                del state_dict[k]\n\n        version = local_meta.get('version', None)\n        if version and version >= self._version:\n            return\n\n        # convert old-version state dict\n        for k in keys:\n            if 'keypoint_head' in k:\n                v = state_dict.pop(k)\n                k = k.replace('keypoint_head', 'head')\n                state_dict[k] = v\n"
  },
  {
    "path": "mmpose/models/pose_estimators/bottomup.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import zip_longest\nfrom typing import List, Optional, Union\n\nfrom mmengine.utils import is_list_of\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptMultiConfig, PixelDataList, SampleList)\nfrom .base import BasePoseEstimator\n\n\n@MODELS.register_module()\nclass BottomupPoseEstimator(BasePoseEstimator):\n    \"\"\"Base class for bottom-up pose estimators.\n\n    Args:\n        backbone (dict): The backbone config\n        neck (dict, optional): The neck config. Defaults to ``None``\n        head (dict, optional): The head config. Defaults to ``None``\n        train_cfg (dict, optional): The runtime config for training process.\n            Defaults to ``None``\n        test_cfg (dict, optional): The runtime config for testing process.\n            Defaults to ``None``\n        use_syncbn (bool): whether to use SyncBatchNorm. Defaults to False.\n        data_preprocessor (dict, optional): The data preprocessing config to\n            build the instance of :class:`BaseDataPreprocessor`. Defaults to\n            ``None``.\n        init_cfg (dict, optional): The config to control the initialization.\n            Defaults to ``None``\n    \"\"\"\n\n    def __init__(self,\n                 backbone: ConfigType,\n                 neck: OptConfigType = None,\n                 head: OptConfigType = None,\n                 train_cfg: OptConfigType = None,\n                 test_cfg: OptConfigType = None,\n                 use_syncbn: bool = False,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None):\n        super().__init__(\n            backbone=backbone,\n            neck=neck,\n            head=head,\n            train_cfg=train_cfg,\n            test_cfg=test_cfg,\n            use_syncbn=use_syncbn,\n            data_preprocessor=data_preprocessor,\n            init_cfg=init_cfg)\n\n    def loss(self, inputs: Tensor, data_samples: SampleList) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W).\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples.\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        feats = self.extract_feat(inputs)\n\n        losses = dict()\n\n        if self.with_head:\n            losses.update(\n                self.head.loss(feats, data_samples, train_cfg=self.train_cfg))\n\n        return losses\n\n    def predict(self, inputs: Union[Tensor, List[Tensor]],\n                data_samples: SampleList) -> SampleList:\n        \"\"\"Predict results from a batch of inputs and data samples with post-\n        processing.\n\n        Args:\n            inputs (Tensor | List[Tensor]): Input image in tensor or image\n                pyramid as a list of tensors. Each tensor is in shape\n                [B, C, H, W]\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n\n        Returns:\n            list[:obj:`PoseDataSample`]: The pose estimation results of the\n            input images. The return value is `PoseDataSample` instances with\n            ``pred_instances`` and ``pred_fields``(optional) field , and\n            ``pred_instances`` usually contains the following keys:\n\n                - keypoints (Tensor): predicted keypoint coordinates in shape\n                    (num_instances, K, D) where K is the keypoint number and D\n                    is the keypoint dimension\n                - keypoint_scores (Tensor): predicted keypoint scores in shape\n                    (num_instances, K)\n        \"\"\"\n        assert self.with_head, (\n            'The model must have head to perform prediction.')\n\n        multiscale_test = self.test_cfg.get('multiscale_test', False)\n        flip_test = self.test_cfg.get('flip_test', False)\n\n        # enable multi-scale test\n        aug_scales = data_samples[0].metainfo.get('aug_scales', None)\n        if multiscale_test:\n            assert isinstance(aug_scales, list)\n            assert is_list_of(inputs, Tensor)\n            # `inputs` includes images in original and augmented scales\n            assert len(inputs) == len(aug_scales) + 1\n        else:\n            assert isinstance(inputs, Tensor)\n            # single-scale test\n            inputs = [inputs]\n\n        feats = []\n        for _inputs in inputs:\n            if flip_test:\n                _feats_orig = self.extract_feat(_inputs)\n                _feats_flip = self.extract_feat(_inputs.flip(-1))\n                _feats = [_feats_orig, _feats_flip]\n            else:\n                _feats = self.extract_feat(_inputs)\n\n            feats.append(_feats)\n\n        if not multiscale_test:\n            feats = feats[0]\n\n        preds = self.head.predict(feats, data_samples, test_cfg=self.test_cfg)\n\n        if isinstance(preds, tuple):\n            batch_pred_instances, batch_pred_fields = preds\n        else:\n            batch_pred_instances = preds\n            batch_pred_fields = None\n\n        results = self.add_pred_to_datasample(batch_pred_instances,\n                                              batch_pred_fields, data_samples)\n\n        return results\n\n    def add_pred_to_datasample(self, batch_pred_instances: InstanceList,\n                               batch_pred_fields: Optional[PixelDataList],\n                               batch_data_samples: SampleList) -> SampleList:\n        \"\"\"Add predictions into data samples.\n\n        Args:\n            batch_pred_instances (List[InstanceData]): The predicted instances\n                of the input data batch\n            batch_pred_fields (List[PixelData], optional): The predicted\n                fields (e.g. heatmaps) of the input batch\n            batch_data_samples (List[PoseDataSample]): The input data batch\n\n        Returns:\n            List[PoseDataSample]: A list of data samples where the predictions\n            are stored in the ``pred_instances`` field of each data sample.\n            The length of the list is the batch size when ``merge==False``, or\n            1 when ``merge==True``.\n        \"\"\"\n        assert len(batch_pred_instances) == len(batch_data_samples)\n        if batch_pred_fields is None:\n            batch_pred_fields = []\n\n        for pred_instances, pred_fields, data_sample in zip_longest(\n                batch_pred_instances, batch_pred_fields, batch_data_samples):\n\n            input_size = data_sample.metainfo['input_size']\n            input_center = data_sample.metainfo['input_center']\n            input_scale = data_sample.metainfo['input_scale']\n\n            # convert keypoint coordinates from input space to image space\n            pred_instances.keypoints = pred_instances.keypoints / input_size \\\n                * input_scale + input_center - 0.5 * input_scale\n            if 'keypoints_visible' not in pred_instances:\n                pred_instances.keypoints_visible = \\\n                    pred_instances.keypoint_scores\n\n            # convert bbox coordinates from input space to image space\n            if 'bboxes' in pred_instances:\n                bboxes = pred_instances.bboxes.reshape(\n                    pred_instances.bboxes.shape[0], 2, 2)\n                bboxes = bboxes / input_size * input_scale + input_center \\\n                    - 0.5 * input_scale\n                pred_instances.bboxes = bboxes.reshape(bboxes.shape[0], 4)\n\n            data_sample.pred_instances = pred_instances\n\n            if pred_fields is not None:\n                data_sample.pred_fields = pred_fields\n\n        return batch_data_samples\n"
  },
  {
    "path": "mmpose/models/pose_estimators/pose_lifter.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import zip_longest\nfrom typing import Tuple, Union\n\nimport torch\nfrom torch import Tensor\n\nfrom mmpose.models.utils import check_and_update_config\nfrom mmpose.models.utils.tta import flip_coordinates\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 Optional, OptMultiConfig, OptSampleList,\n                                 PixelDataList, SampleList)\nfrom .base import BasePoseEstimator\n\n\n@MODELS.register_module()\nclass PoseLifter(BasePoseEstimator):\n    \"\"\"Base class for pose lifter.\n\n    Args:\n        backbone (dict): The backbone config\n        neck (dict, optional): The neck config. Defaults to ``None``\n        head (dict, optional): The head config. Defaults to ``None``\n        traj_backbone (dict, optional): The backbone config for trajectory\n            model. Defaults to ``None``\n        traj_neck (dict, optional): The neck config for trajectory model.\n            Defaults to ``None``\n        traj_head (dict, optional): The head config for trajectory model.\n            Defaults to ``None``\n        semi_loss (dict, optional): The semi-supervised loss config.\n            Defaults to ``None``\n        train_cfg (dict, optional): The runtime config for training process.\n            Defaults to ``None``\n        test_cfg (dict, optional): The runtime config for testing process.\n            Defaults to ``None``\n        data_preprocessor (dict, optional): The data preprocessing config to\n            build the instance of :class:`BaseDataPreprocessor`. Defaults to\n            ``None``\n        init_cfg (dict, optional): The config to control the initialization.\n            Defaults to ``None``\n        metainfo (dict): Meta information for dataset, such as keypoints\n            definition and properties. If set, the metainfo of the input data\n            batch will be overridden. For more details, please refer to\n            https://mmpose.readthedocs.io/en/latest/user_guides/\n            prepare_datasets.html#create-a-custom-dataset-info-\n            config-file-for-the-dataset. Defaults to ``None``\n    \"\"\"\n\n    def __init__(self,\n                 backbone: ConfigType,\n                 neck: OptConfigType = None,\n                 head: OptConfigType = None,\n                 traj_backbone: OptConfigType = None,\n                 traj_neck: OptConfigType = None,\n                 traj_head: OptConfigType = None,\n                 semi_loss: OptConfigType = None,\n                 train_cfg: OptConfigType = None,\n                 test_cfg: OptConfigType = None,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None,\n                 metainfo: Optional[dict] = None):\n        super().__init__(\n            backbone=backbone,\n            neck=neck,\n            head=head,\n            train_cfg=train_cfg,\n            test_cfg=test_cfg,\n            data_preprocessor=data_preprocessor,\n            init_cfg=init_cfg,\n            metainfo=metainfo)\n\n        # trajectory model\n        self.share_backbone = False\n        if traj_head is not None:\n            if traj_backbone is not None:\n                self.traj_backbone = MODELS.build(traj_backbone)\n            else:\n                self.share_backbone = True\n\n            # the PR #2108 and #2126 modified the interface of neck and head.\n            # The following function automatically detects outdated\n            # configurations and updates them accordingly, while also providing\n            # clear and concise information on the changes made.\n            traj_neck, traj_head = check_and_update_config(\n                traj_neck, traj_head)\n\n            if traj_neck is not None:\n                self.traj_neck = MODELS.build(traj_neck)\n\n            self.traj_head = MODELS.build(traj_head)\n\n        # semi-supervised loss\n        self.semi_supervised = semi_loss is not None\n        if self.semi_supervised:\n            assert any([head, traj_head])\n            self.semi_loss = MODELS.build(semi_loss)\n\n    @property\n    def with_traj_backbone(self):\n        \"\"\"bool: Whether the pose lifter has trajectory backbone.\"\"\"\n        return hasattr(self, 'traj_backbone') and \\\n            self.traj_backbone is not None\n\n    @property\n    def with_traj_neck(self):\n        \"\"\"bool: Whether the pose lifter has trajectory neck.\"\"\"\n        return hasattr(self, 'traj_neck') and self.traj_neck is not None\n\n    @property\n    def with_traj(self):\n        \"\"\"bool: Whether the pose lifter has trajectory head.\"\"\"\n        return hasattr(self, 'traj_head')\n\n    @property\n    def causal(self):\n        \"\"\"bool: Whether the pose lifter is causal.\"\"\"\n        if hasattr(self.backbone, 'causal'):\n            return self.backbone.causal\n        else:\n            raise AttributeError('A PoseLifter\\'s backbone should have '\n                                 'the bool attribute \"causal\" to indicate if'\n                                 'it performs causal inference.')\n\n    def extract_feat(self, inputs: Tensor) -> Tuple[Tensor]:\n        \"\"\"Extract features.\n\n        Args:\n            inputs (Tensor): Image tensor with shape (N, K, C, T).\n\n        Returns:\n            tuple[Tensor]: Multi-level features that may have various\n            resolutions.\n        \"\"\"\n        # supervised learning\n        # pose model\n        feats = self.backbone(inputs)\n        if self.with_neck:\n            feats = self.neck(feats)\n\n        # trajectory model\n        if self.with_traj:\n            if self.share_backbone:\n                traj_x = feats\n            else:\n                traj_x = self.traj_backbone(inputs)\n\n            if self.with_traj_neck:\n                traj_x = self.traj_neck(traj_x)\n            return feats, traj_x\n        else:\n            return feats\n\n    def _forward(self,\n                 inputs: Tensor,\n                 data_samples: OptSampleList = None\n                 ) -> Union[Tensor, Tuple[Tensor]]:\n        \"\"\"Network forward process. Usually includes backbone, neck and head\n        forward without any post-processing.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, K, C, T).\n\n        Returns:\n            Union[Tensor | Tuple[Tensor]]: forward output of the network.\n        \"\"\"\n        feats = self.extract_feat(inputs)\n\n        if self.with_traj:\n            # forward with trajectory model\n            x, traj_x = feats\n            if self.with_head:\n                x = self.head.forward(x)\n\n            traj_x = self.traj_head.forward(traj_x)\n            return x, traj_x\n        else:\n            # forward without trajectory model\n            x = feats\n            if self.with_head:\n                x = self.head.forward(x)\n            return x\n\n    def loss(self, inputs: Tensor, data_samples: SampleList) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, K, C, T).\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples.\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        feats = self.extract_feat(inputs)\n\n        losses = {}\n\n        if self.with_traj:\n            x, traj_x = feats\n            # loss of trajectory model\n            losses.update(\n                self.traj_head.loss(\n                    traj_x, data_samples, train_cfg=self.train_cfg))\n        else:\n            x = feats\n\n        if self.with_head:\n            # loss of pose model\n            losses.update(\n                self.head.loss(x, data_samples, train_cfg=self.train_cfg))\n\n        # TODO: support semi-supervised learning\n        if self.semi_supervised:\n            losses.update(semi_loss=self.semi_loss(inputs, data_samples))\n\n        return losses\n\n    def predict(self, inputs: Tensor, data_samples: SampleList) -> SampleList:\n        \"\"\"Predict results from a batch of inputs and data samples with post-\n        processing.\n\n        Note:\n            - batch_size: B\n            - num_input_keypoints: K\n            - input_keypoint_dim: C\n            - input_sequence_len: T\n\n        Args:\n            inputs (Tensor): Inputs with shape like (B, K, C, T).\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n\n        Returns:\n            list[:obj:`PoseDataSample`]: The pose estimation results of the\n            input images. The return value is `PoseDataSample` instances with\n            ``pred_instances`` and ``pred_fields``(optional) field , and\n            ``pred_instances`` usually contains the following keys:\n\n                - keypoints (Tensor): predicted keypoint coordinates in shape\n                    (num_instances, K, D) where K is the keypoint number and D\n                    is the keypoint dimension\n                - keypoint_scores (Tensor): predicted keypoint scores in shape\n                    (num_instances, K)\n        \"\"\"\n        assert self.with_head, (\n            'The model must have head to perform prediction.')\n\n        if self.test_cfg.get('flip_test', False):\n            flip_indices = data_samples[0].metainfo['flip_indices']\n            _feats = self.extract_feat(inputs)\n            _feats_flip = self.extract_feat(\n                torch.stack([\n                    flip_coordinates(\n                        _input,\n                        flip_indices=flip_indices,\n                        shift_coords=self.test_cfg.get('shift_coords', True),\n                        input_size=(1, 1)) for _input in inputs\n                ],\n                            dim=0))\n\n            feats = [_feats, _feats_flip]\n        else:\n            feats = self.extract_feat(inputs)\n\n        pose_preds, batch_pred_instances, batch_pred_fields = None, None, None\n        traj_preds, batch_traj_instances, batch_traj_fields = None, None, None\n        if self.with_traj:\n            x, traj_x = feats\n            traj_preds = self.traj_head.predict(\n                traj_x, data_samples, test_cfg=self.test_cfg)\n        else:\n            x = feats\n\n        if self.with_head:\n            pose_preds = self.head.predict(\n                x, data_samples, test_cfg=self.test_cfg)\n\n        if isinstance(pose_preds, tuple):\n            batch_pred_instances, batch_pred_fields = pose_preds\n        else:\n            batch_pred_instances = pose_preds\n\n        if isinstance(traj_preds, tuple):\n            batch_traj_instances, batch_traj_fields = traj_preds\n        else:\n            batch_traj_instances = traj_preds\n\n        results = self.add_pred_to_datasample(batch_pred_instances,\n                                              batch_pred_fields,\n                                              batch_traj_instances,\n                                              batch_traj_fields, data_samples)\n\n        return results\n\n    def add_pred_to_datasample(\n        self,\n        batch_pred_instances: InstanceList,\n        batch_pred_fields: Optional[PixelDataList],\n        batch_traj_instances: InstanceList,\n        batch_traj_fields: Optional[PixelDataList],\n        batch_data_samples: SampleList,\n    ) -> SampleList:\n        \"\"\"Add predictions into data samples.\n\n        Args:\n            batch_pred_instances (List[InstanceData]): The predicted instances\n                of the input data batch\n            batch_pred_fields (List[PixelData], optional): The predicted\n                fields (e.g. heatmaps) of the input batch\n            batch_traj_instances (List[InstanceData]): The predicted instances\n                of the input data batch\n            batch_traj_fields (List[PixelData], optional): The predicted\n                fields (e.g. heatmaps) of the input batch\n            batch_data_samples (List[PoseDataSample]): The input data batch\n\n        Returns:\n            List[PoseDataSample]: A list of data samples where the predictions\n            are stored in the ``pred_instances`` field of each data sample.\n        \"\"\"\n        assert len(batch_pred_instances) == len(batch_data_samples)\n        if batch_pred_fields is None:\n            batch_pred_fields, batch_traj_fields = [], []\n        if batch_traj_instances is None:\n            batch_traj_instances = []\n        output_keypoint_indices = self.test_cfg.get('output_keypoint_indices',\n                                                    None)\n\n        for (pred_instances, pred_fields, traj_instances, traj_fields,\n             data_sample) in zip_longest(batch_pred_instances,\n                                         batch_pred_fields,\n                                         batch_traj_instances,\n                                         batch_traj_fields,\n                                         batch_data_samples):\n\n            if output_keypoint_indices is not None:\n                # select output keypoints with given indices\n                num_keypoints = pred_instances.keypoints.shape[1]\n                for key, value in pred_instances.all_items():\n                    if key.startswith('keypoint'):\n                        pred_instances.set_field(\n                            value[:, output_keypoint_indices], key)\n\n            data_sample.pred_instances = pred_instances\n\n            if pred_fields is not None:\n                if output_keypoint_indices is not None:\n                    # select output heatmap channels with keypoint indices\n                    # when the number of heatmap channel matches num_keypoints\n                    for key, value in pred_fields.all_items():\n                        if value.shape[0] != num_keypoints:\n                            continue\n                        pred_fields.set_field(value[output_keypoint_indices],\n                                              key)\n                data_sample.pred_fields = pred_fields\n\n        return batch_data_samples\n"
  },
  {
    "path": "mmpose/models/pose_estimators/topdown.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import zip_longest\nfrom typing import Optional\n\nfrom torch import Tensor\n\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptMultiConfig, PixelDataList, SampleList)\nfrom .base import BasePoseEstimator\n\n\n@MODELS.register_module()\nclass TopdownPoseEstimator(BasePoseEstimator):\n    \"\"\"Base class for top-down pose estimators.\n\n    Args:\n        backbone (dict): The backbone config\n        neck (dict, optional): The neck config. Defaults to ``None``\n        head (dict, optional): The head config. Defaults to ``None``\n        train_cfg (dict, optional): The runtime config for training process.\n            Defaults to ``None``\n        test_cfg (dict, optional): The runtime config for testing process.\n            Defaults to ``None``\n        data_preprocessor (dict, optional): The data preprocessing config to\n            build the instance of :class:`BaseDataPreprocessor`. Defaults to\n            ``None``\n        init_cfg (dict, optional): The config to control the initialization.\n            Defaults to ``None``\n        metainfo (dict): Meta information for dataset, such as keypoints\n            definition and properties. If set, the metainfo of the input data\n            batch will be overridden. For more details, please refer to\n            https://mmpose.readthedocs.io/en/latest/user_guides/\n            prepare_datasets.html#create-a-custom-dataset-info-\n            config-file-for-the-dataset. Defaults to ``None``\n    \"\"\"\n\n    def __init__(self,\n                 backbone: ConfigType,\n                 neck: OptConfigType = None,\n                 head: OptConfigType = None,\n                 train_cfg: OptConfigType = None,\n                 test_cfg: OptConfigType = None,\n                 data_preprocessor: OptConfigType = None,\n                 init_cfg: OptMultiConfig = None,\n                 metainfo: Optional[dict] = None):\n        super().__init__(\n            backbone=backbone,\n            neck=neck,\n            head=head,\n            train_cfg=train_cfg,\n            test_cfg=test_cfg,\n            data_preprocessor=data_preprocessor,\n            init_cfg=init_cfg,\n            metainfo=metainfo)\n\n    def loss(self, inputs: Tensor, data_samples: SampleList) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W).\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples.\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        feats = self.extract_feat(inputs)\n\n        losses = dict()\n\n        if self.with_head:\n            losses.update(\n                self.head.loss(feats, data_samples, train_cfg=self.train_cfg))\n\n        return losses\n\n    def predict(self, inputs: Tensor, data_samples: SampleList) -> SampleList:\n        \"\"\"Predict results from a batch of inputs and data samples with post-\n        processing.\n\n        Args:\n            inputs (Tensor): Inputs with shape (N, C, H, W)\n            data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n\n        Returns:\n            list[:obj:`PoseDataSample`]: The pose estimation results of the\n            input images. The return value is `PoseDataSample` instances with\n            ``pred_instances`` and ``pred_fields``(optional) field , and\n            ``pred_instances`` usually contains the following keys:\n\n                - keypoints (Tensor): predicted keypoint coordinates in shape\n                    (num_instances, K, D) where K is the keypoint number and D\n                    is the keypoint dimension\n                - keypoint_scores (Tensor): predicted keypoint scores in shape\n                    (num_instances, K)\n        \"\"\"\n        assert self.with_head, (\n            'The model must have head to perform prediction.')\n\n        if self.test_cfg.get('flip_test', False):\n            _feats = self.extract_feat(inputs)\n            _feats_flip = self.extract_feat(inputs.flip(-1))\n            feats = [_feats, _feats_flip]\n        else:\n            feats = self.extract_feat(inputs)\n\n        preds = self.head.predict(feats, data_samples, test_cfg=self.test_cfg)\n\n        if isinstance(preds, tuple):\n            batch_pred_instances, batch_pred_fields = preds\n        else:\n            batch_pred_instances = preds\n            batch_pred_fields = None\n\n        results = self.add_pred_to_datasample(batch_pred_instances,\n                                              batch_pred_fields, data_samples)\n\n        return results\n\n    def add_pred_to_datasample(self, batch_pred_instances: InstanceList,\n                               batch_pred_fields: Optional[PixelDataList],\n                               batch_data_samples: SampleList) -> SampleList:\n        \"\"\"Add predictions into data samples.\n\n        Args:\n            batch_pred_instances (List[InstanceData]): The predicted instances\n                of the input data batch\n            batch_pred_fields (List[PixelData], optional): The predicted\n                fields (e.g. heatmaps) of the input batch\n            batch_data_samples (List[PoseDataSample]): The input data batch\n\n        Returns:\n            List[PoseDataSample]: A list of data samples where the predictions\n            are stored in the ``pred_instances`` field of each data sample.\n        \"\"\"\n        assert len(batch_pred_instances) == len(batch_data_samples)\n        if batch_pred_fields is None:\n            batch_pred_fields = []\n        output_keypoint_indices = self.test_cfg.get('output_keypoint_indices',\n                                                    None)\n\n        for pred_instances, pred_fields, data_sample in zip_longest(\n                batch_pred_instances, batch_pred_fields, batch_data_samples):\n\n            gt_instances = data_sample.gt_instances\n\n            # convert keypoint coordinates from input space to image space\n            input_center = data_sample.metainfo['input_center']\n            input_scale = data_sample.metainfo['input_scale']\n            input_size = data_sample.metainfo['input_size']\n\n            pred_instances.keypoints[..., :2] = \\\n                pred_instances.keypoints[..., :2] / input_size * input_scale \\\n                + input_center - 0.5 * input_scale\n            if 'keypoints_visible' not in pred_instances:\n                pred_instances.keypoints_visible = \\\n                    pred_instances.keypoint_scores\n\n            if output_keypoint_indices is not None:\n                # select output keypoints with given indices\n                num_keypoints = pred_instances.keypoints.shape[1]\n                for key, value in pred_instances.all_items():\n                    if key.startswith('keypoint'):\n                        pred_instances.set_field(\n                            value[:, output_keypoint_indices], key)\n\n            # add bbox information into pred_instances\n            pred_instances.bboxes = gt_instances.bboxes\n            pred_instances.bbox_scores = gt_instances.bbox_scores\n\n            data_sample.pred_instances = pred_instances\n\n            if pred_fields is not None:\n                if output_keypoint_indices is not None:\n                    # select output heatmap channels with keypoint indices\n                    # when the number of heatmap channel matches num_keypoints\n                    for key, value in pred_fields.all_items():\n                        if value.shape[0] != num_keypoints:\n                            continue\n                        pred_fields.set_field(value[output_keypoint_indices],\n                                              key)\n                data_sample.pred_fields = pred_fields\n\n        return batch_data_samples\n"
  },
  {
    "path": "mmpose/models/task_modules/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .assigners import *  # noqa\nfrom .prior_generators import *  # noqa\n"
  },
  {
    "path": "mmpose/models/task_modules/assigners/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .metric_calculators import BBoxOverlaps2D, PoseOKS\nfrom .sim_ota_assigner import SimOTAAssigner\n\n__all__ = ['SimOTAAssigner', 'PoseOKS', 'BBoxOverlaps2D']\n"
  },
  {
    "path": "mmpose/models/task_modules/assigners/metric_calculators.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional\n\nimport torch\nfrom torch import Tensor\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.registry import TASK_UTILS\nfrom mmpose.structures.bbox import bbox_overlaps\n\n\ndef cast_tensor_type(x, scale=1., dtype=None):\n    if dtype == 'fp16':\n        # scale is for preventing overflows\n        x = (x / scale).half()\n    return x\n\n\n@TASK_UTILS.register_module()\nclass BBoxOverlaps2D:\n    \"\"\"2D Overlaps (e.g. IoUs, GIoUs) Calculator.\"\"\"\n\n    def __init__(self, scale=1., dtype=None):\n        self.scale = scale\n        self.dtype = dtype\n\n    @torch.no_grad()\n    def __call__(self, bboxes1, bboxes2, mode='iou', is_aligned=False):\n        \"\"\"Calculate IoU between 2D bboxes.\n\n        Args:\n            bboxes1 (Tensor or :obj:`BaseBoxes`): bboxes have shape (m, 4)\n                in <x1, y1, x2, y2> format, or shape (m, 5) in <x1, y1, x2,\n                y2, score> format.\n            bboxes2 (Tensor or :obj:`BaseBoxes`): bboxes have shape (m, 4)\n                in <x1, y1, x2, y2> format, shape (m, 5) in <x1, y1, x2, y2,\n                score> format, or be empty. If ``is_aligned `` is ``True``,\n                then m and n must be equal.\n            mode (str): \"iou\" (intersection over union), \"iof\" (intersection\n                over foreground), or \"giou\" (generalized intersection over\n                union).\n            is_aligned (bool, optional): If True, then m and n must be equal.\n                Default False.\n\n        Returns:\n            Tensor: shape (m, n) if ``is_aligned `` is False else shape (m,)\n        \"\"\"\n        assert bboxes1.size(-1) in [0, 4, 5]\n        assert bboxes2.size(-1) in [0, 4, 5]\n        if bboxes2.size(-1) == 5:\n            bboxes2 = bboxes2[..., :4]\n        if bboxes1.size(-1) == 5:\n            bboxes1 = bboxes1[..., :4]\n\n        if self.dtype == 'fp16':\n            # change tensor type to save cpu and cuda memory and keep speed\n            bboxes1 = cast_tensor_type(bboxes1, self.scale, self.dtype)\n            bboxes2 = cast_tensor_type(bboxes2, self.scale, self.dtype)\n            overlaps = bbox_overlaps(bboxes1, bboxes2, mode, is_aligned)\n            if not overlaps.is_cuda and overlaps.dtype == torch.float16:\n                # resume cpu float32\n                overlaps = overlaps.float()\n            return overlaps\n\n        return bbox_overlaps(bboxes1, bboxes2, mode, is_aligned)\n\n    def __repr__(self):\n        \"\"\"str: a string describing the module\"\"\"\n        repr_str = self.__class__.__name__ + f'(' \\\n            f'scale={self.scale}, dtype={self.dtype})'\n        return repr_str\n\n\n@TASK_UTILS.register_module()\nclass PoseOKS:\n    \"\"\"OKS score Calculator.\"\"\"\n\n    def __init__(self,\n                 metainfo: Optional[str] = 'configs/_base_/datasets/coco.py'):\n\n        if metainfo is not None:\n            metainfo = parse_pose_metainfo(dict(from_file=metainfo))\n            sigmas = metainfo.get('sigmas', None)\n            if sigmas is not None:\n                self.sigmas = torch.as_tensor(sigmas)\n\n    @torch.no_grad()\n    def __call__(self,\n                 output: Tensor,\n                 target: Tensor,\n                 target_weights: Tensor,\n                 areas: Tensor,\n                 eps: float = 1e-8) -> Tensor:\n\n        dist = torch.norm(output - target, dim=-1)\n        areas = areas.reshape(*((1, ) * (dist.ndim - 2)), -1, 1)\n        dist = dist / areas.pow(0.5).clip(min=eps)\n\n        if hasattr(self, 'sigmas'):\n            if self.sigmas.device != dist.device:\n                self.sigmas = self.sigmas.to(dist.device)\n            sigmas = self.sigmas.reshape(*((1, ) * (dist.ndim - 1)), -1)\n            dist = dist / (sigmas * 2)\n\n        target_weights = target_weights / target_weights.sum(\n            dim=-1, keepdims=True).clip(min=eps)\n        oks = (torch.exp(-dist.pow(2) / 2) * target_weights).sum(dim=-1)\n        return oks\n"
  },
  {
    "path": "mmpose/models/task_modules/assigners/sim_ota_assigner.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport torch\nimport torch.nn.functional as F\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor\n\nfrom mmpose.registry import TASK_UTILS\nfrom mmpose.utils.typing import ConfigType\n\nINF = 100000.0\nEPS = 1.0e-7\n\n\n@TASK_UTILS.register_module()\nclass SimOTAAssigner:\n    \"\"\"Computes matching between predictions and ground truth.\n\n    Args:\n        center_radius (float): Radius of center area to determine\n            if a prior is in the center of a gt. Defaults to 2.5.\n        candidate_topk (int): Top-k ious candidates to calculate dynamic-k.\n            Defaults to 10.\n        iou_weight (float): Weight of bbox iou cost. Defaults to 3.0.\n        cls_weight (float): Weight of classification cost. Defaults to 1.0.\n        oks_weight (float): Weight of keypoint OKS cost. Defaults to 3.0.\n        vis_weight (float): Weight of keypoint visibility cost. Defaults to 0.0\n        dynamic_k_indicator (str): Cost type for calculating dynamic-k,\n            either 'iou' or 'oks'. Defaults to 'iou'.\n        use_keypoints_for_center (bool): Whether to use keypoints to determine\n            if a prior is in the center of a gt. Defaults to False.\n        iou_calculator (dict): Config of IoU calculation method.\n            Defaults to dict(type='BBoxOverlaps2D').\n        oks_calculator (dict): Config of OKS calculation method.\n            Defaults to dict(type='PoseOKS').\n    \"\"\"\n\n    def __init__(self,\n                 center_radius: float = 2.5,\n                 candidate_topk: int = 10,\n                 iou_weight: float = 3.0,\n                 cls_weight: float = 1.0,\n                 oks_weight: float = 3.0,\n                 vis_weight: float = 0.0,\n                 dynamic_k_indicator: str = 'iou',\n                 use_keypoints_for_center: bool = False,\n                 iou_calculator: ConfigType = dict(type='BBoxOverlaps2D'),\n                 oks_calculator: ConfigType = dict(type='PoseOKS')):\n        self.center_radius = center_radius\n        self.candidate_topk = candidate_topk\n        self.iou_weight = iou_weight\n        self.cls_weight = cls_weight\n        self.oks_weight = oks_weight\n        self.vis_weight = vis_weight\n        assert dynamic_k_indicator in ('iou', 'oks'), f'the argument ' \\\n            f'`dynamic_k_indicator` should be either \\'iou\\' or \\'oks\\', ' \\\n            f'but got {dynamic_k_indicator}'\n        self.dynamic_k_indicator = dynamic_k_indicator\n\n        self.use_keypoints_for_center = use_keypoints_for_center\n        self.iou_calculator = TASK_UTILS.build(iou_calculator)\n        self.oks_calculator = TASK_UTILS.build(oks_calculator)\n\n    def assign(self, pred_instances: InstanceData, gt_instances: InstanceData,\n               **kwargs) -> dict:\n        \"\"\"Assign gt to priors using SimOTA.\n\n        Args:\n            pred_instances (:obj:`InstanceData`): Instances of model\n                predictions. It includes ``priors``, and the priors can\n                be anchors or points, or the bboxes predicted by the\n                previous stage, has shape (n, 4). The bboxes predicted by\n                the current model or stage will be named ``bboxes``,\n                ``labels``, and ``scores``, the same as the ``InstanceData``\n                in other places.\n            gt_instances (:obj:`InstanceData`): Ground truth of instance\n                annotations. It usually includes ``bboxes``, with shape (k, 4),\n                and ``labels``, with shape (k, ).\n        Returns:\n            dict: Assignment result containing assigned gt indices,\n                max iou overlaps, assigned labels, etc.\n        \"\"\"\n        gt_bboxes = gt_instances.bboxes\n        gt_labels = gt_instances.labels\n        gt_keypoints = gt_instances.keypoints\n        gt_keypoints_visible = gt_instances.keypoints_visible\n        gt_areas = gt_instances.areas\n        num_gt = gt_bboxes.size(0)\n\n        decoded_bboxes = pred_instances.bboxes\n        pred_scores = pred_instances.scores\n        priors = pred_instances.priors\n        keypoints = pred_instances.keypoints\n        keypoints_visible = pred_instances.keypoints_visible\n        num_bboxes = decoded_bboxes.size(0)\n\n        # assign 0 by default\n        assigned_gt_inds = decoded_bboxes.new_full((num_bboxes, ),\n                                                   0,\n                                                   dtype=torch.long)\n        if num_gt == 0 or num_bboxes == 0:\n            # No ground truth or boxes, return empty assignment\n            max_overlaps = decoded_bboxes.new_zeros((num_bboxes, ))\n            assigned_labels = decoded_bboxes.new_full((num_bboxes, ),\n                                                      -1,\n                                                      dtype=torch.long)\n            return dict(\n                num_gts=num_gt,\n                gt_inds=assigned_gt_inds,\n                max_overlaps=max_overlaps,\n                labels=assigned_labels)\n\n        valid_mask, is_in_boxes_and_center = self.get_in_gt_and_in_center_info(\n            priors, gt_bboxes, gt_keypoints, gt_keypoints_visible)\n        valid_decoded_bbox = decoded_bboxes[valid_mask]\n        valid_pred_scores = pred_scores[valid_mask]\n        valid_pred_kpts = keypoints[valid_mask]\n        valid_pred_kpts_vis = keypoints_visible[valid_mask]\n\n        num_valid = valid_decoded_bbox.size(0)\n        if num_valid == 0:\n            # No valid bboxes, return empty assignment\n            max_overlaps = decoded_bboxes.new_zeros((num_bboxes, ))\n            assigned_labels = decoded_bboxes.new_full((num_bboxes, ),\n                                                      -1,\n                                                      dtype=torch.long)\n            return dict(\n                num_gts=num_gt,\n                gt_inds=assigned_gt_inds,\n                max_overlaps=max_overlaps,\n                labels=assigned_labels)\n\n        cost_matrix = (~is_in_boxes_and_center) * INF\n\n        # calculate iou\n        pairwise_ious = self.iou_calculator(valid_decoded_bbox, gt_bboxes)\n        if self.iou_weight > 0:\n            iou_cost = -torch.log(pairwise_ious + EPS)\n            cost_matrix = cost_matrix + iou_cost * self.iou_weight\n\n        # calculate oks\n        if self.oks_weight > 0 or self.dynamic_k_indicator == 'oks':\n            pairwise_oks = self.oks_calculator(\n                valid_pred_kpts.unsqueeze(1),  # [num_valid, 1, k, 2]\n                target=gt_keypoints.unsqueeze(0),  # [1, num_gt, k, 2]\n                target_weights=gt_keypoints_visible.unsqueeze(\n                    0),  # [1, num_gt, k]\n                areas=gt_areas.unsqueeze(0),  # [1, num_gt]\n            )  # -> [num_valid, num_gt]\n\n            oks_cost = -torch.log(pairwise_oks + EPS)\n            cost_matrix = cost_matrix + oks_cost * self.oks_weight\n\n        # calculate cls\n        if self.cls_weight > 0:\n            gt_onehot_label = (\n                F.one_hot(gt_labels.to(torch.int64),\n                          pred_scores.shape[-1]).float().unsqueeze(0).repeat(\n                              num_valid, 1, 1))\n            valid_pred_scores = valid_pred_scores.unsqueeze(1).repeat(\n                1, num_gt, 1)\n            # disable AMP autocast to avoid overflow\n            with torch.cuda.amp.autocast(enabled=False):\n                cls_cost = (\n                    F.binary_cross_entropy(\n                        valid_pred_scores.to(dtype=torch.float32),\n                        gt_onehot_label,\n                        reduction='none',\n                    ).sum(-1).to(dtype=valid_pred_scores.dtype))\n            cost_matrix = cost_matrix + cls_cost * self.cls_weight\n        # calculate vis\n        if self.vis_weight > 0:\n            valid_pred_kpts_vis = valid_pred_kpts_vis.unsqueeze(1).repeat(\n                1, num_gt, 1)  # [num_valid, 1, k]\n            gt_kpt_vis = gt_keypoints_visible.unsqueeze(\n                0).float()  # [1, num_gt, k]\n            with torch.cuda.amp.autocast(enabled=False):\n                vis_cost = (\n                    F.binary_cross_entropy(\n                        valid_pred_kpts_vis.to(dtype=torch.float32),\n                        gt_kpt_vis.repeat(num_valid, 1, 1),\n                        reduction='none',\n                    ).sum(-1).to(dtype=valid_pred_kpts_vis.dtype))\n            cost_matrix = cost_matrix + vis_cost * self.vis_weight\n\n        if self.dynamic_k_indicator == 'iou':\n            matched_pred_ious, matched_gt_inds = \\\n                self.dynamic_k_matching(\n                    cost_matrix, pairwise_ious, num_gt, valid_mask)\n        elif self.dynamic_k_indicator == 'oks':\n            matched_pred_ious, matched_gt_inds = \\\n                self.dynamic_k_matching(\n                    cost_matrix, pairwise_oks, num_gt, valid_mask)\n\n        # convert to AssignResult format\n        assigned_gt_inds[valid_mask] = matched_gt_inds + 1\n        assigned_labels = assigned_gt_inds.new_full((num_bboxes, ), -1)\n        assigned_labels[valid_mask] = gt_labels[matched_gt_inds].long()\n        max_overlaps = assigned_gt_inds.new_full((num_bboxes, ),\n                                                 -INF,\n                                                 dtype=torch.float32)\n        max_overlaps[valid_mask] = matched_pred_ious.to(max_overlaps)\n        return dict(\n            num_gts=num_gt,\n            gt_inds=assigned_gt_inds,\n            max_overlaps=max_overlaps,\n            labels=assigned_labels)\n\n    def get_in_gt_and_in_center_info(\n        self,\n        priors: Tensor,\n        gt_bboxes: Tensor,\n        gt_keypoints: Optional[Tensor] = None,\n        gt_keypoints_visible: Optional[Tensor] = None,\n    ) -> Tuple[Tensor, Tensor]:\n        \"\"\"Get the information of which prior is in gt bboxes and gt center\n        priors.\"\"\"\n        num_gt = gt_bboxes.size(0)\n\n        repeated_x = priors[:, 0].unsqueeze(1).repeat(1, num_gt)\n        repeated_y = priors[:, 1].unsqueeze(1).repeat(1, num_gt)\n        repeated_stride_x = priors[:, 2].unsqueeze(1).repeat(1, num_gt)\n        repeated_stride_y = priors[:, 3].unsqueeze(1).repeat(1, num_gt)\n\n        # is prior centers in gt bboxes, shape: [n_prior, n_gt]\n        l_ = repeated_x - gt_bboxes[:, 0]\n        t_ = repeated_y - gt_bboxes[:, 1]\n        r_ = gt_bboxes[:, 2] - repeated_x\n        b_ = gt_bboxes[:, 3] - repeated_y\n\n        deltas = torch.stack([l_, t_, r_, b_], dim=1)\n        is_in_gts = deltas.min(dim=1).values > 0\n        is_in_gts_all = is_in_gts.sum(dim=1) > 0\n\n        # is prior centers in gt centers\n        gt_cxs = (gt_bboxes[:, 0] + gt_bboxes[:, 2]) / 2.0\n        gt_cys = (gt_bboxes[:, 1] + gt_bboxes[:, 3]) / 2.0\n        if self.use_keypoints_for_center and gt_keypoints_visible is not None:\n            gt_kpts_cts = (gt_keypoints * gt_keypoints_visible.unsqueeze(-1)\n                           ).sum(dim=-2) / gt_keypoints_visible.sum(\n                               dim=-1, keepdims=True).clip(min=0)\n            gt_kpts_cts = gt_kpts_cts.to(gt_bboxes)\n            valid_mask = gt_keypoints_visible.sum(-1) > 0\n            gt_cxs[valid_mask] = gt_kpts_cts[valid_mask][..., 0]\n            gt_cys[valid_mask] = gt_kpts_cts[valid_mask][..., 1]\n\n        ct_box_l = gt_cxs - self.center_radius * repeated_stride_x\n        ct_box_t = gt_cys - self.center_radius * repeated_stride_y\n        ct_box_r = gt_cxs + self.center_radius * repeated_stride_x\n        ct_box_b = gt_cys + self.center_radius * repeated_stride_y\n\n        cl_ = repeated_x - ct_box_l\n        ct_ = repeated_y - ct_box_t\n        cr_ = ct_box_r - repeated_x\n        cb_ = ct_box_b - repeated_y\n\n        ct_deltas = torch.stack([cl_, ct_, cr_, cb_], dim=1)\n        is_in_cts = ct_deltas.min(dim=1).values > 0\n        is_in_cts_all = is_in_cts.sum(dim=1) > 0\n\n        # in boxes or in centers, shape: [num_priors]\n        is_in_gts_or_centers = is_in_gts_all | is_in_cts_all\n\n        # both in boxes and centers, shape: [num_fg, num_gt]\n        is_in_boxes_and_centers = (\n            is_in_gts[is_in_gts_or_centers, :]\n            & is_in_cts[is_in_gts_or_centers, :])\n        return is_in_gts_or_centers, is_in_boxes_and_centers\n\n    def dynamic_k_matching(self, cost: Tensor, pairwise_ious: Tensor,\n                           num_gt: int,\n                           valid_mask: Tensor) -> Tuple[Tensor, Tensor]:\n        \"\"\"Use IoU and matching cost to calculate the dynamic top-k positive\n        targets.\"\"\"\n        matching_matrix = torch.zeros_like(cost, dtype=torch.uint8)\n        # select candidate topk ious for dynamic-k calculation\n        candidate_topk = min(self.candidate_topk, pairwise_ious.size(0))\n        topk_ious, _ = torch.topk(pairwise_ious, candidate_topk, dim=0)\n        # calculate dynamic k for each gt\n        dynamic_ks = torch.clamp(topk_ious.sum(0).int(), min=1)\n        for gt_idx in range(num_gt):\n            _, pos_idx = torch.topk(\n                cost[:, gt_idx], k=dynamic_ks[gt_idx], largest=False)\n            matching_matrix[:, gt_idx][pos_idx] = 1\n\n        del topk_ious, dynamic_ks, pos_idx\n\n        prior_match_gt_mask = matching_matrix.sum(1) > 1\n        if prior_match_gt_mask.sum() > 0:\n            cost_min, cost_argmin = torch.min(\n                cost[prior_match_gt_mask, :], dim=1)\n            matching_matrix[prior_match_gt_mask, :] *= 0\n            matching_matrix[prior_match_gt_mask, cost_argmin] = 1\n        # get foreground mask inside box and center prior\n        fg_mask_inboxes = matching_matrix.sum(1) > 0\n        valid_mask[valid_mask.clone()] = fg_mask_inboxes\n\n        matched_gt_inds = matching_matrix[fg_mask_inboxes, :].argmax(1)\n        matched_pred_ious = (matching_matrix *\n                             pairwise_ious).sum(1)[fg_mask_inboxes]\n        return matched_pred_ious, matched_gt_inds\n"
  },
  {
    "path": "mmpose/models/task_modules/prior_generators/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .mlvl_point_generator import MlvlPointGenerator  # noqa\n"
  },
  {
    "path": "mmpose/models/task_modules/prior_generators/mlvl_point_generator.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple, Union\n\nimport numpy as np\nimport torch\nfrom torch import Tensor\nfrom torch.nn.modules.utils import _pair\n\nfrom mmpose.registry import TASK_UTILS\n\nDeviceType = Union[str, torch.device]\n\n\n@TASK_UTILS.register_module()\nclass MlvlPointGenerator:\n    \"\"\"Standard points generator for multi-level (Mlvl) feature maps in 2D\n    points-based detectors.\n\n    Args:\n        strides (list[int] | list[tuple[int, int]]): Strides of anchors\n            in multiple feature levels in order (w, h).\n        offset (float): The offset of points, the value is normalized with\n            corresponding stride. Defaults to 0.5.\n        centralize_points (bool): Whether to centralize the points to\n            the center of anchors. Defaults to False.\n    \"\"\"\n\n    def __init__(self,\n                 strides: Union[List[int], List[Tuple[int, int]]],\n                 offset: float = 0.5,\n                 centralize_points: bool = False) -> None:\n        self.strides = [_pair(stride) for stride in strides]\n        self.centralize_points = centralize_points\n        self.offset = offset if not centralize_points else 0.0\n\n    @property\n    def num_levels(self) -> int:\n        \"\"\"int: number of feature levels that the generator will be applied\"\"\"\n        return len(self.strides)\n\n    @property\n    def num_base_priors(self) -> List[int]:\n        \"\"\"list[int]: The number of priors (points) at a point\n        on the feature grid\"\"\"\n        return [1 for _ in range(len(self.strides))]\n\n    def _meshgrid(self,\n                  x: Tensor,\n                  y: Tensor,\n                  row_major: bool = True) -> Tuple[Tensor, Tensor]:\n        yy, xx = torch.meshgrid(y, x)\n        if row_major:\n            # warning .flatten() would cause error in ONNX exporting\n            # have to use reshape here\n            return xx.reshape(-1), yy.reshape(-1)\n\n        else:\n            return yy.reshape(-1), xx.reshape(-1)\n\n    def grid_priors(self,\n                    featmap_sizes: List[Tuple],\n                    dtype: torch.dtype = torch.float32,\n                    device: DeviceType = 'cuda',\n                    with_stride: bool = False) -> List[Tensor]:\n        \"\"\"Generate grid points of multiple feature levels.\n\n        Args:\n            featmap_sizes (list[tuple]): List of feature map sizes in\n                multiple feature levels, each size arrange as\n                as (h, w).\n            dtype (:obj:`dtype`): Dtype of priors. Defaults to torch.float32.\n            device (str | torch.device): The device where the anchors will be\n                put on.\n            with_stride (bool): Whether to concatenate the stride to\n                the last dimension of points.\n\n        Return:\n            list[torch.Tensor]: Points of  multiple feature levels.\n            The sizes of each tensor should be (N, 2) when with stride is\n            ``False``, where N = width * height, width and height\n            are the sizes of the corresponding feature level,\n            and the last dimension 2 represent (coord_x, coord_y),\n            otherwise the shape should be (N, 4),\n            and the last dimension 4 represent\n            (coord_x, coord_y, stride_w, stride_h).\n        \"\"\"\n\n        assert self.num_levels == len(featmap_sizes)\n        multi_level_priors = []\n        for i in range(self.num_levels):\n            priors = self.single_level_grid_priors(\n                featmap_sizes[i],\n                level_idx=i,\n                dtype=dtype,\n                device=device,\n                with_stride=with_stride)\n            multi_level_priors.append(priors)\n        return multi_level_priors\n\n    def single_level_grid_priors(self,\n                                 featmap_size: Tuple[int],\n                                 level_idx: int,\n                                 dtype: torch.dtype = torch.float32,\n                                 device: DeviceType = 'cuda',\n                                 with_stride: bool = False) -> Tensor:\n        \"\"\"Generate grid Points of a single level.\n\n        Note:\n            This function is usually called by method ``self.grid_priors``.\n\n        Args:\n            featmap_size (tuple[int]): Size of the feature maps, arrange as\n                (h, w).\n            level_idx (int): The index of corresponding feature map level.\n            dtype (:obj:`dtype`): Dtype of priors. Defaults to torch.float32.\n            device (str | torch.device): The device the tensor will be put on.\n                Defaults to 'cuda'.\n            with_stride (bool): Concatenate the stride to the last dimension\n                of points.\n\n        Return:\n            Tensor: Points of single feature levels.\n            The shape of tensor should be (N, 2) when with stride is\n            ``False``, where N = width * height, width and height\n            are the sizes of the corresponding feature level,\n            and the last dimension 2 represent (coord_x, coord_y),\n            otherwise the shape should be (N, 4),\n            and the last dimension 4 represent\n            (coord_x, coord_y, stride_w, stride_h).\n        \"\"\"\n        feat_h, feat_w = featmap_size\n        stride_w, stride_h = self.strides[level_idx]\n        shift_x = (torch.arange(0, feat_w, device=device) +\n                   self.offset) * stride_w\n        # keep featmap_size as Tensor instead of int, so that we\n        # can convert to ONNX correctly\n        shift_x = shift_x.to(dtype)\n\n        shift_y = (torch.arange(0, feat_h, device=device) +\n                   self.offset) * stride_h\n        # keep featmap_size as Tensor instead of int, so that we\n        # can convert to ONNX correctly\n        shift_y = shift_y.to(dtype)\n\n        if self.centralize_points:\n            shift_x = shift_x + float(stride_w - 1) / 2.0\n            shift_y = shift_y + float(stride_h - 1) / 2.0\n\n        shift_xx, shift_yy = self._meshgrid(shift_x, shift_y)\n        if not with_stride:\n            shifts = torch.stack([shift_xx, shift_yy], dim=-1)\n        else:\n            # use `shape[0]` instead of `len(shift_xx)` for ONNX export\n            stride_w = shift_xx.new_full((shift_xx.shape[0], ),\n                                         stride_w).to(dtype)\n            stride_h = shift_xx.new_full((shift_yy.shape[0], ),\n                                         stride_h).to(dtype)\n            shifts = torch.stack([shift_xx, shift_yy, stride_w, stride_h],\n                                 dim=-1)\n        all_points = shifts.to(device)\n        return all_points\n\n    def valid_flags(self,\n                    featmap_sizes: List[Tuple[int, int]],\n                    pad_shape: Tuple[int],\n                    device: DeviceType = 'cuda') -> List[Tensor]:\n        \"\"\"Generate valid flags of points of multiple feature levels.\n\n        Args:\n            featmap_sizes (list(tuple)): List of feature map sizes in\n                multiple feature levels, each size arrange as\n                as (h, w).\n            pad_shape (tuple(int)): The padded shape of the image,\n                arrange as (h, w).\n            device (str | torch.device): The device where the anchors will be\n                put on.\n\n        Return:\n            list(torch.Tensor): Valid flags of points of multiple levels.\n        \"\"\"\n        assert self.num_levels == len(featmap_sizes)\n        multi_level_flags = []\n        for i in range(self.num_levels):\n            point_stride = self.strides[i]\n            feat_h, feat_w = featmap_sizes[i]\n            h, w = pad_shape[:2]\n            valid_feat_h = min(int(np.ceil(h / point_stride[1])), feat_h)\n            valid_feat_w = min(int(np.ceil(w / point_stride[0])), feat_w)\n            flags = self.single_level_valid_flags((feat_h, feat_w),\n                                                  (valid_feat_h, valid_feat_w),\n                                                  device=device)\n            multi_level_flags.append(flags)\n        return multi_level_flags\n\n    def single_level_valid_flags(self,\n                                 featmap_size: Tuple[int, int],\n                                 valid_size: Tuple[int, int],\n                                 device: DeviceType = 'cuda') -> Tensor:\n        \"\"\"Generate the valid flags of points of a single feature map.\n\n        Args:\n            featmap_size (tuple[int]): The size of feature maps, arrange as\n                as (h, w).\n            valid_size (tuple[int]): The valid size of the feature maps.\n                The size arrange as as (h, w).\n            device (str | torch.device): The device where the flags will be\n            put on. Defaults to 'cuda'.\n\n        Returns:\n            torch.Tensor: The valid flags of each points in a single level \\\n                feature map.\n        \"\"\"\n        feat_h, feat_w = featmap_size\n        valid_h, valid_w = valid_size\n        assert valid_h <= feat_h and valid_w <= feat_w\n        valid_x = torch.zeros(feat_w, dtype=torch.bool, device=device)\n        valid_y = torch.zeros(feat_h, dtype=torch.bool, device=device)\n        valid_x[:valid_w] = 1\n        valid_y[:valid_h] = 1\n        valid_xx, valid_yy = self._meshgrid(valid_x, valid_y)\n        valid = valid_xx & valid_yy\n        return valid\n\n    def sparse_priors(self,\n                      prior_idxs: Tensor,\n                      featmap_size: Tuple[int],\n                      level_idx: int,\n                      dtype: torch.dtype = torch.float32,\n                      device: DeviceType = 'cuda') -> Tensor:\n        \"\"\"Generate sparse points according to the ``prior_idxs``.\n\n        Args:\n            prior_idxs (Tensor): The index of corresponding anchors\n                in the feature map.\n            featmap_size (tuple[int]): feature map size arrange as (w, h).\n            level_idx (int): The level index of corresponding feature\n                map.\n            dtype (obj:`torch.dtype`): Date type of points. Defaults to\n                ``torch.float32``.\n            device (str | torch.device): The device where the points is\n                located.\n        Returns:\n            Tensor: Anchor with shape (N, 2), N should be equal to\n            the length of ``prior_idxs``. And last dimension\n            2 represent (coord_x, coord_y).\n        \"\"\"\n        height, width = featmap_size\n        x = (prior_idxs % width + self.offset) * self.strides[level_idx][0]\n        y = ((prior_idxs // width) % height +\n             self.offset) * self.strides[level_idx][1]\n        prioris = torch.stack([x, y], 1).to(dtype)\n        prioris = prioris.to(device)\n        return prioris\n"
  },
  {
    "path": "mmpose/models/utils/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .check_and_update_config import check_and_update_config\nfrom .ckpt_convert import pvt_convert\nfrom .csp_layer import CSPLayer\nfrom .misc import filter_scores_and_topk\nfrom .ops import FrozenBatchNorm2d, inverse_sigmoid\nfrom .reparam_layers import RepVGGBlock\nfrom .rtmcc_block import RTMCCBlock, rope\nfrom .transformer import (DetrTransformerEncoder, GAUEncoder, PatchEmbed,\n                          SinePositionalEncoding, nchw_to_nlc, nlc_to_nchw)\n\n__all__ = [\n    'PatchEmbed', 'nchw_to_nlc', 'nlc_to_nchw', 'pvt_convert', 'RTMCCBlock',\n    'rope', 'check_and_update_config', 'filter_scores_and_topk', 'CSPLayer',\n    'FrozenBatchNorm2d', 'inverse_sigmoid', 'GAUEncoder',\n    'SinePositionalEncoding', 'RepVGGBlock', 'DetrTransformerEncoder'\n]\n"
  },
  {
    "path": "mmpose/models/utils/check_and_update_config.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, Optional, Tuple, Union\n\nfrom mmengine.config import Config, ConfigDict\nfrom mmengine.dist import master_only\nfrom mmengine.logging import MMLogger\n\nConfigType = Union[Config, ConfigDict]\n\n\ndef process_input_transform(input_transform: str, head: Dict, head_new: Dict,\n                            head_deleted_dict: Dict, head_append_dict: Dict,\n                            neck_new: Dict, input_index: Tuple[int],\n                            align_corners: bool) -> None:\n    \"\"\"Process the input_transform field and update head and neck\n    dictionaries.\"\"\"\n    if input_transform == 'resize_concat':\n        in_channels = head_new.pop('in_channels')\n        head_deleted_dict['in_channels'] = str(in_channels)\n        in_channels = sum([in_channels[i] for i in input_index])\n        head_new['in_channels'] = in_channels\n        head_append_dict['in_channels'] = str(in_channels)\n\n        neck_new.update(\n            dict(\n                type='FeatureMapProcessor',\n                concat=True,\n                select_index=input_index,\n            ))\n        if align_corners:\n            neck_new['align_corners'] = align_corners\n\n    elif input_transform == 'select':\n        if input_index != (-1, ):\n            neck_new.update(\n                dict(type='FeatureMapProcessor', select_index=input_index))\n            if isinstance(head['in_channels'], tuple):\n                in_channels = head_new.pop('in_channels')\n                head_deleted_dict['in_channels'] = str(in_channels)\n                if isinstance(input_index, int):\n                    in_channels = in_channels[input_index]\n                else:\n                    in_channels = tuple([in_channels[i] for i in input_index])\n                head_new['in_channels'] = in_channels\n                head_append_dict['in_channels'] = str(in_channels)\n            if align_corners:\n                neck_new['align_corners'] = align_corners\n\n    else:\n        raise ValueError(f'model.head get invalid value for argument '\n                         f'input_transform: {input_transform}')\n\n\ndef process_extra_field(extra: Dict, head_new: Dict, head_deleted_dict: Dict,\n                        head_append_dict: Dict, neck_new: Dict) -> None:\n    \"\"\"Process the extra field and update head and neck dictionaries.\"\"\"\n    head_deleted_dict['extra'] = 'dict('\n    for key, value in extra.items():\n        head_deleted_dict['extra'] += f'{key}={value},'\n    head_deleted_dict['extra'] = head_deleted_dict['extra'][:-1] + ')'\n    if 'final_conv_kernel' in extra:\n        kernel_size = extra['final_conv_kernel']\n        if kernel_size > 1:\n            padding = kernel_size // 2\n            head_new['final_layer'] = dict(\n                kernel_size=kernel_size, padding=padding)\n            head_append_dict[\n                'final_layer'] = f'dict(kernel_size={kernel_size}, ' \\\n                                 f'padding={padding})'\n        else:\n            head_new['final_layer'] = dict(kernel_size=kernel_size)\n            head_append_dict[\n                'final_layer'] = f'dict(kernel_size={kernel_size})'\n    if 'upsample' in extra:\n        neck_new.update(\n            dict(\n                type='FeatureMapProcessor',\n                scale_factor=float(extra['upsample']),\n                apply_relu=True,\n            ))\n\n\ndef process_has_final_layer(has_final_layer: bool, head_new: Dict,\n                            head_deleted_dict: Dict,\n                            head_append_dict: Dict) -> None:\n    \"\"\"Process the has_final_layer field and update the head dictionary.\"\"\"\n    head_deleted_dict['has_final_layer'] = str(has_final_layer)\n    if not has_final_layer:\n        if 'final_layer' not in head_new:\n            head_new['final_layer'] = None\n        head_append_dict['final_layer'] = 'None'\n\n\ndef check_and_update_config(neck: Optional[ConfigType],\n                            head: ConfigType) -> Tuple[Optional[Dict], Dict]:\n    \"\"\"Check and update the configuration of the head and neck components.\n    Args:\n        neck (Optional[ConfigType]): Configuration for the neck component.\n        head (ConfigType): Configuration for the head component.\n\n    Returns:\n        Tuple[Optional[Dict], Dict]: Updated configurations for the neck\n            and head components.\n    \"\"\"\n    head_new, neck_new = head.copy(), neck.copy() if isinstance(neck,\n                                                                dict) else {}\n    head_deleted_dict, head_append_dict = {}, {}\n\n    if 'input_transform' in head:\n        input_transform = head_new.pop('input_transform')\n        head_deleted_dict['input_transform'] = f'\\'{input_transform}\\''\n    else:\n        input_transform = 'select'\n\n    if 'input_index' in head:\n        input_index = head_new.pop('input_index')\n        head_deleted_dict['input_index'] = str(input_index)\n    else:\n        input_index = (-1, )\n\n    if 'align_corners' in head:\n        align_corners = head_new.pop('align_corners')\n        head_deleted_dict['align_corners'] = str(align_corners)\n    else:\n        align_corners = False\n\n    process_input_transform(input_transform, head, head_new, head_deleted_dict,\n                            head_append_dict, neck_new, input_index,\n                            align_corners)\n\n    if 'extra' in head:\n        extra = head_new.pop('extra')\n        process_extra_field(extra, head_new, head_deleted_dict,\n                            head_append_dict, neck_new)\n\n    if 'has_final_layer' in head:\n        has_final_layer = head_new.pop('has_final_layer')\n        process_has_final_layer(has_final_layer, head_new, head_deleted_dict,\n                                head_append_dict)\n\n    display_modifications(head_deleted_dict, head_append_dict, neck_new)\n\n    neck_new = neck_new if len(neck_new) else None\n    return neck_new, head_new\n\n\n@master_only\ndef display_modifications(head_deleted_dict: Dict, head_append_dict: Dict,\n                          neck: Dict) -> None:\n    \"\"\"Display the modifications made to the head and neck configurations.\n\n    Args:\n        head_deleted_dict (Dict): Dictionary of deleted fields in the head.\n        head_append_dict (Dict): Dictionary of appended fields in the head.\n        neck (Dict): Updated neck configuration.\n    \"\"\"\n    if len(head_deleted_dict) + len(head_append_dict) == 0:\n        return\n\n    old_model_info, new_model_info = build_model_info(head_deleted_dict,\n                                                      head_append_dict, neck)\n\n    total_info = '\\nThe config you are using is outdated. '\\\n                 'The following section of the config:\\n```\\n'\n    total_info += old_model_info\n    total_info += '```\\nshould be updated to\\n```\\n'\n    total_info += new_model_info\n    total_info += '```\\nFor more information, please refer to '\\\n                  'https://mmpose.readthedocs.io/en/latest/' \\\n                  'guide_to_framework.html#step3-model'\n\n    logger: MMLogger = MMLogger.get_current_instance()\n    logger.warning(total_info)\n\n\ndef build_model_info(head_deleted_dict: Dict, head_append_dict: Dict,\n                     neck: Dict) -> Tuple[str, str]:\n    \"\"\"Build the old and new model information strings.\n    Args:\n        head_deleted_dict (Dict): Dictionary of deleted fields in the head.\n        head_append_dict (Dict): Dictionary of appended fields in the head.\n        neck (Dict): Updated neck configuration.\n\n    Returns:\n        Tuple[str, str]: Old and new model information strings.\n    \"\"\"\n    old_head_info = build_head_info(head_deleted_dict)\n    new_head_info = build_head_info(head_append_dict)\n    neck_info = build_neck_info(neck)\n\n    old_model_info = 'model=dict(\\n' + ' ' * 4 + '...,\\n' + old_head_info\n    new_model_info = 'model=dict(\\n' + ' ' * 4 + '...,\\n' \\\n                     + neck_info + new_head_info\n\n    return old_model_info, new_model_info\n\n\ndef build_head_info(head_dict: Dict) -> str:\n    \"\"\"Build the head information string.\n\n    Args:\n        head_dict (Dict): Dictionary of fields in the head configuration.\n    Returns:\n        str: Head information string.\n    \"\"\"\n    head_info = ' ' * 4 + 'head=dict(\\n'\n    for key, value in head_dict.items():\n        head_info += ' ' * 8 + f'{key}={value},\\n'\n    head_info += ' ' * 8 + '...),\\n'\n    return head_info\n\n\ndef build_neck_info(neck: Dict) -> str:\n    \"\"\"Build the neck information string.\n    Args:\n        neck (Dict): Updated neck configuration.\n\n    Returns:\n        str: Neck information string.\n    \"\"\"\n    if len(neck) > 0:\n        neck = neck.copy()\n        neck_info = ' ' * 4 + 'neck=dict(\\n' + ' ' * 8 + \\\n                    f'type=\\'{neck.pop(\"type\")}\\',\\n'\n        for key, value in neck.items():\n            neck_info += ' ' * 8 + f'{key}={str(value)},\\n'\n        neck_info += ' ' * 4 + '),\\n'\n    else:\n        neck_info = ''\n    return neck_info\n"
  },
  {
    "path": "mmpose/models/utils/ckpt_convert.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\n# This script consists of several convert functions which\n# can modify the weights of model in original repo to be\n# pre-trained weights.\n\nfrom collections import OrderedDict\n\nimport torch\n\n\ndef pvt_convert(ckpt):\n    new_ckpt = OrderedDict()\n    # Process the concat between q linear weights and kv linear weights\n    use_abs_pos_embed = False\n    use_conv_ffn = False\n    for k in ckpt.keys():\n        if k.startswith('pos_embed'):\n            use_abs_pos_embed = True\n        if k.find('dwconv') >= 0:\n            use_conv_ffn = True\n    for k, v in ckpt.items():\n        if k.startswith('head'):\n            continue\n        if k.startswith('norm.'):\n            continue\n        if k.startswith('cls_token'):\n            continue\n        if k.startswith('pos_embed'):\n            stage_i = int(k.replace('pos_embed', ''))\n            new_k = k.replace(f'pos_embed{stage_i}',\n                              f'layers.{stage_i - 1}.1.0.pos_embed')\n            if stage_i == 4 and v.size(1) == 50:  # 1 (cls token) + 7 * 7\n                new_v = v[:, 1:, :]  # remove cls token\n            else:\n                new_v = v\n        elif k.startswith('patch_embed'):\n            stage_i = int(k.split('.')[0].replace('patch_embed', ''))\n            new_k = k.replace(f'patch_embed{stage_i}',\n                              f'layers.{stage_i - 1}.0')\n            new_v = v\n            if 'proj.' in new_k:\n                new_k = new_k.replace('proj.', 'projection.')\n        elif k.startswith('block'):\n            stage_i = int(k.split('.')[0].replace('block', ''))\n            layer_i = int(k.split('.')[1])\n            new_layer_i = layer_i + use_abs_pos_embed\n            new_k = k.replace(f'block{stage_i}.{layer_i}',\n                              f'layers.{stage_i - 1}.1.{new_layer_i}')\n            new_v = v\n            if 'attn.q.' in new_k:\n                sub_item_k = k.replace('q.', 'kv.')\n                new_k = new_k.replace('q.', 'attn.in_proj_')\n                new_v = torch.cat([v, ckpt[sub_item_k]], dim=0)\n            elif 'attn.kv.' in new_k:\n                continue\n            elif 'attn.proj.' in new_k:\n                new_k = new_k.replace('proj.', 'attn.out_proj.')\n            elif 'attn.sr.' in new_k:\n                new_k = new_k.replace('sr.', 'sr.')\n            elif 'mlp.' in new_k:\n                string = f'{new_k}-'\n                new_k = new_k.replace('mlp.', 'ffn.layers.')\n                if 'fc1.weight' in new_k or 'fc2.weight' in new_k:\n                    new_v = v.reshape((*v.shape, 1, 1))\n                new_k = new_k.replace('fc1.', '0.')\n                new_k = new_k.replace('dwconv.dwconv.', '1.')\n                if use_conv_ffn:\n                    new_k = new_k.replace('fc2.', '4.')\n                else:\n                    new_k = new_k.replace('fc2.', '3.')\n                string += f'{new_k} {v.shape}-{new_v.shape}'\n        elif k.startswith('norm'):\n            stage_i = int(k[4])\n            new_k = k.replace(f'norm{stage_i}', f'layers.{stage_i - 1}.2')\n            new_v = v\n        else:\n            new_k = k\n            new_v = v\n        new_ckpt[new_k] = new_v\n\n    return new_ckpt\n"
  },
  {
    "path": "mmpose/models/utils/csp_layer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, DepthwiseSeparableConvModule\nfrom mmengine.model import BaseModule\nfrom mmengine.utils import digit_version\nfrom torch import Tensor\n\nfrom mmpose.utils.typing import ConfigType, OptConfigType, OptMultiConfig\n\n\nclass ChannelAttention(BaseModule):\n    \"\"\"Channel attention Module.\n\n    Args:\n        channels (int): The input (and output) channels of the attention layer.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Defaults to None\n    \"\"\"\n\n    def __init__(self, channels: int, init_cfg: OptMultiConfig = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        self.global_avgpool = nn.AdaptiveAvgPool2d(1)\n        self.fc = nn.Conv2d(channels, channels, 1, 1, 0, bias=True)\n        if digit_version(torch.__version__) < (1, 7, 0):\n            self.act = nn.Hardsigmoid()\n        else:\n            self.act = nn.Hardsigmoid(inplace=True)\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward function for ChannelAttention.\"\"\"\n        with torch.cuda.amp.autocast(enabled=False):\n            out = self.global_avgpool(x)\n        out = self.fc(out)\n        out = self.act(out)\n        return x * out\n\n\nclass DarknetBottleneck(BaseModule):\n    \"\"\"The basic bottleneck block used in Darknet.\n\n    Each ResBlock consists of two ConvModules and the input is added to the\n    final output. Each ConvModule is composed of Conv, BN, and LeakyReLU.\n    The first convLayer has filter size of 1x1 and the second one has the\n    filter size of 3x3.\n\n    Args:\n        in_channels (int): The input channels of this Module.\n        out_channels (int): The output channels of this Module.\n        expansion (float): The kernel size of the convolution.\n            Defaults to 0.5.\n        add_identity (bool): Whether to add identity to the out.\n            Defaults to True.\n        use_depthwise (bool): Whether to use depthwise separable convolution.\n            Defaults to False.\n        conv_cfg (dict): Config dict for convolution layer. Defaults to None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Defaults to dict(type='BN').\n        act_cfg (dict): Config dict for activation layer.\n            Defaults to dict(type='Swish').\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int,\n                 out_channels: int,\n                 expansion: float = 0.5,\n                 add_identity: bool = True,\n                 use_depthwise: bool = False,\n                 conv_cfg: OptConfigType = None,\n                 norm_cfg: ConfigType = dict(\n                     type='BN', momentum=0.03, eps=0.001),\n                 act_cfg: ConfigType = dict(type='Swish'),\n                 init_cfg: OptMultiConfig = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        hidden_channels = int(out_channels * expansion)\n        conv = DepthwiseSeparableConvModule if use_depthwise else ConvModule\n        self.conv1 = ConvModule(\n            in_channels,\n            hidden_channels,\n            1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.conv2 = conv(\n            hidden_channels,\n            out_channels,\n            3,\n            stride=1,\n            padding=1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.add_identity = \\\n            add_identity and in_channels == out_channels\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward function.\"\"\"\n        identity = x\n        out = self.conv1(x)\n        out = self.conv2(out)\n\n        if self.add_identity:\n            return out + identity\n        else:\n            return out\n\n\nclass CSPNeXtBlock(BaseModule):\n    \"\"\"The basic bottleneck block used in CSPNeXt.\n\n    Args:\n        in_channels (int): The input channels of this Module.\n        out_channels (int): The output channels of this Module.\n        expansion (float): Expand ratio of the hidden channel. Defaults to 0.5.\n        add_identity (bool): Whether to add identity to the out. Only works\n            when in_channels == out_channels. Defaults to True.\n        use_depthwise (bool): Whether to use depthwise separable convolution.\n            Defaults to False.\n        kernel_size (int): The kernel size of the second convolution layer.\n            Defaults to 5.\n        conv_cfg (dict): Config dict for convolution layer. Defaults to None,\n            which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Defaults to dict(type='BN', momentum=0.03, eps=0.001).\n        act_cfg (dict): Config dict for activation layer.\n            Defaults to dict(type='SiLU').\n        init_cfg (:obj:`ConfigDict` or dict or list[dict] or\n            list[:obj:`ConfigDict`], optional): Initialization config dict.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int,\n                 out_channels: int,\n                 expansion: float = 0.5,\n                 add_identity: bool = True,\n                 use_depthwise: bool = False,\n                 kernel_size: int = 5,\n                 conv_cfg: OptConfigType = None,\n                 norm_cfg: ConfigType = dict(\n                     type='BN', momentum=0.03, eps=0.001),\n                 act_cfg: ConfigType = dict(type='SiLU'),\n                 init_cfg: OptMultiConfig = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        hidden_channels = int(out_channels * expansion)\n        conv = DepthwiseSeparableConvModule if use_depthwise else ConvModule\n        self.conv1 = conv(\n            in_channels,\n            hidden_channels,\n            3,\n            stride=1,\n            padding=1,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.conv2 = DepthwiseSeparableConvModule(\n            hidden_channels,\n            out_channels,\n            kernel_size,\n            stride=1,\n            padding=kernel_size // 2,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.add_identity = \\\n            add_identity and in_channels == out_channels\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward function.\"\"\"\n        identity = x\n        out = self.conv1(x)\n        out = self.conv2(out)\n\n        if self.add_identity:\n            return out + identity\n        else:\n            return out\n\n\nclass CSPLayer(BaseModule):\n    \"\"\"Cross Stage Partial Layer.\n\n    Args:\n        in_channels (int): The input channels of the CSP layer.\n        out_channels (int): The output channels of the CSP layer.\n        expand_ratio (float): Ratio to adjust the number of channels of the\n            hidden layer. Defaults to 0.5.\n        num_blocks (int): Number of blocks. Defaults to 1.\n        add_identity (bool): Whether to add identity in blocks.\n            Defaults to True.\n        use_cspnext_block (bool): Whether to use CSPNeXt block.\n            Defaults to False.\n        use_depthwise (bool): Whether to use depthwise separable convolution in\n            blocks. Defaults to False.\n        channel_attention (bool): Whether to add channel attention in each\n            stage. Defaults to True.\n        conv_cfg (dict, optional): Config dict for convolution layer.\n            Defaults to None, which means using conv2d.\n        norm_cfg (dict): Config dict for normalization layer.\n            Defaults to dict(type='BN')\n        act_cfg (dict): Config dict for activation layer.\n            Defaults to dict(type='Swish')\n        init_cfg (:obj:`ConfigDict` or dict or list[dict] or\n            list[:obj:`ConfigDict`], optional): Initialization config dict.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int,\n                 out_channels: int,\n                 expand_ratio: float = 0.5,\n                 num_blocks: int = 1,\n                 add_identity: bool = True,\n                 use_depthwise: bool = False,\n                 use_cspnext_block: bool = False,\n                 channel_attention: bool = False,\n                 conv_cfg: OptConfigType = None,\n                 norm_cfg: ConfigType = dict(\n                     type='BN', momentum=0.03, eps=0.001),\n                 act_cfg: ConfigType = dict(type='Swish'),\n                 init_cfg: OptMultiConfig = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        block = CSPNeXtBlock if use_cspnext_block else DarknetBottleneck\n        mid_channels = int(out_channels * expand_ratio)\n        self.channel_attention = channel_attention\n        self.main_conv = ConvModule(\n            in_channels,\n            mid_channels,\n            1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.short_conv = ConvModule(\n            in_channels,\n            mid_channels,\n            1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n        self.final_conv = ConvModule(\n            2 * mid_channels,\n            out_channels,\n            1,\n            conv_cfg=conv_cfg,\n            norm_cfg=norm_cfg,\n            act_cfg=act_cfg)\n\n        self.blocks = nn.Sequential(*[\n            block(\n                mid_channels,\n                mid_channels,\n                1.0,\n                add_identity,\n                use_depthwise,\n                conv_cfg=conv_cfg,\n                norm_cfg=norm_cfg,\n                act_cfg=act_cfg) for _ in range(num_blocks)\n        ])\n        if channel_attention:\n            self.attention = ChannelAttention(2 * mid_channels)\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward function.\"\"\"\n        x_short = self.short_conv(x)\n\n        x_main = self.main_conv(x)\n        x_main = self.blocks(x_main)\n\n        x_final = torch.cat((x_main, x_short), dim=1)\n\n        if self.channel_attention:\n            x_final = self.attention(x_final)\n        return self.final_conv(x_final)\n"
  },
  {
    "path": "mmpose/models/utils/geometry.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nfrom torch.nn import functional as F\n\n\ndef rot6d_to_rotmat(x):\n    \"\"\"Convert 6D rotation representation to 3x3 rotation matrix.\n\n    Based on Zhou et al., \"On the Continuity of Rotation\n    Representations in Neural Networks\", CVPR 2019\n    Input:\n        (B,6) Batch of 6-D rotation representations\n    Output:\n        (B,3,3) Batch of corresponding rotation matrices\n    \"\"\"\n    x = x.view(-1, 3, 2)\n    a1 = x[:, :, 0]\n    a2 = x[:, :, 1]\n    b1 = F.normalize(a1)\n    b2 = F.normalize(a2 - torch.einsum('bi,bi->b', b1, a2).unsqueeze(-1) * b1)\n    b3 = torch.cross(b1, b2)\n    return torch.stack((b1, b2, b3), dim=-1)\n\n\ndef batch_rodrigues(theta):\n    \"\"\"Convert axis-angle representation to rotation matrix.\n    Args:\n        theta: size = [B, 3]\n    Returns:\n        Rotation matrix corresponding to the quaternion\n            -- size = [B, 3, 3]\n    \"\"\"\n    l2norm = torch.norm(theta + 1e-8, p=2, dim=1)\n    angle = torch.unsqueeze(l2norm, -1)\n    normalized = torch.div(theta, angle)\n    angle = angle * 0.5\n    v_cos = torch.cos(angle)\n    v_sin = torch.sin(angle)\n    quat = torch.cat([v_cos, v_sin * normalized], dim=1)\n    return quat_to_rotmat(quat)\n\n\ndef quat_to_rotmat(quat):\n    \"\"\"Convert quaternion coefficients to rotation matrix.\n    Args:\n        quat: size = [B, 4] 4 <===>(w, x, y, z)\n    Returns:\n        Rotation matrix corresponding to the quaternion\n            -- size = [B, 3, 3]\n    \"\"\"\n    norm_quat = quat\n    norm_quat = norm_quat / norm_quat.norm(p=2, dim=1, keepdim=True)\n    w, x, y, z = norm_quat[:, 0], norm_quat[:, 1],\\\n        norm_quat[:, 2], norm_quat[:, 3]\n\n    B = quat.size(0)\n\n    w2, x2, y2, z2 = w.pow(2), x.pow(2), y.pow(2), z.pow(2)\n    wx, wy, wz = w * x, w * y, w * z\n    xy, xz, yz = x * y, x * z, y * z\n\n    rotMat = torch.stack([\n        w2 + x2 - y2 - z2, 2 * xy - 2 * wz, 2 * wy + 2 * xz, 2 * wz + 2 * xy,\n        w2 - x2 + y2 - z2, 2 * yz - 2 * wx, 2 * xz - 2 * wy, 2 * wx + 2 * yz,\n        w2 - x2 - y2 + z2\n    ],\n                         dim=1).view(B, 3, 3)\n    return rotMat\n"
  },
  {
    "path": "mmpose/models/utils/misc.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom functools import partial\n\nimport torch\nfrom six.moves import map, zip\n\n\ndef multi_apply(func, *args, **kwargs):\n    \"\"\"Apply function to a list of arguments.\n\n    Note:\n        This function applies the ``func`` to multiple inputs and\n        map the multiple outputs of the ``func`` into different\n        list. Each list contains the same type of outputs corresponding\n        to different inputs.\n\n    Args:\n        func (Function): A function that will be applied to a list of\n            arguments\n\n    Returns:\n        tuple(list): A tuple containing multiple list, each list contains\n            a kind of returned results by the function\n    \"\"\"\n    pfunc = partial(func, **kwargs) if kwargs else func\n    map_results = map(pfunc, *args)\n    return tuple(map(list, zip(*map_results)))\n\n\ndef filter_scores_and_topk(scores, score_thr, topk, results=None):\n    \"\"\"Filter results using score threshold and topk candidates.\n\n    Args:\n        scores (Tensor): The scores, shape (num_bboxes, K).\n        score_thr (float): The score filter threshold.\n        topk (int): The number of topk candidates.\n        results (dict or list or Tensor, Optional): The results to\n           which the filtering rule is to be applied. The shape\n           of each item is (num_bboxes, N).\n\n    Returns:\n        tuple: Filtered results\n\n            - scores (Tensor): The scores after being filtered, \\\n                shape (num_bboxes_filtered, ).\n            - labels (Tensor): The class labels, shape \\\n                (num_bboxes_filtered, ).\n            - anchor_idxs (Tensor): The anchor indexes, shape \\\n                (num_bboxes_filtered, ).\n            - filtered_results (dict or list or Tensor, Optional): \\\n                The filtered results. The shape of each item is \\\n                (num_bboxes_filtered, N).\n    \"\"\"\n    valid_mask = scores > score_thr\n    scores = scores[valid_mask]\n    valid_idxs = torch.nonzero(valid_mask)\n\n    num_topk = min(topk, valid_idxs.size(0))\n    # torch.sort is actually faster than .topk (at least on GPUs)\n    scores, idxs = scores.sort(descending=True)\n    scores = scores[:num_topk]\n    topk_idxs = valid_idxs[idxs[:num_topk]]\n    keep_idxs, labels = topk_idxs.unbind(dim=1)\n\n    filtered_results = None\n    if results is not None:\n        if isinstance(results, dict):\n            filtered_results = {k: v[keep_idxs] for k, v in results.items()}\n        elif isinstance(results, list):\n            filtered_results = [result[keep_idxs] for result in results]\n        elif isinstance(results, torch.Tensor):\n            filtered_results = results[keep_idxs]\n        else:\n            raise NotImplementedError(f'Only supports dict or list or Tensor, '\n                                      f'but get {type(results)}.')\n    return scores, labels, keep_idxs, filtered_results\n"
  },
  {
    "path": "mmpose/models/utils/ops.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import Optional, Tuple, Union\n\nimport torch\nfrom torch import Tensor\nfrom torch.nn import functional as F\n\nfrom mmpose.registry import MODELS\n\n\ndef resize(input: torch.Tensor,\n           size: Optional[Union[Tuple[int, int], torch.Size]] = None,\n           scale_factor: Optional[float] = None,\n           mode: str = 'nearest',\n           align_corners: Optional[bool] = None,\n           warning: bool = True) -> torch.Tensor:\n    \"\"\"Resize a given input tensor using specified size or scale_factor.\n\n    Args:\n        input (torch.Tensor): The input tensor to be resized.\n        size (Optional[Union[Tuple[int, int], torch.Size]]): The desired\n            output size. Defaults to None.\n        scale_factor (Optional[float]): The scaling factor for resizing.\n            Defaults to None.\n        mode (str): The interpolation mode. Defaults to 'nearest'.\n        align_corners (Optional[bool]): Determines whether to align the\n            corners when using certain interpolation modes. Defaults to None.\n        warning (bool): Whether to display a warning when the input and\n            output sizes are not ideal for alignment. Defaults to True.\n\n    Returns:\n        torch.Tensor: The resized tensor.\n    \"\"\"\n    # Check if a warning should be displayed regarding input and output sizes\n    if warning:\n        if size is not None and align_corners:\n            input_h, input_w = tuple(int(x) for x in input.shape[2:])\n            output_h, output_w = tuple(int(x) for x in size)\n            if output_h > input_h or output_w > output_h:\n                if ((output_h > 1 and output_w > 1 and input_h > 1\n                     and input_w > 1) and (output_h - 1) % (input_h - 1)\n                        and (output_w - 1) % (input_w - 1)):\n                    warnings.warn(\n                        f'When align_corners={align_corners}, '\n                        'the output would be more aligned if '\n                        f'input size {(input_h, input_w)} is `x+1` and '\n                        f'out size {(output_h, output_w)} is `nx+1`')\n\n    # Convert torch.Size to tuple if necessary\n    if isinstance(size, torch.Size):\n        size = tuple(int(x) for x in size)\n\n    # Perform the resizing operation\n    return F.interpolate(input, size, scale_factor, mode, align_corners)\n\n\n@MODELS.register_module()\nclass FrozenBatchNorm2d(torch.nn.Module):\n    \"\"\"BatchNorm2d where the batch statistics and the affine parameters are\n    fixed.\n\n    Copy-paste from torchvision.misc.ops with added eps before rqsrt, without\n    which any other models than torchvision.models.resnet[18,34,50,101] produce\n    nans.\n    \"\"\"\n\n    def __init__(self, n, eps: int = 1e-5):\n        super(FrozenBatchNorm2d, self).__init__()\n        self.register_buffer('weight', torch.ones(n))\n        self.register_buffer('bias', torch.zeros(n))\n        self.register_buffer('running_mean', torch.zeros(n))\n        self.register_buffer('running_var', torch.ones(n))\n        self.eps = eps\n\n    def _load_from_state_dict(self, state_dict, prefix, local_metadata, strict,\n                              missing_keys, unexpected_keys, error_msgs):\n        num_batches_tracked_key = prefix + 'num_batches_tracked'\n        if num_batches_tracked_key in state_dict:\n            del state_dict[num_batches_tracked_key]\n\n        super(FrozenBatchNorm2d,\n              self)._load_from_state_dict(state_dict, prefix, local_metadata,\n                                          strict, missing_keys,\n                                          unexpected_keys, error_msgs)\n\n    def forward(self, x):\n        w = self.weight.reshape(1, -1, 1, 1)\n        b = self.bias.reshape(1, -1, 1, 1)\n        rv = self.running_var.reshape(1, -1, 1, 1)\n        rm = self.running_mean.reshape(1, -1, 1, 1)\n        scale = w * (rv + self.eps).rsqrt()\n        bias = b - rm * scale\n        return x * scale + bias\n\n\ndef inverse_sigmoid(x: Tensor, eps: float = 1e-3) -> Tensor:\n    \"\"\"Inverse function of sigmoid.\n\n    Args:\n        x (Tensor): The tensor to do the inverse.\n        eps (float): EPS avoid numerical overflow. Defaults 1e-5.\n    Returns:\n        Tensor: The x has passed the inverse function of sigmoid, has the same\n        shape with input.\n    \"\"\"\n    x = x.clamp(min=0, max=1)\n    x1 = x.clamp(min=eps)\n    x2 = (1 - x).clamp(min=eps)\n    return torch.log(x1 / x2)\n"
  },
  {
    "path": "mmpose/models/utils/realnvp.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\nimport torch.nn as nn\nfrom torch import distributions\n\n\nclass RealNVP(nn.Module):\n    \"\"\"RealNVP: a flow-based generative model\n\n    `Density estimation using Real NVP\n    arXiv: <https://arxiv.org/abs/1605.08803>`_.\n\n    Code is modified from `the official implementation of RLE\n    <https://github.com/Jeff-sjtu/res-loglikelihood-regression>`_.\n\n    See also `real-nvp-pytorch\n    <https://github.com/senya-ashukha/real-nvp-pytorch>`_.\n    \"\"\"\n\n    @staticmethod\n    def get_scale_net():\n        \"\"\"Get the scale model in a single invertable mapping.\"\"\"\n        return nn.Sequential(\n            nn.Linear(2, 64), nn.LeakyReLU(), nn.Linear(64, 64),\n            nn.LeakyReLU(), nn.Linear(64, 2), nn.Tanh())\n\n    @staticmethod\n    def get_trans_net():\n        \"\"\"Get the translation model in a single invertable mapping.\"\"\"\n        return nn.Sequential(\n            nn.Linear(2, 64), nn.LeakyReLU(), nn.Linear(64, 64),\n            nn.LeakyReLU(), nn.Linear(64, 2))\n\n    @property\n    def prior(self):\n        \"\"\"The prior distribution.\"\"\"\n        return distributions.MultivariateNormal(self.loc, self.cov)\n\n    def __init__(self):\n        super(RealNVP, self).__init__()\n\n        self.register_buffer('loc', torch.zeros(2))\n        self.register_buffer('cov', torch.eye(2))\n        self.register_buffer(\n            'mask', torch.tensor([[0, 1], [1, 0]] * 3, dtype=torch.float32))\n\n        self.s = torch.nn.ModuleList(\n            [self.get_scale_net() for _ in range(len(self.mask))])\n        self.t = torch.nn.ModuleList(\n            [self.get_trans_net() for _ in range(len(self.mask))])\n        self.init_weights()\n\n    def init_weights(self):\n        \"\"\"Initialization model weights.\"\"\"\n        for m in self.modules():\n            if isinstance(m, nn.Linear):\n                nn.init.xavier_uniform_(m.weight, gain=0.01)\n\n    def backward_p(self, x):\n        \"\"\"Apply mapping form the data space to the latent space and calculate\n        the log determinant of the Jacobian matrix.\"\"\"\n\n        log_det_jacob, z = x.new_zeros(x.shape[0]), x\n        for i in reversed(range(len(self.t))):\n            z_ = self.mask[i] * z\n            s = self.s[i](z_) * (1 - self.mask[i])  # torch.exp(s): betas\n            t = self.t[i](z_) * (1 - self.mask[i])  # gammas\n            z = (1 - self.mask[i]) * (z - t) * torch.exp(-s) + z_\n            log_det_jacob -= s.sum(dim=1)\n        return z, log_det_jacob\n\n    def log_prob(self, x):\n        \"\"\"Calculate the log probability of given sample in data space.\"\"\"\n\n        z, log_det = self.backward_p(x)\n        return self.prior.log_prob(z) + log_det\n"
  },
  {
    "path": "mmpose/models/utils/regularizations.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta, abstractmethod, abstractproperty\n\nimport torch\n\n\nclass PytorchModuleHook(metaclass=ABCMeta):\n    \"\"\"Base class for PyTorch module hook registers.\n\n    An instance of a subclass of PytorchModuleHook can be used to\n    register hook to a pytorch module using the `register` method like:\n        hook_register.register(module)\n\n    Subclasses should add/overwrite the following methods:\n        - __init__\n        - hook\n        - hook_type\n    \"\"\"\n\n    @abstractmethod\n    def hook(self, *args, **kwargs):\n        \"\"\"Hook function.\"\"\"\n\n    @abstractproperty\n    def hook_type(self) -> str:\n        \"\"\"Hook type Subclasses should overwrite this function to return a\n        string value in.\n\n        {`forward`, `forward_pre`, `backward`}\n        \"\"\"\n\n    def register(self, module):\n        \"\"\"Register the hook function to the module.\n\n        Args:\n            module (pytorch module): the module to register the hook.\n\n        Returns:\n            handle (torch.utils.hooks.RemovableHandle): a handle to remove\n                the hook by calling handle.remove()\n        \"\"\"\n        assert isinstance(module, torch.nn.Module)\n\n        if self.hook_type == 'forward':\n            h = module.register_forward_hook(self.hook)\n        elif self.hook_type == 'forward_pre':\n            h = module.register_forward_pre_hook(self.hook)\n        elif self.hook_type == 'backward':\n            h = module.register_backward_hook(self.hook)\n        else:\n            raise ValueError(f'Invalid hook type {self.hook}')\n\n        return h\n\n\nclass WeightNormClipHook(PytorchModuleHook):\n    \"\"\"Apply weight norm clip regularization.\n\n    The module's parameter will be clip to a given maximum norm before each\n    forward pass.\n\n    Args:\n        max_norm (float): The maximum norm of the parameter.\n        module_param_names (str|list): The parameter name (or name list) to\n            apply weight norm clip.\n    \"\"\"\n\n    def __init__(self, max_norm=1.0, module_param_names='weight'):\n        self.module_param_names = module_param_names if isinstance(\n            module_param_names, list) else [module_param_names]\n        self.max_norm = max_norm\n\n    @property\n    def hook_type(self):\n        return 'forward_pre'\n\n    def hook(self, module, _input):\n        for name in self.module_param_names:\n            assert name in module._parameters, f'{name} is not a parameter' \\\n                f' of the module {type(module)}'\n            param = module._parameters[name]\n\n            with torch.no_grad():\n                m = param.norm().item()\n                if m > self.max_norm:\n                    param.mul_(self.max_norm / (m + 1e-6))\n"
  },
  {
    "path": "mmpose/models/utils/reparam_layers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport types\nfrom typing import Dict, Optional\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule, build_activation_layer, build_norm_layer\nfrom mmengine.model import BaseModule\nfrom torch import Tensor\n\nfrom mmpose.utils.typing import OptConfigType\n\n\nclass RepVGGBlock(BaseModule):\n    \"\"\"A block in RepVGG architecture, supporting optional normalization in the\n    identity branch.\n\n    This block consists of 3x3 and 1x1 convolutions, with an optional identity\n    shortcut branch that includes normalization.\n\n    Args:\n        in_channels (int): The input channels of the block.\n        out_channels (int): The output channels of the block.\n        stride (int): The stride of the block. Defaults to 1.\n        padding (int): The padding of the block. Defaults to 1.\n        dilation (int): The dilation of the block. Defaults to 1.\n        groups (int): The groups of the block. Defaults to 1.\n        padding_mode (str): The padding mode of the block. Defaults to 'zeros'.\n        norm_cfg (dict): The config dict for normalization layers.\n            Defaults to dict(type='BN').\n        act_cfg (dict): The config dict for activation layers.\n            Defaults to dict(type='ReLU').\n        without_branch_norm (bool): Whether to skip branch_norm.\n            Defaults to True.\n        init_cfg (dict): The config dict for initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels: int,\n                 out_channels: int,\n                 stride: int = 1,\n                 padding: int = 1,\n                 dilation: int = 1,\n                 groups: int = 1,\n                 padding_mode: str = 'zeros',\n                 norm_cfg: OptConfigType = dict(type='BN'),\n                 act_cfg: OptConfigType = dict(type='ReLU'),\n                 without_branch_norm: bool = True,\n                 init_cfg: OptConfigType = None):\n        super(RepVGGBlock, self).__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.stride = stride\n        self.padding = padding\n        self.dilation = dilation\n        self.groups = groups\n        self.norm_cfg = norm_cfg\n        self.act_cfg = act_cfg\n\n        # judge if input shape and output shape are the same.\n        # If true, add a normalized identity shortcut.\n        self.branch_norm = None\n        if out_channels == in_channels and stride == 1 and \\\n                padding == dilation and not without_branch_norm:\n            self.branch_norm = build_norm_layer(norm_cfg, in_channels)[1]\n\n        self.branch_3x3 = ConvModule(\n            self.in_channels,\n            self.out_channels,\n            3,\n            stride=self.stride,\n            padding=self.padding,\n            groups=self.groups,\n            dilation=self.dilation,\n            norm_cfg=self.norm_cfg,\n            act_cfg=None)\n\n        self.branch_1x1 = ConvModule(\n            self.in_channels,\n            self.out_channels,\n            1,\n            groups=self.groups,\n            norm_cfg=self.norm_cfg,\n            act_cfg=None)\n\n        self.act = build_activation_layer(act_cfg)\n\n    def forward(self, x: Tensor) -> Tensor:\n        \"\"\"Forward pass through the RepVGG block.\n\n        The output is the sum of 3x3 and 1x1 convolution outputs,\n        along with the normalized identity branch output, followed by\n        activation.\n\n        Args:\n            x (Tensor): The input tensor.\n\n        Returns:\n            Tensor: The output tensor.\n        \"\"\"\n\n        if self.branch_norm is None:\n            branch_norm_out = 0\n        else:\n            branch_norm_out = self.branch_norm(x)\n\n        out = self.branch_3x3(x) + self.branch_1x1(x) + branch_norm_out\n\n        out = self.act(out)\n\n        return out\n\n    def _pad_1x1_to_3x3_tensor(self, kernel1x1):\n        \"\"\"Pad 1x1 tensor to 3x3.\n        Args:\n            kernel1x1 (Tensor): The input 1x1 kernel need to be padded.\n\n        Returns:\n            Tensor: 3x3 kernel after padded.\n        \"\"\"\n        if kernel1x1 is None:\n            return 0\n        else:\n            return torch.nn.functional.pad(kernel1x1, [1, 1, 1, 1])\n\n    def _fuse_bn_tensor(self, branch: nn.Module) -> Tensor:\n        \"\"\"Derives the equivalent kernel and bias of a specific branch layer.\n\n        Args:\n            branch (nn.Module): The layer that needs to be equivalently\n                transformed, which can be nn.Sequential or nn.Batchnorm2d\n\n        Returns:\n            tuple: Equivalent kernel and bias\n        \"\"\"\n        if branch is None:\n            return 0, 0\n\n        if isinstance(branch, ConvModule):\n            kernel = branch.conv.weight\n            running_mean = branch.bn.running_mean\n            running_var = branch.bn.running_var\n            gamma = branch.bn.weight\n            beta = branch.bn.bias\n            eps = branch.bn.eps\n        else:\n            assert isinstance(branch, (nn.SyncBatchNorm, nn.BatchNorm2d))\n            if not hasattr(self, 'id_tensor'):\n                input_dim = self.in_channels // self.groups\n                kernel_value = np.zeros((self.in_channels, input_dim, 3, 3),\n                                        dtype=np.float32)\n                for i in range(self.in_channels):\n                    kernel_value[i, i % input_dim, 1, 1] = 1\n                self.id_tensor = torch.from_numpy(kernel_value).to(\n                    branch.weight.device)\n            kernel = self.id_tensor\n            running_mean = branch.running_mean\n            running_var = branch.running_var\n            gamma = branch.weight\n            beta = branch.bias\n            eps = branch.eps\n\n        std = (running_var + eps).sqrt()\n        t = (gamma / std).reshape(-1, 1, 1, 1)\n        return kernel * t, beta - running_mean * gamma / std\n\n    def get_equivalent_kernel_bias(self):\n        \"\"\"Derives the equivalent kernel and bias in a differentiable way.\n\n        Returns:\n            tuple: Equivalent kernel and bias\n        \"\"\"\n        kernel3x3, bias3x3 = self._fuse_bn_tensor(self.branch_3x3)\n        kernel1x1, bias1x1 = self._fuse_bn_tensor(self.branch_1x1)\n        kernelid, biasid = (0, 0) if self.branch_norm is None else \\\n            self._fuse_bn_tensor(self.branch_norm)\n\n        return (kernel3x3 + self._pad_1x1_to_3x3_tensor(kernel1x1) + kernelid,\n                bias3x3 + bias1x1 + biasid)\n\n    def switch_to_deploy(self, test_cfg: Optional[Dict] = None):\n        \"\"\"Switches the block to deployment mode.\n\n        In deployment mode, the block uses a single convolution operation\n        derived from the equivalent kernel and bias, replacing the original\n        branches. This reduces computational complexity during inference.\n        \"\"\"\n        if getattr(self, 'deploy', False):\n            return\n\n        kernel, bias = self.get_equivalent_kernel_bias()\n        self.conv_reparam = nn.Conv2d(\n            in_channels=self.branch_3x3.conv.in_channels,\n            out_channels=self.branch_3x3.conv.out_channels,\n            kernel_size=self.branch_3x3.conv.kernel_size,\n            stride=self.branch_3x3.conv.stride,\n            padding=self.branch_3x3.conv.padding,\n            dilation=self.branch_3x3.conv.dilation,\n            groups=self.branch_3x3.conv.groups,\n            bias=True)\n        self.conv_reparam.weight.data = kernel\n        self.conv_reparam.bias.data = bias\n        for para in self.parameters():\n            para.detach_()\n        self.__delattr__('branch_3x3')\n        self.__delattr__('branch_1x1')\n        if hasattr(self, 'branch_norm'):\n            self.__delattr__('branch_norm')\n\n        def _forward(self, x):\n            return self.act(self.conv_reparam(x))\n\n        self.forward = types.MethodType(_forward, self)\n\n        self.deploy = True\n"
  },
  {
    "path": "mmpose/models/utils/rtmcc_block.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn.bricks import DropPath\nfrom mmengine.utils import digit_version\nfrom mmengine.utils.dl_utils import TORCH_VERSION\n\nfrom .transformer import ScaleNorm\n\n\ndef rope(x, dim):\n    \"\"\"Applies Rotary Position Embedding to input tensor.\n\n    Args:\n        x (torch.Tensor): Input tensor.\n        dim (int | list[int]): The spatial dimension(s) to apply\n            rotary position embedding.\n\n    Returns:\n        torch.Tensor: The tensor after applying rotary position\n            embedding.\n\n    Reference:\n        `RoFormer: Enhanced Transformer with Rotary\n        Position Embedding <https://arxiv.org/abs/2104.09864>`_\n    \"\"\"\n    shape = x.shape\n    if isinstance(dim, int):\n        dim = [dim]\n\n    spatial_shape = [shape[i] for i in dim]\n    total_len = 1\n    for i in spatial_shape:\n        total_len *= i\n\n    position = torch.reshape(\n        torch.arange(total_len, dtype=torch.int, device=x.device),\n        spatial_shape)\n\n    for i in range(dim[-1] + 1, len(shape) - 1, 1):\n        position = torch.unsqueeze(position, dim=-1)\n\n    half_size = shape[-1] // 2\n    freq_seq = -torch.arange(\n        half_size, dtype=torch.int, device=x.device) / float(half_size)\n    inv_freq = 10000**-freq_seq\n\n    sinusoid = position[..., None] * inv_freq[None, None, :]\n\n    sin = torch.sin(sinusoid)\n    cos = torch.cos(sinusoid)\n    x1, x2 = torch.chunk(x, 2, dim=-1)\n\n    return torch.cat([x1 * cos - x2 * sin, x2 * cos + x1 * sin], dim=-1)\n\n\nclass Scale(nn.Module):\n    \"\"\"Scale vector by element multiplications.\n\n    Args:\n        dim (int): The dimension of the scale vector.\n        init_value (float, optional): The initial value of the scale vector.\n            Defaults to 1.0.\n        trainable (bool, optional): Whether the scale vector is trainable.\n            Defaults to True.\n    \"\"\"\n\n    def __init__(self, dim, init_value=1., trainable=True):\n        super().__init__()\n        self.scale = nn.Parameter(\n            init_value * torch.ones(dim), requires_grad=trainable)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        return x * self.scale\n\n\nclass RTMCCBlock(nn.Module):\n    \"\"\"Gated Attention Unit (GAU) in RTMBlock.\n\n    Args:\n        num_token (int): The number of tokens.\n        in_token_dims (int): The input token dimension.\n        out_token_dims (int): The output token dimension.\n        expansion_factor (int, optional): The expansion factor of the\n            intermediate token dimension. Defaults to 2.\n        s (int, optional): The self-attention feature dimension.\n            Defaults to 128.\n        eps (float, optional): The minimum value in clamp. Defaults to 1e-5.\n        dropout_rate (float, optional): The dropout rate. Defaults to 0.0.\n        drop_path (float, optional): The drop path rate. Defaults to 0.0.\n        attn_type (str, optional): Type of attention which should be one of\n            the following options:\n\n            - 'self-attn': Self-attention.\n            - 'cross-attn': Cross-attention.\n\n            Defaults to 'self-attn'.\n        act_fn (str, optional): The activation function which should be one\n            of the following options:\n\n            - 'ReLU': ReLU activation.\n            - 'SiLU': SiLU activation.\n\n            Defaults to 'SiLU'.\n        bias (bool, optional): Whether to use bias in linear layers.\n            Defaults to False.\n        use_rel_bias (bool, optional): Whether to use relative bias.\n            Defaults to True.\n        pos_enc (bool, optional): Whether to use rotary position\n            embedding. Defaults to False.\n\n    Reference:\n        `Transformer Quality in Linear Time\n        <https://arxiv.org/abs/2202.10447>`_\n    \"\"\"\n\n    def __init__(self,\n                 num_token,\n                 in_token_dims,\n                 out_token_dims,\n                 expansion_factor=2,\n                 s=128,\n                 eps=1e-5,\n                 dropout_rate=0.,\n                 drop_path=0.,\n                 attn_type='self-attn',\n                 act_fn='SiLU',\n                 bias=False,\n                 use_rel_bias=True,\n                 pos_enc=False):\n\n        super(RTMCCBlock, self).__init__()\n        self.s = s\n        self.num_token = num_token\n        self.use_rel_bias = use_rel_bias\n        self.attn_type = attn_type\n        self.pos_enc = pos_enc\n        self.drop_path = DropPath(drop_path) \\\n            if drop_path > 0. else nn.Identity()\n\n        self.e = int(in_token_dims * expansion_factor)\n        if use_rel_bias:\n            if attn_type == 'self-attn':\n                self.w = nn.Parameter(\n                    torch.rand([2 * num_token - 1], dtype=torch.float))\n            else:\n                self.a = nn.Parameter(torch.rand([1, s], dtype=torch.float))\n                self.b = nn.Parameter(torch.rand([1, s], dtype=torch.float))\n        self.o = nn.Linear(self.e, out_token_dims, bias=bias)\n\n        if attn_type == 'self-attn':\n            self.uv = nn.Linear(in_token_dims, 2 * self.e + self.s, bias=bias)\n            self.gamma = nn.Parameter(torch.rand((2, self.s)))\n            self.beta = nn.Parameter(torch.rand((2, self.s)))\n        else:\n            self.uv = nn.Linear(in_token_dims, self.e + self.s, bias=bias)\n            self.k_fc = nn.Linear(in_token_dims, self.s, bias=bias)\n            self.v_fc = nn.Linear(in_token_dims, self.e, bias=bias)\n            nn.init.xavier_uniform_(self.k_fc.weight)\n            nn.init.xavier_uniform_(self.v_fc.weight)\n\n        self.ln = ScaleNorm(in_token_dims, eps=eps)\n\n        nn.init.xavier_uniform_(self.uv.weight)\n\n        if act_fn == 'SiLU' or act_fn == nn.SiLU:\n            assert digit_version(TORCH_VERSION) >= digit_version('1.7.0'), \\\n                'SiLU activation requires PyTorch version >= 1.7'\n\n            self.act_fn = nn.SiLU(True)\n        elif act_fn == 'ReLU' or act_fn == nn.ReLU:\n            self.act_fn = nn.ReLU(True)\n        else:\n            raise NotImplementedError\n\n        if in_token_dims == out_token_dims:\n            self.shortcut = True\n            self.res_scale = Scale(in_token_dims)\n        else:\n            self.shortcut = False\n\n        self.sqrt_s = math.sqrt(s)\n\n        self.dropout_rate = dropout_rate\n\n        if dropout_rate > 0.:\n            self.dropout = nn.Dropout(dropout_rate)\n\n    def rel_pos_bias(self, seq_len, k_len=None):\n        \"\"\"Add relative position bias.\"\"\"\n\n        if self.attn_type == 'self-attn':\n            t = F.pad(self.w[:2 * seq_len - 1], [0, seq_len]).repeat(seq_len)\n            t = t[..., :-seq_len].reshape(-1, seq_len, 3 * seq_len - 2)\n            r = (2 * seq_len - 1) // 2\n            t = t[..., r:-r]\n        else:\n            a = rope(self.a.repeat(seq_len, 1), dim=0)\n            b = rope(self.b.repeat(k_len, 1), dim=0)\n            t = torch.bmm(a, b.permute(0, 2, 1))\n        return t\n\n    def _forward(self, inputs):\n        \"\"\"GAU Forward function.\"\"\"\n\n        if self.attn_type == 'self-attn':\n            x = inputs\n        else:\n            x, k, v = inputs\n\n        x = self.ln(x)\n\n        # [B, K, in_token_dims] -> [B, K, e + e + s]\n        uv = self.uv(x)\n        uv = self.act_fn(uv)\n\n        if self.attn_type == 'self-attn':\n            # [B, K, e + e + s] -> [B, K, e], [B, K, e], [B, K, s]\n            u, v, base = torch.split(uv, [self.e, self.e, self.s], dim=2)\n            # [B, K, 1, s] * [1, 1, 2, s] + [2, s] -> [B, K, 2, s]\n            base = base.unsqueeze(2) * self.gamma[None, None, :] + self.beta\n\n            if self.pos_enc:\n                base = rope(base, dim=1)\n            # [B, K, 2, s] -> [B, K, s], [B, K, s]\n            q, k = torch.unbind(base, dim=2)\n\n        else:\n            # [B, K, e + s] -> [B, K, e], [B, K, s]\n            u, q = torch.split(uv, [self.e, self.s], dim=2)\n\n            k = self.k_fc(k)  # -> [B, K, s]\n            v = self.v_fc(v)  # -> [B, K, e]\n\n            if self.pos_enc:\n                q = rope(q, 1)\n                k = rope(k, 1)\n\n        # [B, K, s].permute() -> [B, s, K]\n        # [B, K, s] x [B, s, K] -> [B, K, K]\n        qk = torch.bmm(q, k.permute(0, 2, 1))\n\n        if self.use_rel_bias:\n            if self.attn_type == 'self-attn':\n                bias = self.rel_pos_bias(q.size(1))\n            else:\n                bias = self.rel_pos_bias(q.size(1), k.size(1))\n            qk += bias[:, :q.size(1), :k.size(1)]\n        # [B, K, K]\n        kernel = torch.square(F.relu(qk / self.sqrt_s))\n\n        if self.dropout_rate > 0.:\n            kernel = self.dropout(kernel)\n        # [B, K, K] x [B, K, e] -> [B, K, e]\n        x = u * torch.bmm(kernel, v)\n        # [B, K, e] -> [B, K, out_token_dims]\n        x = self.o(x)\n\n        return x\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        if self.shortcut:\n            if self.attn_type == 'cross-attn':\n                res_shortcut = x[0]\n            else:\n                res_shortcut = x\n            main_branch = self.drop_path(self._forward(x))\n            return self.res_scale(res_shortcut) + main_branch\n        else:\n            return self.drop_path(self._forward(x))\n"
  },
  {
    "path": "mmpose/models/utils/transformer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Optional, Sequence, Union\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import build_conv_layer, build_norm_layer\nfrom mmcv.cnn.bricks import DropPath\nfrom mmcv.cnn.bricks.transformer import FFN, MultiheadAttention\nfrom mmengine.model import BaseModule, ModuleList\nfrom mmengine.utils import digit_version, to_2tuple\nfrom mmengine.utils.dl_utils import TORCH_VERSION\nfrom torch import Tensor\n\nfrom mmpose.utils.typing import ConfigType, OptConfigType\n\ntry:\n    from fairscale.nn.checkpoint import checkpoint_wrapper\nexcept ImportError:\n    checkpoint_wrapper = None\n\n\ndef nlc_to_nchw(x, hw_shape):\n    \"\"\"Convert [N, L, C] shape tensor to [N, C, H, W] shape tensor.\n\n    Args:\n        x (Tensor): The input tensor of shape [N, L, C] before conversion.\n        hw_shape (Sequence[int]): The height and width of output feature map.\n\n    Returns:\n        Tensor: The output tensor of shape [N, C, H, W] after conversion.\n    \"\"\"\n    H, W = hw_shape\n    assert len(x.shape) == 3\n    B, L, C = x.shape\n    assert L == H * W, 'The seq_len does not match H, W'\n    return x.transpose(1, 2).reshape(B, C, H, W).contiguous()\n\n\ndef nchw_to_nlc(x):\n    \"\"\"Flatten [N, C, H, W] shape tensor to [N, L, C] shape tensor.\n\n    Args:\n        x (Tensor): The input tensor of shape [N, C, H, W] before conversion.\n\n    Returns:\n        Tensor: The output tensor of shape [N, L, C] after conversion.\n    \"\"\"\n    assert len(x.shape) == 4\n    return x.flatten(2).transpose(1, 2).contiguous()\n\n\nclass AdaptivePadding(nn.Module):\n    \"\"\"Applies padding to input (if needed) so that input can get fully covered\n    by filter you specified. It support two modes \"same\" and \"corner\". The\n    \"same\" mode is same with \"SAME\" padding mode in TensorFlow, pad zero around\n    input. The \"corner\"  mode would pad zero to bottom right.\n\n    Args:\n        kernel_size (int | tuple): Size of the kernel:\n        stride (int | tuple): Stride of the filter. Default: 1:\n        dilation (int | tuple): Spacing between kernel elements.\n            Default: 1\n        padding (str): Support \"same\" and \"corner\", \"corner\" mode\n            would pad zero to bottom right, and \"same\" mode would\n            pad zero around input. Default: \"corner\".\n    Example:\n        >>> kernel_size = 16\n        >>> stride = 16\n        >>> dilation = 1\n        >>> input = torch.rand(1, 1, 15, 17)\n        >>> adap_pad = AdaptivePadding(\n        >>>     kernel_size=kernel_size,\n        >>>     stride=stride,\n        >>>     dilation=dilation,\n        >>>     padding=\"corner\")\n        >>> out = adap_pad(input)\n        >>> assert (out.shape[2], out.shape[3]) == (16, 32)\n        >>> input = torch.rand(1, 1, 16, 17)\n        >>> out = adap_pad(input)\n        >>> assert (out.shape[2], out.shape[3]) == (16, 32)\n    \"\"\"\n\n    def __init__(self, kernel_size=1, stride=1, dilation=1, padding='corner'):\n\n        super(AdaptivePadding, self).__init__()\n\n        assert padding in ('same', 'corner')\n\n        kernel_size = to_2tuple(kernel_size)\n        stride = to_2tuple(stride)\n        padding = to_2tuple(padding)\n        dilation = to_2tuple(dilation)\n\n        self.padding = padding\n        self.kernel_size = kernel_size\n        self.stride = stride\n        self.dilation = dilation\n\n    def get_pad_shape(self, input_shape):\n        \"\"\"Get horizontal and vertical padding shapes.\"\"\"\n\n        input_h, input_w = input_shape\n        kernel_h, kernel_w = self.kernel_size\n        stride_h, stride_w = self.stride\n        output_h = math.ceil(input_h / stride_h)\n        output_w = math.ceil(input_w / stride_w)\n        pad_h = max((output_h - 1) * stride_h +\n                    (kernel_h - 1) * self.dilation[0] + 1 - input_h, 0)\n        pad_w = max((output_w - 1) * stride_w +\n                    (kernel_w - 1) * self.dilation[1] + 1 - input_w, 0)\n        return pad_h, pad_w\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        pad_h, pad_w = self.get_pad_shape(x.size()[-2:])\n        if pad_h > 0 or pad_w > 0:\n            if self.padding == 'corner':\n                x = F.pad(x, [0, pad_w, 0, pad_h])\n            elif self.padding == 'same':\n                x = F.pad(x, [\n                    pad_w // 2, pad_w - pad_w // 2, pad_h // 2,\n                    pad_h - pad_h // 2\n                ])\n        return x\n\n\nclass PatchEmbed(BaseModule):\n    \"\"\"Image to Patch Embedding.\n\n    We use a conv layer to implement PatchEmbed.\n\n    Args:\n        in_channels (int): The num of input channels. Default: 3\n        embed_dims (int): The dimensions of embedding. Default: 768\n        conv_type (str): The config dict for embedding\n            conv layer type selection. Default: \"Conv2d.\n        kernel_size (int): The kernel_size of embedding conv. Default: 16.\n        stride (int): The slide stride of embedding conv.\n            Default: None (Would be set as `kernel_size`).\n        padding (int | tuple | string ): The padding length of\n            embedding conv. When it is a string, it means the mode\n            of adaptive padding, support \"same\" and \"corner\" now.\n            Default: \"corner\".\n        dilation (int): The dilation rate of embedding conv. Default: 1.\n        bias (bool): Bias of embed conv. Default: True.\n        norm_cfg (dict, optional): Config dict for normalization layer.\n            Default: None.\n        input_size (int | tuple | None): The size of input, which will be\n            used to calculate the out size. Only work when `dynamic_size`\n            is False. Default: None.\n        init_cfg (`mmcv.ConfigDict`, optional): The Config for initialization.\n            Default: None.\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels=3,\n        embed_dims=768,\n        conv_type='Conv2d',\n        kernel_size=16,\n        stride=16,\n        padding='corner',\n        dilation=1,\n        bias=True,\n        norm_cfg=None,\n        input_size=None,\n        init_cfg=None,\n    ):\n        super(PatchEmbed, self).__init__(init_cfg=init_cfg)\n\n        self.embed_dims = embed_dims\n        if stride is None:\n            stride = kernel_size\n\n        kernel_size = to_2tuple(kernel_size)\n        stride = to_2tuple(stride)\n        dilation = to_2tuple(dilation)\n\n        if isinstance(padding, str):\n            self.adap_padding = AdaptivePadding(\n                kernel_size=kernel_size,\n                stride=stride,\n                dilation=dilation,\n                padding=padding)\n            # disable the padding of conv\n            padding = 0\n        else:\n            self.adap_padding = None\n        padding = to_2tuple(padding)\n\n        self.projection = build_conv_layer(\n            dict(type=conv_type),\n            in_channels=in_channels,\n            out_channels=embed_dims,\n            kernel_size=kernel_size,\n            stride=stride,\n            padding=padding,\n            dilation=dilation,\n            bias=bias)\n\n        if norm_cfg is not None:\n            self.norm = build_norm_layer(norm_cfg, embed_dims)[1]\n        else:\n            self.norm = None\n\n        if input_size:\n            input_size = to_2tuple(input_size)\n            # `init_out_size` would be used outside to\n            # calculate the num_patches\n            # when `use_abs_pos_embed` outside\n            self.init_input_size = input_size\n            if self.adap_padding:\n                pad_h, pad_w = self.adap_padding.get_pad_shape(input_size)\n                input_h, input_w = input_size\n                input_h = input_h + pad_h\n                input_w = input_w + pad_w\n                input_size = (input_h, input_w)\n\n            # https://pytorch.org/docs/stable/generated/torch.nn.Conv2d.html\n            h_out = (input_size[0] + 2 * padding[0] - dilation[0] *\n                     (kernel_size[0] - 1) - 1) // stride[0] + 1\n            w_out = (input_size[1] + 2 * padding[1] - dilation[1] *\n                     (kernel_size[1] - 1) - 1) // stride[1] + 1\n            self.init_out_size = (h_out, w_out)\n        else:\n            self.init_input_size = None\n            self.init_out_size = None\n\n    def forward(self, x):\n        \"\"\"\n        Args:\n            x (Tensor): Has shape (B, C, H, W). In most case, C is 3.\n\n        Returns:\n            tuple: Contains merged results and its spatial shape.\n\n                - x (Tensor): Has shape (B, out_h * out_w, embed_dims)\n                - out_size (tuple[int]): Spatial shape of x, arrange as\n                    (out_h, out_w).\n        \"\"\"\n\n        if self.adap_padding:\n            x = self.adap_padding(x)\n\n        x = self.projection(x)\n        out_size = (x.shape[2], x.shape[3])\n        x = x.flatten(2).transpose(1, 2)\n        if self.norm is not None:\n            x = self.norm(x)\n        return x, out_size\n\n\nclass PatchMerging(BaseModule):\n    \"\"\"Merge patch feature map.\n\n    This layer groups feature map by kernel_size, and applies norm and linear\n    layers to the grouped feature map. Our implementation uses `nn.Unfold` to\n    merge patch, which is about 25% faster than original implementation.\n    Instead, we need to modify pretrained models for compatibility.\n\n    Args:\n        in_channels (int): The num of input channels.\n            to gets fully covered by filter and stride you specified..\n            Default: True.\n        out_channels (int): The num of output channels.\n        kernel_size (int | tuple, optional): the kernel size in the unfold\n            layer. Defaults to 2.\n        stride (int | tuple, optional): the stride of the sliding blocks in the\n            unfold layer. Default: None. (Would be set as `kernel_size`)\n        padding (int | tuple | string ): The padding length of\n            embedding conv. When it is a string, it means the mode\n            of adaptive padding, support \"same\" and \"corner\" now.\n            Default: \"corner\".\n        dilation (int | tuple, optional): dilation parameter in the unfold\n            layer. Default: 1.\n        bias (bool, optional): Whether to add bias in linear layer or not.\n            Defaults: False.\n        norm_cfg (dict, optional): Config dict for normalization layer.\n            Default: dict(type='LN').\n        init_cfg (dict, optional): The extra config for initialization.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 out_channels,\n                 kernel_size=2,\n                 stride=None,\n                 padding='corner',\n                 dilation=1,\n                 bias=False,\n                 norm_cfg=dict(type='LN'),\n                 init_cfg=None):\n        super().__init__(init_cfg=init_cfg)\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        if stride:\n            stride = stride\n        else:\n            stride = kernel_size\n\n        kernel_size = to_2tuple(kernel_size)\n        stride = to_2tuple(stride)\n        dilation = to_2tuple(dilation)\n\n        if isinstance(padding, str):\n            self.adap_padding = AdaptivePadding(\n                kernel_size=kernel_size,\n                stride=stride,\n                dilation=dilation,\n                padding=padding)\n            # disable the padding of unfold\n            padding = 0\n        else:\n            self.adap_padding = None\n\n        padding = to_2tuple(padding)\n        self.sampler = nn.Unfold(\n            kernel_size=kernel_size,\n            dilation=dilation,\n            padding=padding,\n            stride=stride)\n\n        sample_dim = kernel_size[0] * kernel_size[1] * in_channels\n\n        if norm_cfg is not None:\n            self.norm = build_norm_layer(norm_cfg, sample_dim)[1]\n        else:\n            self.norm = None\n\n        self.reduction = nn.Linear(sample_dim, out_channels, bias=bias)\n\n    def forward(self, x, input_size):\n        \"\"\"\n        Args:\n            x (Tensor): Has shape (B, H*W, C_in).\n            input_size (tuple[int]): The spatial shape of x, arrange as (H, W).\n                Default: None.\n\n        Returns:\n            tuple: Contains merged results and its spatial shape.\n\n                - x (Tensor): Has shape (B, Merged_H * Merged_W, C_out)\n                - out_size (tuple[int]): Spatial shape of x, arrange as\n                    (Merged_H, Merged_W).\n        \"\"\"\n        B, L, C = x.shape\n        assert isinstance(input_size, Sequence), f'Expect ' \\\n                                                 f'input_size is ' \\\n                                                 f'`Sequence` ' \\\n                                                 f'but get {input_size}'\n\n        H, W = input_size\n        assert L == H * W, 'input feature has wrong size'\n\n        x = x.view(B, H, W, C).permute([0, 3, 1, 2])  # B, C, H, W\n        # Use nn.Unfold to merge patch. About 25% faster than original method,\n        # but need to modify pretrained model for compatibility\n\n        if self.adap_padding:\n            x = self.adap_padding(x)\n            H, W = x.shape[-2:]\n\n        x = self.sampler(x)\n        # if kernel_size=2 and stride=2, x should has shape (B, 4*C, H/2*W/2)\n\n        out_h = (H + 2 * self.sampler.padding[0] - self.sampler.dilation[0] *\n                 (self.sampler.kernel_size[0] - 1) -\n                 1) // self.sampler.stride[0] + 1\n        out_w = (W + 2 * self.sampler.padding[1] - self.sampler.dilation[1] *\n                 (self.sampler.kernel_size[1] - 1) -\n                 1) // self.sampler.stride[1] + 1\n\n        output_size = (out_h, out_w)\n        x = x.transpose(1, 2)  # B, H/2*W/2, 4*C\n        x = self.norm(x) if self.norm else x\n        x = self.reduction(x)\n        return x, output_size\n\n\nclass ScaleNorm(nn.Module):\n    \"\"\"Scale Norm.\n\n    Args:\n        dim (int): The dimension of the scale vector.\n        eps (float, optional): The minimum value in clamp. Defaults to 1e-5.\n\n    Reference:\n        `Transformers without Tears: Improving the Normalization\n        of Self-Attention <https://arxiv.org/abs/1910.05895>`_\n    \"\"\"\n\n    def __init__(self, dim, eps=1e-5):\n        super().__init__()\n        self.scale = dim**-0.5\n        self.eps = eps\n        self.g = nn.Parameter(torch.ones(1))\n\n    def forward(self, x):\n        \"\"\"Forward function.\n\n        Args:\n            x (torch.Tensor): Input tensor.\n\n        Returns:\n            torch.Tensor: The tensor after applying scale norm.\n        \"\"\"\n\n        if torch.onnx.is_in_onnx_export() and \\\n                digit_version(TORCH_VERSION) >= digit_version('1.12'):\n\n            norm = torch.linalg.norm(x, dim=-1, keepdim=True)\n\n        else:\n            norm = torch.norm(x, dim=-1, keepdim=True)\n        norm = norm * self.scale\n        return x / norm.clamp(min=self.eps) * self.g\n\n\nclass SinePositionalEncoding(nn.Module):\n    \"\"\"Sine Positional Encoding Module. This module implements sine positional\n    encoding, which is commonly used in transformer-based models to add\n    positional information to the input sequences. It uses sine and cosine\n    functions to create positional embeddings for each element in the input\n    sequence.\n\n    Args:\n        out_channels (int): The number of features in the input sequence.\n        temperature (int): A temperature parameter used to scale\n            the positional encodings. Defaults to 10000.\n        spatial_dim (int): The number of spatial dimension of input\n            feature. 1 represents sequence data and 2 represents grid data.\n            Defaults to 1.\n        learnable (bool): Whether to optimize the frequency base. Defaults\n            to False.\n        eval_size (int, tuple[int], optional): The fixed spatial size of\n            input features. Defaults to None.\n    \"\"\"\n\n    def __init__(\n        self,\n        out_channels: int,\n        spatial_dim: int = 1,\n        temperature: int = 1e5,\n        learnable: bool = False,\n        eval_size: Optional[Union[int, Sequence[int]]] = None,\n    ) -> None:\n\n        super().__init__()\n\n        assert out_channels % 2 == 0\n        assert temperature > 0\n\n        self.spatial_dim = spatial_dim\n        self.out_channels = out_channels\n        self.temperature = temperature\n        self.eval_size = eval_size\n        self.learnable = learnable\n\n        pos_dim = out_channels // 2\n        dim_t = torch.arange(pos_dim, dtype=torch.float32) / pos_dim\n        dim_t = self.temperature**(dim_t)\n\n        if not learnable:\n            self.register_buffer('dim_t', dim_t)\n        else:\n            self.dim_t = nn.Parameter(dim_t.detach())\n\n        # set parameters\n        if eval_size:\n            if hasattr(self, f'pos_enc_{eval_size}'):\n                delattr(self, f'pos_enc_{eval_size}')\n            pos_enc = self.generate_pos_encoding(size=eval_size)\n            self.register_buffer(f'pos_enc_{eval_size}', pos_enc)\n\n    def forward(self, *args, **kwargs):\n        return self.generate_pos_encoding(*args, **kwargs)\n\n    def generate_pos_encoding(self,\n                              size: Union[int, Sequence[int]] = None,\n                              position: Optional[Tensor] = None):\n        \"\"\"Generate positional encoding for input features.\n\n        Args:\n            size (int or tuple[int]): Size of the input features. Required\n                if position is None.\n            position (Tensor, optional): Position tensor. Required if size\n                is None.\n        \"\"\"\n\n        assert (size is not None) ^ (position is not None)\n\n        if (not (self.learnable\n                 and self.training)) and size is not None and hasattr(\n                     self, f'pos_enc_{size}'):\n            return getattr(self, f'pos_enc_{size}')\n\n        if self.spatial_dim == 1:\n            if size is not None:\n                if isinstance(size, (tuple, list)):\n                    size = size[0]\n                position = torch.arange(\n                    size, dtype=torch.float32, device=self.dim_t.device)\n\n            dim_t = self.dim_t.reshape(*((1, ) * position.ndim), -1)\n            freq = position.unsqueeze(-1) / dim_t\n            pos_enc = torch.cat((freq.cos(), freq.sin()), dim=-1)\n\n        elif self.spatial_dim == 2:\n            if size is not None:\n                if isinstance(size, (tuple, list)):\n                    h, w = size[:2]\n                elif isinstance(size, (int, float)):\n                    h, w = int(size), int(size)\n                else:\n                    raise ValueError(f'got invalid type {type(size)} for size')\n                grid_h, grid_w = torch.meshgrid(\n                    torch.arange(\n                        int(h), dtype=torch.float32, device=self.dim_t.device),\n                    torch.arange(\n                        int(w), dtype=torch.float32, device=self.dim_t.device))\n                grid_h, grid_w = grid_h.flatten(), grid_w.flatten()\n            else:\n                assert position.size(-1) == 2\n                grid_h, grid_w = torch.unbind(position, dim=-1)\n\n            dim_t = self.dim_t.reshape(*((1, ) * grid_h.ndim), -1)\n            freq_h = grid_h.unsqueeze(-1) / dim_t\n            freq_w = grid_w.unsqueeze(-1) / dim_t\n            pos_enc_h = torch.cat((freq_h.cos(), freq_h.sin()), dim=-1)\n            pos_enc_w = torch.cat((freq_w.cos(), freq_w.sin()), dim=-1)\n            pos_enc = torch.stack((pos_enc_h, pos_enc_w), dim=-1)\n\n        return pos_enc\n\n    @staticmethod\n    def apply_additional_pos_enc(feature: Tensor,\n                                 pos_enc: Tensor,\n                                 spatial_dim: int = 1):\n        \"\"\"Apply additional positional encoding to input features.\n\n        Args:\n            feature (Tensor): Input feature tensor.\n            pos_enc (Tensor): Positional encoding tensor.\n            spatial_dim (int): Spatial dimension of input features.\n        \"\"\"\n\n        assert spatial_dim in (1, 2), f'the argument spatial_dim must be ' \\\n            f'either 1 or 2, but got {spatial_dim}'\n        if spatial_dim == 2:\n            pos_enc = pos_enc.flatten(-2)\n        for _ in range(feature.ndim - pos_enc.ndim):\n            pos_enc = pos_enc.unsqueeze(0)\n        return feature + pos_enc\n\n    @staticmethod\n    def apply_rotary_pos_enc(feature: Tensor,\n                             pos_enc: Tensor,\n                             spatial_dim: int = 1):\n        \"\"\"Apply rotary positional encoding to input features.\n\n        Args:\n            feature (Tensor): Input feature tensor.\n            pos_enc (Tensor): Positional encoding tensor.\n            spatial_dim (int): Spatial dimension of input features.\n        \"\"\"\n\n        assert spatial_dim in (1, 2), f'the argument spatial_dim must be ' \\\n            f'either 1 or 2, but got {spatial_dim}'\n\n        for _ in range(feature.ndim - pos_enc.ndim + spatial_dim - 1):\n            pos_enc = pos_enc.unsqueeze(0)\n\n        x1, x2 = torch.chunk(feature, 2, dim=-1)\n        if spatial_dim == 1:\n            cos, sin = torch.chunk(pos_enc, 2, dim=-1)\n            feature = torch.cat((x1 * cos - x2 * sin, x2 * cos + x1 * sin),\n                                dim=-1)\n        elif spatial_dim == 2:\n            pos_enc_h, pos_enc_w = torch.unbind(pos_enc, dim=-1)\n            cos_h, sin_h = torch.chunk(pos_enc_h, 2, dim=-1)\n            cos_w, sin_w = torch.chunk(pos_enc_w, 2, dim=-1)\n            feature = torch.cat(\n                (x1 * cos_h - x2 * sin_h, x1 * cos_w + x2 * sin_w), dim=-1)\n\n        return feature\n\n\nclass ChannelWiseScale(nn.Module):\n    \"\"\"Scale vector by element multiplications.\n\n    Args:\n        dim (int): The dimension of the scale vector.\n        init_value (float, optional): The initial value of the scale vector.\n            Defaults to 1.0.\n        trainable (bool, optional): Whether the scale vector is trainable.\n            Defaults to True.\n    \"\"\"\n\n    def __init__(self, dim, init_value=1., trainable=True):\n        super().__init__()\n        self.scale = nn.Parameter(\n            init_value * torch.ones(dim), requires_grad=trainable)\n\n    def forward(self, x):\n        \"\"\"Forward function.\"\"\"\n\n        return x * self.scale\n\n\nclass GAUEncoder(BaseModule):\n    \"\"\"Gated Attention Unit (GAU) Encoder.\n\n    Args:\n        in_token_dims (int): The input token dimension.\n        out_token_dims (int): The output token dimension.\n        expansion_factor (int, optional): The expansion factor of the\n            intermediate token dimension. Defaults to 2.\n        s (int, optional): The self-attention feature dimension.\n            Defaults to 128.\n        eps (float, optional): The minimum value in clamp. Defaults to 1e-5.\n        dropout_rate (float, optional): The dropout rate. Defaults to 0.0.\n        drop_path (float, optional): The drop path rate. Defaults to 0.0.\n        act_fn (str, optional): The activation function which should be one\n            of the following options:\n\n            - 'ReLU': ReLU activation.\n            - 'SiLU': SiLU activation.\n\n            Defaults to 'SiLU'.\n        bias (bool, optional): Whether to use bias in linear layers.\n            Defaults to False.\n        pos_enc (bool, optional): Whether to use rotary position\n            embedding. Defaults to False.\n        spatial_dim (int, optional): The spatial dimension of inputs\n\n    Reference:\n        `Transformer Quality in Linear Time\n        <https://arxiv.org/abs/2202.10447>`_\n    \"\"\"\n\n    def __init__(self,\n                 in_token_dims,\n                 out_token_dims,\n                 expansion_factor=2,\n                 s=128,\n                 eps=1e-5,\n                 dropout_rate=0.,\n                 drop_path=0.,\n                 act_fn='SiLU',\n                 bias=False,\n                 pos_enc: str = 'none',\n                 spatial_dim: int = 1):\n\n        super(GAUEncoder, self).__init__()\n        self.s = s\n        self.bias = bias\n        self.pos_enc = pos_enc\n        self.in_token_dims = in_token_dims\n        self.spatial_dim = spatial_dim\n        self.drop_path = DropPath(drop_path) \\\n            if drop_path > 0. else nn.Identity()\n\n        self.e = int(in_token_dims * expansion_factor)\n        self.o = nn.Linear(self.e, out_token_dims, bias=bias)\n\n        self._build_layers()\n\n        self.ln = ScaleNorm(in_token_dims, eps=eps)\n\n        nn.init.xavier_uniform_(self.uv.weight)\n\n        if act_fn == 'SiLU':\n            assert digit_version(TORCH_VERSION) >= digit_version('1.7.0'), \\\n                'SiLU activation requires PyTorch version >= 1.7'\n\n            self.act_fn = nn.SiLU(True)\n        else:\n            self.act_fn = nn.ReLU(True)\n\n        if in_token_dims == out_token_dims:\n            self.shortcut = True\n            self.res_scale = ChannelWiseScale(in_token_dims)\n        else:\n            self.shortcut = False\n\n        self.sqrt_s = math.sqrt(s)\n        self.dropout_rate = dropout_rate\n\n        if dropout_rate > 0.:\n            self.dropout = nn.Dropout(dropout_rate)\n\n    def _build_layers(self):\n        self.uv = nn.Linear(\n            self.in_token_dims, 2 * self.e + self.s, bias=self.bias)\n        self.gamma = nn.Parameter(torch.rand((2, self.s)))\n        self.beta = nn.Parameter(torch.rand((2, self.s)))\n\n    def _forward(self, x, mask=None, pos_enc=None):\n        \"\"\"GAU Forward function.\"\"\"\n\n        x = self.ln(x)\n\n        # [B, K, in_token_dims] -> [B, K, e + e + s]\n        uv = self.uv(x)\n        uv = self.act_fn(uv)\n\n        # [B, K, e + e + s] -> [B, K, e], [B, K, e], [B, K, s]\n        u, v, base = torch.split(uv, [self.e, self.e, self.s], dim=-1)\n        # [B, K, 1, s] * [1, 1, 2, s] + [2, s] -> [B, K, 2, s]\n        dim = base.ndim - self.gamma.ndim + 1\n        gamma = self.gamma.view(*((1, ) * dim), *self.gamma.size())\n        beta = self.beta.view(*((1, ) * dim), *self.beta.size())\n        base = base.unsqueeze(-2) * gamma + beta\n        # [B, K, 2, s] -> [B, K, s], [B, K, s]\n        q, k = torch.unbind(base, dim=-2)\n\n        if self.pos_enc == 'rope':\n            q = SinePositionalEncoding.apply_rotary_pos_enc(\n                q, pos_enc, self.spatial_dim)\n            k = SinePositionalEncoding.apply_rotary_pos_enc(\n                k, pos_enc, self.spatial_dim)\n        elif self.pos_enc == 'add':\n            pos_enc = pos_enc.reshape(*((1, ) * (q.ndim - 2)), q.size(-2),\n                                      q.size(-1))\n            q = q + pos_enc\n            k = k + pos_enc\n\n        # [B, K, s].transpose(-1, -2) -> [B, s, K]\n        # [B, K, s] x [B, s, K] -> [B, K, K]\n        qk = torch.matmul(q, k.transpose(-1, -2))\n\n        # [B, K, K]\n        kernel = torch.square(F.relu(qk / self.sqrt_s))\n\n        if mask is not None:\n            kernel = kernel * mask\n\n        if self.dropout_rate > 0.:\n            kernel = self.dropout(kernel)\n\n        # [B, K, K] x [B, K, e] -> [B, K, e]\n        x = u * torch.matmul(kernel, v)\n        # [B, K, e] -> [B, K, out_token_dims]\n        x = self.o(x)\n\n        return x\n\n    def forward(self, x, mask=None, pos_enc=None):\n        \"\"\"Forward function.\"\"\"\n        out = self.drop_path(self._forward(x, mask=mask, pos_enc=pos_enc))\n        if self.shortcut:\n            return self.res_scale(x) + out\n        else:\n            return out\n\n\nclass DetrTransformerEncoder(BaseModule):\n    \"\"\"Encoder of DETR.\n\n    Args:\n        num_layers (int): Number of encoder layers.\n        layer_cfg (:obj:`ConfigDict` or dict): the config of each encoder\n            layer. All the layers will share the same config.\n        num_cp (int): Number of checkpointing blocks in encoder layer.\n            Default to -1.\n        init_cfg (:obj:`ConfigDict` or dict, optional): the config to control\n            the initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 num_layers: int,\n                 layer_cfg: ConfigType,\n                 num_cp: int = -1,\n                 init_cfg: OptConfigType = None) -> None:\n\n        super().__init__(init_cfg=init_cfg)\n        self.num_layers = num_layers\n        self.layer_cfg = layer_cfg\n        self.num_cp = num_cp\n        assert self.num_cp <= self.num_layers\n        self._init_layers()\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize encoder layers.\"\"\"\n        self.layers = ModuleList([\n            DetrTransformerEncoderLayer(**self.layer_cfg)\n            for _ in range(self.num_layers)\n        ])\n\n        if self.num_cp > 0:\n            if checkpoint_wrapper is None:\n                raise NotImplementedError(\n                    'If you want to reduce GPU memory usage, \\\n                    please install fairscale by executing the \\\n                    following command: pip install fairscale.')\n            for i in range(self.num_cp):\n                self.layers[i] = checkpoint_wrapper(self.layers[i])\n\n        self.embed_dims = self.layers[0].embed_dims\n\n    def forward(self, query: Tensor, query_pos: Tensor,\n                key_padding_mask: Tensor, **kwargs) -> Tensor:\n        \"\"\"Forward function of encoder.\n\n        Args:\n            query (Tensor): Input queries of encoder, has shape\n                (bs, num_queries, dim).\n            query_pos (Tensor): The positional embeddings of the queries, has\n                shape (bs, num_queries, dim).\n            key_padding_mask (Tensor): The `key_padding_mask` of `self_attn`\n                input. ByteTensor, has shape (bs, num_queries).\n\n        Returns:\n            Tensor: Has shape (bs, num_queries, dim) if `batch_first` is\n            `True`, otherwise (num_queries, bs, dim).\n        \"\"\"\n        for layer in self.layers:\n            query = layer(query, query_pos, key_padding_mask, **kwargs)\n        return query\n\n\nclass DetrTransformerEncoderLayer(BaseModule):\n    \"\"\"Implements encoder layer in DETR transformer.\n\n    Args:\n        self_attn_cfg (:obj:`ConfigDict` or dict, optional): Config for self\n            attention.\n        ffn_cfg (:obj:`ConfigDict` or dict, optional): Config for FFN.\n        norm_cfg (:obj:`ConfigDict` or dict, optional): Config for\n            normalization layers. All the layers will share the same\n            config. Defaults to `LN`.\n        init_cfg (:obj:`ConfigDict` or dict, optional): Config to control\n            the initialization. Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 self_attn_cfg: OptConfigType = dict(\n                     embed_dims=256, num_heads=8, dropout=0.0),\n                 ffn_cfg: OptConfigType = dict(\n                     embed_dims=256,\n                     feedforward_channels=1024,\n                     num_fcs=2,\n                     ffn_drop=0.,\n                     act_cfg=dict(type='ReLU', inplace=True)),\n                 norm_cfg: OptConfigType = dict(type='LN'),\n                 init_cfg: OptConfigType = None) -> None:\n\n        super().__init__(init_cfg=init_cfg)\n\n        self.self_attn_cfg = self_attn_cfg\n        if 'batch_first' not in self.self_attn_cfg:\n            self.self_attn_cfg['batch_first'] = True\n        else:\n            assert self.self_attn_cfg['batch_first'] is True, 'First \\\n            dimension of all DETRs in mmdet is `batch`, \\\n            please set `batch_first` flag.'\n\n        self.ffn_cfg = ffn_cfg\n        self.norm_cfg = norm_cfg\n        self._init_layers()\n\n    def _init_layers(self) -> None:\n        \"\"\"Initialize self-attention, FFN, and normalization.\"\"\"\n        self.self_attn = MultiheadAttention(**self.self_attn_cfg)\n        self.embed_dims = self.self_attn.embed_dims\n        self.ffn = FFN(**self.ffn_cfg)\n        norms_list = [\n            build_norm_layer(self.norm_cfg, self.embed_dims)[1]\n            for _ in range(2)\n        ]\n        self.norms = ModuleList(norms_list)\n\n    def forward(self, query: Tensor, query_pos: Tensor,\n                key_padding_mask: Tensor, **kwargs) -> Tensor:\n        \"\"\"Forward function of an encoder layer.\n\n        Args:\n            query (Tensor): The input query, has shape (bs, num_queries, dim).\n            query_pos (Tensor): The positional encoding for query, with\n                the same shape as `query`.\n            key_padding_mask (Tensor): The `key_padding_mask` of `self_attn`\n                input. ByteTensor. has shape (bs, num_queries).\n        Returns:\n            Tensor: forwarded results, has shape (bs, num_queries, dim).\n        \"\"\"\n        query = self.self_attn(\n            query=query,\n            key=query,\n            value=query,\n            query_pos=query_pos,\n            key_pos=query_pos,\n            key_padding_mask=key_padding_mask,\n            **kwargs)\n        query = self.norms[0](query)\n        query = self.ffn(query)\n        query = self.norms[1](query)\n\n        return query\n"
  },
  {
    "path": "mmpose/models/utils/tta.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Tuple\n\nimport torch\nimport torch.nn.functional as F\nfrom torch import Tensor\n\n\ndef flip_heatmaps(heatmaps: Tensor,\n                  flip_indices: Optional[List[int]] = None,\n                  flip_mode: str = 'heatmap',\n                  shift_heatmap: bool = True):\n    \"\"\"Flip heatmaps for test-time augmentation.\n\n    Args:\n        heatmaps (Tensor): The heatmaps to flip. Should be a tensor in shape\n            [B, C, H, W]\n        flip_indices (List[int]): The indices of each keypoint's symmetric\n            keypoint. Defaults to ``None``\n        flip_mode (str): Specify the flipping mode. Options are:\n\n            - ``'heatmap'``: horizontally flip the heatmaps and swap heatmaps\n                of symmetric keypoints according to ``flip_indices``\n            - ``'udp_combined'``: similar to ``'heatmap'`` mode but further\n                flip the x_offset values\n            - ``'offset'``: horizontally flip the offset fields and swap\n                heatmaps of symmetric keypoints according to\n                ``flip_indices``. x_offset values are also reversed\n        shift_heatmap (bool): Shift the flipped heatmaps to align with the\n            original heatmaps and improve accuracy. Defaults to ``True``\n\n    Returns:\n        Tensor: flipped heatmaps in shape [B, C, H, W]\n    \"\"\"\n\n    if flip_mode == 'heatmap':\n        heatmaps = heatmaps.flip(-1)\n        if flip_indices is not None:\n            assert len(flip_indices) == heatmaps.shape[1]\n            heatmaps = heatmaps[:, flip_indices]\n    elif flip_mode == 'udp_combined':\n        B, C, H, W = heatmaps.shape\n        heatmaps = heatmaps.view(B, C // 3, 3, H, W)\n        heatmaps = heatmaps.flip(-1)\n        if flip_indices is not None:\n            assert len(flip_indices) == C // 3\n            heatmaps = heatmaps[:, flip_indices]\n        heatmaps[:, :, 1] = -heatmaps[:, :, 1]\n        heatmaps = heatmaps.view(B, C, H, W)\n\n    elif flip_mode == 'offset':\n        B, C, H, W = heatmaps.shape\n        heatmaps = heatmaps.view(B, C // 2, -1, H, W)\n        heatmaps = heatmaps.flip(-1)\n        if flip_indices is not None:\n            assert len(flip_indices) == C // 2\n            heatmaps = heatmaps[:, flip_indices]\n        heatmaps[:, :, 0] = -heatmaps[:, :, 0]\n        heatmaps = heatmaps.view(B, C, H, W)\n\n    else:\n        raise ValueError(f'Invalid flip_mode value \"{flip_mode}\"')\n\n    if shift_heatmap:\n        # clone data to avoid unexpected in-place operation when using CPU\n        heatmaps[..., 1:] = heatmaps[..., :-1].clone()\n\n    return heatmaps\n\n\ndef flip_vectors(x_labels: Tensor, y_labels: Tensor, flip_indices: List[int]):\n    \"\"\"Flip instance-level labels in specific axis for test-time augmentation.\n\n    Args:\n        x_labels (Tensor): The vector labels in x-axis to flip. Should be\n            a tensor in shape [B, C, Wx]\n        y_labels (Tensor): The vector labels in y-axis to flip. Should be\n            a tensor in shape [B, C, Wy]\n        flip_indices (List[int]): The indices of each keypoint's symmetric\n            keypoint\n    \"\"\"\n    assert x_labels.ndim == 3 and y_labels.ndim == 3\n    assert len(flip_indices) == x_labels.shape[1] and len(\n        flip_indices) == y_labels.shape[1]\n    x_labels = x_labels[:, flip_indices].flip(-1)\n    y_labels = y_labels[:, flip_indices]\n\n    return x_labels, y_labels\n\n\ndef flip_coordinates(coords: Tensor, flip_indices: List[int],\n                     shift_coords: bool, input_size: Tuple[int, int]):\n    \"\"\"Flip normalized coordinates for test-time augmentation.\n\n    Args:\n        coords (Tensor): The coordinates to flip. Should be a tensor in shape\n            [B, K, D]\n        flip_indices (List[int]): The indices of each keypoint's symmetric\n            keypoint\n        shift_coords (bool): Shift the flipped coordinates to align with the\n            original coordinates and improve accuracy. Defaults to ``True``\n        input_size (Tuple[int, int]): The size of input image in [w, h]\n    \"\"\"\n    assert coords.ndim == 3\n    assert len(flip_indices) == coords.shape[1]\n\n    coords[:, :, 0] = 1.0 - coords[:, :, 0]\n\n    if shift_coords:\n        img_width = input_size[0]\n        coords[:, :, 0] -= 1.0 / img_width\n\n    coords = coords[:, flip_indices]\n    return coords\n\n\ndef flip_visibility(vis: Tensor, flip_indices: List[int]):\n    \"\"\"Flip keypoints visibility for test-time augmentation.\n\n    Args:\n        vis (Tensor): The keypoints visibility to flip. Should be a tensor\n            in shape [B, K]\n        flip_indices (List[int]): The indices of each keypoint's symmetric\n            keypoint\n    \"\"\"\n    assert vis.ndim == 2\n\n    vis = vis[:, flip_indices]\n    return vis\n\n\ndef aggregate_heatmaps(heatmaps: List[Tensor],\n                       size: Optional[Tuple[int, int]],\n                       align_corners: bool = False,\n                       mode: str = 'average'):\n    \"\"\"Aggregate multiple heatmaps.\n\n    Args:\n        heatmaps (List[Tensor]): Multiple heatmaps to aggregate. Each should\n            be in shape (B, C, H, W)\n        size (Tuple[int, int], optional): The target size in (w, h). All\n            heatmaps will be resized to the target size. If not given, the\n            first heatmap tensor's width and height will be used as the target\n            size. Defaults to ``None``\n        align_corners (bool): Whether align corners when resizing heatmaps.\n            Defaults to ``False``\n        mode (str): Aggregation mode in one of the following:\n\n            - ``'average'``: Get average of heatmaps. All heatmaps mush have\n                the same channel number\n            - ``'concat'``: Concate the heatmaps at the channel dim\n    \"\"\"\n\n    if mode not in {'average', 'concat'}:\n        raise ValueError(f'Invalid aggregation mode `{mode}`')\n\n    if size is None:\n        h, w = heatmaps[0].shape[2:4]\n    else:\n        w, h = size\n\n    for i, _heatmaps in enumerate(heatmaps):\n        assert _heatmaps.ndim == 4\n        if mode == 'average':\n            assert _heatmaps.shape[:2] == heatmaps[0].shape[:2]\n        else:\n            assert _heatmaps.shape[0] == heatmaps[0].shape[0]\n\n        if _heatmaps.shape[2:4] != (h, w):\n            heatmaps[i] = F.interpolate(\n                _heatmaps,\n                size=(h, w),\n                mode='bilinear',\n                align_corners=align_corners)\n\n    if mode == 'average':\n        output = sum(heatmaps).div(len(heatmaps))\n    elif mode == 'concat':\n        output = torch.cat(heatmaps, dim=1)\n    else:\n        raise ValueError()\n\n    return output\n"
  },
  {
    "path": "mmpose/registry.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\"\"\"MMPose provides following registry nodes to support using modules across\nprojects.\n\nEach node is a child of the root registry in MMEngine.\nMore details can be found at\nhttps://mmengine.readthedocs.io/en/latest/tutorials/registry.html.\n\"\"\"\n\nfrom mmengine.registry import DATA_SAMPLERS as MMENGINE_DATA_SAMPLERS\nfrom mmengine.registry import DATASETS as MMENGINE_DATASETS\nfrom mmengine.registry import EVALUATOR as MMENGINE_EVALUATOR\nfrom mmengine.registry import HOOKS as MMENGINE_HOOKS\nfrom mmengine.registry import INFERENCERS as MMENGINE_INFERENCERS\nfrom mmengine.registry import LOG_PROCESSORS as MMENGINE_LOG_PROCESSORS\nfrom mmengine.registry import LOOPS as MMENGINE_LOOPS\nfrom mmengine.registry import METRICS as MMENGINE_METRICS\nfrom mmengine.registry import MODEL_WRAPPERS as MMENGINE_MODEL_WRAPPERS\nfrom mmengine.registry import MODELS as MMENGINE_MODELS\nfrom mmengine.registry import \\\n    OPTIM_WRAPPER_CONSTRUCTORS as MMENGINE_OPTIM_WRAPPER_CONSTRUCTORS\nfrom mmengine.registry import OPTIM_WRAPPERS as MMENGINE_OPTIM_WRAPPERS\nfrom mmengine.registry import OPTIMIZERS as MMENGINE_OPTIMIZERS\nfrom mmengine.registry import PARAM_SCHEDULERS as MMENGINE_PARAM_SCHEDULERS\nfrom mmengine.registry import \\\n    RUNNER_CONSTRUCTORS as MMENGINE_RUNNER_CONSTRUCTORS\nfrom mmengine.registry import RUNNERS as MMENGINE_RUNNERS\nfrom mmengine.registry import TASK_UTILS as MMENGINE_TASK_UTILS\nfrom mmengine.registry import TRANSFORMS as MMENGINE_TRANSFORMS\nfrom mmengine.registry import VISBACKENDS as MMENGINE_VISBACKENDS\nfrom mmengine.registry import VISUALIZERS as MMENGINE_VISUALIZERS\nfrom mmengine.registry import \\\n    WEIGHT_INITIALIZERS as MMENGINE_WEIGHT_INITIALIZERS\nfrom mmengine.registry import Registry\n\n# Registries For Runner and the related\n# manage all kinds of runners like `EpochBasedRunner` and `IterBasedRunner`\nRUNNERS = Registry('runner', parent=MMENGINE_RUNNERS)\n# manage runner constructors that define how to initialize runners\nRUNNER_CONSTRUCTORS = Registry(\n    'runner constructor', parent=MMENGINE_RUNNER_CONSTRUCTORS)\n# manage all kinds of loops like `EpochBasedTrainLoop`\nLOOPS = Registry('loop', parent=MMENGINE_LOOPS)\n# manage all kinds of hooks like `CheckpointHook`\nHOOKS = Registry(\n    'hook', parent=MMENGINE_HOOKS, locations=['mmpose.engine.hooks'])\n\n# Registries For Data and the related\n# manage data-related modules\nDATASETS = Registry(\n    'dataset', parent=MMENGINE_DATASETS, locations=['mmpose.datasets'])\nDATA_SAMPLERS = Registry(\n    'data sampler',\n    parent=MMENGINE_DATA_SAMPLERS,\n    locations=['mmpose.datasets.samplers'])\nTRANSFORMS = Registry(\n    'transform',\n    parent=MMENGINE_TRANSFORMS,\n    locations=['mmpose.datasets.transforms'])\n\n# manage all kinds of modules inheriting `nn.Module`\nMODELS = Registry('model', parent=MMENGINE_MODELS, locations=['mmpose.models'])\n# manage all kinds of model wrappers like 'MMDistributedDataParallel'\nMODEL_WRAPPERS = Registry(\n    'model_wrapper',\n    parent=MMENGINE_MODEL_WRAPPERS,\n    locations=['mmpose.models'])\n# manage all kinds of weight initialization modules like `Uniform`\nWEIGHT_INITIALIZERS = Registry(\n    'weight initializer',\n    parent=MMENGINE_WEIGHT_INITIALIZERS,\n    locations=['mmpose.models'])\n# manage all kinds of batch augmentations like Mixup and CutMix.\nBATCH_AUGMENTS = Registry('batch augment', locations=['mmpose.models'])\n\n# Registries For Optimizer and the related\n# manage all kinds of optimizers like `SGD` and `Adam`\nOPTIMIZERS = Registry(\n    'optimizer', parent=MMENGINE_OPTIMIZERS, locations=['mmpose.engine'])\n# manage optimizer wrapper\nOPTIM_WRAPPERS = Registry(\n    'optimizer_wrapper',\n    parent=MMENGINE_OPTIM_WRAPPERS,\n    locations=['mmpose.engine'])\n# manage constructors that customize the optimization hyperparameters.\nOPTIM_WRAPPER_CONSTRUCTORS = Registry(\n    'optimizer wrapper constructor',\n    parent=MMENGINE_OPTIM_WRAPPER_CONSTRUCTORS,\n    locations=['mmpose.engine.optim_wrappers'])\n# manage all kinds of parameter schedulers like `MultiStepLR`\nPARAM_SCHEDULERS = Registry(\n    'parameter scheduler',\n    parent=MMENGINE_PARAM_SCHEDULERS,\n    locations=['mmpose.engine.schedulers'])\n\n# manage all kinds of metrics\nMETRICS = Registry(\n    'metric', parent=MMENGINE_METRICS, locations=['mmpose.evaluation.metrics'])\n# manage all kinds of evaluators\nEVALUATORS = Registry(\n    'evaluator',\n    parent=MMENGINE_EVALUATOR,\n    locations=['mmpose.evaluation.evaluators'])\n\n# manage task-specific modules like anchor generators and box coders\nTASK_UTILS = Registry(\n    'task util',\n    parent=MMENGINE_TASK_UTILS,\n    locations=['mmpose.models.task_modules'])\n\n# Registries For Visualizer and the related\n# manage visualizer\nVISUALIZERS = Registry(\n    'visualizer',\n    parent=MMENGINE_VISUALIZERS,\n    locations=['mmpose.visualization'])\n# manage visualizer backend\nVISBACKENDS = Registry(\n    'vis_backend',\n    parent=MMENGINE_VISBACKENDS,\n    locations=['mmpose.visualization'])\n\n# manage all kinds log processors\nLOG_PROCESSORS = Registry(\n    'log processor',\n    parent=MMENGINE_LOG_PROCESSORS,\n    locations=['mmpose.visualization'])\n\n# manager keypoint encoder/decoder\nKEYPOINT_CODECS = Registry('KEYPOINT_CODECS', locations=['mmpose.codecs'])\n\n# manage inferencer\nINFERENCERS = Registry(\n    'inferencer',\n    parent=MMENGINE_INFERENCERS,\n    locations=['mmpose.apis.inferencers'])\n"
  },
  {
    "path": "mmpose/structures/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .bbox import (bbox_clip_border, bbox_corner2xyxy, bbox_cs2xywh,\n                   bbox_cs2xyxy, bbox_xywh2cs, bbox_xywh2xyxy,\n                   bbox_xyxy2corner, bbox_xyxy2cs, bbox_xyxy2xywh, flip_bbox,\n                   get_pers_warp_matrix, get_udp_warp_matrix, get_warp_matrix)\nfrom .keypoint import flip_keypoints, keypoint_clip_border\nfrom .multilevel_pixel_data import MultilevelPixelData\nfrom .pose_data_sample import PoseDataSample\nfrom .utils import merge_data_samples, revert_heatmap, split_instances\n\n__all__ = [\n    'PoseDataSample', 'MultilevelPixelData', 'bbox_cs2xywh', 'bbox_cs2xyxy',\n    'bbox_xywh2cs', 'bbox_xywh2xyxy', 'bbox_xyxy2cs', 'bbox_xyxy2xywh',\n    'flip_bbox', 'get_udp_warp_matrix', 'get_warp_matrix', 'flip_keypoints',\n    'merge_data_samples', 'revert_heatmap', 'split_instances',\n    'keypoint_clip_border', 'bbox_clip_border', 'bbox_xyxy2corner',\n    'bbox_corner2xyxy', 'get_pers_warp_matrix'\n]\n"
  },
  {
    "path": "mmpose/structures/bbox/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .bbox_overlaps import bbox_overlaps\nfrom .transforms import (bbox_clip_border, bbox_corner2xyxy, bbox_cs2xywh,\n                         bbox_cs2xyxy, bbox_xywh2cs, bbox_xywh2xyxy,\n                         bbox_xyxy2corner, bbox_xyxy2cs, bbox_xyxy2xywh,\n                         flip_bbox, get_pers_warp_matrix, get_udp_warp_matrix,\n                         get_warp_matrix)\n\n__all__ = [\n    'bbox_cs2xywh', 'bbox_cs2xyxy', 'bbox_xywh2cs', 'bbox_xywh2xyxy',\n    'bbox_xyxy2cs', 'bbox_xyxy2xywh', 'flip_bbox', 'get_udp_warp_matrix',\n    'get_warp_matrix', 'bbox_overlaps', 'bbox_clip_border', 'bbox_xyxy2corner',\n    'bbox_corner2xyxy', 'get_pers_warp_matrix'\n]\n"
  },
  {
    "path": "mmpose/structures/bbox/bbox_overlaps.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch\n\n\ndef fp16_clamp(x, min_val=None, max_val=None):\n    if not x.is_cuda and x.dtype == torch.float16:\n        return x.float().clamp(min_val, max_val).half()\n    return x.clamp(min_val, max_val)\n\n\ndef bbox_overlaps(bboxes1,\n                  bboxes2,\n                  mode='iou',\n                  is_aligned=False,\n                  eps=1e-6) -> torch.Tensor:\n    \"\"\"Calculate overlap between two sets of bounding boxes.\n\n    Args:\n        bboxes1 (torch.Tensor): Bounding boxes of shape (..., m, 4) or empty.\n        bboxes2 (torch.Tensor): Bounding boxes of shape (..., n, 4) or empty.\n        mode (str): \"iou\" (intersection over union),\n                    \"iof\" (intersection over foreground),\n                    or \"giou\" (generalized intersection over union).\n                    Defaults to \"iou\".\n        is_aligned (bool, optional): If True, then m and n must be equal.\n            Default False.\n        eps (float, optional): A small constant added to the denominator for\n            numerical stability. Default 1e-6.\n\n    Returns:\n        torch.Tensor: Overlap values of shape (..., m, n) if is_aligned is\n            False, else shape (..., m).\n\n    Example:\n        >>> bboxes1 = torch.FloatTensor([\n        >>>     [0, 0, 10, 10],\n        >>>     [10, 10, 20, 20],\n        >>>     [32, 32, 38, 42],\n        >>> ])\n        >>> bboxes2 = torch.FloatTensor([\n        >>>     [0, 0, 10, 20],\n        >>>     [0, 10, 10, 19],\n        >>>     [10, 10, 20, 20],\n        >>> ])\n        >>> overlaps = bbox_overlaps(bboxes1, bboxes2)\n        >>> assert overlaps.shape == (3, 3)\n        >>> overlaps = bbox_overlaps(bboxes1, bboxes2, is_aligned=True)\n        >>> assert overlaps.shape == (3, )\n    \"\"\"\n    assert mode in ['iou', 'iof', 'giou'], f'Unsupported mode {mode}'\n    assert (bboxes1.size(-1) == 4 or bboxes1.size(0) == 0)\n    assert (bboxes2.size(-1) == 4 or bboxes2.size(0) == 0)\n\n    if bboxes1.ndim == 1:\n        bboxes1 = bboxes1.unsqueeze(0)\n    if bboxes2.ndim == 1:\n        bboxes2 = bboxes2.unsqueeze(0)\n\n    assert bboxes1.shape[:-2] == bboxes2.shape[:-2]\n    batch_shape = bboxes1.shape[:-2]\n\n    rows = bboxes1.size(-2)\n    cols = bboxes2.size(-2)\n    if is_aligned:\n        assert rows == cols\n\n    if rows * cols == 0:\n        if is_aligned:\n            return bboxes1.new(batch_shape + (rows, ))\n        else:\n            return bboxes1.new(batch_shape + (rows, cols))\n\n    area1 = (bboxes1[..., 2] - bboxes1[..., 0]) * (\n        bboxes1[..., 3] - bboxes1[..., 1])\n    area2 = (bboxes2[..., 2] - bboxes2[..., 0]) * (\n        bboxes2[..., 3] - bboxes2[..., 1])\n\n    if is_aligned:\n        lt = torch.max(bboxes1[..., :2], bboxes2[..., :2])\n        rb = torch.min(bboxes1[..., 2:], bboxes2[..., 2:])\n        wh = fp16_clamp(rb - lt, min_val=0)\n        overlap = wh[..., 0] * wh[..., 1]\n\n        if mode in ['iou', 'giou']:\n            union = area1 + area2 - overlap\n        else:\n            union = area1\n        if mode == 'giou':\n            enclosed_lt = torch.min(bboxes1[..., :2], bboxes2[..., :2])\n            enclosed_rb = torch.max(bboxes1[..., 2:], bboxes2[..., 2:])\n    else:\n        lt = torch.max(bboxes1[..., :, None, :2], bboxes2[..., None, :, :2])\n        rb = torch.min(bboxes1[..., :, None, 2:], bboxes2[..., None, :, 2:])\n        wh = fp16_clamp(rb - lt, min_val=0)\n        overlap = wh[..., 0] * wh[..., 1]\n\n        if mode in ['iou', 'giou']:\n            union = area1[..., None] + area2[..., None, :] - overlap\n        else:\n            union = area1[..., None]\n        if mode == 'giou':\n            enclosed_lt = torch.min(bboxes1[..., :, None, :2],\n                                    bboxes2[..., None, :, :2])\n            enclosed_rb = torch.max(bboxes1[..., :, None, 2:],\n                                    bboxes2[..., None, :, 2:])\n\n    eps_tensor = union.new_tensor([eps])\n    union = torch.max(union, eps_tensor)\n    ious = overlap / union\n    if mode in ['iou', 'iof']:\n        return ious\n    elif mode == 'giou':\n        enclose_wh = fp16_clamp(enclosed_rb - enclosed_lt, min_val=0)\n        enclose_area = enclose_wh[..., 0] * enclose_wh[..., 1]\n        enclose_area = torch.max(enclose_area, eps_tensor)\n        gious = ious - (enclose_area - union) / enclose_area\n        return gious\n"
  },
  {
    "path": "mmpose/structures/bbox/transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Tuple\n\nimport cv2\nimport numpy as np\n\n\ndef bbox_xyxy2xywh(bbox_xyxy: np.ndarray) -> np.ndarray:\n    \"\"\"Transform the bbox format from x1y1x2y2 to xywh.\n\n    Args:\n        bbox_xyxy (np.ndarray): Bounding boxes (with scores), shaped (n, 4) or\n            (n, 5). (left, top, right, bottom, [score])\n\n    Returns:\n        np.ndarray: Bounding boxes (with scores),\n          shaped (n, 4) or (n, 5). (left, top, width, height, [score])\n    \"\"\"\n    bbox_xywh = bbox_xyxy.copy()\n    bbox_xywh[:, 2] = bbox_xywh[:, 2] - bbox_xywh[:, 0]\n    bbox_xywh[:, 3] = bbox_xywh[:, 3] - bbox_xywh[:, 1]\n\n    return bbox_xywh\n\n\ndef bbox_xywh2xyxy(bbox_xywh: np.ndarray) -> np.ndarray:\n    \"\"\"Transform the bbox format from xywh to x1y1x2y2.\n\n    Args:\n        bbox_xywh (ndarray): Bounding boxes (with scores),\n            shaped (n, 4) or (n, 5). (left, top, width, height, [score])\n    Returns:\n        np.ndarray: Bounding boxes (with scores), shaped (n, 4) or\n          (n, 5). (left, top, right, bottom, [score])\n    \"\"\"\n    bbox_xyxy = bbox_xywh.copy()\n    bbox_xyxy[:, 2] = bbox_xyxy[:, 2] + bbox_xyxy[:, 0]\n    bbox_xyxy[:, 3] = bbox_xyxy[:, 3] + bbox_xyxy[:, 1]\n\n    return bbox_xyxy\n\n\ndef bbox_xyxy2cs(bbox: np.ndarray,\n                 padding: float = 1.) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Transform the bbox format from (x,y,w,h) into (center, scale)\n\n    Args:\n        bbox (ndarray): Bounding box(es) in shape (4,) or (n, 4), formatted\n            as (left, top, right, bottom)\n        padding (float): BBox padding factor that will be multilied to scale.\n            Default: 1.0\n\n    Returns:\n        tuple: A tuple containing center and scale.\n        - np.ndarray[float32]: Center (x, y) of the bbox in shape (2,) or\n            (n, 2)\n        - np.ndarray[float32]: Scale (w, h) of the bbox in shape (2,) or\n            (n, 2)\n    \"\"\"\n    # convert single bbox from (4, ) to (1, 4)\n    dim = bbox.ndim\n    if dim == 1:\n        bbox = bbox[None, :]\n\n    scale = (bbox[..., 2:] - bbox[..., :2]) * padding\n    center = (bbox[..., 2:] + bbox[..., :2]) * 0.5\n\n    if dim == 1:\n        center = center[0]\n        scale = scale[0]\n\n    return center, scale\n\n\ndef bbox_xywh2cs(bbox: np.ndarray,\n                 padding: float = 1.) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Transform the bbox format from (x,y,w,h) into (center, scale)\n\n    Args:\n        bbox (ndarray): Bounding box(es) in shape (4,) or (n, 4), formatted\n            as (x, y, h, w)\n        padding (float): BBox padding factor that will be multilied to scale.\n            Default: 1.0\n\n    Returns:\n        tuple: A tuple containing center and scale.\n        - np.ndarray[float32]: Center (x, y) of the bbox in shape (2,) or\n            (n, 2)\n        - np.ndarray[float32]: Scale (w, h) of the bbox in shape (2,) or\n            (n, 2)\n    \"\"\"\n\n    # convert single bbox from (4, ) to (1, 4)\n    dim = bbox.ndim\n    if dim == 1:\n        bbox = bbox[None, :]\n\n    x, y, w, h = np.hsplit(bbox, [1, 2, 3])\n    center = np.hstack([x + w * 0.5, y + h * 0.5])\n    scale = np.hstack([w, h]) * padding\n\n    if dim == 1:\n        center = center[0]\n        scale = scale[0]\n\n    return center, scale\n\n\ndef bbox_cs2xyxy(center: np.ndarray,\n                 scale: np.ndarray,\n                 padding: float = 1.) -> np.ndarray:\n    \"\"\"Transform the bbox format from (center, scale) to (x1,y1,x2,y2).\n\n    Args:\n        center (ndarray): BBox center (x, y) in shape (2,) or (n, 2)\n        scale (ndarray): BBox scale (w, h) in shape (2,) or (n, 2)\n        padding (float): BBox padding factor that will be multilied to scale.\n            Default: 1.0\n\n    Returns:\n        ndarray[float32]: BBox (x1, y1, x2, y2) in shape (4, ) or (n, 4)\n    \"\"\"\n\n    dim = center.ndim\n    assert scale.ndim == dim\n\n    if dim == 1:\n        center = center[None, :]\n        scale = scale[None, :]\n\n    wh = scale / padding\n    xy = center - 0.5 * wh\n    bbox = np.hstack((xy, xy + wh))\n\n    if dim == 1:\n        bbox = bbox[0]\n\n    return bbox\n\n\ndef bbox_cs2xywh(center: np.ndarray,\n                 scale: np.ndarray,\n                 padding: float = 1.) -> np.ndarray:\n    \"\"\"Transform the bbox format from (center, scale) to (x,y,w,h).\n\n    Args:\n        center (ndarray): BBox center (x, y) in shape (2,) or (n, 2)\n        scale (ndarray): BBox scale (w, h) in shape (2,) or (n, 2)\n        padding (float): BBox padding factor that will be multilied to scale.\n            Default: 1.0\n\n    Returns:\n        ndarray[float32]: BBox (x, y, w, h) in shape (4, ) or (n, 4)\n    \"\"\"\n\n    dim = center.ndim\n    assert scale.ndim == dim\n\n    if dim == 1:\n        center = center[None, :]\n        scale = scale[None, :]\n\n    wh = scale / padding\n    xy = center - 0.5 * wh\n    bbox = np.hstack((xy, wh))\n\n    if dim == 1:\n        bbox = bbox[0]\n\n    return bbox\n\n\ndef bbox_xyxy2corner(bbox: np.ndarray):\n    \"\"\"Convert bounding boxes from xyxy format to corner format.\n\n    Given a numpy array containing bounding boxes in the format\n    (xmin, ymin, xmax, ymax), this function converts the bounding\n    boxes to the corner format, where each box is represented by four\n    corner points (top-left, top-right, bottom-right, bottom-left).\n\n    Args:\n        bbox (numpy.ndarray): Input array of shape (N, 4) representing\n            N bounding boxes.\n\n    Returns:\n        numpy.ndarray: An array of shape (N, 4, 2) containing the corner\n            points of the bounding boxes.\n\n    Example:\n        bbox = np.array([[0, 0, 100, 50], [10, 20, 200, 150]])\n        corners = bbox_xyxy2corner(bbox)\n    \"\"\"\n    dim = bbox.ndim\n    if dim == 1:\n        bbox = bbox[None]\n\n    bbox = np.tile(bbox, 2).reshape(-1, 4, 2)\n    bbox[:, 1:3, 0] = bbox[:, 0:2, 0]\n\n    if dim == 1:\n        bbox = bbox[0]\n\n    return bbox\n\n\ndef bbox_corner2xyxy(bbox: np.ndarray):\n    \"\"\"Convert bounding boxes from corner format to xyxy format.\n\n    Given a numpy array containing bounding boxes in the corner\n    format (four corner points for each box), this function converts\n    the bounding boxes to the (xmin, ymin, xmax, ymax) format.\n\n    Args:\n        bbox (numpy.ndarray): Input array of shape (N, 4, 2) representing\n            N bounding boxes.\n\n    Returns:\n        numpy.ndarray: An array of shape (N, 4) containing the bounding\n            boxes in xyxy format.\n\n    Example:\n        corners = np.array([[[0, 0], [100, 0], [100, 50], [0, 50]],\n            [[10, 20], [200, 20], [200, 150], [10, 150]]])\n        bbox = bbox_corner2xyxy(corners)\n    \"\"\"\n    if bbox.shape[-1] == 8:\n        bbox = bbox.reshape(*bbox.shape[:-1], 4, 2)\n\n    dim = bbox.ndim\n    if dim == 2:\n        bbox = bbox[None]\n\n    bbox = np.concatenate((bbox.min(axis=1), bbox.max(axis=1)), axis=1)\n\n    if dim == 2:\n        bbox = bbox[0]\n\n    return bbox\n\n\ndef bbox_clip_border(bbox: np.ndarray, shape: Tuple[int, int]) -> np.ndarray:\n    \"\"\"Clip bounding box coordinates to fit within a specified shape.\n\n    Args:\n        bbox (np.ndarray): Bounding box coordinates of shape (..., 4)\n            or (..., 2).\n        shape (Tuple[int, int]): Shape of the image to which bounding\n            boxes are being clipped in the format of (w, h)\n\n    Returns:\n        np.ndarray: Clipped bounding box coordinates.\n\n    Example:\n        >>> bbox = np.array([[10, 20, 30, 40], [40, 50, 80, 90]])\n        >>> shape = (50, 50)  # Example image shape\n        >>> clipped_bbox = bbox_clip_border(bbox, shape)\n    \"\"\"\n    width, height = shape[:2]\n\n    if bbox.shape[-1] == 2:\n        bbox[..., 0] = np.clip(bbox[..., 0], a_min=0, a_max=width)\n        bbox[..., 1] = np.clip(bbox[..., 1], a_min=0, a_max=height)\n    else:\n        bbox[..., ::2] = np.clip(bbox[..., ::2], a_min=0, a_max=width)\n        bbox[..., 1::2] = np.clip(bbox[..., 1::2], a_min=0, a_max=height)\n\n    return bbox\n\n\ndef flip_bbox(bbox: np.ndarray,\n              image_size: Tuple[int, int],\n              bbox_format: str = 'xywh',\n              direction: str = 'horizontal') -> np.ndarray:\n    \"\"\"Flip the bbox in the given direction.\n\n    Args:\n        bbox (np.ndarray): The bounding boxes. The shape should be (..., 4)\n            if ``bbox_format`` is ``'xyxy'`` or ``'xywh'``, and (..., 2) if\n            ``bbox_format`` is ``'center'``\n        image_size (tuple): The image shape in [w, h]\n        bbox_format (str): The bbox format. Options are ``'xywh'``, ``'xyxy'``\n            and ``'center'``.\n        direction (str): The flip direction. Options are ``'horizontal'``,\n            ``'vertical'`` and ``'diagonal'``. Defaults to ``'horizontal'``\n\n    Returns:\n        np.ndarray: The flipped bounding boxes.\n    \"\"\"\n    direction_options = {'horizontal', 'vertical', 'diagonal'}\n    assert direction in direction_options, (\n        f'Invalid flipping direction \"{direction}\". '\n        f'Options are {direction_options}')\n\n    format_options = {'xywh', 'xyxy', 'center'}\n    assert bbox_format in format_options, (\n        f'Invalid bbox format \"{bbox_format}\". '\n        f'Options are {format_options}')\n\n    bbox_flipped = bbox.copy()\n    w, h = image_size\n\n    # TODO: consider using \"integer corner\" coordinate system\n    if direction == 'horizontal':\n        if bbox_format == 'xywh' or bbox_format == 'center':\n            bbox_flipped[..., 0] = w - bbox[..., 0] - 1\n        elif bbox_format == 'xyxy':\n            bbox_flipped[..., ::2] = w - bbox[..., -2::-2] - 1\n    elif direction == 'vertical':\n        if bbox_format == 'xywh' or bbox_format == 'center':\n            bbox_flipped[..., 1] = h - bbox[..., 1] - 1\n        elif bbox_format == 'xyxy':\n            bbox_flipped[..., 1::2] = h - bbox[..., ::-2] - 1\n    elif direction == 'diagonal':\n        if bbox_format == 'xywh' or bbox_format == 'center':\n            bbox_flipped[..., :2] = [w, h] - bbox[..., :2] - 1\n        elif bbox_format == 'xyxy':\n            bbox_flipped[...] = [w, h, w, h] - bbox - 1\n            bbox_flipped = np.concatenate(\n                (bbox_flipped[..., 2:], bbox_flipped[..., :2]), axis=-1)\n\n    return bbox_flipped\n\n\ndef get_udp_warp_matrix(\n    center: np.ndarray,\n    scale: np.ndarray,\n    rot: float,\n    output_size: Tuple[int, int],\n) -> np.ndarray:\n    \"\"\"Calculate the affine transformation matrix under the unbiased\n    constraint. See `UDP (CVPR 2020)`_ for details.\n\n    Note:\n\n        - The bbox number: N\n\n    Args:\n        center (np.ndarray[2, ]): Center of the bounding box (x, y).\n        scale (np.ndarray[2, ]): Scale of the bounding box\n            wrt [width, height].\n        rot (float): Rotation angle (degree).\n        output_size (tuple): Size ([w, h]) of the output image\n\n    Returns:\n        np.ndarray: A 2x3 transformation matrix\n\n    .. _`UDP (CVPR 2020)`: https://arxiv.org/abs/1911.07524\n    \"\"\"\n    assert len(center) == 2\n    assert len(scale) == 2\n    assert len(output_size) == 2\n\n    input_size = center * 2\n    rot_rad = np.deg2rad(rot)\n    warp_mat = np.zeros((2, 3), dtype=np.float32)\n    scale_x = (output_size[0] - 1) / scale[0]\n    scale_y = (output_size[1] - 1) / scale[1]\n    warp_mat[0, 0] = math.cos(rot_rad) * scale_x\n    warp_mat[0, 1] = -math.sin(rot_rad) * scale_x\n    warp_mat[0, 2] = scale_x * (-0.5 * input_size[0] * math.cos(rot_rad) +\n                                0.5 * input_size[1] * math.sin(rot_rad) +\n                                0.5 * scale[0])\n    warp_mat[1, 0] = math.sin(rot_rad) * scale_y\n    warp_mat[1, 1] = math.cos(rot_rad) * scale_y\n    warp_mat[1, 2] = scale_y * (-0.5 * input_size[0] * math.sin(rot_rad) -\n                                0.5 * input_size[1] * math.cos(rot_rad) +\n                                0.5 * scale[1])\n    return warp_mat\n\n\ndef get_warp_matrix(\n    center: np.ndarray,\n    scale: np.ndarray,\n    rot: float,\n    output_size: Tuple[int, int],\n    shift: Tuple[float, float] = (0., 0.),\n    inv: bool = False,\n    fix_aspect_ratio: bool = True,\n) -> np.ndarray:\n    \"\"\"Calculate the affine transformation matrix that can warp the bbox area\n    in the input image to the output size.\n\n    Args:\n        center (np.ndarray[2, ]): Center of the bounding box (x, y).\n        scale (np.ndarray[2, ]): Scale of the bounding box\n            wrt [width, height].\n        rot (float): Rotation angle (degree).\n        output_size (np.ndarray[2, ] | list(2,)): Size of the\n            destination heatmaps.\n        shift (0-100%): Shift translation ratio wrt the width/height.\n            Default (0., 0.).\n        inv (bool): Option to inverse the affine transform direction.\n            (inv=False: src->dst or inv=True: dst->src)\n        fix_aspect_ratio (bool): Whether to fix aspect ratio during transform.\n            Defaults to True.\n\n    Returns:\n        np.ndarray: A 2x3 transformation matrix\n    \"\"\"\n    assert len(center) == 2\n    assert len(scale) == 2\n    assert len(output_size) == 2\n    assert len(shift) == 2\n\n    shift = np.array(shift)\n    src_w, src_h = scale[:2]\n    dst_w, dst_h = output_size[:2]\n\n    rot_rad = np.deg2rad(rot)\n    src_dir = _rotate_point(np.array([src_w * -0.5, 0.]), rot_rad)\n    dst_dir = np.array([dst_w * -0.5, 0.])\n\n    src = np.zeros((3, 2), dtype=np.float32)\n    src[0, :] = center + scale * shift\n    src[1, :] = center + src_dir + scale * shift\n\n    dst = np.zeros((3, 2), dtype=np.float32)\n    dst[0, :] = [dst_w * 0.5, dst_h * 0.5]\n    dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir\n\n    if fix_aspect_ratio:\n        src[2, :] = _get_3rd_point(src[0, :], src[1, :])\n        dst[2, :] = _get_3rd_point(dst[0, :], dst[1, :])\n    else:\n        src_dir_2 = _rotate_point(np.array([0., src_h * -0.5]), rot_rad)\n        dst_dir_2 = np.array([0., dst_h * -0.5])\n        src[2, :] = center + src_dir_2 + scale * shift\n        dst[2, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir_2\n\n    if inv:\n        warp_mat = cv2.getAffineTransform(np.float32(dst), np.float32(src))\n    else:\n        warp_mat = cv2.getAffineTransform(np.float32(src), np.float32(dst))\n    return warp_mat\n\n\ndef get_pers_warp_matrix(center: np.ndarray, translate: np.ndarray,\n                         scale: float, rot: float,\n                         shear: np.ndarray) -> np.ndarray:\n    \"\"\"Compute a perspective warp matrix based on specified transformations.\n\n    Args:\n        center (np.ndarray): Center of the transformation.\n        translate (np.ndarray): Translation vector.\n        scale (float): Scaling factor.\n        rot (float): Rotation angle in degrees.\n        shear (np.ndarray): Shearing angles in degrees along x and y axes.\n\n    Returns:\n        np.ndarray: Perspective warp matrix.\n\n    Example:\n        >>> center = np.array([0, 0])\n        >>> translate = np.array([10, 20])\n        >>> scale = 1.2\n        >>> rot = 30.0\n        >>> shear = np.array([15.0, 0.0])\n        >>> warp_matrix = get_pers_warp_matrix(center, translate,\n                                               scale, rot, shear)\n    \"\"\"\n    translate_mat = np.array([[1, 0, translate[0] + center[0]],\n                              [0, 1, translate[1] + center[1]], [0, 0, 1]],\n                             dtype=np.float32)\n\n    shear_x = math.radians(shear[0])\n    shear_y = math.radians(shear[1])\n    shear_mat = np.array([[1, np.tan(shear_x), 0], [np.tan(shear_y), 1, 0],\n                          [0, 0, 1]],\n                         dtype=np.float32)\n\n    rotate_angle = math.radians(rot)\n    rotate_mat = np.array([[np.cos(rotate_angle), -np.sin(rotate_angle), 0],\n                           [np.sin(rotate_angle),\n                            np.cos(rotate_angle), 0], [0, 0, 1]],\n                          dtype=np.float32)\n\n    scale_mat = np.array([[scale, 0, 0], [0, scale, 0], [0, 0, 1]],\n                         dtype=np.float32)\n\n    recover_center_mat = np.array([[1, 0, -center[0]], [0, 1, -center[1]],\n                                   [0, 0, 1]],\n                                  dtype=np.float32)\n\n    warp_matrix = np.dot(\n        np.dot(\n            np.dot(np.dot(translate_mat, shear_mat), rotate_mat), scale_mat),\n        recover_center_mat)\n\n    return warp_matrix\n\n\ndef _rotate_point(pt: np.ndarray, angle_rad: float) -> np.ndarray:\n    \"\"\"Rotate a point by an angle.\n\n    Args:\n        pt (np.ndarray): 2D point coordinates (x, y) in shape (2, )\n        angle_rad (float): rotation angle in radian\n\n    Returns:\n        np.ndarray: Rotated point in shape (2, )\n    \"\"\"\n\n    sn, cs = np.sin(angle_rad), np.cos(angle_rad)\n    rot_mat = np.array([[cs, -sn], [sn, cs]])\n    return rot_mat @ pt\n\n\ndef _get_3rd_point(a: np.ndarray, b: np.ndarray):\n    \"\"\"To calculate the affine matrix, three pairs of points are required. This\n    function is used to get the 3rd point, given 2D points a & b.\n\n    The 3rd point is defined by rotating vector `a - b` by 90 degrees\n    anticlockwise, using b as the rotation center.\n\n    Args:\n        a (np.ndarray): The 1st point (x,y) in shape (2, )\n        b (np.ndarray): The 2nd point (x,y) in shape (2, )\n\n    Returns:\n        np.ndarray: The 3rd point.\n    \"\"\"\n    direction = a - b\n    c = b + np.r_[-direction[1], direction[0]]\n    return c\n"
  },
  {
    "path": "mmpose/structures/keypoint/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom .transforms import (flip_keypoints, flip_keypoints_custom_center,\n                         keypoint_clip_border)\n\n__all__ = [\n    'flip_keypoints', 'flip_keypoints_custom_center', 'keypoint_clip_border'\n]\n"
  },
  {
    "path": "mmpose/structures/keypoint/transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Tuple, Union\n\nimport numpy as np\n\n\ndef flip_keypoints(keypoints: np.ndarray,\n                   keypoints_visible: Optional[np.ndarray],\n                   image_size: Tuple[int, int],\n                   flip_indices: List[int],\n                   direction: str = 'horizontal'\n                   ) -> Tuple[np.ndarray, Optional[np.ndarray]]:\n    \"\"\"Flip keypoints in the given direction.\n\n    Note:\n\n        - keypoint number: K\n        - keypoint dimension: D\n\n    Args:\n        keypoints (np.ndarray): Keypoints in shape (..., K, D)\n        keypoints_visible (np.ndarray, optional): The visibility of keypoints\n            in shape (..., K, 1) or (..., K, 2). Set ``None`` if the keypoint\n            visibility is unavailable\n        image_size (tuple): The image shape in [w, h]\n        flip_indices (List[int]): The indices of each keypoint's symmetric\n            keypoint\n        direction (str): The flip direction. Options are ``'horizontal'``,\n            ``'vertical'`` and ``'diagonal'``. Defaults to ``'horizontal'``\n\n    Returns:\n        tuple:\n        - keypoints_flipped (np.ndarray): Flipped keypoints in shape\n            (..., K, D)\n        - keypoints_visible_flipped (np.ndarray, optional): Flipped keypoints'\n            visibility in shape (..., K, 1) or (..., K, 2). Return ``None`` if\n            the input ``keypoints_visible`` is ``None``\n    \"\"\"\n\n    ndim = keypoints.ndim\n    assert keypoints.shape[:-1] == keypoints_visible.shape[:ndim - 1], (\n        f'Mismatched shapes of keypoints {keypoints.shape} and '\n        f'keypoints_visible {keypoints_visible.shape}')\n\n    direction_options = {'horizontal', 'vertical', 'diagonal'}\n    assert direction in direction_options, (\n        f'Invalid flipping direction \"{direction}\". '\n        f'Options are {direction_options}')\n\n    # swap the symmetric keypoint pairs\n    if direction == 'horizontal' or direction == 'vertical':\n        keypoints = keypoints.take(flip_indices, axis=ndim - 2)\n        if keypoints_visible is not None:\n            keypoints_visible = keypoints_visible.take(\n                flip_indices, axis=ndim - 2)\n\n    # flip the keypoints\n    w, h = image_size\n    if direction == 'horizontal':\n        keypoints[..., 0] = w - 1 - keypoints[..., 0]\n    elif direction == 'vertical':\n        keypoints[..., 1] = h - 1 - keypoints[..., 1]\n    else:\n        keypoints = [w, h] - keypoints - 1\n\n    return keypoints, keypoints_visible\n\n\ndef flip_keypoints_custom_center(keypoints: np.ndarray,\n                                 keypoints_visible: np.ndarray,\n                                 flip_indices: List[int],\n                                 center_mode: str = 'static',\n                                 center_x: float = 0.5,\n                                 center_index: Union[int, List] = 0):\n    \"\"\"Flip human joints horizontally.\n\n    Note:\n        - num_keypoint: K\n        - dimension: D\n\n    Args:\n        keypoints (np.ndarray([..., K, D])): Coordinates of keypoints.\n        keypoints_visible (np.ndarray([..., K])): Visibility item of keypoints.\n        flip_indices (list[int]): The indices to flip the keypoints.\n        center_mode (str): The mode to set the center location on the x-axis\n            to flip around. Options are:\n\n            - static: use a static x value (see center_x also)\n            - root: use a root joint (see center_index also)\n\n            Defaults: ``'static'``.\n        center_x (float): Set the x-axis location of the flip center. Only used\n            when ``center_mode`` is ``'static'``. Defaults: 0.5.\n        center_index (Union[int, List]): Set the index of the root joint, whose\n            x location will be used as the flip center. Only used when\n            ``center_mode`` is ``'root'``. Defaults: 0.\n\n    Returns:\n        np.ndarray([..., K, C]): Flipped joints.\n    \"\"\"\n\n    assert keypoints.ndim >= 2, f'Invalid pose shape {keypoints.shape}'\n\n    allowed_center_mode = {'static', 'root'}\n    assert center_mode in allowed_center_mode, 'Get invalid center_mode ' \\\n        f'{center_mode}, allowed choices are {allowed_center_mode}'\n\n    if center_mode == 'static':\n        x_c = center_x\n    elif center_mode == 'root':\n        center_index = [center_index] if isinstance(center_index, int) else \\\n            center_index\n        assert keypoints.shape[-2] > max(center_index)\n        x_c = keypoints[..., center_index, 0].mean(axis=-1)\n\n    keypoints_flipped = keypoints.copy()\n    keypoints_visible_flipped = keypoints_visible.copy()\n    # Swap left-right parts\n    for left, right in enumerate(flip_indices):\n        keypoints_flipped[..., left, :] = keypoints[..., right, :]\n        keypoints_visible_flipped[..., left] = keypoints_visible[..., right]\n\n    # Flip horizontally\n    keypoints_flipped[..., 0] = x_c * 2 - keypoints_flipped[..., 0]\n    return keypoints_flipped, keypoints_visible_flipped\n\n\ndef keypoint_clip_border(keypoints: np.ndarray, keypoints_visible: np.ndarray,\n                         shape: Tuple[int,\n                                      int]) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Set the visibility values for keypoints outside the image border.\n\n    Args:\n        keypoints (np.ndarray): Input keypoints coordinates.\n        keypoints_visible (np.ndarray): Visibility values of keypoints.\n        shape (Tuple[int, int]): Shape of the image to which keypoints are\n            being clipped in the format of (w, h).\n\n    Note:\n        This function sets the visibility values of keypoints that fall outside\n            the specified frame border to zero (0.0).\n    \"\"\"\n    width, height = shape[:2]\n\n    # Create a mask for keypoints outside the frame\n    outside_mask = ((keypoints[..., 0] > width) | (keypoints[..., 0] < 0) |\n                    (keypoints[..., 1] > height) | (keypoints[..., 1] < 0))\n\n    # Update visibility values for keypoints outside the frame\n    if keypoints_visible.ndim == 2:\n        keypoints_visible[outside_mask] = 0.0\n    elif keypoints_visible.ndim == 3:\n        keypoints_visible[outside_mask, 0] = 0.0\n\n    return keypoints, keypoints_visible\n"
  },
  {
    "path": "mmpose/structures/multilevel_pixel_data.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import abc\nfrom typing import Any, Callable, List, Optional, Sequence, Tuple, Type, Union\n\nimport numpy as np\nimport torch\nfrom mmengine.structures import BaseDataElement, PixelData\nfrom mmengine.utils import is_list_of\n\nIndexType = Union[str, slice, int, list, torch.LongTensor,\n                  torch.cuda.LongTensor, torch.BoolTensor,\n                  torch.cuda.BoolTensor, np.ndarray]\n\n\nclass MultilevelPixelData(BaseDataElement):\n    \"\"\"Data structure for multi-level pixel-wise annotations or predictions.\n\n    All data items in ``data_fields`` of ``MultilevelPixelData`` are lists\n    of np.ndarray or torch.Tensor, and should meet the following requirements:\n\n    - Have the same length, which is the number of levels\n    - At each level, the data should have 3 dimensions in order of channel,\n        height and weight\n    - At each level, the data should have the same height and weight\n\n    Examples:\n        >>> metainfo = dict(num_keypoints=17)\n        >>> sizes = [(64, 48), (128, 96), (256, 192)]\n        >>> heatmaps = [np.random.rand(17, h, w) for h, w in sizes]\n        >>> masks = [torch.rand(1, h, w) for h, w in sizes]\n        >>> data = MultilevelPixelData(metainfo=metainfo,\n        ...                            heatmaps=heatmaps,\n        ...                            masks=masks)\n\n        >>> # get data item\n        >>> heatmaps = data.heatmaps  # A list of 3 numpy.ndarrays\n        >>> masks = data.masks  # A list of 3 torch.Tensors\n\n        >>> # get level\n        >>> data_l0 = data[0]  # PixelData with fields 'heatmaps' and 'masks'\n        >>> data.nlevel\n        3\n\n        >>> # get shape\n        >>> data.shape\n        ((64, 48), (128, 96), (256, 192))\n\n        >>> # set\n        >>> offset_maps = [torch.rand(2, h, w) for h, w in sizes]\n        >>> data.offset_maps = offset_maps\n    \"\"\"\n\n    def __init__(self, *, metainfo: Optional[dict] = None, **kwargs) -> None:\n        object.__setattr__(self, '_nlevel', None)\n        super().__init__(metainfo=metainfo, **kwargs)\n\n    @property\n    def nlevel(self):\n        \"\"\"Return the level number.\n\n        Returns:\n            Optional[int]: The level number, or ``None`` if the data has not\n            been assigned.\n        \"\"\"\n        return self._nlevel\n\n    def __getitem__(self, item: Union[int, str, list,\n                                      slice]) -> Union[PixelData, Sequence]:\n        if isinstance(item, int):\n            if self.nlevel is None or item >= self.nlevel:\n                raise IndexError(\n                    f'Lcale index {item} out of range ({self.nlevel})')\n            return self.get(f'_level_{item}')\n\n        if isinstance(item, str):\n            if item not in self:\n                raise KeyError(item)\n            return getattr(self, item)\n\n        # TODO: support indexing by list and slice over levels\n        raise NotImplementedError(\n            f'{self.__class__.__name__} does not support index type '\n            f'{type(item)}')\n\n    def levels(self) -> List[PixelData]:\n        if self.nlevel:\n            return list(self[i] for i in range(self.nlevel))\n        return []\n\n    @property\n    def shape(self) -> Optional[Tuple[Tuple]]:\n        \"\"\"Get the shape of multi-level pixel data.\n\n        Returns:\n            Optional[tuple]: A tuple of data shape at each level, or ``None``\n            if the data has not been assigned.\n        \"\"\"\n        if self.nlevel is None:\n            return None\n\n        return tuple(level.shape for level in self.levels())\n\n    def set_data(self, data: dict) -> None:\n        \"\"\"Set or change key-value pairs in ``data_field`` by parameter\n        ``data``.\n\n        Args:\n            data (dict): A dict contains annotations of image or\n                model predictions.\n        \"\"\"\n        assert isinstance(data,\n                          dict), f'meta should be a `dict` but got {data}'\n        for k, v in data.items():\n            self.set_field(v, k, field_type='data')\n\n    def set_field(self,\n                  value: Any,\n                  name: str,\n                  dtype: Optional[Union[Type, Tuple[Type, ...]]] = None,\n                  field_type: str = 'data') -> None:\n        \"\"\"Special method for set union field, used as property.setter\n        functions.\"\"\"\n        assert field_type in ['metainfo', 'data']\n        if dtype is not None:\n            assert isinstance(\n                value,\n                dtype), f'{value} should be a {dtype} but got {type(value)}'\n\n        if name.startswith('_level_'):\n            raise AttributeError(\n                f'Cannot set {name} to be a field because the pattern '\n                '<_level_{n}> is reserved for inner data field')\n\n        if field_type == 'metainfo':\n            if name in self._data_fields:\n                raise AttributeError(\n                    f'Cannot set {name} to be a field of metainfo '\n                    f'because {name} is already a data field')\n            self._metainfo_fields.add(name)\n\n        else:\n            if name in self._metainfo_fields:\n                raise AttributeError(\n                    f'Cannot set {name} to be a field of data '\n                    f'because {name} is already a metainfo field')\n\n            if not isinstance(value, abc.Sequence):\n                raise TypeError(\n                    'The value should be a sequence (of numpy.ndarray or'\n                    f'torch.Tesnor), but got a {type(value)}')\n\n            if len(value) == 0:\n                raise ValueError('Setting empty value is not allowed')\n\n            if not isinstance(value[0], (torch.Tensor, np.ndarray)):\n                raise TypeError(\n                    'The value should be a sequence of numpy.ndarray or'\n                    f'torch.Tesnor, but got a sequence of {type(value[0])}')\n\n            if self.nlevel is not None:\n                assert len(value) == self.nlevel, (\n                    f'The length of the value ({len(value)}) should match the'\n                    f'number of the levels ({self.nlevel})')\n            else:\n                object.__setattr__(self, '_nlevel', len(value))\n                for i in range(self.nlevel):\n                    object.__setattr__(self, f'_level_{i}', PixelData())\n\n            for i, v in enumerate(value):\n                self[i].set_field(v, name, field_type='data')\n\n            self._data_fields.add(name)\n\n        object.__setattr__(self, name, value)\n\n    def __delattr__(self, item: str):\n        \"\"\"delete the item in dataelement.\n\n        Args:\n            item (str): The key to delete.\n        \"\"\"\n        if item in ('_metainfo_fields', '_data_fields'):\n            raise AttributeError(f'{item} has been used as a '\n                                 'private attribute, which is immutable. ')\n\n        if item in self._metainfo_fields:\n            super().__delattr__(item)\n        else:\n            for level in self.levels():\n                level.__delattr__(item)\n            self._data_fields.remove(item)\n\n    def __getattr__(self, name):\n        if name in {'_data_fields', '_metainfo_fields'\n                    } or name not in self._data_fields:\n            raise AttributeError(\n                f'\\'{self.__class__.__name__}\\' object has no attribute '\n                f'\\'{name}\\'')\n\n        return [getattr(level, name) for level in self.levels()]\n\n    def pop(self, *args) -> Any:\n        \"\"\"pop property in data and metainfo as the same as python.\"\"\"\n        assert len(args) < 3, '``pop`` get more than 2 arguments'\n        name = args[0]\n        if name in self._metainfo_fields:\n            self._metainfo_fields.remove(name)\n            return self.__dict__.pop(*args)\n\n        elif name in self._data_fields:\n            self._data_fields.remove(name)\n            return [level.pop(*args) for level in self.levels()]\n\n        # with default value\n        elif len(args) == 2:\n            return args[1]\n        else:\n            # don't just use 'self.__dict__.pop(*args)' for only popping key in\n            # metainfo or data\n            raise KeyError(f'{args[0]} is not contained in metainfo or data')\n\n    def _convert(self, apply_to: Type,\n                 func: Callable[[Any], Any]) -> 'MultilevelPixelData':\n        \"\"\"Convert data items with the given function.\n\n        Args:\n            apply_to (Type): The type of data items to apply the conversion\n            func (Callable): The conversion function that takes a data item\n                as the input and return the converted result\n\n        Returns:\n            MultilevelPixelData: the converted data element.\n        \"\"\"\n        new_data = self.new()\n        for k, v in self.items():\n            if is_list_of(v, apply_to):\n                v = [func(_v) for _v in v]\n                data = {k: v}\n                new_data.set_data(data)\n        return new_data\n\n    def cpu(self) -> 'MultilevelPixelData':\n        \"\"\"Convert all tensors to CPU in data.\"\"\"\n        return self._convert(apply_to=torch.Tensor, func=lambda x: x.cpu())\n\n    def cuda(self) -> 'MultilevelPixelData':\n        \"\"\"Convert all tensors to GPU in data.\"\"\"\n        return self._convert(apply_to=torch.Tensor, func=lambda x: x.cuda())\n\n    def detach(self) -> 'MultilevelPixelData':\n        \"\"\"Detach all tensors in data.\"\"\"\n        return self._convert(apply_to=torch.Tensor, func=lambda x: x.detach())\n\n    def numpy(self) -> 'MultilevelPixelData':\n        \"\"\"Convert all tensor to np.narray in data.\"\"\"\n        return self._convert(\n            apply_to=torch.Tensor, func=lambda x: x.detach().cpu().numpy())\n\n    def to_tensor(self) -> 'MultilevelPixelData':\n        \"\"\"Convert all tensor to np.narray in data.\"\"\"\n        return self._convert(\n            apply_to=np.ndarray, func=lambda x: torch.from_numpy(x))\n\n    # Tensor-like methods\n    def to(self, *args, **kwargs) -> 'MultilevelPixelData':\n        \"\"\"Apply same name function to all tensors in data_fields.\"\"\"\n        new_data = self.new()\n        for k, v in self.items():\n            if hasattr(v[0], 'to'):\n                v = [v_.to(*args, **kwargs) for v_ in v]\n                data = {k: v}\n                new_data.set_data(data)\n        return new_data\n"
  },
  {
    "path": "mmpose/structures/pose_data_sample.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Union\n\nfrom mmengine.structures import BaseDataElement, InstanceData, PixelData\n\nfrom mmpose.structures import MultilevelPixelData\n\n\nclass PoseDataSample(BaseDataElement):\n    \"\"\"The base data structure of MMPose that is used as the interface between\n    modules.\n\n    The attributes of ``PoseDataSample`` includes:\n\n        - ``gt_instances``(InstanceData): Ground truth of instances with\n            keypoint annotations\n        - ``pred_instances``(InstanceData): Instances with keypoint\n            predictions\n        - ``gt_fields``(PixelData): Ground truth of spatial distribution\n            annotations like keypoint heatmaps and part affine fields (PAF)\n        - ``pred_fields``(PixelData): Predictions of spatial distributions\n\n    Examples:\n        >>> import torch\n        >>> from mmengine.structures import InstanceData, PixelData\n        >>> from mmpose.structures import PoseDataSample\n\n        >>> pose_meta = dict(img_shape=(800, 1216),\n        ...                  crop_size=(256, 192),\n        ...                  heatmap_size=(64, 48))\n        >>> gt_instances = InstanceData()\n        >>> gt_instances.bboxes = torch.rand((1, 4))\n        >>> gt_instances.keypoints = torch.rand((1, 17, 2))\n        >>> gt_instances.keypoints_visible = torch.rand((1, 17, 1))\n        >>> gt_fields = PixelData()\n        >>> gt_fields.heatmaps = torch.rand((17, 64, 48))\n\n        >>> data_sample = PoseDataSample(gt_instances=gt_instances,\n        ...                              gt_fields=gt_fields,\n        ...                              metainfo=pose_meta)\n        >>> assert 'img_shape' in data_sample\n        >>> len(data_sample.gt_instances)\n        1\n    \"\"\"\n\n    @property\n    def gt_instances(self) -> InstanceData:\n        return self._gt_instances\n\n    @gt_instances.setter\n    def gt_instances(self, value: InstanceData):\n        self.set_field(value, '_gt_instances', dtype=InstanceData)\n\n    @gt_instances.deleter\n    def gt_instances(self):\n        del self._gt_instances\n\n    @property\n    def gt_instance_labels(self) -> InstanceData:\n        return self._gt_instance_labels\n\n    @gt_instance_labels.setter\n    def gt_instance_labels(self, value: InstanceData):\n        self.set_field(value, '_gt_instance_labels', dtype=InstanceData)\n\n    @gt_instance_labels.deleter\n    def gt_instance_labels(self):\n        del self._gt_instance_labels\n\n    @property\n    def pred_instances(self) -> InstanceData:\n        return self._pred_instances\n\n    @pred_instances.setter\n    def pred_instances(self, value: InstanceData):\n        self.set_field(value, '_pred_instances', dtype=InstanceData)\n\n    @pred_instances.deleter\n    def pred_instances(self):\n        del self._pred_instances\n\n    @property\n    def gt_fields(self) -> Union[PixelData, MultilevelPixelData]:\n        return self._gt_fields\n\n    @gt_fields.setter\n    def gt_fields(self, value: Union[PixelData, MultilevelPixelData]):\n        self.set_field(value, '_gt_fields', dtype=type(value))\n\n    @gt_fields.deleter\n    def gt_fields(self):\n        del self._gt_fields\n\n    @property\n    def pred_fields(self) -> PixelData:\n        return self._pred_heatmaps\n\n    @pred_fields.setter\n    def pred_fields(self, value: PixelData):\n        self.set_field(value, '_pred_heatmaps', dtype=PixelData)\n\n    @pred_fields.deleter\n    def pred_fields(self):\n        del self._pred_heatmaps\n"
  },
  {
    "path": "mmpose/structures/utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport warnings\nfrom typing import List\n\nimport cv2\nimport numpy as np\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom mmengine.utils import is_list_of\n\nfrom .bbox.transforms import get_warp_matrix\nfrom .pose_data_sample import PoseDataSample\n\n\ndef merge_data_samples(data_samples: List[PoseDataSample]) -> PoseDataSample:\n    \"\"\"Merge the given data samples into a single data sample.\n\n    This function can be used to merge the top-down predictions with\n    bboxes from the same image. The merged data sample will contain all\n    instances from the input data samples, and the identical metainfo with\n    the first input data sample.\n\n    Args:\n        data_samples (List[:obj:`PoseDataSample`]): The data samples to\n            merge\n\n    Returns:\n        PoseDataSample: The merged data sample.\n    \"\"\"\n\n    if not is_list_of(data_samples, PoseDataSample):\n        raise ValueError('Invalid input type, should be a list of '\n                         ':obj:`PoseDataSample`')\n\n    if len(data_samples) == 0:\n        warnings.warn('Try to merge an empty list of data samples.')\n        return PoseDataSample()\n\n    merged = PoseDataSample(metainfo=data_samples[0].metainfo)\n\n    if 'gt_instances' in data_samples[0]:\n        merged.gt_instances = InstanceData.cat(\n            [d.gt_instances for d in data_samples])\n\n    if 'pred_instances' in data_samples[0]:\n        merged.pred_instances = InstanceData.cat(\n            [d.pred_instances for d in data_samples])\n\n    if 'pred_fields' in data_samples[0] and 'heatmaps' in data_samples[\n            0].pred_fields:\n        reverted_heatmaps = [\n            revert_heatmap(data_sample.pred_fields.heatmaps,\n                           data_sample.input_center, data_sample.input_scale,\n                           data_sample.ori_shape)\n            for data_sample in data_samples\n        ]\n\n        merged_heatmaps = np.max(reverted_heatmaps, axis=0)\n        pred_fields = PixelData()\n        pred_fields.set_data(dict(heatmaps=merged_heatmaps))\n        merged.pred_fields = pred_fields\n\n    if 'gt_fields' in data_samples[0] and 'heatmaps' in data_samples[\n            0].gt_fields:\n        reverted_heatmaps = [\n            revert_heatmap(data_sample.gt_fields.heatmaps,\n                           data_sample.input_center, data_sample.input_scale,\n                           data_sample.ori_shape)\n            for data_sample in data_samples\n        ]\n\n        merged_heatmaps = np.max(reverted_heatmaps, axis=0)\n        gt_fields = PixelData()\n        gt_fields.set_data(dict(heatmaps=merged_heatmaps))\n        merged.gt_fields = gt_fields\n\n    return merged\n\n\ndef revert_heatmap(heatmap, input_center, input_scale, img_shape):\n    \"\"\"Revert predicted heatmap on the original image.\n\n    Args:\n        heatmap (np.ndarray or torch.tensor): predicted heatmap.\n        input_center (np.ndarray): bounding box center coordinate.\n        input_scale (np.ndarray): bounding box scale.\n        img_shape (tuple or list): size of original image.\n    \"\"\"\n    if torch.is_tensor(heatmap):\n        heatmap = heatmap.cpu().detach().numpy()\n\n    ndim = heatmap.ndim\n    # [K, H, W] -> [H, W, K]\n    if ndim == 3:\n        heatmap = heatmap.transpose(1, 2, 0)\n\n    hm_h, hm_w = heatmap.shape[:2]\n    img_h, img_w = img_shape\n    warp_mat = get_warp_matrix(\n        input_center.reshape((2, )),\n        input_scale.reshape((2, )),\n        rot=0,\n        output_size=(hm_w, hm_h),\n        inv=True)\n\n    heatmap = cv2.warpAffine(\n        heatmap, warp_mat, (img_w, img_h), flags=cv2.INTER_LINEAR)\n\n    # [H, W, K] -> [K, H, W]\n    if ndim == 3:\n        heatmap = heatmap.transpose(2, 0, 1)\n\n    return heatmap\n\n\ndef split_instances(instances: InstanceData) -> List[InstanceData]:\n    \"\"\"Convert instances into a list where each element is a dict that contains\n    information about one instance.\"\"\"\n    results = []\n\n    # return an empty list if there is no instance detected by the model\n    if instances is None:\n        return results\n\n    for i in range(len(instances.keypoints)):\n        result = dict(\n            keypoints=instances.keypoints[i].tolist(),\n            keypoint_scores=instances.keypoint_scores[i].tolist(),\n        )\n        if 'bboxes' in instances:\n            result['bbox'] = instances.bboxes[i].tolist(),\n            if 'bbox_scores' in instances:\n                result['bbox_score'] = instances.bbox_scores[i]\n        results.append(result)\n\n    return results\n"
  },
  {
    "path": "mmpose/testing/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom ._utils import (get_coco_sample, get_config_file, get_packed_inputs,\n                     get_pose_estimator_cfg, get_repo_dir)\n\n__all__ = [\n    'get_packed_inputs', 'get_coco_sample', 'get_config_file',\n    'get_pose_estimator_cfg', 'get_repo_dir'\n]\n"
  },
  {
    "path": "mmpose/testing/_utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom copy import deepcopy\nfrom typing import Optional\n\nimport numpy as np\nimport torch\nfrom mmengine.config import Config\nfrom mmengine.dataset import pseudo_collate\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.structures import MultilevelPixelData, PoseDataSample\nfrom mmpose.structures.bbox import bbox_xyxy2cs\n\n\ndef get_coco_sample(\n        img_shape=(240, 320),\n        img_fill: Optional[int] = None,\n        num_instances=1,\n        with_bbox_cs=True,\n        with_img_mask=False,\n        random_keypoints_visible=False,\n        non_occlusion=False):\n    \"\"\"Create a dummy data sample in COCO style.\"\"\"\n    rng = np.random.RandomState(0)\n    h, w = img_shape\n    if img_fill is None:\n        img = np.random.randint(0, 256, (h, w, 3), dtype=np.uint8)\n    else:\n        img = np.full((h, w, 3), img_fill, dtype=np.uint8)\n\n    if non_occlusion:\n        bbox = _rand_bboxes(rng, num_instances, w / num_instances, h)\n        for i in range(num_instances):\n            bbox[i, 0::2] += w / num_instances * i\n    else:\n        bbox = _rand_bboxes(rng, num_instances, w, h)\n\n    keypoints = _rand_keypoints(rng, bbox, 17)\n    if random_keypoints_visible:\n        keypoints_visible = np.random.randint(0, 2, (num_instances,\n                                                     17)).astype(np.float32)\n    else:\n        keypoints_visible = np.full((num_instances, 17), 1, dtype=np.float32)\n\n    upper_body_ids = [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10]\n    lower_body_ids = [11, 12, 13, 14, 15, 16]\n    flip_pairs = [[2, 1], [1, 2], [4, 3], [3, 4], [6, 5], [5, 6], [8, 7],\n                  [7, 8], [10, 9], [9, 10], [12, 11], [11, 12], [14, 13],\n                  [13, 14], [16, 15], [15, 16]]\n    flip_indices = [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15]\n    dataset_keypoint_weights = np.array([\n        1., 1., 1., 1., 1., 1., 1., 1.2, 1.2, 1.5, 1.5, 1., 1., 1.2, 1.2, 1.5,\n        1.5\n    ]).astype(np.float32)\n\n    data = {\n        'img': img,\n        'img_shape': img_shape,\n        'ori_shape': img_shape,\n        'bbox': bbox,\n        'keypoints': keypoints,\n        'keypoints_visible': keypoints_visible,\n        'upper_body_ids': upper_body_ids,\n        'lower_body_ids': lower_body_ids,\n        'flip_pairs': flip_pairs,\n        'flip_indices': flip_indices,\n        'dataset_keypoint_weights': dataset_keypoint_weights,\n        'invalid_segs': [],\n    }\n\n    if with_bbox_cs:\n        data['bbox_center'], data['bbox_scale'] = bbox_xyxy2cs(data['bbox'])\n\n    if with_img_mask:\n        data['img_mask'] = np.random.randint(0, 2, (h, w), dtype=np.uint8)\n\n    return data\n\n\ndef get_packed_inputs(batch_size=2,\n                      num_instances=1,\n                      num_keypoints=17,\n                      num_levels=1,\n                      img_shape=(256, 192),\n                      input_size=(192, 256),\n                      heatmap_size=(48, 64),\n                      simcc_split_ratio=2.0,\n                      with_heatmap=True,\n                      with_reg_label=True,\n                      with_simcc_label=True):\n    \"\"\"Create a dummy batch of model inputs and data samples.\"\"\"\n    rng = np.random.RandomState(0)\n\n    inputs_list = []\n    for idx in range(batch_size):\n        inputs = dict()\n\n        # input\n        h, w = img_shape\n        image = rng.randint(0, 255, size=(3, h, w), dtype=np.uint8)\n        inputs['inputs'] = torch.from_numpy(image)\n\n        # attributes\n        bboxes = _rand_bboxes(rng, num_instances, w, h)\n        bbox_centers, bbox_scales = bbox_xyxy2cs(bboxes)\n\n        keypoints = _rand_keypoints(rng, bboxes, num_keypoints)\n        keypoints_visible = np.ones((num_instances, num_keypoints),\n                                    dtype=np.float32)\n\n        # meta\n        img_meta = {\n            'id': idx,\n            'img_id': idx,\n            'img_path': '<demo>.png',\n            'img_shape': img_shape,\n            'input_size': input_size,\n            'input_center': bbox_centers,\n            'input_scale': bbox_scales,\n            'flip': False,\n            'flip_direction': None,\n            'flip_indices': list(range(num_keypoints))\n        }\n\n        np.random.shuffle(img_meta['flip_indices'])\n        data_sample = PoseDataSample(metainfo=img_meta)\n\n        # gt_instance\n        gt_instances = InstanceData()\n        gt_instance_labels = InstanceData()\n\n        # [N, K] -> [N, num_levels, K]\n        # keep the first dimension as the num_instances\n        if num_levels > 1:\n            keypoint_weights = np.tile(keypoints_visible[:, None],\n                                       (1, num_levels, 1))\n        else:\n            keypoint_weights = keypoints_visible.copy()\n\n        gt_instances.bboxes = bboxes\n        gt_instances.bbox_centers = bbox_centers\n        gt_instances.bbox_scales = bbox_scales\n        gt_instances.bbox_scores = np.ones((num_instances, ), dtype=np.float32)\n        gt_instances.keypoints = keypoints\n        gt_instances.keypoints_visible = keypoints_visible\n\n        gt_instance_labels.keypoint_weights = torch.FloatTensor(\n            keypoint_weights)\n\n        if with_reg_label:\n            gt_instance_labels.keypoint_labels = torch.FloatTensor(keypoints /\n                                                                   input_size)\n\n        if with_simcc_label:\n            len_x = np.around(input_size[0] * simcc_split_ratio)\n            len_y = np.around(input_size[1] * simcc_split_ratio)\n            gt_instance_labels.keypoint_x_labels = torch.FloatTensor(\n                _rand_simcc_label(rng, num_instances, num_keypoints, len_x))\n            gt_instance_labels.keypoint_y_labels = torch.FloatTensor(\n                _rand_simcc_label(rng, num_instances, num_keypoints, len_y))\n\n        # gt_fields\n        if with_heatmap:\n            if num_levels == 1:\n                gt_fields = PixelData()\n                # generate single-level heatmaps\n                W, H = heatmap_size\n                heatmaps = rng.rand(num_keypoints, H, W)\n                gt_fields.heatmaps = torch.FloatTensor(heatmaps)\n            else:\n                # generate multilevel heatmaps\n                heatmaps = []\n                for _ in range(num_levels):\n                    W, H = heatmap_size\n                    heatmaps_ = rng.rand(num_keypoints, H, W)\n                    heatmaps.append(torch.FloatTensor(heatmaps_))\n                # [num_levels*K, H, W]\n                gt_fields = MultilevelPixelData()\n                gt_fields.heatmaps = heatmaps\n            data_sample.gt_fields = gt_fields\n\n        data_sample.gt_instances = gt_instances\n        data_sample.gt_instance_labels = gt_instance_labels\n\n        inputs['data_samples'] = data_sample\n        inputs_list.append(inputs)\n\n    packed_inputs = pseudo_collate(inputs_list)\n    return packed_inputs\n\n\ndef _rand_keypoints(rng, bboxes, num_keypoints):\n    n = bboxes.shape[0]\n    relative_pos = rng.rand(n, num_keypoints, 2)\n    keypoints = relative_pos * bboxes[:, None, :2] + (\n        1 - relative_pos) * bboxes[:, None, 2:4]\n\n    return keypoints\n\n\ndef _rand_simcc_label(rng, num_instances, num_keypoints, len_feats):\n    simcc_label = rng.rand(num_instances, num_keypoints, int(len_feats))\n    return simcc_label\n\n\ndef _rand_bboxes(rng, num_instances, img_w, img_h):\n    cx, cy = rng.rand(num_instances, 2).T\n    bw, bh = 0.2 + 0.8 * rng.rand(num_instances, 2).T\n\n    tl_x = ((cx * img_w) - (img_w * bw / 2)).clip(0, img_w)\n    tl_y = ((cy * img_h) - (img_h * bh / 2)).clip(0, img_h)\n    br_x = ((cx * img_w) + (img_w * bw / 2)).clip(0, img_w)\n    br_y = ((cy * img_h) + (img_h * bh / 2)).clip(0, img_h)\n\n    bboxes = np.vstack([tl_x, tl_y, br_x, br_y]).T\n    return bboxes\n\n\ndef get_repo_dir():\n    \"\"\"Return the path of the MMPose repo directory.\"\"\"\n    try:\n        # Assume the function in invoked is the source mmpose repo\n        repo_dir = osp.dirname(osp.dirname(osp.dirname(__file__)))\n    except NameError:\n        # For IPython development when __file__ is not defined\n        import mmpose\n        repo_dir = osp.dirname(osp.dirname(mmpose.__file__))\n\n    return repo_dir\n\n\ndef get_config_file(fn: str):\n    \"\"\"Return full path of a config file from the given relative path.\"\"\"\n    repo_dir = get_repo_dir()\n    if fn.startswith('configs'):\n        fn_config = osp.join(repo_dir, fn)\n    else:\n        fn_config = osp.join(repo_dir, 'configs', fn)\n\n    if not osp.isfile(fn_config):\n        raise FileNotFoundError(f'Cannot find config file {fn_config}')\n\n    return fn_config\n\n\ndef get_pose_estimator_cfg(fn: str):\n    \"\"\"Load model config from a config file.\"\"\"\n\n    fn_config = get_config_file(fn)\n    config = Config.fromfile(fn_config)\n    return deepcopy(config.model)\n"
  },
  {
    "path": "mmpose/utils/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .camera import SimpleCamera, SimpleCameraTorch\nfrom .collect_env import collect_env\nfrom .config_utils import adapt_mmdet_pipeline\nfrom .dist_utils import reduce_mean\nfrom .logger import get_root_logger\nfrom .setup_env import register_all_modules, setup_multi_processes\nfrom .timer import StopWatch\n\n__all__ = [\n    'get_root_logger', 'collect_env', 'StopWatch', 'setup_multi_processes',\n    'register_all_modules', 'SimpleCamera', 'SimpleCameraTorch',\n    'adapt_mmdet_pipeline', 'reduce_mean'\n]\n"
  },
  {
    "path": "mmpose/utils/camera.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom abc import ABCMeta, abstractmethod\n\nimport numpy as np\nimport torch\nfrom mmengine.registry import Registry\n\nCAMERAS = Registry('camera')\n\n\nclass SingleCameraBase(metaclass=ABCMeta):\n    \"\"\"Base class for single camera model.\n\n    Args:\n        param (dict): Camera parameters\n\n    Methods:\n        world_to_camera: Project points from world coordinates to camera\n            coordinates\n        camera_to_world: Project points from camera coordinates to world\n            coordinates\n        camera_to_pixel: Project points from camera coordinates to pixel\n            coordinates\n        world_to_pixel: Project points from world coordinates to pixel\n            coordinates\n    \"\"\"\n\n    @abstractmethod\n    def __init__(self, param):\n        \"\"\"Load camera parameters and check validity.\"\"\"\n\n    def world_to_camera(self, X):\n        \"\"\"Project points from world coordinates to camera coordinates.\"\"\"\n        raise NotImplementedError\n\n    def camera_to_world(self, X):\n        \"\"\"Project points from camera coordinates to world coordinates.\"\"\"\n        raise NotImplementedError\n\n    def camera_to_pixel(self, X):\n        \"\"\"Project points from camera coordinates to pixel coordinates.\"\"\"\n        raise NotImplementedError\n\n    def world_to_pixel(self, X):\n        \"\"\"Project points from world coordinates to pixel coordinates.\"\"\"\n        _X = self.world_to_camera(X)\n        return self.camera_to_pixel(_X)\n\n\n@CAMERAS.register_module()\nclass SimpleCamera(SingleCameraBase):\n    \"\"\"Camera model to calculate coordinate transformation with given\n    intrinsic/extrinsic camera parameters.\n\n    Note:\n        The keypoint coordinate should be an np.ndarray with a shape of\n    [...,J, C] where J is the keypoint number of an instance, and C is\n    the coordinate dimension. For example:\n\n        [J, C]: shape of joint coordinates of a person with J joints.\n        [N, J, C]: shape of a batch of person joint coordinates.\n        [N, T, J, C]: shape of a batch of pose sequences.\n\n    Args:\n        param (dict): camera parameters including:\n            - R: 3x3, camera rotation matrix (camera-to-world)\n            - T: 3x1, camera translation (camera-to-world)\n            - K: (optional) 2x3, camera intrinsic matrix\n            - k: (optional) nx1, camera radial distortion coefficients\n            - p: (optional) mx1, camera tangential distortion coefficients\n            - f: (optional) 2x1, camera focal length\n            - c: (optional) 2x1, camera center\n        if K is not provided, it will be calculated from f and c.\n\n    Methods:\n        world_to_camera: Project points from world coordinates to camera\n            coordinates\n        camera_to_pixel: Project points from camera coordinates to pixel\n            coordinates\n        world_to_pixel: Project points from world coordinates to pixel\n            coordinates\n    \"\"\"\n\n    def __init__(self, param):\n\n        self.param = {}\n        # extrinsic param\n        R = np.array(param['R'], dtype=np.float32)\n        T = np.array(param['T'], dtype=np.float32)\n        assert R.shape == (3, 3)\n        assert T.shape == (3, 1)\n        # The camera matrices are transposed in advance because the joint\n        # coordinates are stored as row vectors.\n        self.param['R_c2w'] = R.T\n        self.param['T_c2w'] = T.T\n        self.param['R_w2c'] = R\n        self.param['T_w2c'] = -self.param['T_c2w'] @ self.param['R_w2c']\n\n        # intrinsic param\n        if 'K' in param:\n            K = np.array(param['K'], dtype=np.float32)\n            assert K.shape == (2, 3)\n            self.param['K'] = K.T\n            self.param['f'] = np.array([K[0, 0], K[1, 1]])[:, np.newaxis]\n            self.param['c'] = np.array([K[0, 2], K[1, 2]])[:, np.newaxis]\n        elif 'f' in param and 'c' in param:\n            f = np.array(param['f'], dtype=np.float32)\n            c = np.array(param['c'], dtype=np.float32)\n            assert f.shape == (2, 1)\n            assert c.shape == (2, 1)\n            self.param['K'] = np.concatenate((np.diagflat(f), c), axis=-1).T\n            self.param['f'] = f\n            self.param['c'] = c\n        else:\n            raise ValueError('Camera intrinsic parameters are missing. '\n                             'Either \"K\" or \"f\"&\"c\" should be provided.')\n\n        # distortion param\n        if 'k' in param and 'p' in param:\n            self.undistortion = True\n            self.param['k'] = np.array(param['k'], dtype=np.float32).flatten()\n            self.param['p'] = np.array(param['p'], dtype=np.float32).flatten()\n            assert self.param['k'].size in {3, 6}\n            assert self.param['p'].size == 2\n        else:\n            self.undistortion = False\n\n    def world_to_camera(self, X):\n        assert isinstance(X, np.ndarray)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n        return X @ self.param['R_w2c'] + self.param['T_w2c']\n\n    def camera_to_world(self, X):\n        assert isinstance(X, np.ndarray)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n        return X @ self.param['R_c2w'] + self.param['T_c2w']\n\n    def camera_to_pixel(self, X):\n        assert isinstance(X, np.ndarray)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n\n        _X = X / X[..., 2:]\n\n        if self.undistortion:\n            k = self.param['k']\n            p = self.param['p']\n            _X_2d = _X[..., :2]\n            r2 = (_X_2d**2).sum(-1)\n            radial = 1 + sum(ki * r2**(i + 1) for i, ki in enumerate(k[:3]))\n            if k.size == 6:\n                radial /= 1 + sum(\n                    (ki * r2**(i + 1) for i, ki in enumerate(k[3:])))\n\n            tangential = 2 * (p[1] * _X[..., 0] + p[0] * _X[..., 1])\n\n            _X[..., :2] = _X_2d * (radial + tangential)[..., None] + np.outer(\n                r2, p[::-1]).reshape(_X_2d.shape)\n        return _X @ self.param['K']\n\n    def pixel_to_camera(self, X):\n        assert isinstance(X, np.ndarray)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n        _X = X.copy()\n        _X[:, :2] = (X[:, :2] - self.param['c'].T) / self.param['f'].T * X[:,\n                                                                           [2]]\n        return _X\n\n\n@CAMERAS.register_module()\nclass SimpleCameraTorch(SingleCameraBase):\n    \"\"\"Camera model to calculate coordinate transformation with given\n    intrinsic/extrinsic camera parameters.\n\n    Notes:\n        The keypoint coordinate should be an np.ndarray with a shape of\n    [...,J, C] where J is the keypoint number of an instance, and C is\n    the coordinate dimension. For example:\n\n        [J, C]: shape of joint coordinates of a person with J joints.\n        [N, J, C]: shape of a batch of person joint coordinates.\n        [N, T, J, C]: shape of a batch of pose sequences.\n\n    Args:\n        param (dict): camera parameters including:\n            - R: 3x3, camera rotation matrix (camera-to-world)\n            - T: 3x1, camera translation (camera-to-world)\n            - K: (optional) 2x3, camera intrinsic matrix\n            - k: (optional) nx1, camera radial distortion coefficients\n            - p: (optional) mx1, camera tangential distortion coefficients\n            - f: (optional) 2x1, camera focal length\n            - c: (optional) 2x1, camera center\n        if K is not provided, it will be calculated from f and c.\n\n    Methods:\n        world_to_camera: Project points from world coordinates to camera\n            coordinates\n        camera_to_pixel: Project points from camera coordinates to pixel\n            coordinates\n        world_to_pixel: Project points from world coordinates to pixel\n            coordinates\n    \"\"\"\n\n    def __init__(self, param, device):\n\n        self.param = {}\n        # extrinsic param\n        R = torch.tensor(param['R'], device=device)\n        T = torch.tensor(param['T'], device=device)\n\n        assert R.shape == (3, 3)\n        assert T.shape == (3, 1)\n        # The camera matrices are transposed in advance because the joint\n        # coordinates are stored as row vectors.\n        self.param['R_c2w'] = R.T\n        self.param['T_c2w'] = T.T\n        self.param['R_w2c'] = R\n        self.param['T_w2c'] = -self.param['T_c2w'] @ self.param['R_w2c']\n\n        # intrinsic param\n        if 'K' in param:\n            K = torch.tensor(param['K'], device=device)\n            assert K.shape == (2, 3)\n            self.param['K'] = K.T\n            self.param['f'] = torch.tensor([[K[0, 0]], [K[1, 1]]],\n                                           device=device)\n            self.param['c'] = torch.tensor([[K[0, 2]], [K[1, 2]]],\n                                           device=device)\n        elif 'f' in param and 'c' in param:\n            f = torch.tensor(param['f'], device=device)\n            c = torch.tensor(param['c'], device=device)\n            assert f.shape == (2, 1)\n            assert c.shape == (2, 1)\n            self.param['K'] = torch.cat([torch.diagflat(f), c], dim=-1).T\n            self.param['f'] = f\n            self.param['c'] = c\n        else:\n            raise ValueError('Camera intrinsic parameters are missing. '\n                             'Either \"K\" or \"f\"&\"c\" should be provided.')\n\n        # distortion param\n        if 'k' in param and 'p' in param:\n            self.undistortion = True\n            self.param['k'] = torch.tensor(param['k'], device=device).view(-1)\n            self.param['p'] = torch.tensor(param['p'], device=device).view(-1)\n            assert len(self.param['k']) in {3, 6}\n            assert len(self.param['p']) == 2\n        else:\n            self.undistortion = False\n\n    def world_to_camera(self, X):\n        assert isinstance(X, torch.Tensor)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n        return X @ self.param['R_w2c'] + self.param['T_w2c']\n\n    def camera_to_world(self, X):\n        assert isinstance(X, torch.Tensor)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n        return X @ self.param['R_c2w'] + self.param['T_c2w']\n\n    def camera_to_pixel(self, X):\n        assert isinstance(X, torch.Tensor)\n        assert X.ndim >= 2 and X.shape[-1] == 3\n\n        _X = X / X[..., 2:]\n\n        if self.undistortion:\n            k = self.param['k']\n            p = self.param['p']\n            _X_2d = _X[..., :2]\n            r2 = (_X_2d**2).sum(-1)\n            radial = 1 + sum(ki * r2**(i + 1) for i, ki in enumerate(k[:3]))\n            if k.size == 6:\n                radial /= 1 + sum(\n                    (ki * r2**(i + 1) for i, ki in enumerate(k[3:])))\n\n            tangential = 2 * (p[1] * _X[..., 0] + p[0] * _X[..., 1])\n\n            _X[..., :2] = _X_2d * (radial + tangential)[..., None] + torch.ger(\n                r2, p.flip([0])).reshape(_X_2d.shape)\n        return _X @ self.param['K']\n"
  },
  {
    "path": "mmpose/utils/collect_env.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmengine.utils import get_git_hash\nfrom mmengine.utils.dl_utils import collect_env as collect_base_env\n\nimport mmpose\n\n\ndef collect_env():\n    env_info = collect_base_env()\n    env_info['MMPose'] = (mmpose.__version__ + '+' + get_git_hash(digits=7))\n    return env_info\n\n\nif __name__ == '__main__':\n    for name, val in collect_env().items():\n        print(f'{name}: {val}')\n"
  },
  {
    "path": "mmpose/utils/config_utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom mmpose.utils.typing import ConfigDict\n\n\ndef adapt_mmdet_pipeline(cfg: ConfigDict) -> ConfigDict:\n    \"\"\"Converts pipeline types in MMDetection's test dataloader to use the\n    'mmdet' namespace.\n\n    Args:\n        cfg (ConfigDict): Configuration dictionary for MMDetection.\n\n    Returns:\n        ConfigDict: Configuration dictionary with updated pipeline types.\n    \"\"\"\n    # use lazy import to avoid hard dependence on mmdet\n    from mmdet.datasets import transforms\n\n    if 'test_dataloader' not in cfg:\n        return cfg\n\n    pipeline = cfg.test_dataloader.dataset.pipeline\n    for trans in pipeline:\n        if trans['type'] in dir(transforms):\n            trans['type'] = 'mmdet.' + trans['type']\n\n    return cfg\n"
  },
  {
    "path": "mmpose/utils/dist_utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.distributed as dist\n\n\ndef reduce_mean(tensor):\n    \"\"\"\"Obtain the mean of tensor on different GPUs.\"\"\"\n    if not (dist.is_available() and dist.is_initialized()):\n        return tensor\n    tensor = tensor.clone()\n    dist.all_reduce(tensor.div_(dist.get_world_size()), op=dist.ReduceOp.SUM)\n    return tensor\n"
  },
  {
    "path": "mmpose/utils/hooks.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport functools\n\n\nclass OutputHook:\n\n    def __init__(self, module, outputs=None, as_tensor=False):\n        self.outputs = outputs\n        self.as_tensor = as_tensor\n        self.layer_outputs = {}\n        self.register(module)\n\n    def register(self, module):\n\n        def hook_wrapper(name):\n\n            def hook(model, input, output):\n                if self.as_tensor:\n                    self.layer_outputs[name] = output\n                else:\n                    if isinstance(output, list):\n                        self.layer_outputs[name] = [\n                            out.detach().cpu().numpy() for out in output\n                        ]\n                    else:\n                        self.layer_outputs[name] = output.detach().cpu().numpy(\n                        )\n\n            return hook\n\n        self.handles = []\n        if isinstance(self.outputs, (list, tuple)):\n            for name in self.outputs:\n                try:\n                    layer = rgetattr(module, name)\n                    h = layer.register_forward_hook(hook_wrapper(name))\n                except ModuleNotFoundError as module_not_found:\n                    raise ModuleNotFoundError(\n                        f'Module {name} not found') from module_not_found\n                self.handles.append(h)\n\n    def remove(self):\n        for h in self.handles:\n            h.remove()\n\n    def __enter__(self):\n        return self\n\n    def __exit__(self, exc_type, exc_val, exc_tb):\n        self.remove()\n\n\n# using wonder's beautiful simplification:\n# https://stackoverflow.com/questions/31174295/getattr-and-setattr-on-nested-objects\ndef rsetattr(obj, attr, val):\n    \"\"\"Set the value of a nested attribute of an object.\n\n    This function splits the attribute path and sets the value of the\n    nested attribute. If the attribute path is nested (e.g., 'x.y.z'), it\n    traverses through each attribute until it reaches the last one and sets\n    its value.\n\n    Args:\n        obj (object): The object whose attribute needs to be set.\n        attr (str): The attribute path in dot notation (e.g., 'x.y.z').\n        val (any): The value to set at the specified attribute path.\n    \"\"\"\n    pre, _, post = attr.rpartition('.')\n    return setattr(rgetattr(obj, pre) if pre else obj, post, val)\n\n\ndef rgetattr(obj, attr, *args):\n    \"\"\"Recursively get a nested attribute of an object.\n\n    This function splits the attribute path and retrieves the value of the\n    nested attribute. If the attribute path is nested (e.g., 'x.y.z'), it\n    traverses through each attribute. If an attribute in the path does not\n    exist, it returns the value specified as the third argument.\n\n    Args:\n        obj (object): The object whose attribute needs to be retrieved.\n        attr (str): The attribute path in dot notation (e.g., 'x.y.z').\n        *args (any): Optional default value to return if the attribute\n            does not exist.\n    \"\"\"\n\n    def _getattr(obj, attr):\n        return getattr(obj, attr, *args)\n\n    return functools.reduce(_getattr, [obj] + attr.split('.'))\n"
  },
  {
    "path": "mmpose/utils/logger.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\n\nfrom mmengine.logging import MMLogger\n\n\ndef get_root_logger(log_file=None, log_level=logging.INFO):\n    \"\"\"Use `MMLogger` class in mmengine to get the root logger.\n\n    The logger will be initialized if it has not been initialized. By default a\n    StreamHandler will be added. If `log_file` is specified, a FileHandler will\n    also be added. The name of the root logger is the top-level package name,\n    e.g., \"mmpose\".\n\n    Args:\n        log_file (str | None): The log filename. If specified, a FileHandler\n            will be added to the root logger.\n        log_level (int): The root logger level. Note that only the process of\n            rank 0 is affected, while other processes will set the level to\n            \"Error\" and be silent most of the time.\n\n    Returns:\n        logging.Logger: The root logger.\n    \"\"\"\n    return MMLogger('MMLogger', __name__.split('.')[0], log_file, log_level)\n"
  },
  {
    "path": "mmpose/utils/setup_env.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport datetime\nimport os\nimport platform\nimport warnings\n\nimport cv2\nimport torch.multiprocessing as mp\nfrom mmengine import DefaultScope\n\n\ndef setup_multi_processes(cfg):\n    \"\"\"Setup multi-processing environment variables.\"\"\"\n    # set multi-process start method as `fork` to speed up the training\n    if platform.system() != 'Windows':\n        mp_start_method = cfg.get('mp_start_method', 'fork')\n        current_method = mp.get_start_method(allow_none=True)\n        if current_method is not None and current_method != mp_start_method:\n            warnings.warn(\n                f'Multi-processing start method `{mp_start_method}` is '\n                f'different from the previous setting `{current_method}`.'\n                f'It will be force set to `{mp_start_method}`. You can change '\n                f'this behavior by changing `mp_start_method` in your config.')\n        mp.set_start_method(mp_start_method, force=True)\n\n    # disable opencv multithreading to avoid system being overloaded\n    opencv_num_threads = cfg.get('opencv_num_threads', 0)\n    cv2.setNumThreads(opencv_num_threads)\n\n    # setup OMP threads\n    # This code is referred from https://github.com/pytorch/pytorch/blob/master/torch/distributed/run.py  # noqa\n    if 'OMP_NUM_THREADS' not in os.environ and cfg.data.workers_per_gpu > 1:\n        omp_num_threads = 1\n        warnings.warn(\n            f'Setting OMP_NUM_THREADS environment variable for each process '\n            f'to be {omp_num_threads} in default, to avoid your system being '\n            f'overloaded, please further tune the variable for optimal '\n            f'performance in your application as needed.')\n        os.environ['OMP_NUM_THREADS'] = str(omp_num_threads)\n\n    # setup MKL threads\n    if 'MKL_NUM_THREADS' not in os.environ and cfg.data.workers_per_gpu > 1:\n        mkl_num_threads = 1\n        warnings.warn(\n            f'Setting MKL_NUM_THREADS environment variable for each process '\n            f'to be {mkl_num_threads} in default, to avoid your system being '\n            f'overloaded, please further tune the variable for optimal '\n            f'performance in your application as needed.')\n        os.environ['MKL_NUM_THREADS'] = str(mkl_num_threads)\n\n\ndef register_all_modules(init_default_scope: bool = True) -> None:\n    \"\"\"Register all modules in mmpose into the registries.\n\n    Args:\n        init_default_scope (bool): Whether initialize the mmpose default scope.\n            When `init_default_scope=True`, the global default scope will be\n            set to `mmpose`, and all registries will build modules from mmpose's\n            registry node. To understand more about the registry, please refer\n            to https://github.com/open-mmlab/mmengine/blob/main/docs/en/tutorials/registry.md\n            Defaults to True.\n    \"\"\"  # noqa\n\n    import mmpose.codecs  # noqa: F401, F403\n    import mmpose.datasets  # noqa: F401,F403\n    import mmpose.engine  # noqa: F401,F403\n    import mmpose.evaluation  # noqa: F401,F403\n    import mmpose.models  # noqa: F401,F403\n    import mmpose.visualization  # noqa: F401,F403\n\n    if init_default_scope:\n        never_created = DefaultScope.get_current_instance() is None \\\n                        or not DefaultScope.check_instance_created('mmpose')\n        if never_created:\n            DefaultScope.get_instance('mmpose', scope_name='mmpose')\n            return\n        current_scope = DefaultScope.get_current_instance()\n        if current_scope.scope_name != 'mmpose':\n            warnings.warn('The current default scope '\n                          f'\"{current_scope.scope_name}\" is not \"mmpose\", '\n                          '`register_all_modules` will force the current'\n                          'default scope to be \"mmpose\". If this is not '\n                          'expected, please set `init_default_scope=False`.')\n            # avoid name conflict\n            new_instance_name = f'mmpose-{datetime.datetime.now()}'\n            DefaultScope.get_instance(new_instance_name, scope_name='mmpose')\n"
  },
  {
    "path": "mmpose/utils/tensor_utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom typing import Any, Optional, Sequence, Union\n\nimport numpy as np\nimport torch\nfrom mmengine.utils import is_seq_of\nfrom torch import Tensor\n\n\ndef to_numpy(x: Union[Tensor, Sequence[Tensor]],\n             return_device: bool = False,\n             unzip: bool = False) -> Union[np.ndarray, tuple]:\n    \"\"\"Convert torch tensor to numpy.ndarray.\n\n    Args:\n        x (Tensor | Sequence[Tensor]): A single tensor or a sequence of\n            tensors\n        return_device (bool): Whether return the tensor device. Defaults to\n            ``False``\n        unzip (bool): Whether unzip the input sequence. Defaults to ``False``\n\n    Returns:\n        np.ndarray | tuple: If ``return_device`` is ``True``, return a tuple\n        of converted numpy array(s) and the device indicator; otherwise only\n        return the numpy array(s)\n    \"\"\"\n\n    if isinstance(x, Tensor):\n        arrays = x.detach().cpu().numpy()\n        device = x.device\n    elif isinstance(x, np.ndarray) or is_seq_of(x, np.ndarray):\n        arrays = x\n        device = 'cpu'\n    elif is_seq_of(x, Tensor):\n        if unzip:\n            # convert (A, B) -> [(A[0], B[0]), (A[1], B[1]), ...]\n            arrays = [\n                tuple(to_numpy(_x[None, :]) for _x in _each)\n                for _each in zip(*x)\n            ]\n        else:\n            arrays = [to_numpy(_x) for _x in x]\n\n        device = x[0].device\n\n    else:\n        raise ValueError(f'Invalid input type {type(x)}')\n\n    if return_device:\n        return arrays, device\n    else:\n        return arrays\n\n\ndef to_tensor(x: Union[np.ndarray, Sequence[np.ndarray]],\n              device: Optional[Any] = None) -> Union[Tensor, Sequence[Tensor]]:\n    \"\"\"Convert numpy.ndarray to torch tensor.\n\n    Args:\n        x (np.ndarray | Sequence[np.ndarray]): A single np.ndarray or a\n            sequence of tensors\n        tensor (Any, optional): The device indicator. Defaults to ``None``\n\n    Returns:\n        tuple:\n        - Tensor | Sequence[Tensor]: The converted Tensor or Tensor sequence\n    \"\"\"\n    if isinstance(x, np.ndarray):\n        return torch.tensor(x, device=device)\n    elif is_seq_of(x, np.ndarray):\n        return [to_tensor(_x, device=device) for _x in x]\n    else:\n        raise ValueError(f'Invalid input type {type(x)}')\n"
  },
  {
    "path": "mmpose/utils/timer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import defaultdict\nfrom contextlib import contextmanager\nfrom functools import partial\n\nimport numpy as np\nfrom mmengine import Timer\n\n\nclass RunningAverage():\n    r\"\"\"A helper class to calculate running average in a sliding window.\n\n    Args:\n        window (int): The size of the sliding window.\n    \"\"\"\n\n    def __init__(self, window: int = 1):\n        self.window = window\n        self._data = []\n\n    def update(self, value):\n        \"\"\"Update a new data sample.\"\"\"\n        self._data.append(value)\n        self._data = self._data[-self.window:]\n\n    def average(self):\n        \"\"\"Get the average value of current window.\"\"\"\n        return np.mean(self._data)\n\n\nclass StopWatch:\n    r\"\"\"A helper class to measure FPS and detailed time consuming of each phase\n    in a video processing loop or similar scenarios.\n\n    Args:\n        window (int): The sliding window size to calculate the running average\n            of the time consuming.\n\n    Example:\n        >>> from mmpose.utils import StopWatch\n        >>> import time\n        >>> stop_watch = StopWatch(window=10)\n        >>> with stop_watch.timeit('total'):\n        >>>     time.sleep(0.1)\n        >>>     # 'timeit' support nested use\n        >>>     with stop_watch.timeit('phase1'):\n        >>>         time.sleep(0.1)\n        >>>     with stop_watch.timeit('phase2'):\n        >>>         time.sleep(0.2)\n        >>>     time.sleep(0.2)\n        >>> report = stop_watch.report()\n    \"\"\"\n\n    def __init__(self, window=1):\n        self.window = window\n        self._record = defaultdict(partial(RunningAverage, window=self.window))\n        self._timer_stack = []\n\n    @contextmanager\n    def timeit(self, timer_name='_FPS_'):\n        \"\"\"Timing a code snippet with an assigned name.\n\n        Args:\n            timer_name (str): The unique name of the interested code snippet to\n                handle multiple timers and generate reports. Note that '_FPS_'\n                is a special key that the measurement will be in `fps` instead\n                of `millisecond`. Also see `report` and `report_strings`.\n                Default: '_FPS_'.\n        Note:\n            This function should always be used in a `with` statement, as shown\n            in the example.\n        \"\"\"\n        self._timer_stack.append((timer_name, Timer()))\n        try:\n            yield\n        finally:\n            timer_name, timer = self._timer_stack.pop()\n            self._record[timer_name].update(timer.since_start())\n\n    def report(self, key=None):\n        \"\"\"Report timing information.\n\n        Returns:\n            dict: The key is the timer name and the value is the \\\n                corresponding average time consuming.\n        \"\"\"\n        result = {\n            name: r.average() * 1000.\n            for name, r in self._record.items()\n        }\n\n        if '_FPS_' in result:\n            result['_FPS_'] = 1000. / result.pop('_FPS_')\n\n        if key is None:\n            return result\n        return result[key]\n\n    def report_strings(self):\n        \"\"\"Report timing information in texture strings.\n\n        Returns:\n            list(str): Each element is the information string of a timed \\\n                event, in format of '{timer_name}: {time_in_ms}'. \\\n                Specially, if timer_name is '_FPS_', the result will \\\n                be converted to fps.\n        \"\"\"\n        result = self.report()\n        strings = []\n        if '_FPS_' in result:\n            strings.append(f'FPS: {result[\"_FPS_\"]:>5.1f}')\n        strings += [f'{name}: {val:>3.0f}' for name, val in result.items()]\n        return strings\n\n    def reset(self):\n        self._record = defaultdict(list)\n        self._active_timer_stack = []\n"
  },
  {
    "path": "mmpose/utils/typing.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, List, Optional, Tuple, Union\n\nfrom mmengine.config import ConfigDict\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import Tensor\n\nfrom mmpose.structures import PoseDataSample\n\n# Type hint of config data\nConfigType = Union[ConfigDict, dict]\nOptConfigType = Optional[ConfigType]\n# Type hint of one or more config data\nMultiConfig = Union[ConfigType, List[ConfigType]]\nOptMultiConfig = Optional[MultiConfig]\n# Type hint of data samples\nSampleList = List[PoseDataSample]\nOptSampleList = Optional[SampleList]\nInstanceList = List[InstanceData]\nPixelDataList = List[PixelData]\nPredictions = Union[InstanceList, Tuple[InstanceList, PixelDataList]]\n# Type hint of model outputs\nForwardResults = Union[Dict[str, Tensor], List[PoseDataSample], Tuple[Tensor],\n                       Tensor]\n# Type hint of features\n#   - Tuple[Tensor]: multi-level features extracted by the network\n#   - List[Tuple[Tensor]]: multiple feature pyramids for TTA\n#   - List[List[Tuple[Tensor]]]: multi-scale feature pyramids\nFeatures = Union[Tuple[Tensor], List[Tuple[Tensor]], List[List[Tuple[Tensor]]]]\n"
  },
  {
    "path": "mmpose/version.py",
    "content": "# Copyright (c) Open-MMLab. All rights reserved.\n\n__version__ = '1.3.2'\nshort_version = __version__\n\n\ndef parse_version_info(version_str):\n    \"\"\"Parse a version string into a tuple.\n\n    Args:\n        version_str (str): The version string.\n    Returns:\n        tuple[int | str]: The version info, e.g., \"1.3.0\" is parsed into\n            (1, 3, 0), and \"2.0.0rc1\" is parsed into (2, 0, 0, 'rc1').\n    \"\"\"\n    version_info = []\n    for x in version_str.split('.'):\n        if x.isdigit():\n            version_info.append(int(x))\n        elif x.find('rc') != -1:\n            patch_version = x.split('rc')\n            version_info.append(int(patch_version[0]))\n            version_info.append(f'rc{patch_version[1]}')\n        elif x.find('b') != -1:\n            patch_version = x.split('b')\n            version_info.append(int(patch_version[0]))\n            version_info.append(f'b{patch_version[1]}')\n    return tuple(version_info)\n\n\nversion_info = parse_version_info(__version__)\n"
  },
  {
    "path": "mmpose/visualization/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .fast_visualizer import FastVisualizer\nfrom .local_visualizer import PoseLocalVisualizer\nfrom .local_visualizer_3d import Pose3dLocalVisualizer\n\n__all__ = ['PoseLocalVisualizer', 'FastVisualizer', 'Pose3dLocalVisualizer']\n"
  },
  {
    "path": "mmpose/visualization/fast_visualizer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Dict, List, Optional, Tuple, Union\n\nimport cv2\nimport numpy as np\n\n\nclass Instances:\n    keypoints: List[List[Tuple[int, int]]]\n    keypoint_scores: List[List[float]]\n\n\nclass FastVisualizer:\n    \"\"\"MMPose Fast Visualizer.\n\n    A simple yet fast visualizer for video/webcam inference.\n\n    Args:\n        metainfo (dict): pose meta information\n        radius (int, optional): Keypoint radius for visualization.\n            Defaults to 6.\n        line_width (int, optional): Link width for visualization.\n            Defaults to 3.\n        kpt_thr (float, optional): Threshold for keypoints' confidence score,\n            keypoints with score below this value will not be drawn.\n            Defaults to 0.3.\n    \"\"\"\n\n    def __init__(self,\n                 metainfo: Dict,\n                 radius: Optional[int] = 6,\n                 line_width: Optional[int] = 3,\n                 kpt_thr: Optional[float] = 0.3):\n        self.radius = radius\n        self.line_width = line_width\n        self.kpt_thr = kpt_thr\n\n        self.keypoint_id2name = metainfo.get('keypoint_id2name', None)\n        self.keypoint_name2id = metainfo.get('keypoint_name2id', None)\n        self.keypoint_colors = metainfo.get('keypoint_colors',\n                                            [(255, 255, 255)])\n        self.skeleton_links = metainfo.get('skeleton_links', None)\n        self.skeleton_link_colors = metainfo.get('skeleton_link_colors', None)\n\n    def draw_pose(self, img: np.ndarray, instances: Instances):\n        \"\"\"Draw pose estimations on the given image.\n\n        This method draws keypoints and skeleton links on the input image\n        using the provided instances.\n\n        Args:\n            img (numpy.ndarray): The input image on which to\n                draw the pose estimations.\n            instances (object): An object containing detected instances'\n                information, including keypoints and keypoint_scores.\n\n        Returns:\n            None: The input image will be modified in place.\n        \"\"\"\n\n        if instances is None:\n            print('no instance detected')\n            return\n\n        keypoints = instances.keypoints\n        scores = instances.keypoint_scores\n\n        for kpts, score in zip(keypoints, scores):\n            for sk_id, sk in enumerate(self.skeleton_links):\n                if score[sk[0]] < self.kpt_thr or score[sk[1]] < self.kpt_thr:\n                    # skip the link that should not be drawn\n                    continue\n\n                pos1 = (int(kpts[sk[0], 0]), int(kpts[sk[0], 1]))\n                pos2 = (int(kpts[sk[1], 0]), int(kpts[sk[1], 1]))\n\n                color = self.skeleton_link_colors[sk_id].tolist()\n                cv2.line(img, pos1, pos2, color, thickness=self.line_width)\n\n            for kid, kpt in enumerate(kpts):\n                if score[kid] < self.kpt_thr:\n                    # skip the point that should not be drawn\n                    continue\n\n                x_coord, y_coord = int(kpt[0]), int(kpt[1])\n\n                color = self.keypoint_colors[kid].tolist()\n                cv2.circle(img, (int(x_coord), int(y_coord)), self.radius,\n                           color, -1)\n                cv2.circle(img, (int(x_coord), int(y_coord)), self.radius,\n                           (255, 255, 255))\n\n    def draw_points(self, img: np.ndarray, instances: Union[Instances, Dict,\n                                                            np.ndarray]):\n        \"\"\"Draw points on the given image.\n\n        This method draws keypoints on the input image\n        using the provided instances.\n\n        Args:\n            img (numpy.ndarray): The input image on which to\n                draw the keypoints.\n            instances (object|dict|np.ndarray):\n                An object containing keypoints,\n                or a dict containing 'keypoints',\n                or a np.ndarray in shape of\n                (Instance_num, Point_num, Point_dim)\n\n        Returns:\n            None: The input image will be modified in place.\n        \"\"\"\n\n        if instances is None:\n            print('no instance detected')\n            return\n\n        # support different types of keypoints inputs\n        if hasattr(instances, 'keypoints'):\n            keypoints = instances.keypoints\n        elif isinstance(instances, dict) and 'keypoints' in instances:\n            keypoints = instances['keypoints']\n        elif isinstance(instances, np.ndarray):\n            shape = instances.shape\n            assert shape[-1] == 2, 'only support 2-dim point!'\n            if len(shape) == 2:\n                keypoints = instances[None]\n            elif len(shape) == 3:\n                pass\n            else:\n                raise ValueError('input keypoints should be in shape of'\n                                 '(Instance_num, Point_num, Point_dim)')\n        else:\n            raise ValueError('The keypoints should be:'\n                             'object containing keypoints,'\n                             \"or a dict containing 'keypoints',\"\n                             'or a np.ndarray in shape of'\n                             '(Instance_num, Point_num, Point_dim)')\n\n        if len(self.keypoint_colors) < len(keypoints[0]):\n            repeat_num = len(keypoints[0]) - len(self.keypoint_colors)\n            self.keypoint_colors += [(255, 255, 255)] * repeat_num\n        self.keypoint_colors = np.array(self.keypoint_colors)\n\n        for kpts in keypoints:\n            for kid, kpt in enumerate(kpts):\n                x_coord, y_coord = int(kpt[0]), int(kpt[1])\n\n                color = self.keypoint_colors[kid].tolist()\n                cv2.circle(img, (int(x_coord), int(y_coord)), self.radius,\n                           color, -1)\n                cv2.circle(img, (int(x_coord), int(y_coord)), self.radius,\n                           (255, 255, 255))\n"
  },
  {
    "path": "mmpose/visualization/local_visualizer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nimport warnings\nfrom typing import Dict, List, Optional, Tuple, Union\n\nimport cv2\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmengine.dist import master_only\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import PoseDataSample\nfrom .opencv_backend_visualizer import OpencvBackendVisualizer\nfrom .simcc_vis import SimCCVisualizer\n\n\ndef _get_adaptive_scales(areas: np.ndarray,\n                         min_area: int = 800,\n                         max_area: int = 30000) -> np.ndarray:\n    \"\"\"Get adaptive scales according to areas.\n\n    The scale range is [0.5, 1.0]. When the area is less than\n    ``min_area``, the scale is 0.5 while the area is larger than\n    ``max_area``, the scale is 1.0.\n\n    Args:\n        areas (ndarray): The areas of bboxes or masks with the\n            shape of (n, ).\n        min_area (int): Lower bound areas for adaptive scales.\n            Defaults to 800.\n        max_area (int): Upper bound areas for adaptive scales.\n            Defaults to 30000.\n\n    Returns:\n        ndarray: The adaotive scales with the shape of (n, ).\n    \"\"\"\n    scales = 0.5 + (areas - min_area) / (max_area - min_area)\n    scales = np.clip(scales, 0.5, 1.0)\n    return scales\n\n\n@VISUALIZERS.register_module()\nclass PoseLocalVisualizer(OpencvBackendVisualizer):\n    \"\"\"MMPose Local Visualizer.\n\n    Args:\n        name (str): Name of the instance. Defaults to 'visualizer'.\n        image (np.ndarray, optional): the origin image to draw. The format\n            should be RGB. Defaults to ``None``\n        vis_backends (list, optional): Visual backend config list. Defaults to\n            ``None``\n        save_dir (str, optional): Save file dir for all storage backends.\n            If it is ``None``, the backend storage will not save any data.\n            Defaults to ``None``\n        bbox_color (str, tuple(int), optional): Color of bbox lines.\n            The tuple of color should be in BGR order. Defaults to ``'green'``\n        kpt_color (str, tuple(tuple(int)), optional): Color of keypoints.\n            The tuple of color should be in BGR order. Defaults to ``'red'``\n        link_color (str, tuple(tuple(int)), optional): Color of skeleton.\n            The tuple of color should be in BGR order. Defaults to ``None``\n        line_width (int, float): The width of lines. Defaults to 1\n        radius (int, float): The radius of keypoints. Defaults to 4\n        show_keypoint_weight (bool): Whether to adjust the transparency\n            of keypoints according to their score. Defaults to ``False``\n        alpha (int, float): The transparency of bboxes. Defaults to ``1.0``\n\n    Examples:\n        >>> import numpy as np\n        >>> from mmengine.structures import InstanceData\n        >>> from mmpose.structures import PoseDataSample\n        >>> from mmpose.visualization import PoseLocalVisualizer\n\n        >>> pose_local_visualizer = PoseLocalVisualizer(radius=1)\n        >>> image = np.random.randint(0, 256,\n        ...                     size=(10, 12, 3)).astype('uint8')\n        >>> gt_instances = InstanceData()\n        >>> gt_instances.keypoints = np.array([[[1, 1], [2, 2], [4, 4],\n        ...                                          [8, 8]]])\n        >>> gt_pose_data_sample = PoseDataSample()\n        >>> gt_pose_data_sample.gt_instances = gt_instances\n        >>> dataset_meta = {'skeleton_links': [[0, 1], [1, 2], [2, 3]]}\n        >>> pose_local_visualizer.set_dataset_meta(dataset_meta)\n        >>> pose_local_visualizer.add_datasample('image', image,\n        ...                         gt_pose_data_sample)\n        >>> pose_local_visualizer.add_datasample(\n        ...                       'image', image, gt_pose_data_sample,\n        ...                        out_file='out_file.jpg')\n        >>> pose_local_visualizer.add_datasample(\n        ...                        'image', image, gt_pose_data_sample,\n        ...                         show=True)\n        >>> pred_instances = InstanceData()\n        >>> pred_instances.keypoints = np.array([[[1, 1], [2, 2], [4, 4],\n        ...                                       [8, 8]]])\n        >>> pred_instances.score = np.array([0.8, 1, 0.9, 1])\n        >>> pred_pose_data_sample = PoseDataSample()\n        >>> pred_pose_data_sample.pred_instances = pred_instances\n        >>> pose_local_visualizer.add_datasample('image', image,\n        ...                         gt_pose_data_sample,\n        ...                         pred_pose_data_sample)\n    \"\"\"\n\n    def __init__(self,\n                 name: str = 'visualizer',\n                 image: Optional[np.ndarray] = None,\n                 vis_backends: Optional[Dict] = None,\n                 save_dir: Optional[str] = None,\n                 bbox_color: Optional[Union[str, Tuple[int]]] = 'green',\n                 kpt_color: Optional[Union[str, Tuple[Tuple[int]]]] = 'red',\n                 link_color: Optional[Union[str, Tuple[Tuple[int]]]] = None,\n                 text_color: Optional[Union[str,\n                                            Tuple[int]]] = (255, 255, 255),\n                 skeleton: Optional[Union[List, Tuple]] = None,\n                 line_width: Union[int, float] = 1,\n                 radius: Union[int, float] = 3,\n                 show_keypoint_weight: bool = False,\n                 backend: str = 'opencv',\n                 alpha: float = 1.0):\n\n        warnings.filterwarnings(\n            'ignore',\n            message='.*please provide the `save_dir` argument.*',\n            category=UserWarning)\n\n        super().__init__(\n            name=name,\n            image=image,\n            vis_backends=vis_backends,\n            save_dir=save_dir,\n            backend=backend)\n\n        self.bbox_color = bbox_color\n        self.kpt_color = kpt_color\n        self.link_color = link_color\n        self.line_width = line_width\n        self.text_color = text_color\n        self.skeleton = skeleton\n        self.radius = radius\n        self.alpha = alpha\n        self.show_keypoint_weight = show_keypoint_weight\n        # Set default value. When calling\n        # `PoseLocalVisualizer().set_dataset_meta(xxx)`,\n        # it will override the default value.\n        self.dataset_meta = {}\n\n    def set_dataset_meta(self,\n                         dataset_meta: Dict,\n                         skeleton_style: str = 'mmpose'):\n        \"\"\"Assign dataset_meta to the visualizer. The default visualization\n        settings will be overridden.\n\n        Args:\n            dataset_meta (dict): meta information of dataset.\n        \"\"\"\n        if skeleton_style == 'openpose':\n            dataset_name = dataset_meta['dataset_name']\n            if dataset_name == 'coco':\n                dataset_meta = parse_pose_metainfo(\n                    dict(from_file='configs/_base_/datasets/coco_openpose.py'))\n            elif dataset_name == 'coco_wholebody':\n                dataset_meta = parse_pose_metainfo(\n                    dict(from_file='configs/_base_/datasets/'\n                         'coco_wholebody_openpose.py'))\n            else:\n                raise NotImplementedError(\n                    f'openpose style has not been '\n                    f'supported for {dataset_name} dataset')\n\n        if isinstance(dataset_meta, dict):\n            self.dataset_meta = dataset_meta.copy()\n            self.bbox_color = dataset_meta.get('bbox_color', self.bbox_color)\n            self.kpt_color = dataset_meta.get('keypoint_colors',\n                                              self.kpt_color)\n            self.link_color = dataset_meta.get('skeleton_link_colors',\n                                               self.link_color)\n            self.skeleton = dataset_meta.get('skeleton_links', self.skeleton)\n        # sometimes self.dataset_meta is manually set, which might be None.\n        # it should be converted to a dict at these times\n        if self.dataset_meta is None:\n            self.dataset_meta = {}\n\n    def _draw_instances_bbox(self, image: np.ndarray,\n                             instances: InstanceData) -> np.ndarray:\n        \"\"\"Draw bounding boxes and corresponding labels of GT or prediction.\n\n        Args:\n            image (np.ndarray): The image to draw.\n            instances (:obj:`InstanceData`): Data structure for\n                instance-level annotations or predictions.\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n        self.set_image(image)\n\n        if 'bboxes' in instances:\n            bboxes = instances.bboxes\n            self.draw_bboxes(\n                bboxes,\n                edge_colors=self.bbox_color,\n                alpha=self.alpha,\n                line_widths=self.line_width)\n        else:\n            return self.get_image()\n\n        if 'labels' in instances and self.text_color is not None:\n            classes = self.dataset_meta.get('classes', None)\n            labels = instances.labels\n\n            positions = bboxes[:, :2]\n            areas = (bboxes[:, 3] - bboxes[:, 1]) * (\n                bboxes[:, 2] - bboxes[:, 0])\n            scales = _get_adaptive_scales(areas)\n\n            for i, (pos, label) in enumerate(zip(positions, labels)):\n                label_text = classes[\n                    label] if classes is not None else f'class {label}'\n\n                if isinstance(self.bbox_color,\n                              tuple) and max(self.bbox_color) > 1:\n                    facecolor = [c / 255.0 for c in self.bbox_color]\n                else:\n                    facecolor = self.bbox_color\n\n                self.draw_texts(\n                    label_text,\n                    pos,\n                    colors=self.text_color,\n                    font_sizes=int(13 * scales[i]),\n                    vertical_alignments='bottom',\n                    bboxes=[{\n                        'facecolor': facecolor,\n                        'alpha': 0.8,\n                        'pad': 0.7,\n                        'edgecolor': 'none'\n                    }])\n\n        return self.get_image()\n\n    def _draw_instances_kpts(self,\n                             image: np.ndarray,\n                             instances: InstanceData,\n                             kpt_thr: float = 0.3,\n                             show_kpt_idx: bool = False,\n                             skeleton_style: str = 'mmpose'):\n        \"\"\"Draw keypoints and skeletons (optional) of GT or prediction.\n\n        Args:\n            image (np.ndarray): The image to draw.\n            instances (:obj:`InstanceData`): Data structure for\n                instance-level annotations or predictions.\n            kpt_thr (float, optional): Minimum threshold of keypoints\n                to be shown. Default: 0.3.\n            show_kpt_idx (bool): Whether to show the index of keypoints.\n                Defaults to ``False``\n            skeleton_style (str): Skeleton style selection. Defaults to\n                ``'mmpose'``\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n\n        if skeleton_style == 'openpose':\n            return self._draw_instances_kpts_openpose(image, instances,\n                                                      kpt_thr)\n\n        self.set_image(image)\n        img_h, img_w, _ = image.shape\n\n        if 'keypoints' in instances:\n            keypoints = instances.get('transformed_keypoints',\n                                      instances.keypoints)\n\n            if 'keypoints_visible' in instances:\n                keypoints_visible = instances.keypoints_visible\n            else:\n                keypoints_visible = np.ones(keypoints.shape[:-1])\n\n            for kpts, visible in zip(keypoints, keypoints_visible):\n                kpts = np.array(kpts, copy=False)\n\n                if self.kpt_color is None or isinstance(self.kpt_color, str):\n                    kpt_color = [self.kpt_color] * len(kpts)\n                elif len(self.kpt_color) == len(kpts):\n                    kpt_color = self.kpt_color\n                else:\n                    raise ValueError(\n                        f'the length of kpt_color '\n                        f'({len(self.kpt_color)}) does not matches '\n                        f'that of keypoints ({len(kpts)})')\n\n                # draw links\n                if self.skeleton is not None and self.link_color is not None:\n                    if self.link_color is None or isinstance(\n                            self.link_color, str):\n                        link_color = [self.link_color] * len(self.skeleton)\n                    elif len(self.link_color) == len(self.skeleton):\n                        link_color = self.link_color\n                    else:\n                        raise ValueError(\n                            f'the length of link_color '\n                            f'({len(self.link_color)}) does not matches '\n                            f'that of skeleton ({len(self.skeleton)})')\n\n                    for sk_id, sk in enumerate(self.skeleton):\n                        pos1 = (int(kpts[sk[0], 0]), int(kpts[sk[0], 1]))\n                        pos2 = (int(kpts[sk[1], 0]), int(kpts[sk[1], 1]))\n\n                        if (pos1[0] <= 0 or pos1[0] >= img_w or pos1[1] <= 0\n                                or pos1[1] >= img_h or pos2[0] <= 0\n                                or pos2[0] >= img_w or pos2[1] <= 0\n                                or pos2[1] >= img_h or visible[sk[0]] < kpt_thr\n                                or visible[sk[1]] < kpt_thr\n                                or link_color[sk_id] is None):\n                            # skip the link that should not be drawn\n                            continue\n\n                        X = np.array((pos1[0], pos2[0]))\n                        Y = np.array((pos1[1], pos2[1]))\n                        color = link_color[sk_id]\n                        if not isinstance(color, str):\n                            color = tuple(int(c) for c in color)\n                        transparency = self.alpha\n                        if self.show_keypoint_weight:\n                            transparency *= max(\n                                0,\n                                min(1,\n                                    0.5 * (visible[sk[0]] + visible[sk[1]])))\n\n                        self.draw_lines(\n                            X, Y, color, line_widths=self.line_width)\n\n                # draw each point on image\n                for kid, kpt in enumerate(kpts):\n                    if visible[kid] < kpt_thr or kpt_color[kid] is None:\n                        # skip the point that should not be drawn\n                        continue\n\n                    color = kpt_color[kid]\n                    if not isinstance(color, str):\n                        color = tuple(int(c) for c in color)\n                    transparency = self.alpha\n                    if self.show_keypoint_weight:\n                        transparency *= max(0, min(1, visible[kid]))\n                    self.draw_circles(\n                        kpt,\n                        radius=np.array([self.radius]),\n                        face_colors=color,\n                        edge_colors=color,\n                        alpha=transparency,\n                        line_widths=self.radius)\n                    if show_kpt_idx:\n                        kpt_idx_coords = kpt + [self.radius, -self.radius]\n                        self.draw_texts(\n                            str(kid),\n                            kpt_idx_coords,\n                            colors=color,\n                            font_sizes=self.radius * 3,\n                            vertical_alignments='bottom',\n                            horizontal_alignments='center')\n\n        return self.get_image()\n\n    def _draw_instances_kpts_openpose(self,\n                                      image: np.ndarray,\n                                      instances: InstanceData,\n                                      kpt_thr: float = 0.3):\n        \"\"\"Draw keypoints and skeletons (optional) of GT or prediction in\n        openpose style.\n\n        Args:\n            image (np.ndarray): The image to draw.\n            instances (:obj:`InstanceData`): Data structure for\n                instance-level annotations or predictions.\n            kpt_thr (float, optional): Minimum threshold of keypoints\n                to be shown. Default: 0.3.\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n\n        self.set_image(image)\n        img_h, img_w, _ = image.shape\n\n        if 'keypoints' in instances:\n            keypoints = instances.get('transformed_keypoints',\n                                      instances.keypoints)\n\n            if 'keypoints_visible' in instances:\n                keypoints_visible = instances.keypoints_visible\n            else:\n                keypoints_visible = np.ones(keypoints.shape[:-1])\n\n            keypoints_info = np.concatenate(\n                (keypoints, keypoints_visible[..., None]), axis=-1)\n            # compute neck joint\n            neck = np.mean(keypoints_info[:, [5, 6]], axis=1)\n            # neck score when visualizing pred\n            neck[:, 2:3] = np.logical_and(\n                keypoints_info[:, 5, 2:3] > kpt_thr,\n                keypoints_info[:, 6, 2:3] > kpt_thr).astype(int)\n            new_keypoints_info = np.insert(keypoints_info, 17, neck, axis=1)\n\n            mmpose_idx = [17, 6, 8, 10, 7, 9, 12, 14, 16, 13, 15, 2, 1, 4, 3]\n            openpose_idx = [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17]\n            new_keypoints_info[:, openpose_idx] = \\\n                new_keypoints_info[:, mmpose_idx]\n            keypoints_info = new_keypoints_info\n\n            keypoints, keypoints_visible = keypoints_info[\n                ..., :2], keypoints_info[..., 2]\n\n            for kpts, visible in zip(keypoints, keypoints_visible):\n                kpts = np.array(kpts, copy=False)\n\n                if self.kpt_color is None or isinstance(self.kpt_color, str):\n                    kpt_color = [self.kpt_color] * len(kpts)\n                elif len(self.kpt_color) == len(kpts):\n                    kpt_color = self.kpt_color\n                else:\n                    raise ValueError(\n                        f'the length of kpt_color '\n                        f'({len(self.kpt_color)}) does not matches '\n                        f'that of keypoints ({len(kpts)})')\n\n                # draw links\n                if self.skeleton is not None and self.link_color is not None:\n                    if self.link_color is None or isinstance(\n                            self.link_color, str):\n                        link_color = [self.link_color] * len(self.skeleton)\n                    elif len(self.link_color) == len(self.skeleton):\n                        link_color = self.link_color\n                    else:\n                        raise ValueError(\n                            f'the length of link_color '\n                            f'({len(self.link_color)}) does not matches '\n                            f'that of skeleton ({len(self.skeleton)})')\n\n                    for sk_id, sk in enumerate(self.skeleton):\n                        pos1 = (int(kpts[sk[0], 0]), int(kpts[sk[0], 1]))\n                        pos2 = (int(kpts[sk[1], 0]), int(kpts[sk[1], 1]))\n\n                        if (pos1[0] <= 0 or pos1[0] >= img_w or pos1[1] <= 0\n                                or pos1[1] >= img_h or pos2[0] <= 0\n                                or pos2[0] >= img_w or pos2[1] <= 0\n                                or pos2[1] >= img_h or visible[sk[0]] < kpt_thr\n                                or visible[sk[1]] < kpt_thr\n                                or link_color[sk_id] is None):\n                            # skip the link that should not be drawn\n                            continue\n\n                        X = np.array((pos1[0], pos2[0]))\n                        Y = np.array((pos1[1], pos2[1]))\n                        color = link_color[sk_id]\n                        if not isinstance(color, str):\n                            color = tuple(int(c) for c in color)\n                        transparency = self.alpha\n                        if self.show_keypoint_weight:\n                            transparency *= max(\n                                0,\n                                min(1,\n                                    0.5 * (visible[sk[0]] + visible[sk[1]])))\n\n                        if sk_id <= 16:\n                            # body part\n                            mX = np.mean(X)\n                            mY = np.mean(Y)\n                            length = ((Y[0] - Y[1])**2 + (X[0] - X[1])**2)**0.5\n                            transparency = 0.6\n                            angle = math.degrees(\n                                math.atan2(Y[0] - Y[1], X[0] - X[1]))\n                            polygons = cv2.ellipse2Poly(\n                                (int(mX), int(mY)),\n                                (int(length / 2), int(self.line_width)),\n                                int(angle), 0, 360, 1)\n\n                            self.draw_polygons(\n                                polygons,\n                                edge_colors=color,\n                                face_colors=color,\n                                alpha=transparency)\n\n                        else:\n                            # hand part\n                            self.draw_lines(X, Y, color, line_widths=2)\n\n                # draw each point on image\n                for kid, kpt in enumerate(kpts):\n                    if visible[kid] < kpt_thr or kpt_color[\n                            kid] is None or kpt_color[kid].sum() == 0:\n                        # skip the point that should not be drawn\n                        continue\n\n                    color = kpt_color[kid]\n                    if not isinstance(color, str):\n                        color = tuple(int(c) for c in color)\n                    transparency = self.alpha\n                    if self.show_keypoint_weight:\n                        transparency *= max(0, min(1, visible[kid]))\n\n                    # draw smaller dots for face & hand keypoints\n                    radius = self.radius // 2 if kid > 17 else self.radius\n\n                    self.draw_circles(\n                        kpt,\n                        radius=np.array([radius]),\n                        face_colors=color,\n                        edge_colors=color,\n                        alpha=transparency,\n                        line_widths=radius)\n\n        return self.get_image()\n\n    def _draw_instance_heatmap(\n        self,\n        fields: PixelData,\n        overlaid_image: Optional[np.ndarray] = None,\n    ):\n        \"\"\"Draw heatmaps of GT or prediction.\n\n        Args:\n            fields (:obj:`PixelData`): Data structure for\n                pixel-level annotations or predictions.\n            overlaid_image (np.ndarray): The image to draw.\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n        if 'heatmaps' not in fields:\n            return None\n        heatmaps = fields.heatmaps\n        if isinstance(heatmaps, np.ndarray):\n            heatmaps = torch.from_numpy(heatmaps)\n        if heatmaps.dim() == 3:\n            heatmaps, _ = heatmaps.max(dim=0)\n        heatmaps = heatmaps.unsqueeze(0)\n        out_image = self.draw_featmap(heatmaps, overlaid_image)\n        return out_image\n\n    def _draw_instance_xy_heatmap(\n        self,\n        fields: PixelData,\n        overlaid_image: Optional[np.ndarray] = None,\n        n: int = 20,\n    ):\n        \"\"\"Draw heatmaps of GT or prediction.\n\n        Args:\n            fields (:obj:`PixelData`): Data structure for\n            pixel-level annotations or predictions.\n            overlaid_image (np.ndarray): The image to draw.\n            n (int): Number of keypoint, up to 20.\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n        if 'heatmaps' not in fields:\n            return None\n        heatmaps = fields.heatmaps\n        _, h, w = heatmaps.shape\n        if isinstance(heatmaps, np.ndarray):\n            heatmaps = torch.from_numpy(heatmaps)\n        out_image = SimCCVisualizer().draw_instance_xy_heatmap(\n            heatmaps, overlaid_image, n)\n        out_image = cv2.resize(out_image[:, :, ::-1], (w, h))\n        return out_image\n\n    @master_only\n    def add_datasample(self,\n                       name: str,\n                       image: np.ndarray,\n                       data_sample: PoseDataSample,\n                       draw_gt: bool = True,\n                       draw_pred: bool = True,\n                       draw_heatmap: bool = False,\n                       draw_bbox: bool = False,\n                       show_kpt_idx: bool = False,\n                       skeleton_style: str = 'mmpose',\n                       show: bool = False,\n                       wait_time: float = 0,\n                       out_file: Optional[str] = None,\n                       kpt_thr: float = 0.3,\n                       step: int = 0) -> None:\n        \"\"\"Draw datasample and save to all backends.\n\n        - If GT and prediction are plotted at the same time, they are\n        displayed in a stitched image where the left image is the\n        ground truth and the right image is the prediction.\n        - If ``show`` is True, all storage backends are ignored, and\n        the images will be displayed in a local window.\n        - If ``out_file`` is specified, the drawn image will be\n        saved to ``out_file``. t is usually used when the display\n        is not available.\n\n        Args:\n            name (str): The image identifier\n            image (np.ndarray): The image to draw\n            data_sample (:obj:`PoseDataSample`, optional): The data sample\n                to visualize\n            draw_gt (bool): Whether to draw GT PoseDataSample. Default to\n                ``True``\n            draw_pred (bool): Whether to draw Prediction PoseDataSample.\n                Defaults to ``True``\n            draw_bbox (bool): Whether to draw bounding boxes. Default to\n                ``False``\n            draw_heatmap (bool): Whether to draw heatmaps. Defaults to\n                ``False``\n            show_kpt_idx (bool): Whether to show the index of keypoints.\n                Defaults to ``False``\n            skeleton_style (str): Skeleton style selection. Defaults to\n                ``'mmpose'``\n            show (bool): Whether to display the drawn image. Default to\n                ``False``\n            wait_time (float): The interval of show (s). Defaults to 0\n            out_file (str): Path to output file. Defaults to ``None``\n            kpt_thr (float, optional): Minimum threshold of keypoints\n                to be shown. Default: 0.3.\n            step (int): Global step value to record. Defaults to 0\n        \"\"\"\n\n        gt_img_data = None\n        pred_img_data = None\n\n        if draw_gt:\n            gt_img_data = image.copy()\n            gt_img_heatmap = None\n\n            # draw bboxes & keypoints\n            if 'gt_instances' in data_sample:\n                gt_img_data = self._draw_instances_kpts(\n                    gt_img_data, data_sample.gt_instances, kpt_thr,\n                    show_kpt_idx, skeleton_style)\n                if draw_bbox:\n                    gt_img_data = self._draw_instances_bbox(\n                        gt_img_data, data_sample.gt_instances)\n\n            # draw heatmaps\n            if 'gt_fields' in data_sample and draw_heatmap:\n                gt_img_heatmap = self._draw_instance_heatmap(\n                    data_sample.gt_fields, image)\n                if gt_img_heatmap is not None:\n                    gt_img_data = np.concatenate((gt_img_data, gt_img_heatmap),\n                                                 axis=0)\n\n        if draw_pred:\n            pred_img_data = image.copy()\n            pred_img_heatmap = None\n\n            # draw bboxes & keypoints\n            if 'pred_instances' in data_sample:\n                pred_img_data = self._draw_instances_kpts(\n                    pred_img_data, data_sample.pred_instances, kpt_thr,\n                    show_kpt_idx, skeleton_style)\n                if draw_bbox:\n                    pred_img_data = self._draw_instances_bbox(\n                        pred_img_data, data_sample.pred_instances)\n\n            # draw heatmaps\n            if 'pred_fields' in data_sample and draw_heatmap:\n                if 'keypoint_x_labels' in data_sample.pred_instances:\n                    pred_img_heatmap = self._draw_instance_xy_heatmap(\n                        data_sample.pred_fields, image)\n                else:\n                    pred_img_heatmap = self._draw_instance_heatmap(\n                        data_sample.pred_fields, image)\n                if pred_img_heatmap is not None:\n                    pred_img_data = np.concatenate(\n                        (pred_img_data, pred_img_heatmap), axis=0)\n\n        # merge visualization results\n        if gt_img_data is not None and pred_img_data is not None:\n            if gt_img_heatmap is None and pred_img_heatmap is not None:\n                gt_img_data = np.concatenate((gt_img_data, image), axis=0)\n            elif gt_img_heatmap is not None and pred_img_heatmap is None:\n                pred_img_data = np.concatenate((pred_img_data, image), axis=0)\n\n            drawn_img = np.concatenate((gt_img_data, pred_img_data), axis=1)\n\n        elif gt_img_data is not None:\n            drawn_img = gt_img_data\n        else:\n            drawn_img = pred_img_data\n\n        # It is convenient for users to obtain the drawn image.\n        # For example, the user wants to obtain the drawn image and\n        # save it as a video during video inference.\n        self.set_image(drawn_img)\n\n        if show:\n            self.show(drawn_img, win_name=name, wait_time=wait_time)\n\n        if out_file is not None:\n            mmcv.imwrite(drawn_img[..., ::-1], out_file)\n        else:\n            # save drawn_img to backends\n            self.add_image(name, drawn_img, step)\n\n        return self.get_image()\n"
  },
  {
    "path": "mmpose/visualization/local_visualizer_3d.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nfrom typing import Dict, List, Optional, Tuple, Union\n\nimport cv2\nimport mmcv\nimport numpy as np\nfrom matplotlib import pyplot as plt\nfrom mmengine.dist import master_only\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.apis import convert_keypoint_definition\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import PoseDataSample\nfrom . import PoseLocalVisualizer\n\n\n@VISUALIZERS.register_module()\nclass Pose3dLocalVisualizer(PoseLocalVisualizer):\n    \"\"\"MMPose 3d Local Visualizer.\n\n    Args:\n        name (str): Name of the instance. Defaults to 'visualizer'.\n        image (np.ndarray, optional): the origin image to draw. The format\n            should be RGB. Defaults to ``None``\n        vis_backends (list, optional): Visual backend config list. Defaults to\n            ``None``\n        save_dir (str, optional): Save file dir for all storage backends.\n            If it is ``None``, the backend storage will not save any data.\n            Defaults to ``None``\n        bbox_color (str, tuple(int), optional): Color of bbox lines.\n            The tuple of color should be in BGR order. Defaults to ``'green'``\n        kpt_color (str, tuple(tuple(int)), optional): Color of keypoints.\n            The tuple of color should be in BGR order. Defaults to ``'red'``\n        link_color (str, tuple(tuple(int)), optional): Color of skeleton.\n            The tuple of color should be in BGR order. Defaults to ``None``\n        line_width (int, float): The width of lines. Defaults to 1\n        radius (int, float): The radius of keypoints. Defaults to 4\n        show_keypoint_weight (bool): Whether to adjust the transparency\n            of keypoints according to their score. Defaults to ``False``\n        alpha (int, float): The transparency of bboxes. Defaults to ``0.8``\n        det_kpt_color (str, tuple(tuple(int)), optional): Keypoints color\n             info for detection. Defaults to ``None``\n        det_dataset_skeleton (list): Skeleton info for detection. Defaults to\n            ``None``\n        det_dataset_link_color (list): Link color for detection. Defaults to\n            ``None``\n    \"\"\"\n\n    def __init__(\n            self,\n            name: str = 'visualizer',\n            image: Optional[np.ndarray] = None,\n            vis_backends: Optional[Dict] = None,\n            save_dir: Optional[str] = None,\n            bbox_color: Optional[Union[str, Tuple[int]]] = 'green',\n            kpt_color: Optional[Union[str, Tuple[Tuple[int]]]] = 'red',\n            link_color: Optional[Union[str, Tuple[Tuple[int]]]] = None,\n            text_color: Optional[Union[str, Tuple[int]]] = (255, 255, 255),\n            skeleton: Optional[Union[List, Tuple]] = None,\n            line_width: Union[int, float] = 1,\n            radius: Union[int, float] = 3,\n            show_keypoint_weight: bool = False,\n            backend: str = 'opencv',\n            alpha: float = 0.8,\n            det_kpt_color: Optional[Union[str, Tuple[Tuple[int]]]] = None,\n            det_dataset_skeleton: Optional[Union[str,\n                                                 Tuple[Tuple[int]]]] = None,\n            det_dataset_link_color: Optional[np.ndarray] = None):\n        super().__init__(name, image, vis_backends, save_dir, bbox_color,\n                         kpt_color, link_color, text_color, skeleton,\n                         line_width, radius, show_keypoint_weight, backend,\n                         alpha)\n        self.det_kpt_color = det_kpt_color\n        self.det_dataset_skeleton = det_dataset_skeleton\n        self.det_dataset_link_color = det_dataset_link_color\n\n    def _draw_3d_data_samples(self,\n                              image: np.ndarray,\n                              pose_samples: PoseDataSample,\n                              draw_gt: bool = True,\n                              kpt_thr: float = 0.3,\n                              num_instances=-1,\n                              axis_azimuth: float = 70,\n                              axis_limit: float = 1.7,\n                              axis_dist: float = 10.0,\n                              axis_elev: float = 15.0,\n                              show_kpt_idx: bool = False,\n                              scores_2d: Optional[np.ndarray] = None):\n        \"\"\"Draw keypoints and skeletons (optional) of GT or prediction.\n\n        Args:\n            image (np.ndarray): The image to draw.\n            instances (:obj:`InstanceData`): Data structure for\n                instance-level annotations or predictions.\n            draw_gt (bool): Whether to draw GT PoseDataSample. Default to\n                ``True``\n            kpt_thr (float, optional): Minimum threshold of keypoints\n                to be shown. Default: 0.3.\n            num_instances (int): Number of instances to be shown in 3D. If\n                smaller than 0, all the instances in the pose_result will be\n                shown. Otherwise, pad or truncate the pose_result to a length\n                of num_instances.\n            axis_azimuth (float): axis azimuth angle for 3D visualizations.\n            axis_dist (float): axis distance for 3D visualizations.\n            axis_elev (float): axis elevation view angle for 3D visualizations.\n            axis_limit (float): The axis limit to visualize 3d pose. The xyz\n                range will be set as:\n                - x: [x_c - axis_limit/2, x_c + axis_limit/2]\n                - y: [y_c - axis_limit/2, y_c + axis_limit/2]\n                - z: [0, axis_limit]\n                Where x_c, y_c is the mean value of x and y coordinates\n            show_kpt_idx (bool): Whether to show the index of keypoints.\n                Defaults to ``False``\n            scores_2d (np.ndarray, optional): Keypoint scores of 2d estimation\n                that will be used to filter 3d instances.\n\n        Returns:\n            Tuple(np.ndarray): the drawn image which channel is RGB.\n        \"\"\"\n        vis_width = max(image.shape)\n        vis_height = vis_width\n\n        if 'pred_instances' in pose_samples:\n            pred_instances = pose_samples.pred_instances\n        else:\n            pred_instances = InstanceData()\n        if num_instances < 0:\n            if 'keypoints' in pred_instances:\n                num_instances = len(pred_instances)\n            else:\n                num_instances = 0\n        else:\n            if len(pred_instances) > num_instances:\n                pred_instances_ = InstanceData()\n                for k in pred_instances.keys():\n                    new_val = pred_instances[k][:num_instances]\n                    pred_instances_.set_field(new_val, k)\n                pred_instances = pred_instances_\n            elif num_instances < len(pred_instances):\n                num_instances = len(pred_instances)\n\n        num_fig = num_instances\n        if draw_gt:\n            vis_width *= 2\n            num_fig *= 2\n\n        plt.ioff()\n        fig = plt.figure(\n            figsize=(vis_width * num_instances * 0.01, vis_height * 0.01))\n\n        def _draw_3d_instances_kpts(keypoints,\n                                    scores,\n                                    scores_2d,\n                                    keypoints_visible,\n                                    fig_idx,\n                                    show_kpt_idx,\n                                    title=None):\n\n            for idx, (kpts, score, score_2d) in enumerate(\n                    zip(keypoints, scores, scores_2d)):\n\n                valid = np.logical_and(score >= kpt_thr, score_2d >= kpt_thr,\n                                       np.any(~np.isnan(kpts), axis=-1))\n\n                kpts_valid = kpts[valid]\n                ax = fig.add_subplot(\n                    1, num_fig, fig_idx * (idx + 1), projection='3d')\n                ax.view_init(elev=axis_elev, azim=axis_azimuth)\n                ax.set_aspect('auto')\n                ax.set_xticks([])\n                ax.set_yticks([])\n                ax.set_zticks([])\n                ax.set_xticklabels([])\n                ax.set_yticklabels([])\n                ax.set_zticklabels([])\n                if title:\n                    ax.set_title(f'{title} ({idx})')\n                ax.dist = axis_dist\n\n                x_c = np.mean(kpts_valid[:, 0]) if valid.any() else 0\n                y_c = np.mean(kpts_valid[:, 1]) if valid.any() else 0\n                z_c = np.mean(kpts_valid[:, 2]) if valid.any() else 0\n\n                ax.set_xlim3d([x_c - axis_limit / 2, x_c + axis_limit / 2])\n                ax.set_ylim3d([y_c - axis_limit / 2, y_c + axis_limit / 2])\n                ax.set_zlim3d(\n                    [min(0, z_c - axis_limit / 2), z_c + axis_limit / 2])\n\n                if self.kpt_color is None or isinstance(self.kpt_color, str):\n                    kpt_color = [self.kpt_color] * len(kpts)\n                elif len(self.kpt_color) == len(kpts):\n                    kpt_color = self.kpt_color\n                else:\n                    raise ValueError(\n                        f'the length of kpt_color '\n                        f'({len(self.kpt_color)}) does not matches '\n                        f'that of keypoints ({len(kpts)})')\n\n                x_3d, y_3d, z_3d = np.split(kpts_valid[:, :3], [1, 2], axis=1)\n\n                kpt_color = kpt_color[valid] / 255.\n\n                ax.scatter(x_3d, y_3d, z_3d, marker='o', c=kpt_color)\n\n                if show_kpt_idx:\n                    for kpt_idx in range(len(x_3d)):\n                        ax.text(x_3d[kpt_idx][0], y_3d[kpt_idx][0],\n                                z_3d[kpt_idx][0], str(kpt_idx))\n\n                if self.skeleton is not None and self.link_color is not None:\n                    if self.link_color is None or isinstance(\n                            self.link_color, str):\n                        link_color = [self.link_color] * len(self.skeleton)\n                    elif len(self.link_color) == len(self.skeleton):\n                        link_color = self.link_color\n                    else:\n                        raise ValueError(\n                            f'the length of link_color '\n                            f'({len(self.link_color)}) does not matches '\n                            f'that of skeleton ({len(self.skeleton)})')\n\n                    for sk_id, sk in enumerate(self.skeleton):\n                        sk_indices = [_i for _i in sk]\n                        xs_3d = kpts[sk_indices, 0]\n                        ys_3d = kpts[sk_indices, 1]\n                        zs_3d = kpts[sk_indices, 2]\n                        kpt_score = score[sk_indices]\n                        kpt_score_2d = score_2d[sk_indices]\n                        if kpt_score.min() > kpt_thr and kpt_score_2d.min(\n                        ) > kpt_thr:\n                            # matplotlib uses RGB color in [0, 1] value range\n                            _color = link_color[sk_id] / 255.\n                            ax.plot(\n                                xs_3d, ys_3d, zs_3d, color=_color, zdir='z')\n\n        if 'keypoints' in pred_instances:\n            keypoints = pred_instances.get('keypoints',\n                                           pred_instances.keypoints)\n\n            if 'keypoint_scores' in pred_instances:\n                scores = pred_instances.keypoint_scores\n            else:\n                scores = np.ones(keypoints.shape[:-1])\n\n            if scores_2d is None:\n                scores_2d = np.ones(keypoints.shape[:-1])\n\n            if 'keypoints_visible' in pred_instances:\n                keypoints_visible = pred_instances.keypoints_visible\n            else:\n                keypoints_visible = np.ones(keypoints.shape[:-1])\n\n            _draw_3d_instances_kpts(keypoints, scores, scores_2d,\n                                    keypoints_visible, 1, show_kpt_idx,\n                                    'Prediction')\n\n        if draw_gt and 'gt_instances' in pose_samples:\n            gt_instances = pose_samples.gt_instances\n            if 'lifting_target' in gt_instances:\n                keypoints = gt_instances.get('lifting_target',\n                                             gt_instances.lifting_target)\n                scores = np.ones(keypoints.shape[:-1])\n\n                if 'lifting_target_visible' in gt_instances:\n                    keypoints_visible = gt_instances.lifting_target_visible\n                else:\n                    keypoints_visible = np.ones(keypoints.shape[:-1])\n            elif 'keypoints_gt' in gt_instances:\n                keypoints = gt_instances.get('keypoints_gt',\n                                             gt_instances.keypoints_gt)\n                scores = np.ones(keypoints.shape[:-1])\n\n                if 'keypoints_visible' in gt_instances:\n                    keypoints_visible = gt_instances.keypoints_visible\n                else:\n                    keypoints_visible = np.ones(keypoints.shape[:-1])\n            else:\n                raise ValueError('to visualize ground truth results, '\n                                 'data sample must contain '\n                                 '\"lifting_target\" or \"keypoints_gt\"')\n\n            if scores_2d is None:\n                scores_2d = np.ones(keypoints.shape[:-1])\n\n            _draw_3d_instances_kpts(keypoints, scores, scores_2d,\n                                    keypoints_visible, 2, show_kpt_idx,\n                                    'Ground Truth')\n\n        # convert figure to numpy array\n        fig.tight_layout()\n        fig.canvas.draw()\n\n        pred_img_data = np.frombuffer(\n            fig.canvas.tostring_rgb(), dtype=np.uint8)\n\n        if not pred_img_data.any():\n            pred_img_data = np.full((vis_height, vis_width, 3), 255)\n        else:\n            width, height = fig.get_size_inches() * fig.get_dpi()\n            pred_img_data = pred_img_data.reshape(\n                int(height),\n                int(width) * num_instances, 3)\n\n        plt.close(fig)\n\n        return pred_img_data\n\n    def _draw_instances_kpts(self,\n                             image: np.ndarray,\n                             instances: InstanceData,\n                             kpt_thr: float = 0.3,\n                             show_kpt_idx: bool = False,\n                             skeleton_style: str = 'mmpose'):\n        \"\"\"Draw keypoints and skeletons (optional) of GT or prediction.\n\n        Args:\n            image (np.ndarray): The image to draw.\n            instances (:obj:`InstanceData`): Data structure for\n                instance-level annotations or predictions.\n            kpt_thr (float, optional): Minimum threshold of keypoints\n                to be shown. Default: 0.3.\n            show_kpt_idx (bool): Whether to show the index of keypoints.\n                Defaults to ``False``\n            skeleton_style (str): Skeleton style selection. Defaults to\n                ``'mmpose'``\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n\n        self.set_image(image)\n        img_h, img_w, _ = image.shape\n        scores = None\n\n        if 'keypoints' in instances:\n            keypoints = instances.get('transformed_keypoints',\n                                      instances.keypoints)\n\n            if 'keypoint_scores' in instances:\n                scores = instances.keypoint_scores\n            else:\n                scores = np.ones(keypoints.shape[:-1])\n\n            if 'keypoints_visible' in instances:\n                keypoints_visible = instances.keypoints_visible\n            else:\n                keypoints_visible = np.ones(keypoints.shape[:-1])\n\n            if skeleton_style == 'openpose':\n                keypoints_info = np.concatenate(\n                    (keypoints, scores[..., None], keypoints_visible[...,\n                                                                     None]),\n                    axis=-1)\n                # compute neck joint\n                neck = np.mean(keypoints_info[:, [5, 6]], axis=1)\n                # neck score when visualizing pred\n                neck[:, 2:4] = np.logical_and(\n                    keypoints_info[:, 5, 2:4] > kpt_thr,\n                    keypoints_info[:, 6, 2:4] > kpt_thr).astype(int)\n                new_keypoints_info = np.insert(\n                    keypoints_info, 17, neck, axis=1)\n\n                mmpose_idx = [\n                    17, 6, 8, 10, 7, 9, 12, 14, 16, 13, 15, 2, 1, 4, 3\n                ]\n                openpose_idx = [\n                    1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17\n                ]\n                new_keypoints_info[:, openpose_idx] = \\\n                    new_keypoints_info[:, mmpose_idx]\n                keypoints_info = new_keypoints_info\n\n                keypoints, scores, keypoints_visible = keypoints_info[\n                    ..., :2], keypoints_info[..., 2], keypoints_info[..., 3]\n\n            kpt_color = self.kpt_color\n            if self.det_kpt_color is not None:\n                kpt_color = self.det_kpt_color\n\n            for kpts, score, visible in zip(keypoints, scores,\n                                            keypoints_visible):\n                kpts = np.array(kpts[..., :2], copy=False)\n\n                if kpt_color is None or isinstance(kpt_color, str):\n                    kpt_color = [kpt_color] * len(kpts)\n                elif len(kpt_color) == len(kpts):\n                    kpt_color = kpt_color\n                else:\n                    raise ValueError(f'the length of kpt_color '\n                                     f'({len(kpt_color)}) does not matches '\n                                     f'that of keypoints ({len(kpts)})')\n\n                # draw each point on image\n                for kid, kpt in enumerate(kpts):\n                    if score[kid] < kpt_thr or not visible[\n                            kid] or kpt_color[kid] is None:\n                        # skip the point that should not be drawn\n                        continue\n\n                    color = kpt_color[kid]\n                    if not isinstance(color, str):\n                        color = tuple(int(c) for c in color)\n                    transparency = self.alpha\n                    if self.show_keypoint_weight:\n                        transparency *= max(0, min(1, score[kid]))\n                    self.draw_circles(\n                        kpt,\n                        radius=np.array([self.radius]),\n                        face_colors=color,\n                        edge_colors=color,\n                        alpha=transparency,\n                        line_widths=self.radius)\n                    if show_kpt_idx:\n                        self.draw_texts(\n                            str(kid),\n                            kpt,\n                            colors=color,\n                            font_sizes=self.radius * 3,\n                            vertical_alignments='bottom',\n                            horizontal_alignments='center')\n\n                # draw links\n                skeleton = self.skeleton\n                if self.det_dataset_skeleton is not None:\n                    skeleton = self.det_dataset_skeleton\n                link_color = self.link_color\n                if self.det_dataset_link_color is not None:\n                    link_color = self.det_dataset_link_color\n                if skeleton is not None and link_color is not None:\n                    if link_color is None or isinstance(link_color, str):\n                        link_color = [link_color] * len(skeleton)\n                    elif len(link_color) == len(skeleton):\n                        link_color = link_color\n                    else:\n                        raise ValueError(\n                            f'the length of link_color '\n                            f'({len(link_color)}) does not matches '\n                            f'that of skeleton ({len(skeleton)})')\n\n                    for sk_id, sk in enumerate(skeleton):\n                        pos1 = (int(kpts[sk[0], 0]), int(kpts[sk[0], 1]))\n                        pos2 = (int(kpts[sk[1], 0]), int(kpts[sk[1], 1]))\n                        if not (visible[sk[0]] and visible[sk[1]]):\n                            continue\n\n                        if (pos1[0] <= 0 or pos1[0] >= img_w or pos1[1] <= 0\n                                or pos1[1] >= img_h or pos2[0] <= 0\n                                or pos2[0] >= img_w or pos2[1] <= 0\n                                or pos2[1] >= img_h or score[sk[0]] < kpt_thr\n                                or score[sk[1]] < kpt_thr\n                                or link_color[sk_id] is None):\n                            # skip the link that should not be drawn\n                            continue\n                        X = np.array((pos1[0], pos2[0]))\n                        Y = np.array((pos1[1], pos2[1]))\n                        color = link_color[sk_id]\n                        if not isinstance(color, str):\n                            color = tuple(int(c) for c in color)\n                        transparency = self.alpha\n                        if self.show_keypoint_weight:\n                            transparency *= max(\n                                0, min(1, 0.5 * (score[sk[0]] + score[sk[1]])))\n\n                        if skeleton_style == 'openpose':\n                            mX = np.mean(X)\n                            mY = np.mean(Y)\n                            length = ((Y[0] - Y[1])**2 + (X[0] - X[1])**2)**0.5\n                            angle = math.degrees(\n                                math.atan2(Y[0] - Y[1], X[0] - X[1]))\n                            stickwidth = 2\n                            polygons = cv2.ellipse2Poly(\n                                (int(mX), int(mY)),\n                                (int(length / 2), int(stickwidth)), int(angle),\n                                0, 360, 1)\n\n                            self.draw_polygons(\n                                polygons,\n                                edge_colors=color,\n                                face_colors=color,\n                                alpha=transparency)\n\n                        else:\n                            self.draw_lines(\n                                X, Y, color, line_widths=self.line_width)\n\n        return self.get_image(), scores\n\n    @master_only\n    def add_datasample(self,\n                       name: str,\n                       image: np.ndarray,\n                       data_sample: PoseDataSample,\n                       det_data_sample: Optional[PoseDataSample] = None,\n                       draw_gt: bool = True,\n                       draw_pred: bool = True,\n                       draw_2d: bool = True,\n                       draw_bbox: bool = False,\n                       show_kpt_idx: bool = False,\n                       skeleton_style: str = 'mmpose',\n                       dataset_2d: str = 'coco',\n                       dataset_3d: str = 'h36m',\n                       convert_keypoint: bool = True,\n                       axis_azimuth: float = 70,\n                       axis_limit: float = 1.7,\n                       axis_dist: float = 10.0,\n                       axis_elev: float = 15.0,\n                       num_instances: int = -1,\n                       show: bool = False,\n                       wait_time: float = 0,\n                       out_file: Optional[str] = None,\n                       kpt_thr: float = 0.3,\n                       step: int = 0) -> None:\n        \"\"\"Draw datasample and save to all backends.\n\n        - If GT and prediction are plotted at the same time, they are\n        displayed in a stitched image where the left image is the\n        ground truth and the right image is the prediction.\n        - If ``show`` is True, all storage backends are ignored, and\n        the images will be displayed in a local window.\n        - If ``out_file`` is specified, the drawn image will be\n        saved to ``out_file``. t is usually used when the display\n        is not available.\n\n        Args:\n            name (str): The image identifier\n            image (np.ndarray): The image to draw\n            data_sample (:obj:`PoseDataSample`): The 3d data sample\n                to visualize\n            det_data_sample (:obj:`PoseDataSample`, optional): The 2d detection\n                data sample to visualize\n            draw_gt (bool): Whether to draw GT PoseDataSample. Default to\n                ``True``\n            draw_pred (bool): Whether to draw Prediction PoseDataSample.\n                Defaults to ``True``\n            draw_2d (bool): Whether to draw 2d detection results. Defaults to\n                ``True``\n            draw_bbox (bool): Whether to draw bounding boxes. Default to\n                ``False``\n            show_kpt_idx (bool): Whether to show the index of keypoints.\n                Defaults to ``False``\n            skeleton_style (str): Skeleton style selection. Defaults to\n                ``'mmpose'``\n            dataset_2d (str): Name of 2d keypoint dataset. Defaults to\n                ``'CocoDataset'``\n            dataset_3d (str): Name of 3d keypoint dataset. Defaults to\n                ``'Human36mDataset'``\n            convert_keypoint (bool): Whether to convert keypoint definition.\n                Defaults to ``True``\n            axis_azimuth (float): axis azimuth angle for 3D visualizations.\n            axis_dist (float): axis distance for 3D visualizations.\n            axis_elev (float): axis elevation view angle for 3D visualizations.\n            axis_limit (float): The axis limit to visualize 3d pose. The xyz\n                range will be set as:\n                - x: [x_c - axis_limit/2, x_c + axis_limit/2]\n                - y: [y_c - axis_limit/2, y_c + axis_limit/2]\n                - z: [0, axis_limit]\n                Where x_c, y_c is the mean value of x and y coordinates\n            num_instances (int): Number of instances to be shown in 3D. If\n                smaller than 0, all the instances in the pose_result will be\n                shown. Otherwise, pad or truncate the pose_result to a length\n                of num_instances. Defaults to -1\n            show (bool): Whether to display the drawn image. Default to\n                ``False``\n            wait_time (float): The interval of show (s). Defaults to 0\n            out_file (str): Path to output file. Defaults to ``None``\n            kpt_thr (float, optional): Minimum threshold of keypoints\n                to be shown. Default: 0.3.\n            step (int): Global step value to record. Defaults to 0\n        \"\"\"\n\n        det_img_data = None\n        scores_2d = None\n\n        if draw_2d:\n            det_img_data = image.copy()\n\n            # draw bboxes & keypoints\n            if (det_data_sample is not None\n                    and 'pred_instances' in det_data_sample):\n                det_img_data, scores_2d = self._draw_instances_kpts(\n                    image=det_img_data,\n                    instances=det_data_sample.pred_instances,\n                    kpt_thr=kpt_thr,\n                    show_kpt_idx=show_kpt_idx,\n                    skeleton_style=skeleton_style)\n                if draw_bbox:\n                    det_img_data = self._draw_instances_bbox(\n                        det_img_data, det_data_sample.pred_instances)\n        if scores_2d is not None and convert_keypoint:\n            if scores_2d.ndim == 2:\n                scores_2d = scores_2d[..., None]\n            scores_2d = np.squeeze(\n                convert_keypoint_definition(scores_2d, dataset_2d, dataset_3d),\n                axis=-1)\n        pred_img_data = self._draw_3d_data_samples(\n            image.copy(),\n            data_sample,\n            draw_gt=draw_gt,\n            num_instances=num_instances,\n            axis_azimuth=axis_azimuth,\n            axis_limit=axis_limit,\n            show_kpt_idx=show_kpt_idx,\n            axis_dist=axis_dist,\n            axis_elev=axis_elev,\n            scores_2d=scores_2d)\n\n        # merge visualization results\n        if det_img_data is not None:\n            width = max(pred_img_data.shape[1] - det_img_data.shape[1], 0)\n            height = max(pred_img_data.shape[0] - det_img_data.shape[0], 0)\n            det_img_data = cv2.copyMakeBorder(\n                det_img_data,\n                height // 2,\n                (height // 2 + 1) if height % 2 == 1 else height // 2,\n                width // 2, (width // 2 + 1) if width % 2 == 1 else width // 2,\n                cv2.BORDER_CONSTANT,\n                value=(255, 255, 255))\n            drawn_img = np.concatenate((det_img_data, pred_img_data), axis=1)\n        else:\n            drawn_img = pred_img_data\n\n        # It is convenient for users to obtain the drawn image.\n        # For example, the user wants to obtain the drawn image and\n        # save it as a video during video inference.\n        self.set_image(drawn_img)\n\n        if show:\n            self.show(drawn_img, win_name=name, wait_time=wait_time)\n\n        if out_file is not None:\n            mmcv.imwrite(drawn_img[..., ::-1], out_file)\n        else:\n            # save drawn_img to backends\n            self.add_image(name, drawn_img, step)\n\n        return self.get_image()\n"
  },
  {
    "path": "mmpose/visualization/opencv_backend_visualizer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Optional, Union\n\nimport cv2\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmengine.dist import master_only\nfrom mmengine.visualization import Visualizer\n\n\nclass OpencvBackendVisualizer(Visualizer):\n    \"\"\"Base visualizer with opencv backend support.\n\n    Args:\n        name (str): Name of the instance. Defaults to 'visualizer'.\n        image (np.ndarray, optional): the origin image to draw. The format\n            should be RGB. Defaults to None.\n        vis_backends (list, optional): Visual backend config list.\n            Defaults to None.\n        save_dir (str, optional): Save file dir for all storage backends.\n            If it is None, the backend storage will not save any data.\n        fig_save_cfg (dict): Keyword parameters of figure for saving.\n            Defaults to empty dict.\n        fig_show_cfg (dict): Keyword parameters of figure for showing.\n            Defaults to empty dict.\n        backend (str): Backend used to draw elements on the image and display\n            the image. Defaults to 'matplotlib'.\n        alpha (int, float): The transparency of bboxes. Defaults to ``1.0``\n    \"\"\"\n\n    def __init__(self,\n                 name='visualizer',\n                 backend: str = 'matplotlib',\n                 *args,\n                 **kwargs):\n        super().__init__(name, *args, **kwargs)\n        assert backend in ('opencv', 'matplotlib'), f'the argument ' \\\n            f'\\'backend\\' must be either \\'opencv\\' or \\'matplotlib\\', ' \\\n            f'but got \\'{backend}\\'.'\n        self.backend = backend\n\n    @master_only\n    def set_image(self, image: np.ndarray) -> None:\n        \"\"\"Set the image to draw.\n\n        Args:\n            image (np.ndarray): The image to draw.\n            backend (str): The backend to save the image.\n        \"\"\"\n        assert image is not None\n        image = image.astype('uint8')\n        self._image = image\n        self.width, self.height = image.shape[1], image.shape[0]\n        self._default_font_size = max(\n            np.sqrt(self.height * self.width) // 90, 10)\n\n        if self.backend == 'matplotlib':\n            # add a small 1e-2 to avoid precision lost due to matplotlib's\n            # truncation (https://github.com/matplotlib/matplotlib/issues/15363)  # noqa\n            self.fig_save.set_size_inches(  # type: ignore\n                (self.width + 1e-2) / self.dpi,\n                (self.height + 1e-2) / self.dpi)\n            # self.canvas = mpl.backends.backend_cairo.FigureCanvasCairo(fig)\n            self.ax_save.cla()\n            self.ax_save.axis(False)\n            self.ax_save.imshow(\n                image,\n                extent=(0, self.width, self.height, 0),\n                interpolation='none')\n\n    @master_only\n    def get_image(self) -> np.ndarray:\n        \"\"\"Get the drawn image. The format is RGB.\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n        assert self._image is not None, 'Please set image using `set_image`'\n        if self.backend == 'matplotlib':\n            return super().get_image()\n        else:\n            return self._image\n\n    @master_only\n    def draw_circles(self,\n                     center: Union[np.ndarray, torch.Tensor],\n                     radius: Union[np.ndarray, torch.Tensor],\n                     face_colors: Union[str, tuple, List[str],\n                                        List[tuple]] = 'none',\n                     alpha: float = 1.0,\n                     **kwargs) -> 'Visualizer':\n        \"\"\"Draw single or multiple circles.\n\n        Args:\n            center (Union[np.ndarray, torch.Tensor]): The x coordinate of\n                each line' start and end points.\n            radius (Union[np.ndarray, torch.Tensor]): The y coordinate of\n                each line' start and end points.\n            edge_colors (Union[str, tuple, List[str], List[tuple]]): The\n                colors of circles. ``colors`` can have the same length with\n                lines or just single value. If ``colors`` is single value,\n                all the lines will have the same colors. Reference to\n                https://matplotlib.org/stable/gallery/color/named_colors.html\n                for more details. Defaults to 'g.\n            line_styles (Union[str, List[str]]): The linestyle\n                of lines. ``line_styles`` can have the same length with\n                texts or just single value. If ``line_styles`` is single\n                value, all the lines will have the same linestyle.\n                Reference to\n                https://matplotlib.org/stable/api/collections_api.html?highlight=collection#matplotlib.collections.AsteriskPolygonCollection.set_linestyle\n                for more details. Defaults to '-'.\n            line_widths (Union[Union[int, float], List[Union[int, float]]]):\n                The linewidth of lines. ``line_widths`` can have\n                the same length with lines or just single value.\n                If ``line_widths`` is single value, all the lines will\n                have the same linewidth. Defaults to 2.\n            face_colors (Union[str, tuple, List[str], List[tuple]]):\n                The face colors. Defaults to None.\n            alpha (Union[int, float]): The transparency of circles.\n                Defaults to 0.8.\n        \"\"\"\n        if self.backend == 'matplotlib':\n            super().draw_circles(\n                center=center,\n                radius=radius,\n                face_colors=face_colors,\n                alpha=alpha,\n                **kwargs)\n        elif self.backend == 'opencv':\n            if isinstance(face_colors, str):\n                face_colors = mmcv.color_val(face_colors)[::-1]\n\n            if alpha == 1.0:\n                self._image = cv2.circle(self._image,\n                                         (int(center[0]), int(center[1])),\n                                         int(radius), face_colors, -1)\n            else:\n                img = cv2.circle(self._image.copy(),\n                                 (int(center[0]), int(center[1])), int(radius),\n                                 face_colors, -1)\n                self._image = cv2.addWeighted(self._image, 1 - alpha, img,\n                                              alpha, 0)\n        else:\n            raise ValueError(f'got unsupported backend {self.backend}')\n\n    @master_only\n    def draw_texts(\n        self,\n        texts: Union[str, List[str]],\n        positions: Union[np.ndarray, torch.Tensor],\n        font_sizes: Optional[Union[int, List[int]]] = None,\n        colors: Union[str, tuple, List[str], List[tuple]] = 'g',\n        vertical_alignments: Union[str, List[str]] = 'top',\n        horizontal_alignments: Union[str, List[str]] = 'left',\n        bboxes: Optional[Union[dict, List[dict]]] = None,\n        **kwargs,\n    ) -> 'Visualizer':\n        \"\"\"Draw single or multiple text boxes.\n\n        Args:\n            texts (Union[str, List[str]]): Texts to draw.\n            positions (Union[np.ndarray, torch.Tensor]): The position to draw\n                the texts, which should have the same length with texts and\n                each dim contain x and y.\n            font_sizes (Union[int, List[int]], optional): The font size of\n                texts. ``font_sizes`` can have the same length with texts or\n                just single value. If ``font_sizes`` is single value, all the\n                texts will have the same font size. Defaults to None.\n            colors (Union[str, tuple, List[str], List[tuple]]): The colors\n                of texts. ``colors`` can have the same length with texts or\n                just single value. If ``colors`` is single value, all the\n                texts will have the same colors. Reference to\n                https://matplotlib.org/stable/gallery/color/named_colors.html\n                for more details. Defaults to 'g.\n            vertical_alignments (Union[str, List[str]]): The verticalalignment\n                of texts. verticalalignment controls whether the y positional\n                argument for the text indicates the bottom, center or top side\n                of the text bounding box.\n                ``vertical_alignments`` can have the same length with\n                texts or just single value. If ``vertical_alignments`` is\n                single value, all the texts will have the same\n                verticalalignment. verticalalignment can be 'center' or\n                'top', 'bottom' or 'baseline'. Defaults to 'top'.\n            horizontal_alignments (Union[str, List[str]]): The\n                horizontalalignment of texts. Horizontalalignment controls\n                whether the x positional argument for the text indicates the\n                left, center or right side of the text bounding box.\n                ``horizontal_alignments`` can have\n                the same length with texts or just single value.\n                If ``horizontal_alignments`` is single value, all the texts\n                will have the same horizontalalignment. Horizontalalignment\n                can be 'center','right' or 'left'. Defaults to 'left'.\n            font_families (Union[str, List[str]]): The font family of\n                texts. ``font_families`` can have the same length with texts or\n                just single value. If ``font_families`` is single value, all\n                the texts will have the same font family.\n                font_familiy can be 'serif', 'sans-serif', 'cursive', 'fantasy'\n                or 'monospace'.  Defaults to 'sans-serif'.\n            bboxes (Union[dict, List[dict]], optional): The bounding box of the\n                texts. If bboxes is None, there are no bounding box around\n                texts. ``bboxes`` can have the same length with texts or\n                just single value. If ``bboxes`` is single value, all\n                the texts will have the same bbox. Reference to\n                https://matplotlib.org/stable/api/_as_gen/matplotlib.patches.FancyBboxPatch.html#matplotlib.patches.FancyBboxPatch\n                for more details. Defaults to None.\n            font_properties (Union[FontProperties, List[FontProperties]], optional):\n                The font properties of texts. FontProperties is\n                a ``font_manager.FontProperties()`` object.\n                If you want to draw Chinese texts, you need to prepare\n                a font file that can show Chinese characters properly.\n                For example: `simhei.ttf`, `simsun.ttc`, `simkai.ttf` and so on.\n                Then set ``font_properties=matplotlib.font_manager.FontProperties(fname='path/to/font_file')``\n                ``font_properties`` can have the same length with texts or\n                just single value. If ``font_properties`` is single value,\n                all the texts will have the same font properties.\n                Defaults to None.\n                `New in version 0.6.0.`\n        \"\"\"  # noqa: E501\n\n        if self.backend == 'matplotlib':\n            super().draw_texts(\n                texts=texts,\n                positions=positions,\n                font_sizes=font_sizes,\n                colors=colors,\n                vertical_alignments=vertical_alignments,\n                horizontal_alignments=horizontal_alignments,\n                bboxes=bboxes,\n                **kwargs)\n\n        elif self.backend == 'opencv':\n            font_scale = max(0.1, font_sizes / 30)\n            thickness = max(1, font_sizes // 15)\n\n            text_size, text_baseline = cv2.getTextSize(texts,\n                                                       cv2.FONT_HERSHEY_DUPLEX,\n                                                       font_scale, thickness)\n\n            x = int(positions[0])\n            if horizontal_alignments == 'right':\n                x = max(0, x - text_size[0])\n            elif horizontal_alignments == 'center':\n                x = max(0, x - text_size[0] // 2)\n            y = int(positions[1])\n            if vertical_alignments == 'top':\n                y = min(self.height, y + text_size[1])\n            elif vertical_alignments == 'center':\n                y = min(self.height, y + text_size[1] // 2)\n\n            if bboxes is not None:\n                bbox_color = bboxes[0]['facecolor']\n                if isinstance(bbox_color, str):\n                    bbox_color = mmcv.color_val(bbox_color)[::-1]\n\n                y = y - text_baseline // 2\n                self._image = cv2.rectangle(\n                    self._image, (x, y - text_size[1] - text_baseline // 2),\n                    (x + text_size[0], y + text_baseline // 2), bbox_color,\n                    cv2.FILLED)\n\n            self._image = cv2.putText(self._image, texts, (x, y),\n                                      cv2.FONT_HERSHEY_SIMPLEX, font_scale,\n                                      colors, thickness - 1)\n        else:\n            raise ValueError(f'got unsupported backend {self.backend}')\n\n    @master_only\n    def draw_bboxes(self,\n                    bboxes: Union[np.ndarray, torch.Tensor],\n                    edge_colors: Union[str, tuple, List[str],\n                                       List[tuple]] = 'g',\n                    line_widths: Union[Union[int, float],\n                                       List[Union[int, float]]] = 2,\n                    **kwargs) -> 'Visualizer':\n        \"\"\"Draw single or multiple bboxes.\n\n        Args:\n            bboxes (Union[np.ndarray, torch.Tensor]): The bboxes to draw with\n                the format of(x1,y1,x2,y2).\n            edge_colors (Union[str, tuple, List[str], List[tuple]]): The\n                colors of bboxes. ``colors`` can have the same length with\n                lines or just single value. If ``colors`` is single value, all\n                the lines will have the same colors. Refer to `matplotlib.\n                colors` for full list of formats that are accepted.\n                Defaults to 'g'.\n            line_styles (Union[str, List[str]]): The linestyle\n                of lines. ``line_styles`` can have the same length with\n                texts or just single value. If ``line_styles`` is single\n                value, all the lines will have the same linestyle.\n                Reference to\n                https://matplotlib.org/stable/api/collections_api.html?highlight=collection#matplotlib.collections.AsteriskPolygonCollection.set_linestyle\n                for more details. Defaults to '-'.\n            line_widths (Union[Union[int, float], List[Union[int, float]]]):\n                The linewidth of lines. ``line_widths`` can have\n                the same length with lines or just single value.\n                If ``line_widths`` is single value, all the lines will\n                have the same linewidth. Defaults to 2.\n            face_colors (Union[str, tuple, List[str], List[tuple]]):\n                The face colors. Defaults to None.\n            alpha (Union[int, float]): The transparency of bboxes.\n                Defaults to 0.8.\n        \"\"\"\n        if self.backend == 'matplotlib':\n            super().draw_bboxes(\n                bboxes=bboxes,\n                edge_colors=edge_colors,\n                line_widths=line_widths,\n                **kwargs)\n\n        elif self.backend == 'opencv':\n            self._image = mmcv.imshow_bboxes(\n                self._image,\n                bboxes,\n                edge_colors,\n                top_k=-1,\n                thickness=line_widths,\n                show=False)\n        else:\n            raise ValueError(f'got unsupported backend {self.backend}')\n\n    @master_only\n    def draw_lines(self,\n                   x_datas: Union[np.ndarray, torch.Tensor],\n                   y_datas: Union[np.ndarray, torch.Tensor],\n                   colors: Union[str, tuple, List[str], List[tuple]] = 'g',\n                   line_widths: Union[Union[int, float],\n                                      List[Union[int, float]]] = 2,\n                   **kwargs) -> 'Visualizer':\n        \"\"\"Draw single or multiple line segments.\n\n        Args:\n            x_datas (Union[np.ndarray, torch.Tensor]): The x coordinate of\n                each line' start and end points.\n            y_datas (Union[np.ndarray, torch.Tensor]): The y coordinate of\n                each line' start and end points.\n            colors (Union[str, tuple, List[str], List[tuple]]): The colors of\n                lines. ``colors`` can have the same length with lines or just\n                single value. If ``colors`` is single value, all the lines\n                will have the same colors. Reference to\n                https://matplotlib.org/stable/gallery/color/named_colors.html\n                for more details. Defaults to 'g'.\n            line_styles (Union[str, List[str]]): The linestyle\n                of lines. ``line_styles`` can have the same length with\n                texts or just single value. If ``line_styles`` is single\n                value, all the lines will have the same linestyle.\n                Reference to\n                https://matplotlib.org/stable/api/collections_api.html?highlight=collection#matplotlib.collections.AsteriskPolygonCollection.set_linestyle\n                for more details. Defaults to '-'.\n            line_widths (Union[Union[int, float], List[Union[int, float]]]):\n                The linewidth of lines. ``line_widths`` can have\n                the same length with lines or just single value.\n                If ``line_widths`` is single value, all the lines will\n                have the same linewidth. Defaults to 2.\n        \"\"\"\n        if self.backend == 'matplotlib':\n            super().draw_lines(\n                x_datas=x_datas,\n                y_datas=y_datas,\n                colors=colors,\n                line_widths=line_widths,\n                **kwargs)\n\n        elif self.backend == 'opencv':\n            if isinstance(colors, str):\n                colors = mmcv.color_val(colors)[::-1]\n            self._image = cv2.line(\n                self._image, (x_datas[0], y_datas[0]),\n                (x_datas[1], y_datas[1]),\n                colors,\n                thickness=line_widths)\n        else:\n            raise ValueError(f'got unsupported backend {self.backend}')\n\n    @master_only\n    def draw_polygons(self,\n                      polygons: Union[Union[np.ndarray, torch.Tensor],\n                                      List[Union[np.ndarray, torch.Tensor]]],\n                      edge_colors: Union[str, tuple, List[str],\n                                         List[tuple]] = 'g',\n                      alpha: float = 1.0,\n                      **kwargs) -> 'Visualizer':\n        \"\"\"Draw single or multiple bboxes.\n\n        Args:\n            polygons (Union[Union[np.ndarray, torch.Tensor],\\\n                List[Union[np.ndarray, torch.Tensor]]]): The polygons to draw\n                with the format of (x1,y1,x2,y2,...,xn,yn).\n            edge_colors (Union[str, tuple, List[str], List[tuple]]): The\n                colors of polygons. ``colors`` can have the same length with\n                lines or just single value. If ``colors`` is single value,\n                all the lines will have the same colors. Refer to\n                `matplotlib.colors` for full list of formats that are accepted.\n                Defaults to 'g.\n            line_styles (Union[str, List[str]]): The linestyle\n                of lines. ``line_styles`` can have the same length with\n                texts or just single value. If ``line_styles`` is single\n                value, all the lines will have the same linestyle.\n                Reference to\n                https://matplotlib.org/stable/api/collections_api.html?highlight=collection#matplotlib.collections.AsteriskPolygonCollection.set_linestyle\n                for more details. Defaults to '-'.\n            line_widths (Union[Union[int, float], List[Union[int, float]]]):\n                The linewidth of lines. ``line_widths`` can have\n                the same length with lines or just single value.\n                If ``line_widths`` is single value, all the lines will\n                have the same linewidth. Defaults to 2.\n            face_colors (Union[str, tuple, List[str], List[tuple]]):\n                The face colors. Defaults to None.\n            alpha (Union[int, float]): The transparency of polygons.\n                Defaults to 0.8.\n        \"\"\"\n        if self.backend == 'matplotlib':\n            super().draw_polygons(\n                polygons=polygons,\n                edge_colors=edge_colors,\n                alpha=alpha,\n                **kwargs)\n\n        elif self.backend == 'opencv':\n            if alpha == 1.0:\n                self._image = cv2.fillConvexPoly(self._image, polygons,\n                                                 edge_colors)\n            else:\n                img = cv2.fillConvexPoly(self._image.copy(), polygons,\n                                         edge_colors)\n                self._image = cv2.addWeighted(self._image, 1 - alpha, img,\n                                              alpha, 0)\n        else:\n            raise ValueError(f'got unsupported backend {self.backend}')\n\n    @master_only\n    def show(self,\n             drawn_img: Optional[np.ndarray] = None,\n             win_name: str = 'image',\n             wait_time: float = 0.,\n             continue_key=' ') -> None:\n        \"\"\"Show the drawn image.\n\n        Args:\n            drawn_img (np.ndarray, optional): The image to show. If drawn_img\n                is None, it will show the image got by Visualizer. Defaults\n                to None.\n            win_name (str):  The image title. Defaults to 'image'.\n            wait_time (float): Delay in seconds. 0 is the special\n                value that means \"forever\". Defaults to 0.\n            continue_key (str): The key for users to continue. Defaults to\n                the space key.\n        \"\"\"\n        if self.backend == 'matplotlib':\n            super().show(\n                drawn_img=drawn_img,\n                win_name=win_name,\n                wait_time=wait_time,\n                continue_key=continue_key)\n\n        elif self.backend == 'opencv':\n            # Keep images are shown in the same window, and the title of window\n            # will be updated with `win_name`.\n            if not hasattr(self, win_name):\n                self._cv_win_name = win_name\n                cv2.namedWindow(winname=f'{id(self)}')\n                cv2.setWindowTitle(f'{id(self)}', win_name)\n            else:\n                cv2.setWindowTitle(f'{id(self)}', win_name)\n            shown_img = self.get_image() if drawn_img is None else drawn_img\n            cv2.imshow(str(id(self)), mmcv.bgr2rgb(shown_img))\n            cv2.waitKey(int(np.ceil(wait_time * 1000)))\n        else:\n            raise ValueError(f'got unsupported backend {self.backend}')\n"
  },
  {
    "path": "mmpose/visualization/simcc_vis.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Union\n\nimport cv2 as cv\nimport numpy as np\nimport torch\nfrom torchvision.transforms import ToPILImage\n\n\nclass SimCCVisualizer:\n\n    def draw_instance_xy_heatmap(self,\n                                 heatmap: torch.Tensor,\n                                 overlaid_image: Optional[np.ndarray],\n                                 n: int = 20,\n                                 mix: bool = True,\n                                 weight: float = 0.5):\n        \"\"\"Draw heatmaps of GT or prediction.\n\n        Args:\n            heatmap (torch.Tensor): Tensor of heatmap.\n            overlaid_image (np.ndarray): The image to draw.\n            n (int): Number of keypoint, up to 20.\n            mix (bool):Whether to merge heatmap and original image.\n            weight (float): Weight of original image during fusion.\n\n        Returns:\n            np.ndarray: the drawn image which channel is RGB.\n        \"\"\"\n        heatmap2d = heatmap.data.max(0, keepdim=True)[0]\n        xy_heatmap, K = self.split_simcc_xy(heatmap)\n        K = K if K <= n else n\n        blank_size = tuple(heatmap.size()[1:])\n        maps = {'x': [], 'y': []}\n        for i in xy_heatmap:\n            x, y = self.draw_1d_heatmaps(i['x']), self.draw_1d_heatmaps(i['y'])\n            maps['x'].append(x)\n            maps['y'].append(y)\n        white = self.creat_blank(blank_size, K)\n        map2d = self.draw_2d_heatmaps(heatmap2d)\n        if mix:\n            map2d = cv.addWeighted(overlaid_image, 1 - weight, map2d, weight,\n                                   0)\n        self.image_cover(white, map2d, int(blank_size[1] * 0.1),\n                         int(blank_size[0] * 0.1))\n        white = self.add_1d_heatmaps(maps, white, blank_size, K)\n        return white\n\n    def split_simcc_xy(self, heatmap: Union[np.ndarray, torch.Tensor]):\n        \"\"\"Extract one-dimensional heatmap from two-dimensional heatmap and\n        calculate the number of keypoint.\"\"\"\n        size = heatmap.size()\n        k = size[0] if size[0] <= 20 else 20\n        maps = []\n        for _ in range(k):\n            xy_dict = {}\n            single_heatmap = heatmap[_]\n            xy_dict['x'], xy_dict['y'] = self.merge_maps(single_heatmap)\n            maps.append(xy_dict)\n        return maps, k\n\n    def merge_maps(self, map_2d):\n        \"\"\"Synthesis of one-dimensional heatmap.\"\"\"\n        x = map_2d.data.max(0, keepdim=True)[0]\n        y = map_2d.data.max(1, keepdim=True)[0]\n        return x, y\n\n    def draw_1d_heatmaps(self, heatmap_1d):\n        \"\"\"Draw one-dimensional heatmap.\"\"\"\n        size = heatmap_1d.size()\n        length = max(size)\n        np_heatmap = ToPILImage()(heatmap_1d).convert('RGB')\n        cv_img = cv.cvtColor(np.asarray(np_heatmap), cv.COLOR_RGB2BGR)\n        if size[0] < size[1]:\n            cv_img = cv.resize(cv_img, (length, 15))\n        else:\n            cv_img = cv.resize(cv_img, (15, length))\n        single_map = cv.applyColorMap(cv_img, cv.COLORMAP_JET)\n        return single_map\n\n    def creat_blank(self,\n                    size: Union[list, tuple],\n                    K: int = 20,\n                    interval: int = 10):\n        \"\"\"Create the background.\"\"\"\n        blank_height = int(\n            max(size[0] * 2, size[0] * 1.1 + (K + 1) * (15 + interval)))\n        blank_width = int(\n            max(size[1] * 2, size[1] * 1.1 + (K + 1) * (15 + interval)))\n        blank = np.zeros((blank_height, blank_width, 3), np.uint8)\n        blank.fill(255)\n        return blank\n\n    def draw_2d_heatmaps(self, heatmap_2d):\n        \"\"\"Draw a two-dimensional heatmap fused with the original image.\"\"\"\n        np_heatmap = ToPILImage()(heatmap_2d).convert('RGB')\n        cv_img = cv.cvtColor(np.asarray(np_heatmap), cv.COLOR_RGB2BGR)\n        map_2d = cv.applyColorMap(cv_img, cv.COLORMAP_JET)\n        return map_2d\n\n    def image_cover(self, background: np.ndarray, foreground: np.ndarray,\n                    x: int, y: int):\n        \"\"\"Paste the foreground on the background.\"\"\"\n        fore_size = foreground.shape\n        background[y:y + fore_size[0], x:x + fore_size[1]] = foreground\n        return background\n\n    def add_1d_heatmaps(self,\n                        maps: dict,\n                        background: np.ndarray,\n                        map2d_size: Union[tuple, list],\n                        K: int,\n                        interval: int = 10):\n        \"\"\"Paste one-dimensional heatmaps onto the background in turn.\"\"\"\n        y_startpoint, x_startpoint = [int(1.1*map2d_size[1]),\n                                      int(0.1*map2d_size[0])],\\\n                                     [int(0.1*map2d_size[1]),\n                                      int(1.1*map2d_size[0])]\n        x_startpoint[1] += interval * 2\n        y_startpoint[0] += interval * 2\n        add = interval + 10\n        for i in range(K):\n            self.image_cover(background, maps['x'][i], x_startpoint[0],\n                             x_startpoint[1])\n            cv.putText(background, str(i),\n                       (x_startpoint[0] - 30, x_startpoint[1] + 10),\n                       cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)\n            self.image_cover(background, maps['y'][i], y_startpoint[0],\n                             y_startpoint[1])\n            cv.putText(background, str(i),\n                       (y_startpoint[0], y_startpoint[1] - 5),\n                       cv.FONT_HERSHEY_SIMPLEX, 0.5, (255, 0, 0), 2)\n            x_startpoint[1] += add\n            y_startpoint[0] += add\n        return background[:x_startpoint[1] + y_startpoint[1] +\n                          1, :y_startpoint[0] + x_startpoint[0] + 1]\n"
  },
  {
    "path": "model-index.yml",
    "content": "Import:\n- configs/animal_2d_keypoint/rtmpose/ap10k/rtmpose_ap10k.yml\n- configs/animal_2d_keypoint/topdown_heatmap/ak/hrnet_animalkingdom.yml\n- configs/animal_2d_keypoint/topdown_heatmap/animalpose/hrnet_animalpose.yml\n- configs/animal_2d_keypoint/topdown_heatmap/animalpose/resnet_animalpose.yml\n- configs/animal_2d_keypoint/topdown_heatmap/ap10k/cspnext_udp_ap10k.yml\n- configs/animal_2d_keypoint/topdown_heatmap/ap10k/hrnet_ap10k.yml\n- configs/animal_2d_keypoint/topdown_heatmap/ap10k/resnet_ap10k.yml\n- configs/animal_2d_keypoint/topdown_heatmap/locust/resnet_locust.yml\n- configs/animal_2d_keypoint/topdown_heatmap/zebra/resnet_zebra.yml\n- configs/body_2d_keypoint/associative_embedding/coco/hrnet_coco.yml\n- configs/body_2d_keypoint/cid/coco/hrnet_coco.yml\n- configs/body_2d_keypoint/dekr/coco/hrnet_coco.yml\n- configs/body_2d_keypoint/dekr/crowdpose/hrnet_crowdpose.yml\n- configs/body_2d_keypoint/edpose/coco/edpose_coco.yml\n- configs/body_2d_keypoint/integral_regression/coco/resnet_debias_coco.yml\n- configs/body_2d_keypoint/integral_regression/coco/resnet_dsnt_coco.yml\n- configs/body_2d_keypoint/integral_regression/coco/resnet_ipr_coco.yml\n- configs/body_2d_keypoint/rtmpose/body8/rtmpose_body8-coco.yml\n- configs/body_2d_keypoint/rtmpose/body8/rtmpose_body8-halpe26.yml\n- configs/body_2d_keypoint/rtmpose/coco/rtmpose_coco.yml\n- configs/body_2d_keypoint/rtmpose/crowdpose/rtmpose_crowdpose.yml\n- configs/body_2d_keypoint/rtmpose/humanart/rtmpose_humanart.yml\n- configs/body_2d_keypoint/rtmpose/mpii/rtmpose_mpii.yml\n- configs/body_2d_keypoint/rtmo/coco/rtmo_coco.yml\n- configs/body_2d_keypoint/rtmo/body7/rtmo_body7.yml\n- configs/body_2d_keypoint/rtmo/crowdpose/rtmo_crowdpose.yml\n- configs/body_2d_keypoint/simcc/coco/mobilenetv2_coco.yml\n- configs/body_2d_keypoint/simcc/coco/resnet_coco.yml\n- configs/body_2d_keypoint/simcc/coco/vipnas_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/aic/hrnet_aic.yml\n- configs/body_2d_keypoint/topdown_heatmap/aic/resnet_aic.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/alexnet_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/cpm_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/cspnext_udp_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/hourglass_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/hrformer_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_augmentation_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_dark_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_udp_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/litehrnet_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/mobilenetv2_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/mspn_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/pvt_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/resnest_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/resnet_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/resnet_dark_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/resnetv1d_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/resnext_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/rsn_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/scnet_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/seresnet_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/shufflenetv1_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/shufflenetv2_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/swin_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/vgg_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/vipnas_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/coco/vitpose_coco.yml\n- configs/body_2d_keypoint/topdown_heatmap/crowdpose/cspnext_udp_crowdpose.yml\n- configs/body_2d_keypoint/topdown_heatmap/crowdpose/hrnet_crowdpose.yml\n- configs/body_2d_keypoint/topdown_heatmap/crowdpose/resnet_crowdpose.yml\n- configs/body_2d_keypoint/topdown_heatmap/exlpose/hrnet_exlpose.yml\n- configs/body_2d_keypoint/topdown_heatmap/humanart/hrnet_humanart.yml\n- configs/body_2d_keypoint/topdown_heatmap/humanart/vitpose_humanart.yml\n- configs/body_2d_keypoint/topdown_heatmap/jhmdb/cpm_jhmdb.yml\n- configs/body_2d_keypoint/topdown_heatmap/jhmdb/resnet_jhmdb.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/cpm_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/cspnext_udp_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/hourglass_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/hrnet_dark_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/hrnet_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/litehrnet_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/mobilenetv2_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/resnet_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/resnetv1d_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/resnext_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/scnet_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/seresnet_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/shufflenetv1_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/mpii/shufflenetv2_mpii.yml\n- configs/body_2d_keypoint/topdown_heatmap/posetrack18/hrnet_posetrack18.yml\n- configs/body_2d_keypoint/topdown_heatmap/posetrack18/resnet_posetrack18.yml\n- configs/body_2d_keypoint/topdown_regression/coco/mobilenetv2_rle_coco.yml\n- configs/body_2d_keypoint/topdown_regression/coco/resnet_coco.yml\n- configs/body_2d_keypoint/topdown_regression/coco/resnet_rle_coco.yml\n- configs/body_2d_keypoint/topdown_regression/mpii/resnet_mpii.yml\n- configs/body_2d_keypoint/topdown_regression/mpii/resnet_rle_mpii.yml\n- configs/body_2d_keypoint/yoloxpose/coco/yoloxpose_coco.yml\n- configs/body_3d_keypoint/image_pose_lift/h36m/simplebaseline3d_h36m.yml\n- configs/body_3d_keypoint/motionbert/h36m/motionbert_h36m.yml\n- configs/body_3d_keypoint/video_pose_lift/h36m/videopose3d_h36m.yml\n- configs/face_2d_keypoint/rtmpose/coco_wholebody_face/rtmpose_coco_wholebody_face.yml\n- configs/face_2d_keypoint/rtmpose/face6/rtmpose_face6.yml\n- configs/face_2d_keypoint/rtmpose/lapa/rtmpose_lapa.yml\n- configs/face_2d_keypoint/rtmpose/wflw/rtmpose_wflw.yml\n- configs/face_2d_keypoint/topdown_heatmap/300w/hrnetv2_300w.yml\n- configs/face_2d_keypoint/topdown_heatmap/300wlp/hrnetv2_300wlp.yml\n- configs/face_2d_keypoint/topdown_heatmap/aflw/hrnetv2_aflw.yml\n- configs/face_2d_keypoint/topdown_heatmap/aflw/hrnetv2_dark_aflw.yml\n- configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hourglass_coco_wholebody_face.yml\n- configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hrnetv2_coco_wholebody_face.yml\n- configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/hrnetv2_dark_coco_wholebody_face.yml\n- configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/mobilenetv2_coco_wholebody_face.yml\n- configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/resnet_coco_wholebody_face.yml\n- configs/face_2d_keypoint/topdown_heatmap/coco_wholebody_face/scnet_coco_wholebody_face.yml\n- configs/face_2d_keypoint/topdown_heatmap/cofw/hrnetv2_cofw.yml\n- configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_awing_wflw.yml\n- configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_dark_wflw.yml\n- configs/face_2d_keypoint/topdown_heatmap/wflw/hrnetv2_wflw.yml\n- configs/face_2d_keypoint/topdown_regression/wflw/resnet_softwingloss_wflw.yml\n- configs/face_2d_keypoint/topdown_regression/wflw/resnet_wflw.yml\n- configs/face_2d_keypoint/topdown_regression/wflw/resnet_wingloss_wflw.yml\n- configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/hrnet_deepfashion.yml\n- configs/fashion_2d_keypoint/topdown_heatmap/deepfashion/resnet_deepfashion.yml\n- configs/fashion_2d_keypoint/topdown_heatmap/deepfashion2/res50_deepfasion2.yml\n- configs/hand_2d_keypoint/rtmpose/coco_wholebody_hand/rtmpose_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/rtmpose/hand5/rtmpose_hand5.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hourglass_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hrnetv2_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/hrnetv2_dark_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/litehrnet_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/mobilenetv2_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/resnet_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/coco_wholebody_hand/scnet_coco_wholebody_hand.yml\n- configs/hand_2d_keypoint/topdown_heatmap/freihand2d/resnet_freihand2d.yml\n- configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_dark_onehand10k.yml\n- configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_onehand10k.yml\n- configs/hand_2d_keypoint/topdown_heatmap/onehand10k/hrnetv2_udp_onehand10k.yml\n- configs/hand_2d_keypoint/topdown_heatmap/onehand10k/mobilenetv2_onehand10k.yml\n- configs/hand_2d_keypoint/topdown_heatmap/onehand10k/resnet_onehand10k.yml\n- configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_dark_rhd2d.yml\n- configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_rhd2d.yml\n- configs/hand_2d_keypoint/topdown_heatmap/rhd2d/hrnetv2_udp_rhd2d.yml\n- configs/hand_2d_keypoint/topdown_heatmap/rhd2d/mobilenetv2_rhd2d.yml\n- configs/hand_2d_keypoint/topdown_heatmap/rhd2d/resnet_rhd2d.yml\n- configs/hand_2d_keypoint/topdown_regression/onehand10k/resnet_onehand10k.yml\n- configs/hand_2d_keypoint/topdown_regression/rhd2d/resnet_rhd2d.yml\n- configs/hand_3d_keypoint/internet/interhand3d/internet_interhand3d.yml\n- configs/wholebody_2d_keypoint/rtmpose/coco-wholebody/rtmpose_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/cspnext_udp_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/hrnet_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/hrnet_dark_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/resnet_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/vipnas_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/coco-wholebody/vipnas_dark_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/topdown_heatmap/ubody2d/hrnet_coco-wholebody.yml\n- configs/wholebody_2d_keypoint/rtmpose/cocktail14/rtmw_cocktail14.yml\n"
  },
  {
    "path": "projects/README.md",
    "content": "# Welcome to Projects of MMPose\n\nHey there! This is the place for you to contribute your awesome keypoint detection techniques to MMPose!\n\nWe know the unit tests in core package can be a bit intimidating, so we've made it easier and more efficient for you to implement your algorithms here.\n\nAnd the **best part**?\n\n- Projects in this folder are designed to be **easier to merge**!\n\n- Projects in this folder are **NOT** strictly required for **writing unit tests**!\n\n- We want to make it **as painless as possible** for you to contribute and make MMPose even greater.\n\nIf you're not sure where to start, check out our [example project](./example_project) to see how to add your algorithms easily. And if you have any questions, take a look at our [FAQ](./faq.md).\n\nWe also provide some documentation listed below to help you get started:\n\n- [New Model Guide](https://mmpose.readthedocs.io/en/latest/guide_to_framework.html#step3-model)\n\n  A guide to help you add new models to MMPose.\n\n- [Contribution Guide](https://mmpose.readthedocs.io/en/latest/contribution_guide.html)\n\n  A guide for new contributors on how to add their projects to MMPose.\n\n- [Discussions](https://github.com/open-mmlab/mmpose/discussions)\n\n  We encourage you to start a discussion and share your ideas!\n\n## Project List\n\n- **[:zap:RTMPose](./rtmpose)**: Real-Time Multi-Person Pose Estimation toolkit based on MMPose <sup>\n  <a href=\"https://openxlab.org.cn/apps/detail/mmpose/RTMPose\">\n  <i>TRY IT NOW</i>\n  </a>\n  </sup>\n\n  <div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/5b637d76-41dd-4376-9a7f-854cd120799d\" width=800 height=200 />\n  </div><br/>\n\n- **[🎳RTMO](./rtmo)**: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation <sup>\n  <a href=\"https://openxlab.org.cn/apps/detail/mmpose/RTMPose\">\n  <i>TRY IT NOW</i>\n  </a>\n  </sup>\n\n  <div align=\"center\">\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/61120930-09e5-4457-aa2c-b2f131d4f710\" width=800  />\n  </div><br/>\n\n- **[♾️PoseAnything](./pose_anything/)**: A Graph-Based Approach for Category-Agnostic Pose Estimation\n\n  <div align=center>\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/47acbd42-e812-4994-b287-b2a2b5ccbd80\" width=\"800\"/>\n  </div><br/>\n\n- **[:art:MMPose4AIGC](./mmpose4aigc)**: Guide AI image generation with MMPose\n\n  <div align=center>\n  <img src=\"https://user-images.githubusercontent.com/13503330/222403836-c65ba905-4bdd-4a44-834c-ff8d5959649d.png\" width=\"800\"/>\n  </div><br/>\n\n- **[:bulb:YOLOX-Pose](./yolox_pose)**: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss\n\n  <div align=center>\n  <img src=\"https://user-images.githubusercontent.com/26127467/226655503-3cee746e-6e42-40be-82ae-6e7cae2a4c7e.jpg\" width=\"800\" style=\"width: 800px; height: 200px; object-fit: cover\"/>\n  </div><br/>\n\n- **[📖Awesome MMPose](./awesome-mmpose/)**: A list of Tutorials, Papers, Datasets related to MMPose\n\n  <div align=center>\n  <img src=\"https://user-images.githubusercontent.com/13503330/231416285-5467d313-0732-4ada-97e1-12be6ec69a28.png\" width=\"800\"/>\n  </div><br/>\n\n- **[💃Just-Dance](./just_dance)**: Enhancing Dance scoring system for comparing dance performances in videos. <sup>\n  <a href=\"https://openxlab.org.cn/apps/detail/mmpose/just_dance-mmpose\">\n  <i>TRY IT NOW</i>\n  </a>\n  </sup>\n\n  <div align=center>\n  <img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/a80978ad-c66d-4bac-bf56-1fa191716f1c\" width=\"800\" style=\"width: 800px; height: 200px; object-fit: cover\"/>\n  </div><br/>\n\n- **What's next? Join the rank of <span style=\"color:blue\"> *MMPose contributors* </span> by creating a new  project**!\n"
  },
  {
    "path": "projects/awesome-mmpose/README.md",
    "content": "# Awesome MMPose\n\nA list of resources related to MMPose. Feel free to contribute!\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/231416285-5467d313-0732-4ada-97e1-12be6ec69a28.png\" width=\"800\"/>\n</div><br/>\n\n## Contents\n\n- [Tutorials](#tutorials)\n- [Papers](#papers)\n- [Datasets](#datasets)\n- [Projects](#projects)\n\n## Tutorials\n\n- [MMPose Tutorial (Chinese)](https://github.com/TommyZihao/MMPose_Tutorials)\n\n  MMPose 中文视频代码教程，from 同济子豪兄\n\n  <div align=center>\n  <img src=\"https://user-images.githubusercontent.com/13503330/231640277-777f611c-b3d9-4d41-830f-8e48a352fd01.jpg\" width=\"500\"/>\n  </div><br/>\n\n- [OpenMMLab Course](https://github.com/open-mmlab/OpenMMLabCourse)\n\n  This repository hosts articles, lectures and tutorials on computer vision and OpenMMLab, helping learners to understand algorithms and master our toolboxes in a systematical way.\n\n## Papers\n\n- [\\[paper\\]](https://arxiv.org/abs/2207.10387) [\\[code\\]](https://github.com/luminxu/Pose-for-Everything)\n\n  ECCV 2022, Pose for Everything: Towards Category-Agnostic Pose Estimation\n\n- [\\[paper\\]](https://arxiv.org/abs/2201.04676) [\\[code\\]](https://github.com/Sense-X/UniFormer)\n\n  ICLR 2022, UniFormer: Unified Transformer for Efficient Spatiotemporal Representation Learning\n\n- [\\[paper\\]](https://arxiv.org/abs/2201.07412) [\\[code\\]](https://github.com/aim-uofa/Poseur)\n\n  ECCV 2022, Poseur:Direct Human Pose Regression with Transformers\n\n- [\\[paper\\]](https://arxiv.org/abs/2106.03348) [\\[code\\]](https://github.com/ViTAE-Transformer/ViTAE-Transformer)\n\n  NeurIPS 2022, ViTAEv2: Vision Transformer Advanced by Exploring Inductive Bias for Image Recognition and Beyond\n\n- [\\[paper\\]](https://arxiv.org/abs/2204.10762) [\\[code\\]](https://github.com/ZiyiZhang27/Dite-HRNet)\n\n  IJCAI-ECAI 2021, Dite-HRNet:Dynamic Lightweight High-Resolution Network for Human Pose Estimation\n\n- [\\[paper\\]](https://arxiv.org/abs/2302.08453) [\\[code\\]](https://github.com/TencentARC/T2I-Adapter)\n\n  T2I-Adapter: Learning Adapters to Dig out More Controllable Ability for Text-to-Image Diffusion Models\n\n- [\\[paper\\]](https://arxiv.org/pdf/2303.11638.pdf) [\\[code\\]](https://github.com/Gengzigang/PCT)\n\n  CVPR 2023, Human Pose as Compositional Tokens\n\n## Datasets\n\n- [\\[github\\]](https://github.com/luminxu/Pose-for-Everything) **MP-100**\n\n  Multi-category Pose (MP-100) dataset, which is a 2D pose dataset of 100 object categories containing over 20K instances and is well-designed for developing CAPE algorithms.\n\n  <div align=center>\n  <img src=\"https://user-images.githubusercontent.com/13503330/231639551-b32ed2ab-aec0-4410-937e-c81a2ac2cb0d.png\" width=\"500\"/>\n  </div><br/>\n\n- [\\[github\\]](https://github.com/facebookresearch/Ego4d/) **Ego4D**\n\n  EGO4D is the world's largest egocentric (first person) video ML dataset and benchmark suite, with 3,600 hrs (and counting) of densely narrated video and a wide range of annotations across five new benchmark tasks. It covers hundreds of scenarios (household, outdoor, workplace, leisure, etc.) of daily life activity captured in-the-wild by 926 unique camera wearers from 74 worldwide locations and 9 different countries.\n\n  <div align=center>\n  <img src=\"https://user-images.githubusercontent.com/13503330/231640003-d43028cc-6f83-45e7-b76a-8e8f0cddcfcb.png\" width=\"500\"/>\n  </div><br/>\n\n## Projects\n\nWaiting for your contribution!\n"
  },
  {
    "path": "projects/example_project/README.md",
    "content": "# Example Project\n\n> A README.md template for releasing a project.\n>\n> All the fields in this README are **mandatory** for others to understand what you have achieved in this implementation.\n> Please read our [Projects FAQ](../faq.md) if you still feel unclear about the requirements, or raise an [issue](https://github.com/open-mmlab/mmpose/issues) to us!\n\n## Description\n\n> Share any information you would like others to know. For example:\n>\n> Author: @xxx.\n>\n> This is an implementation of \\[XXX\\].\n\nAuthor： @xxx.\n\nThis project implements a top-down pose estimator with custom head and loss functions that have been seamlessly inherited from existing modules within MMPose.\n\n## Usage\n\n> For a typical model, this section should contain the commands for training and testing.\n> You are also suggested to dump your environment specification to env.yml by `conda env export > env.yml`.\n\n### Prerequisites\n\n- Python 3.7\n- PyTorch 1.6 or higher\n- [MIM](https://github.com/open-mmlab/mim) v0.33 or higher\n- [MMPose](https://github.com/open-mmlab/mmpose) v1.0.0rc0 or higher\n\nAll the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `example_project/` root directory, run the following line to add the current directory to `PYTHONPATH`:\n\n```shell\nexport PYTHONPATH=`pwd`:$PYTHONPATH\n```\n\n### Data Preparation\n\nPrepare the COCO dataset according to the [instruction](https://mmpose.readthedocs.io/en/dev-1.x/dataset_zoo/2d_body_keypoint.html#coco).\n\n### Training commands\n\n**To train with single GPU:**\n\n```shell\nmim train mmpose configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py\n```\n\n**To train with multiple GPUs:**\n\n```shell\nmim train mmpose configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py --launcher pytorch --gpus 8\n```\n\n**To train with multiple GPUs by slurm:**\n\n```shell\nmim train mmpose configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py --launcher slurm \\\n    --gpus 16 --gpus-per-node 8 --partition $PARTITION\n```\n\n### Testing commands\n\n**To test with single GPU:**\n\n```shell\nmim test mmpose configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py $CHECKPOINT\n```\n\n**To test with multiple GPUs:**\n\n```shell\nmim test mmpose configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py $CHECKPOINT --launcher pytorch --gpus 8\n```\n\n**To test with multiple GPUs by slurm:**\n\n```shell\nmim test mmpose configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py $CHECKPOINT --launcher slurm \\\n    --gpus 16 --gpus-per-node 8 --partition $PARTITION\n```\n\n## Results\n\n> List the results as usually done in other model's README. Here is an [Example](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_coco.md).\n\n> You should claim whether this is based on the pre-trained weights, which are converted from the official release; or it's a reproduced result obtained from retraining the model in this project\n\n|                             Model                             | Backbone  | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                             Download                              |\n| :-----------------------------------------------------------: | :-------: | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :---------------------------------------------------------------: |\n| [ExampleHead + ExampleLoss](./configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py) | HRNet-w32 |  256x912   | 0.749 |      0.906      |      0.821      | 0.804 |      0.945      | [model](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192-81c58e40_20220909.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/body_2d_keypoint/topdown_heatmap/coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192_20220909.log) |\n\n## Citation\n\n> You may remove this section if not applicable.\n\n```bibtex\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n\n## Checklist\n\nHere is a checklist of this project's progress. And you can ignore this part if you don't plan to contribute\nto MMPose projects.\n\n> The PIC (person in charge) or contributors of this project should check all the items that they believe have been finished, which will further be verified by codebase maintainers via a PR.\n\n> OpenMMLab's maintainer will review the code to ensure the project's quality. Reaching the first milestone means that this project suffices the minimum requirement of being merged into 'projects/'. But this project is only eligible to become a part of the core package upon attaining the last milestone.\n\n> Note that keeping this section up-to-date is crucial not only for this project's developers but the entire community, since there might be some other contributors joining this project and deciding their starting point from this list. It also helps maintainers accurately estimate time and effort on further code polishing, if needed.\n\n> A project does not necessarily have to be finished in a single PR, but it's essential for the project to at least reach the first milestone in its very first PR.\n\n- [ ] Milestone 1: PR-ready, and acceptable to be one of the `projects/`.\n\n  - [ ] Finish the code\n\n    > The code's design shall follow existing interfaces and convention. For example, each model component should be registered into `mmpose.registry.MODELS` and configurable via a config file.\n\n  - [ ] Basic docstrings & proper citation\n\n    > Each major class should contains a docstring, describing its functionality and arguments. If your code is copied or modified from other open-source projects, don't forget to cite the source project in docstring and make sure your behavior is not against its license. Typically, we do not accept any code snippet under GPL license. [A Short Guide to Open Source Licenses](https://medium.com/nationwide-technology/a-short-guide-to-open-source-licenses-cf5b1c329edd)\n\n  - [ ] Test-time correctness\n\n    > If you are reproducing the result from a paper, make sure your model's inference-time performance matches that in the original paper. The weights usually could be obtained by simply renaming the keys in the official pre-trained weights. This test could be skipped though, if you are able to prove the training-time correctness and check the second milestone.\n\n  - [ ] A full README\n\n    > As this template does.\n\n- [ ] Milestone 2: Indicates a successful model implementation.\n\n  - [ ] Training-time correctness\n\n    > If you are reproducing the result from a paper, checking this item means that you should have trained your model from scratch based on the original paper's specification and verified that the final result matches the report within a minor error range.\n\n- [ ] Milestone 3: Good to be a part of our core package!\n\n  - [ ] Type hints and docstrings\n\n    > Ideally *all* the methods should have [type hints](https://www.pythontutorial.net/python-basics/python-type-hints/) and [docstrings](https://google.github.io/styleguide/pyguide.html#381-docstrings). [Example](https://github.com/open-mmlab/mmpose/blob/0fb7f22000197181dc0629f767dd99d881d23d76/mmpose/utils/tensor_utils.py#L53)\n\n  - [ ] Unit tests\n\n    > Unit tests for the major module are required. [Example](https://github.com/open-mmlab/mmpose/blob/dev-1.x/tests/test_models/test_heads/test_heatmap_heads/test_heatmap_head.py)\n\n  - [ ] Code polishing\n\n    > Refactor your code according to reviewer's comment.\n\n  - [ ] Metafile.yml\n\n    > It will be parsed by MIM and Inferencer. [Example](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/coco/hrnet_coco.yml)\n\n  - [ ] Move your modules into the core package following the codebase's file hierarchy structure.\n\n    > In particular, you may have to refactor this README into a standard one. [Example](https://github.com/open-mmlab/mmpose/blob/dev-1.x/configs/body_2d_keypoint/topdown_heatmap/README.md)\n\n  - [ ] Refactor your modules into the core package following the codebase's file hierarchy structure.\n"
  },
  {
    "path": "projects/example_project/configs/example-head-loss_hrnet-w32_8xb64-210e_coco-256x192.py",
    "content": "# Directly inherit the entire recipe you want to use.\n_base_ = 'mmpose::body_2d_keypoint/topdown_heatmap/coco/' \\\n         'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py'\n\n# This line is to import your own modules.\ncustom_imports = dict(imports='models')\n\n# Modify the model to use your own head and loss.\n_base_['model']['head'] = dict(\n    type='ExampleHead',\n    in_channels=32,\n    out_channels=17,\n    deconv_out_channels=None,\n    loss=dict(type='ExampleLoss', use_target_weight=True),\n    decoder=_base_['codec'])\n"
  },
  {
    "path": "projects/example_project/models/__init__.py",
    "content": "from .example_head import ExampleHead\nfrom .example_loss import ExampleLoss\n\n__all__ = ['ExampleHead', 'ExampleLoss']\n"
  },
  {
    "path": "projects/example_project/models/example_head.py",
    "content": "from mmpose.models import HeatmapHead\nfrom mmpose.registry import MODELS\n\n\n# Register your head to the `MODELS`.\n@MODELS.register_module()\nclass ExampleHead(HeatmapHead):\n    \"\"\"Implements an example head.\n\n    Implement the model head just like a normal pytorch module.\n    \"\"\"\n\n    def __init__(self, **kwargs) -> None:\n        print('Initializing ExampleHead...')\n        super().__init__(**kwargs)\n\n    def forward(self, feats):\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is the coordinates.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tensor: output coordinates or heatmaps.\n        \"\"\"\n        return super().forward(feats)\n\n    def predict(self, feats, batch_data_samples, test_cfg={}):\n        \"\"\"Predict results from outputs. The behaviour of head during testing\n        should be defined in this function.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): A list of\n                data samples for instances in a batch\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n\n            The heatmap prediction is a list of ``PixelData``, each contains\n            the following fields:\n\n                - heatmaps (Tensor): The predicted heatmaps in shape (K, h, w)\n        \"\"\"\n        return super().predict(feats, batch_data_samples, test_cfg)\n\n    def loss(self, feats, batch_data_samples, train_cfg={}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples. The\n        behaviour of head during training should be defined in this function.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): A list of\n                data samples for instances in a batch\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n\n        return super().loss(feats, batch_data_samples, train_cfg)\n"
  },
  {
    "path": "projects/example_project/models/example_loss.py",
    "content": "from mmpose.models import KeypointMSELoss\nfrom mmpose.registry import MODELS\n\n\n# Register your loss to the `MODELS`.\n@MODELS.register_module()\nclass ExampleLoss(KeypointMSELoss):\n    \"\"\"Implements an example loss.\n\n    Implement the loss just like a normal pytorch module.\n    \"\"\"\n\n    def __init__(self, **kwargs) -> None:\n        print('Initializing ExampleLoss...')\n        super().__init__(**kwargs)\n\n    def forward(self, output, target, target_weights=None, mask=None):\n        \"\"\"Forward function of loss. The input arguments should match those\n        given in `head.loss` function.\n\n        Note:\n            - batch_size: B\n            - num_keypoints: K\n            - heatmaps height: H\n            - heatmaps weight: W\n\n        Args:\n            output (Tensor): The output heatmaps with shape [B, K, H, W]\n            target (Tensor): The target heatmaps with shape [B, K, H, W]\n            target_weights (Tensor, optional): The target weights of differet\n                keypoints, with shape [B, K] (keypoint-wise) or\n                [B, K, H, W] (pixel-wise).\n            mask (Tensor, optional): The masks of valid heatmap pixels in\n                shape [B, K, H, W] or [B, 1, H, W]. If ``None``, no mask will\n                be applied. Defaults to ``None``\n\n        Returns:\n            Tensor: The calculated loss.\n        \"\"\"\n        return super().forward(output, target, target_weights, mask)\n"
  },
  {
    "path": "projects/faq.md",
    "content": "# FAQ\n\nTo help users better understand the `projects/` folder and how to use it effectively, we've created this FAQ page. Here, users can find answers to common questions and learn more about various aspects of the `projects/` folder, such as its usage and contribution guidance.\n\n## Q1: Why set up `projects/` folder?\n\nImplementing new models and features into OpenMMLab's algorithm libraries could be troublesome due to the rigorous requirements on code quality, which could hinder the fast iteration of SOTA models and might discourage our members from sharing their latest outcomes here. And that's why we have this `projects/` folder now, where some experimental features, frameworks and models are placed, only needed to satisfy the minimum requirement on the code quality, and can be used as standalone libraries. Users are welcome to use them if they [use MMPose from source](https://mmpose.readthedocs.io/en/dev-1.x/installation.html#best-practices).\n\n## Q2: Why should there be a checklist for a project?\n\nThis checkelist is crucial not only for this project's developers but the entire community, since there might be some other contributors joining this project and deciding their starting point from this list. It also helps maintainers accurately estimate time and effort on further code polishing, if needed.\n\n## Q3: What kind of PR will be merged?\n\nReaching the first milestone means that this project suffices the minimum requirement of being merged into 'projects/'. That is, the very first PR of a project must have all the terms in the first milestone checked. We do not have any extra requirements on the project's following PRs, so they can be a minor bug fix or update, and do not have to achieve one milestone at once. But keep in mind that this project is only eligible to become a part of the core package upon attaining the last milestone.\n\n## Q4: Compared to other models in the core packages, why do the model implementations in projects have different training/testing commands?\n\nProjects are organized independently from the core package, and therefore their modules cannot be directly imported by `train.py` and `test.py`. Each model implementation in projects should either use `mim` for training/testing as suggested in the example project or provide a custom `train.py`/`test.py`.\n\n## Q5: How to debug a project with a debugger?\n\nDebugger makes our lives easier, but using it becomes a bit tricky if we have to train/test a model via `mim`. The way to circumvent that is that we can take advantage of relative path to import these modules. Assuming that we are developing a project X and the core modules are placed under `projects/X/modules`, then simply adding `custom_imports = dict(imports='projects.X.modules')` to the config allows us to debug from usual entrypoints (e.g. `tools/train.py`) from the root directory of the algorithm library. Just don't forget to remove 'projects.X' before project publishment.\n"
  },
  {
    "path": "projects/just_dance/README.md",
    "content": "# Just Dance - A Simple Implementation\n\n<sup>\n   <a href=\"https://openxlab.org.cn/apps/detail/mmpose/just_dance-mmpose\">\n      <i>Try it on OpenXLab</i>\n   </a>\n</sup>\n\nThis project presents a dance scoring system based on RTMPose. Users can compare the similarity between two dancers in different videos: one referred to as the \"teacher video\" and the other as the \"student video.\"\n\nHere are examples of the output dance comparison:\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/56d5c4d1-55d8-4222-b481-2418cc29a8d4\" width=\"600\"/>\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/f93b94c7-529f-4704-8246-c3c812f4c31a\" width=\"600\"/>\n\n## Usage\n\n### Jupyter Notebook\n\nWe provide a Jupyter Notebook [`just_dance_demo.ipynb`](./just_dance_demo.ipynb) that contains the complete process of dance comparison. It includes steps such as video FPS adjustment, pose estimation, snippet alignment, scoring, and the generation of the merged video.\n\n### CLI tool\n\nUsers can simply run the following command to generate the comparison video:\n\n```shell\npython process_video.py ${TEACHER_VIDEO} ${STUDENT_VIDEO}\n```\n\n### Gradio\n\nUsers can also utilize Gradio to build an application using this system. We provide the script [`app.py`](./app.py). This application supports webcam input in addition to existing videos. To build this application, please follow these two steps:\n\n1. Install Gradio\n   ```shell\n   pip install gradio\n   ```\n2. Run the script [`app.py`](./app.py)\n   ```shell\n   python app.py\n   ```\n"
  },
  {
    "path": "projects/just_dance/app.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport sys\nfrom functools import partial\nfrom typing import Optional\n\nproject_path = os.path.join(os.path.dirname(os.path.abspath(__file__)))\nmmpose_path = project_path.split('/projects', 1)[0]\n\nos.system('python -m pip install Openmim')\nos.system('python -m mim install \"mmcv>=2.0.0\"')\nos.system('python -m mim install mmengine')\nos.system('python -m mim install \"mmdet>=3.0.0\"')\nos.system(f'python -m mim install -e {mmpose_path}')\n\nos.environ['PATH'] = f\"{os.environ['PATH']}:{project_path}\"\nos.environ[\n    'PYTHONPATH'] = f\"{os.environ.get('PYTHONPATH', '.')}:{project_path}\"\nsys.path.append(project_path)\n\nimport gradio as gr  # noqa\nfrom mmengine.utils import mkdir_or_exist  # noqa\nfrom process_video import VideoProcessor  # noqa\n\n\ndef process_video(\n    teacher_video: Optional[str] = None,\n    student_video: Optional[str] = None,\n):\n    print(teacher_video)\n    print(student_video)\n\n    video_processor = VideoProcessor()\n    if student_video is None and teacher_video is not None:\n        # Pre-process the teacher video when users record the student video\n        # using a webcam. This allows users to view the teacher video and\n        # follow the dance moves while recording the student video.\n        _ = video_processor.get_keypoints_from_video(teacher_video)\n        return teacher_video\n    elif teacher_video is None and student_video is not None:\n        _ = video_processor.get_keypoints_from_video(student_video)\n        return student_video\n    elif teacher_video is None and student_video is None:\n        return None\n\n    return video_processor.run(teacher_video, student_video)\n\n\n# download video resources\nmkdir_or_exist(os.path.join(project_path, 'resources'))\nos.system(\n    f'wget -O {project_path}/resources/tom.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/tom.mp4'  # noqa\n)\nos.system(\n    f'wget -O {project_path}/resources/idol_producer.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/idol_producer.mp4'  # noqa\n)\nos.system(\n    f'wget -O {project_path}/resources/tsinghua_30fps.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/tsinghua_30fps.mp4'  # noqa\n)\nos.system(\n    f'wget -O {project_path}/resources/student1.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/student1.mp4'  # noqa\n)\nos.system(\n    f'wget -O {project_path}/resources/bear_teacher.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/bear_teacher.mp4'  # noqa\n)\n\nwith gr.Blocks() as demo:\n    with gr.Tab('Upload-Video'):\n        with gr.Row():\n            with gr.Column():\n                gr.Markdown('Student Video')\n                student_video = gr.Video(type='mp4')\n                gr.Examples([\n                    os.path.join(project_path, 'resources/tom.mp4'),\n                    os.path.join(project_path, 'resources/tsinghua_30fps.mp4'),\n                    os.path.join(project_path, 'resources/student1.mp4')\n                ], student_video)\n            with gr.Column():\n                gr.Markdown('Teacher Video')\n                teacher_video = gr.Video(type='mp4')\n                gr.Examples([\n                    os.path.join(project_path, 'resources/idol_producer.mp4'),\n                    os.path.join(project_path, 'resources/bear_teacher.mp4')\n                ], teacher_video)\n\n        button = gr.Button('Grading', variant='primary')\n        gr.Markdown('## Display')\n        out_video = gr.Video()\n\n        button.click(\n            partial(process_video), [teacher_video, student_video], out_video)\n\n    with gr.Tab('Webcam-Video'):\n        with gr.Row():\n            with gr.Column():\n                gr.Markdown('Student Video')\n                student_video = gr.Video(source='webcam', type='mp4')\n            with gr.Column():\n                gr.Markdown('Teacher Video')\n                teacher_video = gr.Video(type='mp4')\n                gr.Examples([\n                    os.path.join(project_path, 'resources/idol_producer.mp4')\n                ], teacher_video)\n                button_upload = gr.Button('Upload', variant='primary')\n\n        button = gr.Button('Grading', variant='primary')\n        gr.Markdown('## Display')\n        out_video = gr.Video()\n\n        button_upload.click(\n            partial(process_video), [teacher_video, student_video], out_video)\n        button.click(\n            partial(process_video), [teacher_video, student_video], out_video)\n\ngr.close_all()\ndemo.queue()\ndemo.launch()\n"
  },
  {
    "path": "projects/just_dance/calculate_similarity.py",
    "content": "import numpy as np\nimport torch\n\nflip_indices = np.array(\n    [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15])\nvalid_indices = np.array([0] + list(range(5, 17)))\n\n\n@torch.no_grad()\ndef _calculate_similarity(tch_kpts: np.ndarray, stu_kpts: np.ndarray):\n\n    stu_kpts = torch.from_numpy(stu_kpts[:, None, valid_indices])\n    tch_kpts = torch.from_numpy(tch_kpts[None, :, valid_indices])\n    stu_kpts = stu_kpts.expand(stu_kpts.shape[0], tch_kpts.shape[1],\n                               stu_kpts.shape[2], 3)\n    tch_kpts = tch_kpts.expand(stu_kpts.shape[0], tch_kpts.shape[1],\n                               stu_kpts.shape[2], 3)\n\n    matrix = torch.stack((stu_kpts, tch_kpts), dim=4)\n    if torch.cuda.is_available():\n        matrix = matrix.cuda()\n    mask = torch.logical_and(matrix[:, :, :, 2, 0] > 0.3,\n                             matrix[:, :, :, 2, 1] > 0.3)\n    matrix[~mask] = 0.0\n\n    matrix_ = matrix.clone()\n    matrix_[matrix == 0] = 256\n    x_min = matrix_.narrow(3, 0, 1).min(dim=2).values\n    y_min = matrix_.narrow(3, 1, 1).min(dim=2).values\n    matrix_ = matrix.clone()\n    # matrix_[matrix == 0] = 0\n    x_max = matrix_.narrow(3, 0, 1).max(dim=2).values\n    y_max = matrix_.narrow(3, 1, 1).max(dim=2).values\n\n    matrix_ = matrix.clone()\n    matrix_[:, :, :, 0] = (matrix_[:, :, :, 0] - x_min) / (\n        x_max - x_min + 1e-4)\n    matrix_[:, :, :, 1] = (matrix_[:, :, :, 1] - y_min) / (\n        y_max - y_min + 1e-4)\n    matrix_[:, :, :, 2] = (matrix_[:, :, :, 2] > 0.3).float()\n    xy_dist = matrix_[..., :2, 0] - matrix_[..., :2, 1]\n    score = matrix_[..., 2, 0] * matrix_[..., 2, 1]\n\n    similarity = (torch.exp(-50 * xy_dist.pow(2).sum(dim=-1)) *\n                  score).sum(dim=-1) / (\n                      score.sum(dim=-1) + 1e-6)\n    num_visible_kpts = score.sum(dim=-1)\n    similarity = similarity * torch.log(\n        (1 + (num_visible_kpts - 1) * 10).clamp(min=1)) / np.log(161)\n\n    similarity[similarity.isnan()] = 0\n\n    return similarity\n\n\n@torch.no_grad()\ndef calculate_similarity(tch_kpts: np.ndarray, stu_kpts: np.ndarray):\n    assert tch_kpts.shape[1] == 17\n    assert tch_kpts.shape[2] == 3\n    assert stu_kpts.shape[1] == 17\n    assert stu_kpts.shape[2] == 3\n\n    similarity1 = _calculate_similarity(tch_kpts, stu_kpts)\n\n    stu_kpts_flip = stu_kpts[:, flip_indices]\n    stu_kpts_flip[..., 0] = 191.5 - stu_kpts_flip[..., 0]\n    similarity2 = _calculate_similarity(tch_kpts, stu_kpts_flip)\n\n    similarity = torch.stack((similarity1, similarity2)).max(dim=0).values\n\n    return similarity\n\n\n@torch.no_grad()\ndef select_piece_from_similarity(similarity):\n    m, n = similarity.size()\n    row_indices = torch.arange(m).view(-1, 1).expand(m, n).to(similarity)\n    col_indices = torch.arange(n).view(1, -1).expand(m, n).to(similarity)\n    diagonal_indices = similarity.size(0) - 1 - row_indices + col_indices\n    unique_diagonal_indices, inverse_indices = torch.unique(\n        diagonal_indices, return_inverse=True)\n\n    diagonal_sums_list = torch.zeros(\n        unique_diagonal_indices.size(0),\n        dtype=similarity.dtype,\n        device=similarity.device)\n    diagonal_sums_list.scatter_add_(0, inverse_indices.view(-1),\n                                    similarity.view(-1))\n    diagonal_sums_list[:min(m, n) // 4] = 0\n    diagonal_sums_list[-min(m, n) // 4:] = 0\n    index = diagonal_sums_list.argmax().item()\n\n    similarity_smooth = torch.nn.functional.max_pool2d(\n        similarity[None], (1, 11), stride=(1, 1), padding=(0, 5))[0]\n    similarity_vec = similarity_smooth.diagonal(offset=index - m +\n                                                1).cpu().numpy()\n\n    stu_start = max(0, m - 1 - index)\n    tch_start = max(0, index - m + 1)\n\n    return dict(\n        stu_start=stu_start,\n        tch_start=tch_start,\n        length=len(similarity_vec),\n        similarity=similarity_vec)\n"
  },
  {
    "path": "projects/just_dance/configs/rtmdet-nano_one-person.py",
    "content": "_base_ = '../../rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py'\n\nmodel = dict(test_cfg=dict(nms_pre=1, score_thr=0.0, max_per_img=1))\n"
  },
  {
    "path": "projects/just_dance/just_dance_demo.ipynb",
    "content": "{\n \"cells\": [\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"6d999c38-2087-4250-b6a4-a30cf8b44ec0\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T13:11:38.997916Z\",\n     \"iopub.status.busy\": \"2023-07-05T13:11:38.997587Z\",\n     \"iopub.status.idle\": \"2023-07-05T13:11:39.001928Z\",\n     \"shell.execute_reply\": \"2023-07-05T13:11:39.001429Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T13:11:38.997898Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"%matplotlib inline\\n\",\n    \"import matplotlib.pyplot as plt\\n\",\n    \"import os.path as osp\\n\",\n    \"import torch\\n\",\n    \"import numpy as np\\n\",\n    \"import mmcv\\n\",\n    \"import cv2\\n\",\n    \"from mmengine.utils import track_iter_progress\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"bfa9bf9b-dc2c-4803-a034-8ae8778113e0\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:42:15.884465Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:42:15.884167Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:42:19.774569Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:42:19.774020Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:42:15.884448Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# download example videos\\n\",\n    \"from mmengine.utils import mkdir_or_exist\\n\",\n    \"mkdir_or_exist('resources')\\n\",\n    \"! wget -O resources/student_video.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/tom.mp4 \\n\",\n    \"! wget -O resources/teacher_video.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/idol_producer.mp4 \\n\",\n    \"# ! wget -O resources/student_video.mp4 https://download.openmmlab.com/mmpose/v1/projects/just_dance/tsinghua_30fps.mp4 \\n\",\n    \"\\n\",\n    \"student_video = 'resources/student_video.mp4'\\n\",\n    \"teacher_video = 'resources/teacher_video.mp4'\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"652b6b91-e1c0-461b-90e5-653bc35ec380\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:42:20.693931Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:42:20.693353Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:43:14.533985Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:43:14.533431Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:42:20.693910Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# convert the fps of videos to 30\\n\",\n    \"from mmcv import VideoReader\\n\",\n    \"\\n\",\n    \"if VideoReader(student_video) != 30:\\n\",\n    \"    # ffmpeg is required to convert the video fps\\n\",\n    \"    # which can be installed via `sudo apt install ffmpeg` on ubuntu\\n\",\n    \"    student_video_30fps = student_video.replace(\\n\",\n    \"        f\\\".{student_video.rsplit('.', 1)[1]}\\\",\\n\",\n    \"        f\\\"_30fps.{student_video.rsplit('.', 1)[1]}\\\"\\n\",\n    \"    )\\n\",\n    \"    !ffmpeg -i {student_video} -vf \\\"minterpolate='fps=30'\\\" {student_video_30fps}\\n\",\n    \"    student_video = student_video_30fps\\n\",\n    \"    \\n\",\n    \"if VideoReader(teacher_video) != 30:\\n\",\n    \"    teacher_video_30fps = teacher_video.replace(\\n\",\n    \"        f\\\".{teacher_video.rsplit('.', 1)[1]}\\\",\\n\",\n    \"        f\\\"_30fps.{teacher_video.rsplit('.', 1)[1]}\\\"\\n\",\n    \"    )\\n\",\n    \"    !ffmpeg -i {teacher_video} -vf \\\"minterpolate='fps=30'\\\" {teacher_video_30fps}\\n\",\n    \"    teacher_video = teacher_video_30fps    \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"6a4e141d-ee4a-4e06-a380-230418c9b936\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:45:01.672054Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:45:01.671727Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:45:02.417026Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:45:02.416567Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:45:01.672035Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# init pose estimator\\n\",\n    \"from mmpose.apis.inferencers import Pose2DInferencer\\n\",\n    \"pose_estimator = Pose2DInferencer(\\n\",\n    \"    'rtmpose-t_8xb256-420e_aic-coco-256x192',\\n\",\n    \"    det_model='configs/rtmdet-nano_one-person.py',\\n\",\n    \"    det_weights='https://download.openmmlab.com/mmpose/v1/projects/' \\n\",\n    \"    'rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth'\\n\",\n    \")\\n\",\n    \"pose_estimator.model.test_cfg['flip_test'] = False\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"879ba5c0-4d2d-4cca-92d7-d4f94e04a821\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:45:05.192437Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:45:05.191982Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:45:05.197379Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:45:05.196780Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:45:05.192417Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"@torch.no_grad()\\n\",\n    \"def get_keypoints_from_frame(image, pose_estimator):\\n\",\n    \"    \\\"\\\"\\\"Extract keypoints from a single video frame.\\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"    det_results = pose_estimator.detector(\\n\",\n    \"        image, return_datasample=True)['predictions']\\n\",\n    \"    pred_instance = det_results[0].pred_instances.numpy()\\n\",\n    \"\\n\",\n    \"    if len(pred_instance) == 0 or pred_instance.scores[0] < 0.2:\\n\",\n    \"        return np.zeros((1, 17, 3), dtype=np.float32)\\n\",\n    \"\\n\",\n    \"    data_info = dict(\\n\",\n    \"        img=image,\\n\",\n    \"        bbox=pred_instance.bboxes[:1],\\n\",\n    \"        bbox_score=pred_instance.scores[:1])\\n\",\n    \"\\n\",\n    \"    data_info.update(pose_estimator.model.dataset_meta)\\n\",\n    \"    data = pose_estimator.collate_fn(\\n\",\n    \"        [pose_estimator.pipeline(data_info)])\\n\",\n    \"\\n\",\n    \"    # custom forward\\n\",\n    \"    data = pose_estimator.model.data_preprocessor(data, False)\\n\",\n    \"    feats = pose_estimator.model.extract_feat(data['inputs'])\\n\",\n    \"    pred_instances = pose_estimator.model.head.predict(\\n\",\n    \"        feats,\\n\",\n    \"        data['data_samples'],\\n\",\n    \"        test_cfg=pose_estimator.model.test_cfg)[0]\\n\",\n    \"    keypoints = np.concatenate(\\n\",\n    \"        (pred_instances.keypoints, pred_instances.keypoint_scores[...,\\n\",\n    \"                                                                  None]),\\n\",\n    \"        axis=-1)\\n\",\n    \"\\n\",\n    \"    return keypoints    \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"31e5bd4c-4c2b-4fe0-b64c-1afed67b7688\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:47:55.564788Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:47:55.564450Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:49:37.222662Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:49:37.222028Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:47:55.564770Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# pose estimation in two videos\\n\",\n    \"student_poses, teacher_poses = [], []\\n\",\n    \"for frame in VideoReader(student_video):\\n\",\n    \"    student_poses.append(get_keypoints_from_frame(frame, pose_estimator))\\n\",\n    \"for frame in VideoReader(teacher_video):\\n\",\n    \"    teacher_poses.append(get_keypoints_from_frame(frame, pose_estimator))\\n\",\n    \"    \\n\",\n    \"student_poses = np.concatenate(student_poses)\\n\",\n    \"teacher_poses = np.concatenate(teacher_poses)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"38a8d7a5-17ed-4ce2-bb8b-d1637cb49578\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:55:09.342432Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:55:09.342185Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:55:09.350522Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:55:09.350099Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:55:09.342416Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"valid_indices = np.array([0] + list(range(5, 17)))\\n\",\n    \"\\n\",\n    \"@torch.no_grad()\\n\",\n    \"def _calculate_similarity(tch_kpts: np.ndarray, stu_kpts: np.ndarray):\\n\",\n    \"\\n\",\n    \"    stu_kpts = torch.from_numpy(stu_kpts[:, None, valid_indices])\\n\",\n    \"    tch_kpts = torch.from_numpy(tch_kpts[None, :, valid_indices])\\n\",\n    \"    stu_kpts = stu_kpts.expand(stu_kpts.shape[0], tch_kpts.shape[1],\\n\",\n    \"                               stu_kpts.shape[2], 3)\\n\",\n    \"    tch_kpts = tch_kpts.expand(stu_kpts.shape[0], tch_kpts.shape[1],\\n\",\n    \"                               stu_kpts.shape[2], 3)\\n\",\n    \"\\n\",\n    \"    matrix = torch.stack((stu_kpts, tch_kpts), dim=4)\\n\",\n    \"    if torch.cuda.is_available():\\n\",\n    \"        matrix = matrix.cuda()\\n\",\n    \"    # only consider visible keypoints\\n\",\n    \"    mask = torch.logical_and(matrix[:, :, :, 2, 0] > 0.3,\\n\",\n    \"                             matrix[:, :, :, 2, 1] > 0.3)\\n\",\n    \"    matrix[~mask] = 0.0\\n\",\n    \"\\n\",\n    \"    matrix_ = matrix.clone()\\n\",\n    \"    matrix_[matrix == 0] = 256\\n\",\n    \"    x_min = matrix_.narrow(3, 0, 1).min(dim=2).values\\n\",\n    \"    y_min = matrix_.narrow(3, 1, 1).min(dim=2).values\\n\",\n    \"    matrix_ = matrix.clone()\\n\",\n    \"    x_max = matrix_.narrow(3, 0, 1).max(dim=2).values\\n\",\n    \"    y_max = matrix_.narrow(3, 1, 1).max(dim=2).values\\n\",\n    \"\\n\",\n    \"    matrix_ = matrix.clone()\\n\",\n    \"    matrix_[:, :, :, 0] = (matrix_[:, :, :, 0] - x_min) / (\\n\",\n    \"        x_max - x_min + 1e-4)\\n\",\n    \"    matrix_[:, :, :, 1] = (matrix_[:, :, :, 1] - y_min) / (\\n\",\n    \"        y_max - y_min + 1e-4)\\n\",\n    \"    matrix_[:, :, :, 2] = (matrix_[:, :, :, 2] > 0.3).float()\\n\",\n    \"    xy_dist = matrix_[..., :2, 0] - matrix_[..., :2, 1]\\n\",\n    \"    score = matrix_[..., 2, 0] * matrix_[..., 2, 1]\\n\",\n    \"\\n\",\n    \"    similarity = (torch.exp(-50 * xy_dist.pow(2).sum(dim=-1)) *\\n\",\n    \"                  score).sum(dim=-1) / (\\n\",\n    \"                      score.sum(dim=-1) + 1e-6)\\n\",\n    \"    num_visible_kpts = score.sum(dim=-1)\\n\",\n    \"    similarity = similarity * torch.log(\\n\",\n    \"        (1 + (num_visible_kpts - 1) * 10).clamp(min=1)) / np.log(161)\\n\",\n    \"\\n\",\n    \"    similarity[similarity.isnan()] = 0\\n\",\n    \"\\n\",\n    \"    return similarity\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"658bcf89-df06-4c73-9323-8973a49c14c3\",\n   \"metadata\": {\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:55:31.978675Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:55:31.978219Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:55:32.149624Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:55:32.148568Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:55:31.978657Z\"\n    }\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# compute similarity without flip\\n\",\n    \"similarity1 = _calculate_similarity(teacher_poses, student_poses)\\n\",\n    \"\\n\",\n    \"# compute similarity with flip\\n\",\n    \"flip_indices = np.array(\\n\",\n    \"    [0, 2, 1, 4, 3, 6, 5, 8, 7, 10, 9, 12, 11, 14, 13, 16, 15])\\n\",\n    \"student_poses_flip = student_poses[:, flip_indices]\\n\",\n    \"student_poses_flip[..., 0] = 191.5 - student_poses_flip[..., 0]\\n\",\n    \"similarity2 = _calculate_similarity(teacher_poses, student_poses_flip)\\n\",\n    \"\\n\",\n    \"# select the larger similarity\\n\",\n    \"similarity = torch.stack((similarity1, similarity2)).max(dim=0).values\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"f981410d-4585-47c1-98c0-6946f948487d\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": false\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:55:57.321845Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:55:57.321530Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:55:57.582879Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:55:57.582425Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:55:57.321826Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"# visualize the similarity\\n\",\n    \"plt.imshow(similarity.cpu().numpy())\\n\",\n    \"\\n\",\n    \"# there is an apparent diagonal in the figure\\n\",\n    \"# we can select matched video snippets with this diagonal\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"13c189e5-fc53-46a2-9057-f0f2ffc1f46d\",\n   \"metadata\": {\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:58:16.913855Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:58:16.913529Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:58:16.919972Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:58:16.919005Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:58:16.913837Z\"\n    }\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"@torch.no_grad()\\n\",\n    \"def select_piece_from_similarity(similarity):\\n\",\n    \"    m, n = similarity.size()\\n\",\n    \"    row_indices = torch.arange(m).view(-1, 1).expand(m, n).to(similarity)\\n\",\n    \"    col_indices = torch.arange(n).view(1, -1).expand(m, n).to(similarity)\\n\",\n    \"    diagonal_indices = similarity.size(0) - 1 - row_indices + col_indices\\n\",\n    \"    unique_diagonal_indices, inverse_indices = torch.unique(\\n\",\n    \"        diagonal_indices, return_inverse=True)\\n\",\n    \"\\n\",\n    \"    diagonal_sums_list = torch.zeros(\\n\",\n    \"        unique_diagonal_indices.size(0),\\n\",\n    \"        dtype=similarity.dtype,\\n\",\n    \"        device=similarity.device)\\n\",\n    \"    diagonal_sums_list.scatter_add_(0, inverse_indices.view(-1),\\n\",\n    \"                                    similarity.view(-1))\\n\",\n    \"    diagonal_sums_list[:min(m, n) // 4] = 0\\n\",\n    \"    diagonal_sums_list[-min(m, n) // 4:] = 0\\n\",\n    \"    index = diagonal_sums_list.argmax().item()\\n\",\n    \"\\n\",\n    \"    similarity_smooth = torch.nn.functional.max_pool2d(\\n\",\n    \"        similarity[None], (1, 11), stride=(1, 1), padding=(0, 5))[0]\\n\",\n    \"    similarity_vec = similarity_smooth.diagonal(offset=index - m +\\n\",\n    \"                                                1).cpu().numpy()\\n\",\n    \"\\n\",\n    \"    stu_start = max(0, m - 1 - index)\\n\",\n    \"    tch_start = max(0, index - m + 1)\\n\",\n    \"\\n\",\n    \"    return dict(\\n\",\n    \"        stu_start=stu_start,\\n\",\n    \"        tch_start=tch_start,\\n\",\n    \"        length=len(similarity_vec),\\n\",\n    \"        similarity=similarity_vec)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"7c0e19df-949d-471d-804d-409b3b9ddf7d\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T12:58:44.860190Z\",\n     \"iopub.status.busy\": \"2023-07-05T12:58:44.859878Z\",\n     \"iopub.status.idle\": \"2023-07-05T12:58:44.888465Z\",\n     \"shell.execute_reply\": \"2023-07-05T12:58:44.887917Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T12:58:44.860173Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"matched_piece_info = select_piece_from_similarity(similarity)\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"51b0a2bd-253c-4a8f-a82a-263e18a4703e\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T13:01:19.061408Z\",\n     \"iopub.status.busy\": \"2023-07-05T13:01:19.060857Z\",\n     \"iopub.status.idle\": \"2023-07-05T13:01:19.293742Z\",\n     \"shell.execute_reply\": \"2023-07-05T13:01:19.293298Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T13:01:19.061378Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"plt.imshow(similarity.cpu().numpy())\\n\",\n    \"plt.plot((matched_piece_info['tch_start'], \\n\",\n    \"          matched_piece_info['tch_start']+matched_piece_info['length']-1),\\n\",\n    \"         (matched_piece_info['stu_start'],\\n\",\n    \"          matched_piece_info['stu_start']+matched_piece_info['length']-1), 'r')\"\n   ]\n  },\n  {\n   \"cell_type\": \"markdown\",\n   \"id\": \"ffcde4e7-ff50-483a-b515-604c1d8f121a\",\n   \"metadata\": {},\n   \"source\": [\n    \"# Generate Output Video\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"72171a0c-ab33-45bb-b84c-b15f0816ed3a\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T13:11:50.063595Z\",\n     \"iopub.status.busy\": \"2023-07-05T13:11:50.063259Z\",\n     \"iopub.status.idle\": \"2023-07-05T13:11:50.070929Z\",\n     \"shell.execute_reply\": \"2023-07-05T13:11:50.070411Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T13:11:50.063574Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"from typing import Tuple\\n\",\n    \"\\n\",\n    \"def resize_image_to_fixed_height(image: np.ndarray,\\n\",\n    \"                                 fixed_height: int) -> np.ndarray:\\n\",\n    \"    \\\"\\\"\\\"Resizes an input image to a specified fixed height while maintaining its\\n\",\n    \"    aspect ratio.\\n\",\n    \"\\n\",\n    \"    Args:\\n\",\n    \"        image (np.ndarray): Input image as a numpy array [H, W, C]\\n\",\n    \"        fixed_height (int): Desired fixed height of the output image.\\n\",\n    \"\\n\",\n    \"    Returns:\\n\",\n    \"        Resized image as a numpy array (fixed_height, new_width, channels).\\n\",\n    \"    \\\"\\\"\\\"\\n\",\n    \"    original_height, original_width = image.shape[:2]\\n\",\n    \"\\n\",\n    \"    scale_ratio = fixed_height / original_height\\n\",\n    \"    new_width = int(original_width * scale_ratio)\\n\",\n    \"    resized_image = cv2.resize(image, (new_width, fixed_height))\\n\",\n    \"\\n\",\n    \"    return resized_image\\n\",\n    \"\\n\",\n    \"def blend_images(img1: np.ndarray,\\n\",\n    \"                 img2: np.ndarray,\\n\",\n    \"                 blend_ratios: Tuple[float, float] = (1, 1)) -> np.ndarray:\\n\",\n    \"    \\\"\\\"\\\"Blends two input images with specified blend ratios.\\n\",\n    \"\\n\",\n    \"    Args:\\n\",\n    \"        img1 (np.ndarray): First input image as a numpy array [H, W, C].\\n\",\n    \"        img2 (np.ndarray): Second input image as a numpy array [H, W, C]\\n\",\n    \"        blend_ratios (tuple): A tuple of two floats representing the blend\\n\",\n    \"            ratios for the two input images.\\n\",\n    \"\\n\",\n    \"    Returns:\\n\",\n    \"        Blended image as a numpy array [H, W, C]\\n\",\n    \"    \\\"\\\"\\\"\\n\",\n    \"\\n\",\n    \"    def normalize_image(image: np.ndarray) -> np.ndarray:\\n\",\n    \"        if image.dtype == np.uint8:\\n\",\n    \"            return image.astype(np.float32) / 255.0\\n\",\n    \"        return image\\n\",\n    \"\\n\",\n    \"    img1 = normalize_image(img1)\\n\",\n    \"    img2 = normalize_image(img2)\\n\",\n    \"\\n\",\n    \"    blended_image = img1 * blend_ratios[0] + img2 * blend_ratios[1]\\n\",\n    \"    blended_image = blended_image.clip(min=0, max=1)\\n\",\n    \"    blended_image = (blended_image * 255).astype(np.uint8)\\n\",\n    \"\\n\",\n    \"    return blended_image\\n\",\n    \"\\n\",\n    \"def get_smoothed_kpt(kpts, index, sigma=5):\\n\",\n    \"    \\\"\\\"\\\"Smooths keypoints using a Gaussian filter.\\\"\\\"\\\"\\n\",\n    \"    assert kpts.shape[1] == 17\\n\",\n    \"    assert kpts.shape[2] == 3\\n\",\n    \"    assert sigma % 2 == 1\\n\",\n    \"\\n\",\n    \"    num_kpts = len(kpts)\\n\",\n    \"\\n\",\n    \"    start_idx = max(0, index - sigma // 2)\\n\",\n    \"    end_idx = min(num_kpts, index + sigma // 2 + 1)\\n\",\n    \"\\n\",\n    \"    # Extract a piece of the keypoints array to apply the filter\\n\",\n    \"    piece = kpts[start_idx:end_idx].copy()\\n\",\n    \"    original_kpt = kpts[index]\\n\",\n    \"\\n\",\n    \"    # Split the piece into coordinates and scores\\n\",\n    \"    coords, scores = piece[..., :2], piece[..., 2]\\n\",\n    \"\\n\",\n    \"    # Calculate the Gaussian ratio for each keypoint\\n\",\n    \"    gaussian_ratio = np.arange(len(scores)) + start_idx - index\\n\",\n    \"    gaussian_ratio = np.exp(-gaussian_ratio**2 / 2)\\n\",\n    \"\\n\",\n    \"    # Update scores using the Gaussian ratio\\n\",\n    \"    scores *= gaussian_ratio[:, None]\\n\",\n    \"\\n\",\n    \"    # Compute the smoothed coordinates\\n\",\n    \"    smoothed_coords = (coords * scores[..., None]).sum(axis=0) / (\\n\",\n    \"        scores[..., None].sum(axis=0) + 1e-4)\\n\",\n    \"\\n\",\n    \"    original_kpt[..., :2] = smoothed_coords\\n\",\n    \"\\n\",\n    \"    return original_kpt\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"609b5adc-e176-4bf9-b9a4-506f72440017\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T13:12:46.198835Z\",\n     \"iopub.status.busy\": \"2023-07-05T13:12:46.198268Z\",\n     \"iopub.status.idle\": \"2023-07-05T13:12:46.202273Z\",\n     \"shell.execute_reply\": \"2023-07-05T13:12:46.200881Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T13:12:46.198815Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"score, last_vis_score = 0, 0\\n\",\n    \"video_writer = None\\n\",\n    \"output_file = 'output.mp4'\\n\",\n    \"stu_kpts = student_poses\\n\",\n    \"tch_kpts = teacher_poses\"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"a264405a-5d50-49de-8637-2d1f67cb0a70\",\n   \"metadata\": {\n    \"ExecutionIndicator\": {\n     \"show\": true\n    },\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T13:13:11.334760Z\",\n     \"iopub.status.busy\": \"2023-07-05T13:13:11.334433Z\",\n     \"iopub.status.idle\": \"2023-07-05T13:13:17.264181Z\",\n     \"shell.execute_reply\": \"2023-07-05T13:13:17.262931Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T13:13:11.334742Z\"\n    },\n    \"tags\": []\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"from mmengine.structures import InstanceData\\n\",\n    \"\\n\",\n    \"tch_video_reader = VideoReader(teacher_video)\\n\",\n    \"stu_video_reader = VideoReader(student_video)\\n\",\n    \"for _ in range(matched_piece_info['tch_start']):\\n\",\n    \"    _ = next(tch_video_reader)\\n\",\n    \"for _ in range(matched_piece_info['stu_start']):\\n\",\n    \"    _ = next(stu_video_reader)\\n\",\n    \"    \\n\",\n    \"for i in track_iter_progress(range(matched_piece_info['length'])):\\n\",\n    \"    tch_frame = mmcv.bgr2rgb(next(tch_video_reader))\\n\",\n    \"    stu_frame = mmcv.bgr2rgb(next(stu_video_reader))\\n\",\n    \"    tch_frame = resize_image_to_fixed_height(tch_frame, 300)\\n\",\n    \"    stu_frame = resize_image_to_fixed_height(stu_frame, 300)\\n\",\n    \"\\n\",\n    \"    stu_kpt = get_smoothed_kpt(stu_kpts, matched_piece_info['stu_start'] + i,\\n\",\n    \"                               5)\\n\",\n    \"    tch_kpt = get_smoothed_kpt(tch_kpts, matched_piece_info['tch_start'] + i,\\n\",\n    \"                               5)\\n\",\n    \"\\n\",\n    \"    # draw pose\\n\",\n    \"    stu_kpt[..., 1] += (300 - 256)\\n\",\n    \"    tch_kpt[..., 0] += (256 - 192)\\n\",\n    \"    tch_kpt[..., 1] += (300 - 256)\\n\",\n    \"    stu_inst = InstanceData(\\n\",\n    \"        keypoints=stu_kpt[None, :, :2],\\n\",\n    \"        keypoint_scores=stu_kpt[None, :, 2])\\n\",\n    \"    tch_inst = InstanceData(\\n\",\n    \"        keypoints=tch_kpt[None, :, :2],\\n\",\n    \"        keypoint_scores=tch_kpt[None, :, 2])\\n\",\n    \"    \\n\",\n    \"    stu_out_img = pose_estimator.visualizer._draw_instances_kpts(\\n\",\n    \"        np.zeros((300, 256, 3)), stu_inst)\\n\",\n    \"    tch_out_img = pose_estimator.visualizer._draw_instances_kpts(\\n\",\n    \"        np.zeros((300, 256, 3)), tch_inst)\\n\",\n    \"    out_img = blend_images(\\n\",\n    \"        stu_out_img, tch_out_img, blend_ratios=(1, 0.3))\\n\",\n    \"\\n\",\n    \"    # draw score\\n\",\n    \"    score_frame = matched_piece_info['similarity'][i]\\n\",\n    \"    score += score_frame * 1000\\n\",\n    \"    if score - last_vis_score > 1500:\\n\",\n    \"        last_vis_score = score\\n\",\n    \"    pose_estimator.visualizer.set_image(out_img)\\n\",\n    \"    pose_estimator.visualizer.draw_texts(\\n\",\n    \"        'score: ', (60, 30),\\n\",\n    \"        font_sizes=15,\\n\",\n    \"        colors=(255, 255, 255),\\n\",\n    \"        vertical_alignments='bottom')\\n\",\n    \"    pose_estimator.visualizer.draw_texts(\\n\",\n    \"        f'{int(last_vis_score)}', (115, 30),\\n\",\n    \"        font_sizes=30 * max(0.4, score_frame),\\n\",\n    \"        colors=(255, 255, 255),\\n\",\n    \"        vertical_alignments='bottom')\\n\",\n    \"    out_img = pose_estimator.visualizer.get_image()   \\n\",\n    \"    \\n\",\n    \"    # concatenate\\n\",\n    \"    concatenated_image = np.hstack((stu_frame, out_img, tch_frame))\\n\",\n    \"    if video_writer is None:\\n\",\n    \"        video_writer = cv2.VideoWriter(output_file,\\n\",\n    \"                                       cv2.VideoWriter_fourcc(*'mp4v'),\\n\",\n    \"                                       30,\\n\",\n    \"                                       (concatenated_image.shape[1],\\n\",\n    \"                                        concatenated_image.shape[0]))\\n\",\n    \"    video_writer.write(mmcv.rgb2bgr(concatenated_image))\\n\",\n    \"\\n\",\n    \"  \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"745fdd75-6ed4-4cae-9f21-c2cd486ee918\",\n   \"metadata\": {\n    \"execution\": {\n     \"iopub.execute_input\": \"2023-07-05T13:13:18.704492Z\",\n     \"iopub.status.busy\": \"2023-07-05T13:13:18.704179Z\",\n     \"iopub.status.idle\": \"2023-07-05T13:13:18.714843Z\",\n     \"shell.execute_reply\": \"2023-07-05T13:13:18.713866Z\",\n     \"shell.execute_reply.started\": \"2023-07-05T13:13:18.704472Z\"\n    }\n   },\n   \"outputs\": [],\n   \"source\": [\n    \"if video_writer is not None:\\n\",\n    \"    video_writer.release()  \"\n   ]\n  },\n  {\n   \"cell_type\": \"code\",\n   \"execution_count\": null,\n   \"id\": \"7cb0bc99-ca19-44f1-bc0a-38e14afa980f\",\n   \"metadata\": {},\n   \"outputs\": [],\n   \"source\": []\n  }\n ],\n \"metadata\": {\n  \"kernelspec\": {\n   \"display_name\": \"Python 3 (ipykernel)\",\n   \"language\": \"python\",\n   \"name\": \"python3\"\n  },\n  \"language_info\": {\n   \"codemirror_mode\": {\n    \"name\": \"ipython\",\n    \"version\": 3\n   },\n   \"file_extension\": \".py\",\n   \"mimetype\": \"text/x-python\",\n   \"name\": \"python\",\n   \"nbconvert_exporter\": \"python\",\n   \"pygments_lexer\": \"ipython3\",\n   \"version\": \"3.9.15\"\n  }\n },\n \"nbformat\": 4,\n \"nbformat_minor\": 5\n}\n"
  },
  {
    "path": "projects/just_dance/process_video.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport tempfile\nfrom typing import Optional\n\nimport cv2\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmengine.structures import InstanceData\nfrom mmengine.utils import track_iter_progress\n\nfrom mmpose.apis import Pose2DInferencer\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.visualization import PoseLocalVisualizer\n\ntry:\n    from .calculate_similarity import (calculate_similarity,\n                                       select_piece_from_similarity)\n    from .utils import (blend_images, convert_video_fps, get_smoothed_kpt,\n                        resize_image_to_fixed_height)\nexcept ImportError:\n    from calculate_similarity import (calculate_similarity,\n                                      select_piece_from_similarity)\n    from utils import (blend_images, convert_video_fps, get_smoothed_kpt,\n                       resize_image_to_fixed_height)\n\nmodel_cfg = dict(\n    human=dict(\n        model='rtmpose-t_8xb256-420e_aic-coco-256x192',\n        det_model=os.path.join(\n            os.path.dirname(os.path.abspath(__file__)),\n            'configs/rtmdet-nano_one-person.py'),\n        det_weights='https://download.openmmlab.com/mmpose/v1/projects/'\n        'rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth',\n    ),\n    bear=dict(\n        model='rtmpose-l_8xb256-420e_humanart-256x192',\n        det_model='rtmdet-m',\n        det_cat_ids=77,\n    ),\n)\n\n\nclass VideoProcessor:\n    \"\"\"A class to process videos for pose estimation and visualization.\"\"\"\n\n    def __init__(self):\n        self.category = 'human'\n\n    def _set_category(self, category):\n        assert category in model_cfg\n        self.category = category\n\n    @property\n    def pose_estimator(self) -> Pose2DInferencer:\n        if not hasattr(self, '_pose_estimator'):\n            self._pose_estimator = dict()\n        if self.category not in self._pose_estimator:\n            self._pose_estimator[self.category] = Pose2DInferencer(\n                **(model_cfg[self.category]))\n            self._pose_estimator[\n                self.category].model.test_cfg['flip_test'] = False\n        return self._pose_estimator[self.category]\n\n    @property\n    def visualizer(self) -> PoseLocalVisualizer:\n        if hasattr(self, '_visualizer'):\n            return self._visualizer\n        elif hasattr(self, '_pose_estimator'):\n            return self.pose_estimator.visualizer\n\n        # init visualizer\n        self._visualizer = PoseLocalVisualizer()\n        metainfo_file = os.path.join(\n            os.path.dirname(os.path.abspath(__file__)).rsplit(os.sep, 1)[0],\n            'configs/_base_/datasets/coco.py')\n        metainfo = parse_pose_metainfo(dict(from_file=metainfo_file))\n        self._visualizer.set_dataset_meta(metainfo)\n        return self._visualizer\n\n    @torch.no_grad()\n    def get_keypoints_from_frame(self, image: np.ndarray) -> np.ndarray:\n        \"\"\"Extract keypoints from a single video frame.\"\"\"\n\n        det_results = self.pose_estimator.detector(\n            image, return_datasamples=True)['predictions']\n        pred_instance = det_results[0].pred_instances\n\n        if len(pred_instance) == 0:\n            return np.zeros((1, 17, 3), dtype=np.float32)\n\n        # only select the most significant person\n        data_info = dict(\n            img=image,\n            bbox=pred_instance.bboxes.cpu().numpy()[:1],\n            bbox_score=pred_instance.scores.cpu().numpy()[:1])\n\n        if data_info['bbox_score'] < 0.2:\n            return np.zeros((1, 17, 3), dtype=np.float32)\n\n        data_info.update(self.pose_estimator.model.dataset_meta)\n        data = self.pose_estimator.collate_fn(\n            [self.pose_estimator.pipeline(data_info)])\n\n        # custom forward\n        data = self.pose_estimator.model.data_preprocessor(data, False)\n        feats = self.pose_estimator.model.extract_feat(data['inputs'])\n        pred_instances = self.pose_estimator.model.head.predict(\n            feats,\n            data['data_samples'],\n            test_cfg=self.pose_estimator.model.test_cfg)[0]\n        keypoints = np.concatenate(\n            (pred_instances.keypoints, pred_instances.keypoint_scores[...,\n                                                                      None]),\n            axis=-1)\n\n        return keypoints\n\n    @torch.no_grad()\n    def get_keypoints_from_video(self, video: str) -> np.ndarray:\n        \"\"\"Extract keypoints from a video.\"\"\"\n\n        video_fname = video.rsplit('.', 1)[0]\n        if os.path.exists(f'{video_fname}_kpts.pth'):\n            keypoints = torch.load(f'{video_fname}_kpts.pth')\n            return keypoints\n\n        video_reader = mmcv.VideoReader(video)\n\n        if abs(video_reader.fps - 30) > 0.1:\n            video_reader = mmcv.VideoReader(convert_video_fps(video))\n\n        assert abs(video_reader.fps - 30) < 0.1, f'only support videos with ' \\\n            f'30 FPS, but the video {video_fname} has {video_reader.fps} fps'\n\n        if os.path.basename(video_fname).startswith('bear'):\n            self._set_category('bear')\n        else:\n            self._set_category('human')\n        keypoints_list = []\n        for i, frame in enumerate(video_reader):\n            keypoints = self.get_keypoints_from_frame(frame)\n            keypoints_list.append(keypoints)\n        keypoints = np.concatenate(keypoints_list)\n        torch.save(keypoints, f'{video_fname}_kpts.pth')\n        return keypoints\n\n    @torch.no_grad()\n    def run(self,\n            tch_video: str,\n            stu_video: str,\n            output_file: Optional[str] = None):\n        # extract human poses\n        tch_kpts = self.get_keypoints_from_video(tch_video)\n        stu_kpts = self.get_keypoints_from_video(stu_video)\n\n        # compute similarity\n        similarity = calculate_similarity(tch_kpts, stu_kpts)\n\n        # select piece\n        piece_info = select_piece_from_similarity(similarity)\n\n        # output\n        tch_name = os.path.basename(tch_video).rsplit('.', 1)[0]\n        stu_name = os.path.basename(stu_video).rsplit('.', 1)[0]\n        if output_file is None:\n            fname = f'{tch_name}-{stu_name}.mp4'\n            output_file = os.path.join(tempfile.mkdtemp(), fname)\n        return self.generate_output_video(tch_video, stu_video, output_file,\n                                          tch_kpts, stu_kpts, piece_info)\n\n    def generate_output_video(self, tch_video: str, stu_video: str,\n                              output_file: str, tch_kpts: np.ndarray,\n                              stu_kpts: np.ndarray, piece_info: dict) -> str:\n        \"\"\"Generate an output video with keypoints overlay.\"\"\"\n\n        tch_video_reader = mmcv.VideoReader(tch_video)\n        stu_video_reader = mmcv.VideoReader(stu_video)\n        for _ in range(piece_info['tch_start']):\n            _ = next(tch_video_reader)\n        for _ in range(piece_info['stu_start']):\n            _ = next(stu_video_reader)\n\n        score, last_vis_score = 0, 0\n        video_writer = None\n        for i in track_iter_progress(range(piece_info['length'])):\n            tch_frame = mmcv.bgr2rgb(next(tch_video_reader))\n            stu_frame = mmcv.bgr2rgb(next(stu_video_reader))\n            tch_frame = resize_image_to_fixed_height(tch_frame, 300)\n            stu_frame = resize_image_to_fixed_height(stu_frame, 300)\n\n            stu_kpt = get_smoothed_kpt(stu_kpts, piece_info['stu_start'] + i,\n                                       5)\n            tch_kpt = get_smoothed_kpt(tch_kpts, piece_info['tch_start'] + i,\n                                       5)\n\n            # draw pose\n            stu_kpt[..., 1] += (300 - 256)\n            tch_kpt[..., 0] += (256 - 192)\n            tch_kpt[..., 1] += (300 - 256)\n            stu_inst = InstanceData(\n                keypoints=stu_kpt[None, :, :2],\n                keypoint_scores=stu_kpt[None, :, 2])\n            tch_inst = InstanceData(\n                keypoints=tch_kpt[None, :, :2],\n                keypoint_scores=tch_kpt[None, :, 2])\n\n            stu_out_img = self.visualizer._draw_instances_kpts(\n                np.zeros((300, 256, 3)), stu_inst)\n            tch_out_img = self.visualizer._draw_instances_kpts(\n                np.zeros((300, 256, 3)), tch_inst)\n            out_img = blend_images(\n                stu_out_img, tch_out_img, blend_ratios=(1, 0.3))\n\n            # draw score\n            score_frame = piece_info['similarity'][i]\n            score += score_frame * 1000\n            if score - last_vis_score > 1500:\n                last_vis_score = score\n            self.visualizer.set_image(out_img)\n            self.visualizer.draw_texts(\n                'score: ', (60, 30),\n                font_sizes=15,\n                colors=(255, 255, 255),\n                vertical_alignments='bottom')\n            self.visualizer.draw_texts(\n                f'{int(last_vis_score)}', (115, 30),\n                font_sizes=30 * max(0.4, score_frame),\n                colors=(255, 255, 255),\n                vertical_alignments='bottom')\n            out_img = self.visualizer.get_image()\n\n            # concatenate\n            concatenated_image = np.hstack((stu_frame, out_img, tch_frame))\n            if video_writer is None:\n                video_writer = cv2.VideoWriter(output_file,\n                                               cv2.VideoWriter_fourcc(*'mp4v'),\n                                               30,\n                                               (concatenated_image.shape[1],\n                                                concatenated_image.shape[0]))\n            video_writer.write(mmcv.rgb2bgr(concatenated_image))\n\n        if video_writer is not None:\n            video_writer.release()\n        return output_file\n\n\nif __name__ == '__main__':\n    from argparse import ArgumentParser\n    parser = ArgumentParser()\n    parser.add_argument('teacher_video', help='Path to the Teacher Video')\n    parser.add_argument('student_video', help='Path to the Student Video')\n    parser.add_argument(\n        '--output-file', help='Path to save the output Video', default=None)\n    args = parser.parse_args()\n\n    processor = VideoProcessor()\n    processor.run(args.teacher_video, args.student_video, args.output_file)\n"
  },
  {
    "path": "projects/just_dance/utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nfrom typing import Tuple\n\nimport cv2\nimport numpy as np\n\n\ndef resize_image_to_fixed_height(image: np.ndarray,\n                                 fixed_height: int) -> np.ndarray:\n    \"\"\"Resizes an input image to a specified fixed height while maintaining its\n    aspect ratio.\n\n    Args:\n        image (np.ndarray): Input image as a numpy array [H, W, C]\n        fixed_height (int): Desired fixed height of the output image.\n\n    Returns:\n        Resized image as a numpy array (fixed_height, new_width, channels).\n    \"\"\"\n    original_height, original_width = image.shape[:2]\n\n    scale_ratio = fixed_height / original_height\n    new_width = int(original_width * scale_ratio)\n    resized_image = cv2.resize(image, (new_width, fixed_height))\n\n    return resized_image\n\n\ndef blend_images(img1: np.ndarray,\n                 img2: np.ndarray,\n                 blend_ratios: Tuple[float, float] = (1, 1)) -> np.ndarray:\n    \"\"\"Blends two input images with specified blend ratios.\n\n    Args:\n        img1 (np.ndarray): First input image as a numpy array [H, W, C].\n        img2 (np.ndarray): Second input image as a numpy array [H, W, C]\n        blend_ratios (tuple): A tuple of two floats representing the blend\n            ratios for the two input images.\n\n    Returns:\n        Blended image as a numpy array [H, W, C]\n    \"\"\"\n\n    def normalize_image(image: np.ndarray) -> np.ndarray:\n        if image.dtype == np.uint8:\n            return image.astype(np.float32) / 255.0\n        return image\n\n    img1 = normalize_image(img1)\n    img2 = normalize_image(img2)\n\n    blended_image = img1 * blend_ratios[0] + img2 * blend_ratios[1]\n    blended_image = blended_image.clip(min=0, max=1)\n    blended_image = (blended_image * 255).astype(np.uint8)\n\n    return blended_image\n\n\ndef convert_video_fps(video):\n\n    input_video = video\n    video_name, post_fix = input_video.rsplit('.', 1)\n    output_video = f'{video_name}_30fps.{post_fix}'\n    if os.path.exists(output_video):\n        return output_video\n\n    os.system(\n        f\"ffmpeg -i {input_video} -vf \\\"minterpolate='fps=30'\\\" {output_video}\"\n    )\n\n    return output_video\n\n\ndef get_smoothed_kpt(kpts, index, sigma=5):\n    \"\"\"Smooths keypoints using a Gaussian filter.\"\"\"\n    assert kpts.shape[1] == 17\n    assert kpts.shape[2] == 3\n    assert sigma % 2 == 1\n\n    num_kpts = len(kpts)\n\n    start_idx = max(0, index - sigma // 2)\n    end_idx = min(num_kpts, index + sigma // 2 + 1)\n\n    # Extract a piece of the keypoints array to apply the filter\n    piece = kpts[start_idx:end_idx].copy()\n    original_kpt = kpts[index]\n\n    # Split the piece into coordinates and scores\n    coords, scores = piece[..., :2], piece[..., 2]\n\n    # Calculate the Gaussian ratio for each keypoint\n    gaussian_ratio = np.arange(len(scores)) + start_idx - index\n    gaussian_ratio = np.exp(-gaussian_ratio**2 / 2)\n\n    # Update scores using the Gaussian ratio\n    scores *= gaussian_ratio[:, None]\n\n    # Compute the smoothed coordinates\n    smoothed_coords = (coords * scores[..., None]).sum(axis=0) / (\n        scores[..., None].sum(axis=0) + 1e-4)\n\n    original_kpt[..., :2] = smoothed_coords\n\n    return original_kpt\n"
  },
  {
    "path": "projects/mmpose4aigc/README.md",
    "content": "# MMPose for AIGC (AI Generated Content)\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/222403836-c65ba905-4bdd-4a44-834c-ff8d5959649d.png\" width=1000 />\n</div>\n\nEnglish | [简体中文](./README_CN.md)\n\nThis project will demonstrate how to use MMPose to generate skeleton images for pose guided AI image generation.\n\nCurrently, we support:\n\n- [T2I Adapter](https://huggingface.co/spaces/Adapter/T2I-Adapter)\n\nPlease feel free to share interesting pose-guided AIGC projects to us!\n\n## Get Started\n\n### Generate OpenPose-style Skeleton\n\n#### Step 1: Preparation\n\nRun the following commands to prepare the project:\n\n```shell\n# install mmpose mmdet\npip install openmim\ngit clone https://github.com/open-mmlab/mmpose.git\ncd mmpose\nmim install -e .\nmim install \"mmdet>=3.0.0rc6\"\n\n# download models\nbash download_models.sh\n```\n\n#### Step 2: Generate a Skeleton Image\n\nRun the following command to generate a skeleton image:\n\n```shell\n# generate a skeleton image\nbash mmpose_openpose.sh ../../tests/data/coco/000000000785.jpg\n```\n\nThe input image and its skeleton are as follows:\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/226527894-f9d98e75-fc6c-49e5-ba39-d6277b03697a.jpg\" width=450 /><img src='https://user-images.githubusercontent.com/13503330/226527555-58a86ee6-a886-4986-b1c3-b3841b112995.png' width=450/>\n</div>\n\n### Generate MMPose-style Skeleton\n\n#### Step 1: Preparation\n\n**Env Requirements:**\n\n- GCC >= 7.5\n- cmake >= 3.14\n\nRun the following commands to install the project:\n\n```shell\nbash install_posetracker_linux.sh\n```\n\nAfter installation, files are organized as follows:\n\n```shell\n|----mmdeploy-1.0.0-linux-x86_64-cxx11abi\n|    |----README.md\n|    |----rtmpose-ort\n|    |    |----rtmdet-nano\n|    |    |----rtmpose-m\n|    |    |----000000147979.jpg\n|    |    |----t2i-adapter_skeleton.txt\n```\n\n#### Step 2: Generate a Skeleton Image\n\nRun the following command to generate a skeleton image:\n\n```shell\n# generate a skeleton image\nbash mmpose_style_skeleton.sh \\\n    mmdeploy-1.0.0-linux-x86_64-cxx11abi/rtmpose-ort/000000147979.jpg\n```\n\nFor more details, you can refer to [RTMPose](../rtmpose/README.md).\n\nThe input image and its skeleton are as follows:\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/222318807-a0a2a87a-cfc4-46cc-b647-e8f8bc44cfe3.jpg\" width=300 /><img src='https://user-images.githubusercontent.com/13503330/222318943-6dba5f52-158a-427a-8222-03628addc051.jpg' width=300/>\n</div>\n\n### Upload to T2I-Adapter\n\nThe demo page of T2I- Adapter is [Here](https://huggingface.co/spaces/Adapter/T2I-Adapter).\n\n[![Huggingface Gradio](https://img.shields.io/static/v1?label=Demo&message=Huggingface%20Gradio&color=orange)](https://huggingface.co/spaces/ChongMou/T2I-Adapter)\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/226528354-aac50e26-9188-4b81-9692-274415ee5a87.png\" width=900 />\n</div>\n\n## Gallery\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/226529427-4a34f168-caa2-446b-8aa9-2a60c4082921.png\" width=900 />\n</div>\n"
  },
  {
    "path": "projects/mmpose4aigc/README_CN.md",
    "content": "# MMPose for AIGC (AI Generated Content)\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/222403836-c65ba905-4bdd-4a44-834c-ff8d5959649d.png\" width=1000 />\n</div>\n\n简体中文 | [English](./README.md)\n\n本项目将支持使用 MMPose 来生成骨架图片，用于姿态引导的 AI 图像生成。\n\n当前已支持：\n\n- [T2I Adapter](https://huggingface.co/spaces/Adapter/T2I-Adapter)\n\n欢迎分享更多姿态引导的 AIGC 项目给我们！\n\n## 快速上手\n\n### 生成 Openpose 风格的骨架图片\n\n#### Step 1: 准备\n\n运行以下命令准备项目：\n\n```shell\n# install mmpose mmdet\npip install openmim\ngit clone https://github.com/open-mmlab/mmpose.git\ncd mmpose\nmim install -e .\nmim install \"mmdet>=3.0.0rc6\"\n\n# download models\nbash download_models.sh\n```\n\n#### Step 2: 生成骨架图片\n\n运行以下命令生成骨架图片：\n\n```shell\nbash mmpose_openpose.sh ../../tests/data/coco/000000000785.jpg\n```\n\n输入图片与生成骨架图片如下:\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/226527894-f9d98e75-fc6c-49e5-ba39-d6277b03697a.jpg\" width=450 /><img src='https://user-images.githubusercontent.com/13503330/226527555-58a86ee6-a886-4986-b1c3-b3841b112995.png' width=450/>\n</div>\n\n### 生成 MMPose 风格的骨架图片\n\n#### Step 1: 准备\n\n**环境要求：**\n\n- GCC >= 7.5\n- cmake >= 3.14\n\n运行以下命令安装项目：\n\n```shell\nbash install_posetracker_linux.sh\n```\n\n最终的文件结构如下：\n\n```shell\n|----mmdeploy-1.0.0-linux-x86_64-cxx11abi\n|    |----README.md\n|    |----rtmpose-ort\n|    |    |----rtmdet-nano\n|    |    |----rtmpose-m\n|    |    |----000000147979.jpg\n|    |    |----t2i-adapter_skeleton.txt\n```\n\n#### Step 2: 生成姿态骨架图片\n\n运行以下命令生成姿态骨架图片：\n\n```shell\n# 生成骨架图片\nbash mmpose_style_skeleton.sh \\\n    mmdeploy-1.0.0-linux-x86_64-cxx11abi/rtmpose-ort/000000147979.jpg\n```\n\n更多详细信息可以查看 [RTMPose](../rtmpose/README_CN.md)。\n\n输入图片与生成骨架图片如下:\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/222318807-a0a2a87a-cfc4-46cc-b647-e8f8bc44cfe3.jpg\" width=450 /><img src='https://user-images.githubusercontent.com/13503330/222318943-6dba5f52-158a-427a-8222-03628addc051.jpg' width=450/>\n</div>\n\n### 使用 T2I-Adapter\n\nT2I- Adapter 在线试玩请点击 [这里](https://huggingface.co/spaces/Adapter/T2I-Adapter)\n\n[![Huggingface Gradio](https://img.shields.io/static/v1?label=Demo&message=Huggingface%20Gradio&color=orange)](https://huggingface.co/spaces/ChongMou/T2I-Adapter)\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/226528354-aac50e26-9188-4b81-9692-274415ee5a87.png\" width=900 />\n</div>\n\n## 结果展示\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/226529427-4a34f168-caa2-446b-8aa9-2a60c4082921.png\" width=900 />\n</div>\n"
  },
  {
    "path": "projects/mmpose4aigc/download_models.sh",
    "content": "#!/bin/bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\n# Create models folder\nmkdir models\n\n# Go to models folder\ncd models\n\n# Download det model\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth\n\n# Download pose model\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth\n\n# Go back mmpose4aigc\ncd ..\n\n# Success\necho \"Download completed.\"\n"
  },
  {
    "path": "projects/mmpose4aigc/install_posetracker_linux.sh",
    "content": "#!/bin/bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\n# Download pre-compiled files\nwget https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n\n# Unzip files\ntar -xzvf mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n\n# Go to the sdk folder\ncd mmdeploy-1.0.0-linux-x86_64-cxx11abi\n\n# Init environment\nsource set_env.sh\n\n# If opencv 3+ is not installed on your system, execute the following command.\n# If it is installed, skip this command\nbash install_opencv.sh\n\n# Compile executable programs\nbash build_sdk.sh\n\n# Download models\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-cpu.zip\n\n# Unzip files\nunzip rtmpose-cpu.zip\n\n# Success\necho \"Installation completed.\"\n"
  },
  {
    "path": "projects/mmpose4aigc/mmpose_openpose.sh",
    "content": "#!/bin/bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nINPUT_IMAGE=$1\n\npython openpose_visualization.py \\\n    ../rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    models/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    ../rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    models/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input $INPUT_IMAGE \\\n    --device cuda:0 \\\n"
  },
  {
    "path": "projects/mmpose4aigc/mmpose_style_skeleton.sh",
    "content": "#!/bin/bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nWORKSPACE=mmdeploy-1.0.0-linux-x86_64-cxx11abi\nexport LD_LIBRARY_PATH=${WORKSPACE}/lib:${WORKSPACE}/thirdparty/onnxruntime/lib:$LD_LIBRARY_PATH\n\nINPUT_IMAGE=$1\n\n${WORKSPACE}/bin/pose_tracker \\\n    ${WORKSPACE}/rtmpose-ort/rtmdet-nano \\\n    ${WORKSPACE}/rtmpose-ort/rtmpose-m \\\n    $INPUT_IMAGE \\\n    --background black \\\n    --skeleton ${WORKSPACE}/rtmpose-ort/t2i-adapter_skeleton.txt \\\n    --output ./skeleton_res.jpg \\\n    --pose_kpt_thr 0.4 \\\n    --show -1\n"
  },
  {
    "path": "projects/mmpose4aigc/openpose_visualization.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\nimport mimetypes\nimport os\nfrom argparse import ArgumentParser\nfrom itertools import product\n\nimport cv2\nimport mmcv\nimport numpy as np\nfrom mmengine.registry import init_default_scope\n\nfrom mmpose.apis import inference_topdown\nfrom mmpose.apis import init_model as init_pose_estimator\nfrom mmpose.evaluation.functional import nms\nfrom mmpose.structures import merge_data_samples\n\ntry:\n    from mmdet.apis import inference_detector, init_detector\n    has_mmdet = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmdet = False\n\n# openpose format\nlimb_seq = [[2, 3], [2, 6], [3, 4], [4, 5], [6, 7], [7, 8], [2, 9], [9, 10],\n            [10, 11], [2, 12], [12, 13], [13, 14], [2, 1], [1, 15], [15, 17],\n            [1, 16], [16, 18]]\n\ncolors = [[255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255,\n                                                     0], [170, 255, 0],\n          [85, 255, 0], [0, 255, 0],\n          [0, 255, 85], [0, 255, 170], [0, 255, 255], [0, 170, 255],\n          [0, 85, 255], [0, 0, 255], [85, 0, 255], [170, 0,\n                                                    255], [255, 0, 255],\n          [255, 0, 170], [255, 0, 85]]\n\nstickwidth = 4\nnum_openpose_kpt = 18\nnum_link = len(limb_seq)\n\n\ndef mmpose_to_openpose_visualization(args, img_path, detector, pose_estimator):\n    \"\"\"Visualize predicted keypoints of one image in openpose format.\"\"\"\n\n    # predict bbox\n    scope = detector.cfg.get('default_scope', 'mmdet')\n    if scope is not None:\n        init_default_scope(scope)\n    det_result = inference_detector(detector, img_path)\n    pred_instance = det_result.pred_instances.cpu().numpy()\n    bboxes = np.concatenate(\n        (pred_instance.bboxes, pred_instance.scores[:, None]), axis=1)\n    bboxes = bboxes[np.logical_and(pred_instance.labels == args.det_cat_id,\n                                   pred_instance.scores > args.bbox_thr)]\n    bboxes = bboxes[nms(bboxes, args.nms_thr), :4]\n\n    # predict keypoints\n    pose_results = inference_topdown(pose_estimator, img_path, bboxes)\n    data_samples = merge_data_samples(pose_results)\n\n    # concatenate scores and keypoints\n    keypoints = np.concatenate(\n        (data_samples.pred_instances.keypoints,\n         data_samples.pred_instances.keypoint_scores.reshape(-1, 17, 1)),\n        axis=-1)\n\n    # compute neck joint\n    neck = (keypoints[:, 5] + keypoints[:, 6]) / 2\n    if keypoints[:, 5, 2] < args.kpt_thr or keypoints[:, 6, 2] < args.kpt_thr:\n        neck[:, 2] = 0\n\n    # 17 keypoints to 18 keypoints\n    new_keypoints = np.insert(keypoints[:, ], 17, neck, axis=1)\n\n    # mmpose format to openpose format\n    openpose_idx = [15, 14, 17, 16, 2, 6, 3, 7, 4, 8, 12, 9, 13, 10, 1]\n    mmpose_idx = [1, 2, 3, 4, 6, 7, 8, 9, 10, 12, 13, 14, 15, 16, 17]\n    new_keypoints[:, openpose_idx, :] = new_keypoints[:, mmpose_idx, :]\n\n    # show the results\n    img = mmcv.imread(img_path, channel_order='rgb')\n\n    # black background\n    black_img = np.zeros_like(img)\n\n    num_instance = new_keypoints.shape[0]\n\n    # draw keypoints\n    for i, j in product(range(num_instance), range(num_openpose_kpt)):\n        x, y, conf = new_keypoints[i][j]\n        if conf > args.kpt_thr:\n            cv2.circle(black_img, (int(x), int(y)), 4, colors[j], thickness=-1)\n\n    # draw links\n    cur_black_img = black_img.copy()\n    for i, link_idx in product(range(num_instance), range(num_link)):\n        conf = new_keypoints[i][np.array(limb_seq[link_idx]) - 1, 2]\n        if np.sum(conf > args.kpt_thr) == 2:\n            Y = new_keypoints[i][np.array(limb_seq[link_idx]) - 1, 0]\n            X = new_keypoints[i][np.array(limb_seq[link_idx]) - 1, 1]\n            mX = np.mean(X)\n            mY = np.mean(Y)\n            length = ((X[0] - X[1])**2 + (Y[0] - Y[1])**2)**0.5\n            angle = math.degrees(math.atan2(X[0] - X[1], Y[0] - Y[1]))\n            polygon = cv2.ellipse2Poly(\n                (int(mY), int(mX)), (int(length / 2), stickwidth), int(angle),\n                0, 360, 1)\n            cv2.fillConvexPoly(cur_black_img, polygon, colors[link_idx])\n    black_img = cv2.addWeighted(black_img, 0.4, cur_black_img, 0.6, 0)\n\n    # save image\n    out_file = 'openpose_' + os.path.splitext(\n        os.path.basename(img_path))[0] + '.png'\n    cv2.imwrite(out_file, black_img[:, :, [2, 1, 0]])\n\n\ndef main():\n    \"\"\"Visualize the demo images.\n\n    Using mmdet to detect the human.\n    \"\"\"\n    parser = ArgumentParser()\n    parser.add_argument('det_config', help='Config file for detection')\n    parser.add_argument('det_checkpoint', help='Checkpoint file for detection')\n    parser.add_argument('pose_config', help='Config file for pose')\n    parser.add_argument('pose_checkpoint', help='Checkpoint file for pose')\n    parser.add_argument('--input', type=str, help='input Image file')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--det-cat-id',\n        type=int,\n        default=0,\n        help='Category id for bounding box detection model')\n    parser.add_argument(\n        '--bbox-thr',\n        type=float,\n        default=0.4,\n        help='Bounding box score threshold')\n    parser.add_argument(\n        '--nms-thr',\n        type=float,\n        default=0.3,\n        help='IoU threshold for bounding box NMS')\n    parser.add_argument(\n        '--kpt-thr', type=float, default=0.4, help='Keypoint score threshold')\n\n    assert has_mmdet, 'Please install mmdet to run the demo.'\n\n    args = parser.parse_args()\n\n    assert args.input != ''\n    assert args.det_config is not None\n    assert args.det_checkpoint is not None\n\n    # build detector\n    detector = init_detector(\n        args.det_config, args.det_checkpoint, device=args.device)\n\n    # build pose estimator\n    pose_estimator = init_pose_estimator(\n        args.pose_config,\n        args.pose_checkpoint,\n        device=args.device,\n        cfg_options=dict(model=dict(test_cfg=dict(output_heatmaps=False))))\n\n    input_type = mimetypes.guess_type(args.input)[0].split('/')[0]\n    if input_type == 'image':\n        mmpose_to_openpose_visualization(args, args.input, detector,\n                                         pose_estimator)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "projects/pose_anything/README.md",
    "content": "# Pose Anything: A Graph-Based Approach for Category-Agnostic Pose Estimation\n\n## [Paper](https://arxiv.org/pdf/2311.17891.pdf) | [Project Page](https://orhir.github.io/pose-anything/) | [Official Repo](https://github.com/orhir/PoseAnything)\n\nBy [Or Hirschorn](https://scholar.google.co.il/citations?user=GgFuT_QAAAAJ&hl=iw&oi=ao)\nand [Shai Avidan](https://scholar.google.co.il/citations?hl=iw&user=hpItE1QAAAAJ)\n\n![Teaser Figure](https://github.com/open-mmlab/mmpose/assets/26127467/96480360-1a80-41f6-88d3-d6c747506a7e)\n\n## Introduction\n\nWe present a novel approach to CAPE that leverages the inherent geometrical\nrelations between keypoints through a newly designed Graph Transformer Decoder.\nBy capturing and incorporating this crucial structural information, our method\nenhances the accuracy of keypoint localization, marking a significant departure\nfrom conventional CAPE techniques that treat keypoints as isolated entities.\n\n## Citation\n\nIf you find this useful, please cite this work as follows:\n\n```bibtex\n@misc{hirschorn2023pose,\n      title={Pose Anything: A Graph-Based Approach for Category-Agnostic Pose Estimation},\n      author={Or Hirschorn and Shai Avidan},\n      year={2023},\n      eprint={2311.17891},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n## Getting Started\n\n📣 Pose Anything is available on OpenXLab now. [\\[Try it online\\]](https://openxlab.org.cn/apps/detail/orhir/Pose-Anything)\n\n### Install Dependencies\n\nWe recommend using a virtual environment for running our code.\nAfter installing MMPose, you can install the rest of the dependencies by\nrunning:\n\n```\npip install timm\n```\n\n### Pretrained Weights\n\nThe full list of pretrained models can be found in\nthe [Official Repo](https://github.com/orhir/PoseAnything).\n\n## Demo on Custom Images\n\n***A bigger and more accurate version of the model - COMING SOON!***\n\nDownload\nthe [pretrained model](https://drive.google.com/file/d/1RT1Q8AMEa1kj6k9ZqrtWIKyuR4Jn4Pqc/view?usp=drive_link)\nand run:\n\n```\npython demo.py --support [path_to_support_image] --query [path_to_query_image] --config configs/demo_b.py --checkpoint [path_to_pretrained_ckpt]\n```\n\n***Note:*** The demo code supports any config with suitable checkpoint file.\nMore pre-trained models can be found in the official repo.\n\n## Training and Testing on MP-100 Dataset\n\n**We currently only support demo on custom images through the MMPose repo.**\n\n**For training and testing on the MP-100 dataset, please refer to\nthe [Official Repo](https://github.com/orhir/PoseAnything).**\n\n## Acknowledgement\n\nOur code is based on code from:\n\n- [CapeFormer](https://github.com/flyinglynx/CapeFormer)\n\n## License\n\nThis project is released under the Apache 2.0 license.\n"
  },
  {
    "path": "projects/pose_anything/configs/demo.py",
    "content": "log_level = 'INFO'\nload_from = None\nresume_from = None\ndist_params = dict(backend='nccl')\nworkflow = [('train', 1)]\ncheckpoint_config = dict(interval=20)\nevaluation = dict(\n    interval=25,\n    metric=['PCK', 'NME', 'AUC', 'EPE'],\n    key_indicator='PCK',\n    gpu_collect=True,\n    res_folder='')\noptimizer = dict(\n    type='Adam',\n    lr=1e-5,\n)\n\noptimizer_config = dict(grad_clip=None)\n# learning policy\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=1000,\n    warmup_ratio=0.001,\n    step=[160, 180])\ntotal_epochs = 200\nlog_config = dict(\n    interval=50,\n    hooks=[dict(type='TextLoggerHook'),\n           dict(type='TensorboardLoggerHook')])\n\nchannel_cfg = dict(\n    num_output_channels=1,\n    dataset_joints=1,\n    dataset_channel=[\n        [\n            0,\n        ],\n    ],\n    inference_channel=[\n        0,\n    ],\n    max_kpt_num=100)\n\n# model settings\nmodel = dict(\n    type='TransformerPoseTwoStage',\n    pretrained='swinv2_large',\n    encoder_config=dict(\n        type='SwinTransformerV2',\n        embed_dim=192,\n        depths=[2, 2, 18, 2],\n        num_heads=[6, 12, 24, 48],\n        window_size=16,\n        pretrained_window_sizes=[12, 12, 12, 6],\n        drop_path_rate=0.2,\n        img_size=256,\n    ),\n    keypoint_head=dict(\n        type='TwoStageHead',\n        in_channels=1536,\n        transformer=dict(\n            type='TwoStageSupportRefineTransformer',\n            d_model=384,\n            nhead=8,\n            num_encoder_layers=3,\n            num_decoder_layers=3,\n            dim_feedforward=1536,\n            dropout=0.1,\n            similarity_proj_dim=384,\n            dynamic_proj_dim=192,\n            activation='relu',\n            normalize_before=False,\n            return_intermediate_dec=True),\n        share_kpt_branch=False,\n        num_decoder_layer=3,\n        with_heatmap_loss=True,\n        support_pos_embed=False,\n        heatmap_loss_weight=2.0,\n        skeleton_loss_weight=0.02,\n        num_samples=0,\n        support_embedding_type='fixed',\n        num_support=100,\n        support_order_dropout=-1,\n        positional_encoding=dict(\n            type='SinePositionalEncoding', num_feats=192, normalize=True)),\n    # training and testing settings\n    train_cfg=dict(),\n    test_cfg=dict(\n        flip_test=False,\n        post_process='default',\n        shift_heatmap=True,\n        modulate_kernel=11))\n\ndata_cfg = dict(\n    image_size=[256, 256],\n    heatmap_size=[64, 64],\n    num_output_channels=channel_cfg['num_output_channels'],\n    num_joints=channel_cfg['dataset_joints'],\n    dataset_channel=channel_cfg['dataset_channel'],\n    inference_channel=channel_cfg['inference_channel'])\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='TopDownGetRandomScaleRotation', rot_factor=15,\n        scale_factor=0.15),\n    dict(type='TopDownAffineFewShot'),\n    dict(type='ToTensor'),\n    dict(\n        type='NormalizeTensor',\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]),\n    dict(type='TopDownGenerateTargetFewShot', sigma=1),\n    dict(\n        type='Collect',\n        keys=['img', 'target', 'target_weight'],\n        meta_keys=[\n            'image_file',\n            'joints_3d',\n            'joints_3d_visible',\n            'center',\n            'scale',\n            'rotation',\n            'bbox_score',\n            'flip_pairs',\n            'category_id',\n            'skeleton',\n        ]),\n]\n\nvalid_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='TopDownAffineFewShot'),\n    dict(type='ToTensor'),\n    dict(\n        type='NormalizeTensor',\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]),\n    dict(type='TopDownGenerateTargetFewShot', sigma=1),\n    dict(\n        type='Collect',\n        keys=['img', 'target', 'target_weight'],\n        meta_keys=[\n            'image_file',\n            'joints_3d',\n            'joints_3d_visible',\n            'center',\n            'scale',\n            'rotation',\n            'bbox_score',\n            'flip_pairs',\n            'category_id',\n            'skeleton',\n        ]),\n]\n\ntest_pipeline = valid_pipeline\n\ndata_root = 'data/mp100'\ndata = dict(\n    samples_per_gpu=8,\n    workers_per_gpu=8,\n    train=dict(\n        type='TransformerPoseDataset',\n        ann_file=f'{data_root}/annotations/mp100_all.json',\n        img_prefix=f'{data_root}/images/',\n        # img_prefix=f'{data_root}',\n        data_cfg=data_cfg,\n        valid_class_ids=None,\n        max_kpt_num=channel_cfg['max_kpt_num'],\n        num_shots=1,\n        pipeline=train_pipeline),\n    val=dict(\n        type='TransformerPoseDataset',\n        ann_file=f'{data_root}/annotations/mp100_split1_val.json',\n        img_prefix=f'{data_root}/images/',\n        # img_prefix=f'{data_root}',\n        data_cfg=data_cfg,\n        valid_class_ids=None,\n        max_kpt_num=channel_cfg['max_kpt_num'],\n        num_shots=1,\n        num_queries=15,\n        num_episodes=100,\n        pipeline=valid_pipeline),\n    test=dict(\n        type='TestPoseDataset',\n        ann_file=f'{data_root}/annotations/mp100_split1_test.json',\n        img_prefix=f'{data_root}/images/',\n        # img_prefix=f'{data_root}',\n        data_cfg=data_cfg,\n        valid_class_ids=None,\n        max_kpt_num=channel_cfg['max_kpt_num'],\n        num_shots=1,\n        num_queries=15,\n        num_episodes=200,\n        pck_threshold_list=[0.05, 0.10, 0.15, 0.2, 0.25],\n        pipeline=test_pipeline),\n)\nvis_backends = [\n    dict(type='LocalVisBackend'),\n    dict(type='TensorboardVisBackend'),\n]\nvisualizer = dict(\n    type='PoseLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\nshuffle_cfg = dict(interval=1)\n"
  },
  {
    "path": "projects/pose_anything/configs/demo_b.py",
    "content": "custom_imports = dict(imports=['models'])\n\nlog_level = 'INFO'\nload_from = None\nresume_from = None\ndist_params = dict(backend='nccl')\nworkflow = [('train', 1)]\ncheckpoint_config = dict(interval=20)\nevaluation = dict(\n    interval=25,\n    metric=['PCK', 'NME', 'AUC', 'EPE'],\n    key_indicator='PCK',\n    gpu_collect=True,\n    res_folder='')\noptimizer = dict(\n    type='Adam',\n    lr=1e-5,\n)\n\noptimizer_config = dict(grad_clip=None)\n# learning policy\nlr_config = dict(\n    policy='step',\n    warmup='linear',\n    warmup_iters=1000,\n    warmup_ratio=0.001,\n    step=[160, 180])\ntotal_epochs = 200\nlog_config = dict(\n    interval=50,\n    hooks=[dict(type='TextLoggerHook'),\n           dict(type='TensorboardLoggerHook')])\n\nchannel_cfg = dict(\n    num_output_channels=1,\n    dataset_joints=1,\n    dataset_channel=[\n        [\n            0,\n        ],\n    ],\n    inference_channel=[\n        0,\n    ],\n    max_kpt_num=100)\n\n# model settings\nmodel = dict(\n    type='PoseAnythingModel',\n    pretrained='swinv2_base',\n    encoder_config=dict(\n        type='SwinTransformerV2',\n        embed_dim=128,\n        depths=[2, 2, 18, 2],\n        num_heads=[4, 8, 16, 32],\n        window_size=14,\n        pretrained_window_sizes=[12, 12, 12, 6],\n        drop_path_rate=0.1,\n        img_size=224,\n    ),\n    keypoint_head=dict(\n        type='PoseHead',\n        in_channels=1024,\n        transformer=dict(\n            type='EncoderDecoder',\n            d_model=256,\n            nhead=8,\n            num_encoder_layers=3,\n            num_decoder_layers=3,\n            graph_decoder='pre',\n            dim_feedforward=1024,\n            dropout=0.1,\n            similarity_proj_dim=256,\n            dynamic_proj_dim=128,\n            activation='relu',\n            normalize_before=False,\n            return_intermediate_dec=True),\n        share_kpt_branch=False,\n        num_decoder_layer=3,\n        with_heatmap_loss=True,\n        heatmap_loss_weight=2.0,\n        support_order_dropout=-1,\n        positional_encoding=dict(\n            type='SinePositionalEncoding', num_feats=128, normalize=True)),\n    # training and testing settings\n    train_cfg=dict(),\n    test_cfg=dict(\n        flip_test=False,\n        post_process='default',\n        shift_heatmap=True,\n        modulate_kernel=11))\n\ndata_cfg = dict(\n    image_size=[224, 224],\n    heatmap_size=[64, 64],\n    num_output_channels=channel_cfg['num_output_channels'],\n    num_joints=channel_cfg['dataset_joints'],\n    dataset_channel=channel_cfg['dataset_channel'],\n    inference_channel=channel_cfg['inference_channel'])\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(\n        type='TopDownGetRandomScaleRotation', rot_factor=15,\n        scale_factor=0.15),\n    dict(type='TopDownAffineFewShot'),\n    dict(type='ToTensor'),\n    dict(\n        type='NormalizeTensor',\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]),\n    dict(type='TopDownGenerateTargetFewShot', sigma=1),\n    dict(\n        type='Collect',\n        keys=['img', 'target', 'target_weight'],\n        meta_keys=[\n            'image_file',\n            'joints_3d',\n            'joints_3d_visible',\n            'center',\n            'scale',\n            'rotation',\n            'bbox_score',\n            'flip_pairs',\n            'category_id',\n            'skeleton',\n        ]),\n]\n\nvalid_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='TopDownAffineFewShot'),\n    dict(type='ToTensor'),\n    dict(\n        type='NormalizeTensor',\n        mean=[0.485, 0.456, 0.406],\n        std=[0.229, 0.224, 0.225]),\n    dict(type='TopDownGenerateTargetFewShot', sigma=1),\n    dict(\n        type='Collect',\n        keys=['img', 'target', 'target_weight'],\n        meta_keys=[\n            'image_file',\n            'joints_3d',\n            'joints_3d_visible',\n            'center',\n            'scale',\n            'rotation',\n            'bbox_score',\n            'flip_pairs',\n            'category_id',\n            'skeleton',\n        ]),\n]\n\ntest_pipeline = valid_pipeline\n\ndata_root = 'data/mp100'\ndata = dict(\n    samples_per_gpu=8,\n    workers_per_gpu=8,\n    train=dict(\n        type='TransformerPoseDataset',\n        ann_file=f'{data_root}/annotations/mp100_split1_train.json',\n        img_prefix=f'{data_root}/images/',\n        # img_prefix=f'{data_root}',\n        data_cfg=data_cfg,\n        valid_class_ids=None,\n        max_kpt_num=channel_cfg['max_kpt_num'],\n        num_shots=1,\n        pipeline=train_pipeline),\n    val=dict(\n        type='TransformerPoseDataset',\n        ann_file=f'{data_root}/annotations/mp100_split1_val.json',\n        img_prefix=f'{data_root}/images/',\n        # img_prefix=f'{data_root}',\n        data_cfg=data_cfg,\n        valid_class_ids=None,\n        max_kpt_num=channel_cfg['max_kpt_num'],\n        num_shots=1,\n        num_queries=15,\n        num_episodes=100,\n        pipeline=valid_pipeline),\n    test=dict(\n        type='TestPoseDataset',\n        ann_file=f'{data_root}/annotations/mp100_split1_test.json',\n        img_prefix=f'{data_root}/images/',\n        # img_prefix=f'{data_root}',\n        data_cfg=data_cfg,\n        valid_class_ids=None,\n        max_kpt_num=channel_cfg['max_kpt_num'],\n        num_shots=1,\n        num_queries=15,\n        num_episodes=200,\n        pck_threshold_list=[0.05, 0.10, 0.15, 0.2, 0.25],\n        pipeline=test_pipeline),\n)\nvis_backends = [\n    dict(type='LocalVisBackend'),\n    dict(type='TensorboardVisBackend'),\n]\nvisualizer = dict(\n    type='PoseLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\nshuffle_cfg = dict(interval=1)\n"
  },
  {
    "path": "projects/pose_anything/datasets/__init__.py",
    "content": "from .pipelines import *  # noqa\n"
  },
  {
    "path": "projects/pose_anything/datasets/builder.py",
    "content": "from mmengine.dataset import RepeatDataset\nfrom mmengine.registry import build_from_cfg\nfrom torch.utils.data.dataset import ConcatDataset\n\nfrom mmpose.datasets.builder import DATASETS\n\n\ndef _concat_cfg(cfg):\n    replace = ['ann_file', 'img_prefix']\n    channels = ['num_joints', 'dataset_channel']\n    concat_cfg = []\n    for i in range(len(cfg['type'])):\n        cfg_tmp = cfg.deepcopy()\n        cfg_tmp['type'] = cfg['type'][i]\n        for item in replace:\n            assert item in cfg_tmp\n            assert len(cfg['type']) == len(cfg[item]), (cfg[item])\n            cfg_tmp[item] = cfg[item][i]\n        for item in channels:\n            assert item in cfg_tmp['data_cfg']\n            assert len(cfg['type']) == len(cfg['data_cfg'][item])\n            cfg_tmp['data_cfg'][item] = cfg['data_cfg'][item][i]\n        concat_cfg.append(cfg_tmp)\n    return concat_cfg\n\n\ndef _check_vaild(cfg):\n    replace = ['num_joints', 'dataset_channel']\n    if isinstance(cfg['data_cfg'][replace[0]], (list, tuple)):\n        for item in replace:\n            cfg['data_cfg'][item] = cfg['data_cfg'][item][0]\n    return cfg\n\n\ndef build_dataset(cfg, default_args=None):\n    \"\"\"Build a dataset from config dict.\n\n    Args:\n        cfg (dict): Config dict. It should at least contain the key \"type\".\n        default_args (dict, optional): Default initialization arguments.\n            Default: None.\n\n    Returns:\n        Dataset: The constructed dataset.\n    \"\"\"\n    if isinstance(cfg['type'],\n                  (list, tuple)):  # In training, type=TransformerPoseDataset\n        dataset = ConcatDataset(\n            [build_dataset(c, default_args) for c in _concat_cfg(cfg)])\n    elif cfg['type'] == 'RepeatDataset':\n        dataset = RepeatDataset(\n            build_dataset(cfg['dataset'], default_args), cfg['times'])\n    else:\n        cfg = _check_vaild(cfg)\n        dataset = build_from_cfg(cfg, DATASETS, default_args)\n    return dataset\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/__init__.py",
    "content": "from .mp100 import (FewShotBaseDataset, FewShotKeypointDataset,\n                    TransformerBaseDataset, TransformerPoseDataset)\n\n__all__ = [\n    'FewShotBaseDataset', 'FewShotKeypointDataset', 'TransformerBaseDataset',\n    'TransformerPoseDataset'\n]\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/__init__.py",
    "content": "from .fewshot_base_dataset import FewShotBaseDataset\nfrom .fewshot_dataset import FewShotKeypointDataset\nfrom .test_base_dataset import TestBaseDataset\nfrom .test_dataset import TestPoseDataset\nfrom .transformer_base_dataset import TransformerBaseDataset\nfrom .transformer_dataset import TransformerPoseDataset\n\n__all__ = [\n    'FewShotKeypointDataset', 'FewShotBaseDataset', 'TransformerPoseDataset',\n    'TransformerBaseDataset', 'TestBaseDataset', 'TestPoseDataset'\n]\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/fewshot_base_dataset.py",
    "content": "import copy\nfrom abc import ABCMeta, abstractmethod\n\nimport json_tricks as json\nimport numpy as np\nfrom mmcv.parallel import DataContainer as DC\nfrom torch.utils.data import Dataset\n\nfrom mmpose.core.evaluation.top_down_eval import keypoint_pck_accuracy\nfrom mmpose.datasets import DATASETS\nfrom mmpose.datasets.pipelines import Compose\n\n\n@DATASETS.register_module()\nclass FewShotBaseDataset(Dataset, metaclass=ABCMeta):\n\n    def __init__(self,\n                 ann_file,\n                 img_prefix,\n                 data_cfg,\n                 pipeline,\n                 test_mode=False):\n        self.image_info = {}\n        self.ann_info = {}\n\n        self.annotations_path = ann_file\n        if not img_prefix.endswith('/'):\n            img_prefix = img_prefix + '/'\n        self.img_prefix = img_prefix\n        self.pipeline = pipeline\n        self.test_mode = test_mode\n\n        self.ann_info['image_size'] = np.array(data_cfg['image_size'])\n        self.ann_info['heatmap_size'] = np.array(data_cfg['heatmap_size'])\n        self.ann_info['num_joints'] = data_cfg['num_joints']\n\n        self.ann_info['flip_pairs'] = None\n\n        self.ann_info['inference_channel'] = data_cfg['inference_channel']\n        self.ann_info['num_output_channels'] = data_cfg['num_output_channels']\n        self.ann_info['dataset_channel'] = data_cfg['dataset_channel']\n\n        self.db = []\n        self.num_shots = 1\n        self.paired_samples = []\n        self.pipeline = Compose(self.pipeline)\n\n    @abstractmethod\n    def _get_db(self):\n        \"\"\"Load dataset.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    def _select_kpt(self, obj, kpt_id):\n        \"\"\"Select kpt.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    def evaluate(self, cfg, preds, output_dir, *args, **kwargs):\n        \"\"\"Evaluate keypoint results.\"\"\"\n        raise NotImplementedError\n\n    @staticmethod\n    def _write_keypoint_results(keypoints, res_file):\n        \"\"\"Write results into a json file.\"\"\"\n\n        with open(res_file, 'w') as f:\n            json.dump(keypoints, f, sort_keys=True, indent=4)\n\n    def _report_metric(self,\n                       res_file,\n                       metrics,\n                       pck_thr=0.2,\n                       pckh_thr=0.7,\n                       auc_nor=30):\n        \"\"\"Keypoint evaluation.\n\n        Args:\n            res_file (str): Json file stored prediction results.\n            metrics (str | list[str]): Metric to be performed.\n                Options: 'PCK', 'PCKh', 'AUC', 'EPE'.\n            pck_thr (float): PCK threshold, default as 0.2.\n            pckh_thr (float): PCKh threshold, default as 0.7.\n            auc_nor (float): AUC normalization factor, default as 30 pixel.\n\n        Returns:\n            List: Evaluation results for evaluation metric.\n        \"\"\"\n        info_str = []\n\n        with open(res_file, 'r') as fin:\n            preds = json.load(fin)\n        assert len(preds) == len(self.paired_samples)\n\n        outputs = []\n        gts = []\n        masks = []\n        threshold_bbox = []\n        threshold_head_box = []\n\n        for pred, pair in zip(preds, self.paired_samples):\n            item = self.db[pair[-1]]\n            outputs.append(np.array(pred['keypoints'])[:, :-1])\n            gts.append(np.array(item['joints_3d'])[:, :-1])\n\n            mask_query = ((np.array(item['joints_3d_visible'])[:, 0]) > 0)\n            mask_sample = ((np.array(\n                self.db[pair[0]]['joints_3d_visible'])[:, 0]) > 0)\n            for id_s in pair[:-1]:\n                mask_sample = np.bitwise_and(\n                    mask_sample,\n                    ((np.array(self.db[id_s]['joints_3d_visible'])[:, 0]) > 0))\n            masks.append(np.bitwise_and(mask_query, mask_sample))\n\n            if 'PCK' in metrics:\n                bbox = np.array(item['bbox'])\n                bbox_thr = np.max(bbox[2:])\n                threshold_bbox.append(np.array([bbox_thr, bbox_thr]))\n            if 'PCKh' in metrics:\n                head_box_thr = item['head_size']\n                threshold_head_box.append(\n                    np.array([head_box_thr, head_box_thr]))\n\n        if 'PCK' in metrics:\n            pck_avg = []\n            for (output, gt, mask, thr_bbox) in zip(outputs, gts, masks,\n                                                    threshold_bbox):\n                _, pck, _ = keypoint_pck_accuracy(\n                    np.expand_dims(output, 0), np.expand_dims(gt, 0),\n                    np.expand_dims(mask, 0), pck_thr,\n                    np.expand_dims(thr_bbox, 0))\n                pck_avg.append(pck)\n            info_str.append(('PCK', np.mean(pck_avg)))\n\n        return info_str\n\n    def _merge_obj(self, Xs_list, Xq, idx):\n        \"\"\"merge Xs_list and Xq.\n\n        :param Xs_list: N-shot samples X\n        :param Xq: query X\n        :param idx: id of paired_samples\n        :return: Xall\n        \"\"\"\n        Xall = dict()\n        Xall['img_s'] = [Xs['img'] for Xs in Xs_list]\n        Xall['target_s'] = [Xs['target'] for Xs in Xs_list]\n        Xall['target_weight_s'] = [Xs['target_weight'] for Xs in Xs_list]\n        xs_img_metas = [Xs['img_metas'].data for Xs in Xs_list]\n\n        Xall['img_q'] = Xq['img']\n        Xall['target_q'] = Xq['target']\n        Xall['target_weight_q'] = Xq['target_weight']\n        xq_img_metas = Xq['img_metas'].data\n\n        img_metas = dict()\n        for key in xq_img_metas.keys():\n            img_metas['sample_' + key] = [\n                xs_img_meta[key] for xs_img_meta in xs_img_metas\n            ]\n            img_metas['query_' + key] = xq_img_metas[key]\n        img_metas['bbox_id'] = idx\n\n        Xall['img_metas'] = DC(img_metas, cpu_only=True)\n\n        return Xall\n\n    def __len__(self):\n        \"\"\"Get the size of the dataset.\"\"\"\n        return len(self.paired_samples)\n\n    def __getitem__(self, idx):\n        \"\"\"Get the sample given index.\"\"\"\n\n        pair_ids = self.paired_samples[idx]\n        assert len(pair_ids) == self.num_shots + 1\n        sample_id_list = pair_ids[:self.num_shots]\n        query_id = pair_ids[-1]\n\n        sample_obj_list = []\n        for sample_id in sample_id_list:\n            sample_obj = copy.deepcopy(self.db[sample_id])\n            sample_obj['ann_info'] = copy.deepcopy(self.ann_info)\n            sample_obj_list.append(sample_obj)\n\n        query_obj = copy.deepcopy(self.db[query_id])\n        query_obj['ann_info'] = copy.deepcopy(self.ann_info)\n\n        if not self.test_mode:\n            # randomly select \"one\" keypoint\n            sample_valid = (sample_obj_list[0]['joints_3d_visible'][:, 0] > 0)\n            for sample_obj in sample_obj_list:\n                sample_valid = sample_valid & (\n                    sample_obj['joints_3d_visible'][:, 0] > 0)\n            query_valid = (query_obj['joints_3d_visible'][:, 0] > 0)\n\n            valid_s = np.where(sample_valid)[0]\n            valid_q = np.where(query_valid)[0]\n            valid_sq = np.where(sample_valid & query_valid)[0]\n            if len(valid_sq) > 0:\n                kpt_id = np.random.choice(valid_sq)\n            elif len(valid_s) > 0:\n                kpt_id = np.random.choice(valid_s)\n            elif len(valid_q) > 0:\n                kpt_id = np.random.choice(valid_q)\n            else:\n                kpt_id = np.random.choice(np.array(range(len(query_valid))))\n\n            for i in range(self.num_shots):\n                sample_obj_list[i] = self._select_kpt(sample_obj_list[i],\n                                                      kpt_id)\n            query_obj = self._select_kpt(query_obj, kpt_id)\n\n        # when test, all keypoints will be preserved.\n\n        Xs_list = []\n        for sample_obj in sample_obj_list:\n            Xs = self.pipeline(sample_obj)\n            Xs_list.append(Xs)\n        Xq = self.pipeline(query_obj)\n\n        Xall = self._merge_obj(Xs_list, Xq, idx)\n        Xall['skeleton'] = self.db[query_id]['skeleton']\n\n        return Xall\n\n    def _sort_and_unique_bboxes(self, kpts, key='bbox_id'):\n        \"\"\"sort kpts and remove the repeated ones.\"\"\"\n        kpts = sorted(kpts, key=lambda x: x[key])\n        num = len(kpts)\n        for i in range(num - 1, 0, -1):\n            if kpts[i][key] == kpts[i - 1][key]:\n                del kpts[i]\n\n        return kpts\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/fewshot_dataset.py",
    "content": "import os\nimport random\nfrom collections import OrderedDict\n\nimport numpy as np\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets import DATASETS\nfrom .fewshot_base_dataset import FewShotBaseDataset\n\n\n@DATASETS.register_module()\nclass FewShotKeypointDataset(FewShotBaseDataset):\n\n    def __init__(self,\n                 ann_file,\n                 img_prefix,\n                 data_cfg,\n                 pipeline,\n                 valid_class_ids,\n                 num_shots=1,\n                 num_queries=100,\n                 num_episodes=1,\n                 test_mode=False):\n        super().__init__(\n            ann_file, img_prefix, data_cfg, pipeline, test_mode=test_mode)\n\n        self.ann_info['flip_pairs'] = []\n\n        self.ann_info['upper_body_ids'] = []\n        self.ann_info['lower_body_ids'] = []\n\n        self.ann_info['use_different_joint_weights'] = False\n        self.ann_info['joint_weights'] = np.array([\n            1.,\n        ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1))\n\n        self.coco = COCO(ann_file)\n\n        self.id2name, self.name2id = self._get_mapping_id_name(self.coco.imgs)\n        self.img_ids = self.coco.getImgIds()\n        self.classes = [\n            cat['name'] for cat in self.coco.loadCats(self.coco.getCatIds())\n        ]\n\n        self.num_classes = len(self.classes)\n        self._class_to_ind = dict(zip(self.classes, self.coco.getCatIds()))\n        self._ind_to_class = dict(zip(self.coco.getCatIds(), self.classes))\n\n        if valid_class_ids is not None:\n            self.valid_class_ids = valid_class_ids\n        else:\n            self.valid_class_ids = self.coco.getCatIds()\n        self.valid_classes = [\n            self._ind_to_class[ind] for ind in self.valid_class_ids\n        ]\n\n        self.cats = self.coco.cats\n\n        # Also update self.cat2obj\n        self.db = self._get_db()\n\n        self.num_shots = num_shots\n\n        if not test_mode:\n            # Update every training epoch\n            self.random_paired_samples()\n        else:\n            self.num_queries = num_queries\n            self.num_episodes = num_episodes\n            self.make_paired_samples()\n\n    def random_paired_samples(self):\n        num_datas = [\n            len(self.cat2obj[self._class_to_ind[cls]])\n            for cls in self.valid_classes\n        ]\n\n        # balance the dataset\n        max_num_data = max(num_datas)\n\n        all_samples = []\n        for cls in self.valid_class_ids:\n            for i in range(max_num_data):\n                shot = random.sample(self.cat2obj[cls], self.num_shots + 1)\n                all_samples.append(shot)\n\n        self.paired_samples = np.array(all_samples)\n        np.random.shuffle(self.paired_samples)\n\n    def make_paired_samples(self):\n        random.seed(1)\n        np.random.seed(0)\n\n        all_samples = []\n        for cls in self.valid_class_ids:\n            for _ in range(self.num_episodes):\n                shots = random.sample(self.cat2obj[cls],\n                                      self.num_shots + self.num_queries)\n                sample_ids = shots[:self.num_shots]\n                query_ids = shots[self.num_shots:]\n                for query_id in query_ids:\n                    all_samples.append(sample_ids + [query_id])\n\n        self.paired_samples = np.array(all_samples)\n\n    def _select_kpt(self, obj, kpt_id):\n        obj['joints_3d'] = obj['joints_3d'][kpt_id:kpt_id + 1]\n        obj['joints_3d_visible'] = obj['joints_3d_visible'][kpt_id:kpt_id + 1]\n        obj['kpt_id'] = kpt_id\n\n        return obj\n\n    @staticmethod\n    def _get_mapping_id_name(imgs):\n        \"\"\"\n        Args:\n            imgs (dict): dict of image info.\n\n        Returns:\n            tuple: Image name & id mapping dicts.\n\n            - id2name (dict): Mapping image id to name.\n            - name2id (dict): Mapping image name to id.\n        \"\"\"\n        id2name = {}\n        name2id = {}\n        for image_id, image in imgs.items():\n            file_name = image['file_name']\n            id2name[image_id] = file_name\n            name2id[file_name] = image_id\n\n        return id2name, name2id\n\n    def _get_db(self):\n        \"\"\"Ground truth bbox and keypoints.\"\"\"\n        self.obj_id = 0\n\n        self.cat2obj = {}\n        for i in self.coco.getCatIds():\n            self.cat2obj.update({i: []})\n\n        gt_db = []\n        for img_id in self.img_ids:\n            gt_db.extend(self._load_coco_keypoint_annotation_kernel(img_id))\n        return gt_db\n\n    def _load_coco_keypoint_annotation_kernel(self, img_id):\n        \"\"\"load annotation from COCOAPI.\n\n        Note:\n            bbox:[x1, y1, w, h]\n        Args:\n            img_id: coco image id\n        Returns:\n            dict: db entry\n        \"\"\"\n        img_ann = self.coco.loadImgs(img_id)[0]\n        width = img_ann['width']\n        height = img_ann['height']\n\n        ann_ids = self.coco.getAnnIds(imgIds=img_id, iscrowd=False)\n        objs = self.coco.loadAnns(ann_ids)\n\n        # sanitize bboxes\n        valid_objs = []\n        for obj in objs:\n            if 'bbox' not in obj:\n                continue\n            x, y, w, h = obj['bbox']\n            x1 = max(0, x)\n            y1 = max(0, y)\n            x2 = min(width - 1, x1 + max(0, w - 1))\n            y2 = min(height - 1, y1 + max(0, h - 1))\n            if ('area' not in obj or obj['area'] > 0) and x2 > x1 and y2 > y1:\n                obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1]\n                valid_objs.append(obj)\n        objs = valid_objs\n\n        bbox_id = 0\n        rec = []\n        for obj in objs:\n            if 'keypoints' not in obj:\n                continue\n            if max(obj['keypoints']) == 0:\n                continue\n            if 'num_keypoints' in obj and obj['num_keypoints'] == 0:\n                continue\n\n            category_id = obj['category_id']\n            # the number of keypoint for this specific category\n            cat_kpt_num = int(len(obj['keypoints']) / 3)\n\n            joints_3d = np.zeros((cat_kpt_num, 3), dtype=np.float32)\n            joints_3d_visible = np.zeros((cat_kpt_num, 3), dtype=np.float32)\n\n            keypoints = np.array(obj['keypoints']).reshape(-1, 3)\n            joints_3d[:, :2] = keypoints[:, :2]\n            joints_3d_visible[:, :2] = np.minimum(1, keypoints[:, 2:3])\n\n            center, scale = self._xywh2cs(*obj['clean_bbox'][:4])\n\n            image_file = os.path.join(self.img_prefix, self.id2name[img_id])\n\n            self.cat2obj[category_id].append(self.obj_id)\n\n            rec.append({\n                'image_file':\n                image_file,\n                'center':\n                center,\n                'scale':\n                scale,\n                'rotation':\n                0,\n                'bbox':\n                obj['clean_bbox'][:4],\n                'bbox_score':\n                1,\n                'joints_3d':\n                joints_3d,\n                'joints_3d_visible':\n                joints_3d_visible,\n                'category_id':\n                category_id,\n                'cat_kpt_num':\n                cat_kpt_num,\n                'bbox_id':\n                self.obj_id,\n                'skeleton':\n                self.coco.cats[obj['category_id']]['skeleton'],\n            })\n            bbox_id = bbox_id + 1\n            self.obj_id += 1\n\n        return rec\n\n    def _xywh2cs(self, x, y, w, h):\n        \"\"\"This encodes bbox(x,y,w,w) into (center, scale)\n\n        Args:\n            x, y, w, h\n\n        Returns:\n            tuple: A tuple containing center and scale.\n\n            - center (np.ndarray[float32](2,)): center of the bbox (x, y).\n            - scale (np.ndarray[float32](2,)): scale of the bbox w & h.\n        \"\"\"\n        aspect_ratio = self.ann_info['image_size'][0] / self.ann_info[\n            'image_size'][1]\n        center = np.array([x + w * 0.5, y + h * 0.5], dtype=np.float32)\n        #\n        # if (not self.test_mode) and np.random.rand() < 0.3:\n        #     center += 0.4 * (np.random.rand(2) - 0.5) * [w, h]\n\n        if w > aspect_ratio * h:\n            h = w * 1.0 / aspect_ratio\n        elif w < aspect_ratio * h:\n            w = h * aspect_ratio\n\n        # pixel std is 200.0\n        scale = np.array([w / 200.0, h / 200.0], dtype=np.float32)\n        # padding to include proper amount of context\n        scale = scale * 1.25\n\n        return center, scale\n\n    def evaluate(self, outputs, res_folder, metric='PCK', **kwargs):\n        \"\"\"Evaluate interhand2d keypoint results. The pose prediction results\n        will be saved in `${res_folder}/result_keypoints.json`.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n            heatmap height: H\n            heatmap width: W\n\n        Args:\n            outputs (list(preds, boxes, image_path, output_heatmap))\n                :preds (np.ndarray[N,K,3]): The first two dimensions are\n                    coordinates, score is the third dimension of the array.\n                :boxes (np.ndarray[N,6]): [center[0], center[1], scale[0]\n                    , scale[1],area, score]\n                :image_paths (list[str]): For example, ['C', 'a', 'p', 't',\n                    'u', 'r', 'e', '1', '2', '/', '0', '3', '9', '0', '_',\n                    'd', 'h', '_', 't', 'o', 'u', 'c', 'h', 'R', 'O', 'M',\n                    '/', 'c', 'a', 'm', '4', '1', '0', '2', '0', '9', '/',\n                    'i', 'm', 'a', 'g', 'e', '6', '2', '4', '3', '4', '.',\n                    'j', 'p', 'g']\n                :output_heatmap (np.ndarray[N, K, H, W]): model outputs.\n\n            res_folder (str): Path of directory to save the results.\n            metric (str | list[str]): Metric to be performed.\n                Options: 'PCK', 'AUC', 'EPE'.\n\n        Returns:\n            dict: Evaluation results for evaluation metric.\n        \"\"\"\n        metrics = metric if isinstance(metric, list) else [metric]\n        allowed_metrics = ['PCK', 'AUC', 'EPE']\n        for metric in metrics:\n            if metric not in allowed_metrics:\n                raise KeyError(f'metric {metric} is not supported')\n\n        res_file = os.path.join(res_folder, 'result_keypoints.json')\n\n        kpts = []\n        for output in outputs:\n            preds = output['preds']\n            boxes = output['boxes']\n            image_paths = output['image_paths']\n            bbox_ids = output['bbox_ids']\n\n            batch_size = len(image_paths)\n            for i in range(batch_size):\n                image_id = self.name2id[image_paths[i][len(self.img_prefix):]]\n\n                kpts.append({\n                    'keypoints': preds[i].tolist(),\n                    'center': boxes[i][0:2].tolist(),\n                    'scale': boxes[i][2:4].tolist(),\n                    'area': float(boxes[i][4]),\n                    'score': float(boxes[i][5]),\n                    'image_id': image_id,\n                    'bbox_id': bbox_ids[i]\n                })\n        kpts = self._sort_and_unique_bboxes(kpts)\n\n        self._write_keypoint_results(kpts, res_file)\n        info_str = self._report_metric(res_file, metrics)\n        name_value = OrderedDict(info_str)\n\n        return name_value\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/test_base_dataset.py",
    "content": "import copy\nfrom abc import ABCMeta, abstractmethod\n\nimport json_tricks as json\nimport numpy as np\nfrom mmcv.parallel import DataContainer as DC\nfrom torch.utils.data import Dataset\n\nfrom mmpose.core.evaluation.top_down_eval import (keypoint_auc, keypoint_epe,\n                                                  keypoint_nme,\n                                                  keypoint_pck_accuracy)\nfrom mmpose.datasets import DATASETS\nfrom mmpose.datasets.pipelines import Compose\n\n\n@DATASETS.register_module()\nclass TestBaseDataset(Dataset, metaclass=ABCMeta):\n\n    def __init__(self,\n                 ann_file,\n                 img_prefix,\n                 data_cfg,\n                 pipeline,\n                 test_mode=True,\n                 PCK_threshold_list=[0.05, 0.1, 0.15, 0.2, 0.25]):\n        self.image_info = {}\n        self.ann_info = {}\n\n        self.annotations_path = ann_file\n        if not img_prefix.endswith('/'):\n            img_prefix = img_prefix + '/'\n        self.img_prefix = img_prefix\n        self.pipeline = pipeline\n        self.test_mode = test_mode\n        self.PCK_threshold_list = PCK_threshold_list\n\n        self.ann_info['image_size'] = np.array(data_cfg['image_size'])\n        self.ann_info['heatmap_size'] = np.array(data_cfg['heatmap_size'])\n        self.ann_info['num_joints'] = data_cfg['num_joints']\n\n        self.ann_info['flip_pairs'] = None\n\n        self.ann_info['inference_channel'] = data_cfg['inference_channel']\n        self.ann_info['num_output_channels'] = data_cfg['num_output_channels']\n        self.ann_info['dataset_channel'] = data_cfg['dataset_channel']\n\n        self.db = []\n        self.num_shots = 1\n        self.paired_samples = []\n        self.pipeline = Compose(self.pipeline)\n\n    @abstractmethod\n    def _get_db(self):\n        \"\"\"Load dataset.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    def _select_kpt(self, obj, kpt_id):\n        \"\"\"Select kpt.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    def evaluate(self, cfg, preds, output_dir, *args, **kwargs):\n        \"\"\"Evaluate keypoint results.\"\"\"\n        raise NotImplementedError\n\n    @staticmethod\n    def _write_keypoint_results(keypoints, res_file):\n        \"\"\"Write results into a json file.\"\"\"\n\n        with open(res_file, 'w') as f:\n            json.dump(keypoints, f, sort_keys=True, indent=4)\n\n    def _report_metric(self, res_file, metrics):\n        \"\"\"Keypoint evaluation.\n\n        Args:\n            res_file (str): Json file stored prediction results.\n            metrics (str | list[str]): Metric to be performed.\n                Options: 'PCK', 'PCKh', 'AUC', 'EPE'.\n            pck_thr (float): PCK threshold, default as 0.2.\n            pckh_thr (float): PCKh threshold, default as 0.7.\n            auc_nor (float): AUC normalization factor, default as 30 pixel.\n\n        Returns:\n            List: Evaluation results for evaluation metric.\n        \"\"\"\n        info_str = []\n\n        with open(res_file, 'r') as fin:\n            preds = json.load(fin)\n        assert len(preds) == len(self.paired_samples)\n\n        outputs = []\n        gts = []\n        masks = []\n        threshold_bbox = []\n        threshold_head_box = []\n\n        for pred, pair in zip(preds, self.paired_samples):\n            item = self.db[pair[-1]]\n            outputs.append(np.array(pred['keypoints'])[:, :-1])\n            gts.append(np.array(item['joints_3d'])[:, :-1])\n\n            mask_query = ((np.array(item['joints_3d_visible'])[:, 0]) > 0)\n            mask_sample = ((np.array(\n                self.db[pair[0]]['joints_3d_visible'])[:, 0]) > 0)\n            for id_s in pair[:-1]:\n                mask_sample = np.bitwise_and(\n                    mask_sample,\n                    ((np.array(self.db[id_s]['joints_3d_visible'])[:, 0]) > 0))\n            masks.append(np.bitwise_and(mask_query, mask_sample))\n\n            if 'PCK' in metrics or 'NME' in metrics or 'AUC' in metrics:\n                bbox = np.array(item['bbox'])\n                bbox_thr = np.max(bbox[2:])\n                threshold_bbox.append(np.array([bbox_thr, bbox_thr]))\n            if 'PCKh' in metrics:\n                head_box_thr = item['head_size']\n                threshold_head_box.append(\n                    np.array([head_box_thr, head_box_thr]))\n\n        if 'PCK' in metrics:\n            pck_results = dict()\n            for pck_thr in self.PCK_threshold_list:\n                pck_results[pck_thr] = []\n\n            for (output, gt, mask, thr_bbox) in zip(outputs, gts, masks,\n                                                    threshold_bbox):\n                for pck_thr in self.PCK_threshold_list:\n                    _, pck, _ = keypoint_pck_accuracy(\n                        np.expand_dims(output, 0), np.expand_dims(gt, 0),\n                        np.expand_dims(mask, 0), pck_thr,\n                        np.expand_dims(thr_bbox, 0))\n                    pck_results[pck_thr].append(pck)\n\n            mPCK = 0\n            for pck_thr in self.PCK_threshold_list:\n                info_str.append(\n                    ['PCK@' + str(pck_thr),\n                     np.mean(pck_results[pck_thr])])\n                mPCK += np.mean(pck_results[pck_thr])\n            info_str.append(['mPCK', mPCK / len(self.PCK_threshold_list)])\n\n        if 'NME' in metrics:\n            nme_results = []\n            for (output, gt, mask, thr_bbox) in zip(outputs, gts, masks,\n                                                    threshold_bbox):\n                nme = keypoint_nme(\n                    np.expand_dims(output, 0), np.expand_dims(gt, 0),\n                    np.expand_dims(mask, 0), np.expand_dims(thr_bbox, 0))\n                nme_results.append(nme)\n            info_str.append(['NME', np.mean(nme_results)])\n\n        if 'AUC' in metrics:\n            auc_results = []\n            for (output, gt, mask, thr_bbox) in zip(outputs, gts, masks,\n                                                    threshold_bbox):\n                auc = keypoint_auc(\n                    np.expand_dims(output, 0), np.expand_dims(gt, 0),\n                    np.expand_dims(mask, 0), thr_bbox[0])\n                auc_results.append(auc)\n            info_str.append(['AUC', np.mean(auc_results)])\n\n        if 'EPE' in metrics:\n            epe_results = []\n            for (output, gt, mask) in zip(outputs, gts, masks):\n                epe = keypoint_epe(\n                    np.expand_dims(output, 0), np.expand_dims(gt, 0),\n                    np.expand_dims(mask, 0))\n                epe_results.append(epe)\n            info_str.append(['EPE', np.mean(epe_results)])\n        return info_str\n\n    def _merge_obj(self, Xs_list, Xq, idx):\n        \"\"\"merge Xs_list and Xq.\n\n        :param Xs_list: N-shot samples X\n        :param Xq: query X\n        :param idx: id of paired_samples\n        :return: Xall\n        \"\"\"\n        Xall = dict()\n        Xall['img_s'] = [Xs['img'] for Xs in Xs_list]\n        Xall['target_s'] = [Xs['target'] for Xs in Xs_list]\n        Xall['target_weight_s'] = [Xs['target_weight'] for Xs in Xs_list]\n        xs_img_metas = [Xs['img_metas'].data for Xs in Xs_list]\n\n        Xall['img_q'] = Xq['img']\n        Xall['target_q'] = Xq['target']\n        Xall['target_weight_q'] = Xq['target_weight']\n        xq_img_metas = Xq['img_metas'].data\n\n        img_metas = dict()\n        for key in xq_img_metas.keys():\n            img_metas['sample_' + key] = [\n                xs_img_meta[key] for xs_img_meta in xs_img_metas\n            ]\n            img_metas['query_' + key] = xq_img_metas[key]\n        img_metas['bbox_id'] = idx\n\n        Xall['img_metas'] = DC(img_metas, cpu_only=True)\n\n        return Xall\n\n    def __len__(self):\n        \"\"\"Get the size of the dataset.\"\"\"\n        return len(self.paired_samples)\n\n    def __getitem__(self, idx):\n        \"\"\"Get the sample given index.\"\"\"\n\n        pair_ids = self.paired_samples[idx]  # [supported id * shots, query id]\n        assert len(pair_ids) == self.num_shots + 1\n        sample_id_list = pair_ids[:self.num_shots]\n        query_id = pair_ids[-1]\n\n        sample_obj_list = []\n        for sample_id in sample_id_list:\n            sample_obj = copy.deepcopy(self.db[sample_id])\n            sample_obj['ann_info'] = copy.deepcopy(self.ann_info)\n            sample_obj_list.append(sample_obj)\n\n        query_obj = copy.deepcopy(self.db[query_id])\n        query_obj['ann_info'] = copy.deepcopy(self.ann_info)\n\n        Xs_list = []\n        for sample_obj in sample_obj_list:\n            Xs = self.pipeline(\n                sample_obj\n            )  # dict with ['img', 'target', 'target_weight', 'img_metas'],\n            Xs_list.append(Xs)  # Xs['target'] is of shape [100, map_h, map_w]\n        Xq = self.pipeline(query_obj)\n\n        Xall = self._merge_obj(Xs_list, Xq, idx)\n        Xall['skeleton'] = self.db[query_id]['skeleton']\n\n        return Xall\n\n    def _sort_and_unique_bboxes(self, kpts, key='bbox_id'):\n        \"\"\"sort kpts and remove the repeated ones.\"\"\"\n        kpts = sorted(kpts, key=lambda x: x[key])\n        num = len(kpts)\n        for i in range(num - 1, 0, -1):\n            if kpts[i][key] == kpts[i - 1][key]:\n                del kpts[i]\n\n        return kpts\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/test_dataset.py",
    "content": "import os\nimport random\nfrom collections import OrderedDict\n\nimport numpy as np\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets import DATASETS\nfrom .test_base_dataset import TestBaseDataset\n\n\n@DATASETS.register_module()\nclass TestPoseDataset(TestBaseDataset):\n\n    def __init__(self,\n                 ann_file,\n                 img_prefix,\n                 data_cfg,\n                 pipeline,\n                 valid_class_ids,\n                 max_kpt_num=None,\n                 num_shots=1,\n                 num_queries=100,\n                 num_episodes=1,\n                 pck_threshold_list=[0.05, 0.1, 0.15, 0.20, 0.25],\n                 test_mode=True):\n        super().__init__(\n            ann_file,\n            img_prefix,\n            data_cfg,\n            pipeline,\n            test_mode=test_mode,\n            PCK_threshold_list=pck_threshold_list)\n\n        self.ann_info['flip_pairs'] = []\n\n        self.ann_info['upper_body_ids'] = []\n        self.ann_info['lower_body_ids'] = []\n\n        self.ann_info['use_different_joint_weights'] = False\n        self.ann_info['joint_weights'] = np.array([\n            1.,\n        ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1))\n\n        self.coco = COCO(ann_file)\n\n        self.id2name, self.name2id = self._get_mapping_id_name(self.coco.imgs)\n        self.img_ids = self.coco.getImgIds()\n        self.classes = [\n            cat['name'] for cat in self.coco.loadCats(self.coco.getCatIds())\n        ]\n\n        self.num_classes = len(self.classes)\n        self._class_to_ind = dict(zip(self.classes, self.coco.getCatIds()))\n        self._ind_to_class = dict(zip(self.coco.getCatIds(), self.classes))\n\n        if valid_class_ids is not None:  # None by default\n            self.valid_class_ids = valid_class_ids\n        else:\n            self.valid_class_ids = self.coco.getCatIds()\n        self.valid_classes = [\n            self._ind_to_class[ind] for ind in self.valid_class_ids\n        ]\n\n        self.cats = self.coco.cats\n        self.max_kpt_num = max_kpt_num\n\n        # Also update self.cat2obj\n        self.db = self._get_db()\n\n        self.num_shots = num_shots\n\n        if not test_mode:\n            # Update every training epoch\n            self.random_paired_samples()\n        else:\n            self.num_queries = num_queries\n            self.num_episodes = num_episodes\n            self.make_paired_samples()\n\n    def random_paired_samples(self):\n        num_datas = [\n            len(self.cat2obj[self._class_to_ind[cls]])\n            for cls in self.valid_classes\n        ]\n\n        # balance the dataset\n        max_num_data = max(num_datas)\n\n        all_samples = []\n        for cls in self.valid_class_ids:\n            for i in range(max_num_data):\n                shot = random.sample(self.cat2obj[cls], self.num_shots + 1)\n                all_samples.append(shot)\n\n        self.paired_samples = np.array(all_samples)\n        np.random.shuffle(self.paired_samples)\n\n    def make_paired_samples(self):\n        random.seed(1)\n        np.random.seed(0)\n\n        all_samples = []\n        for cls in self.valid_class_ids:\n            for _ in range(self.num_episodes):\n                shots = random.sample(self.cat2obj[cls],\n                                      self.num_shots + self.num_queries)\n                sample_ids = shots[:self.num_shots]\n                query_ids = shots[self.num_shots:]\n                for query_id in query_ids:\n                    all_samples.append(sample_ids + [query_id])\n\n        self.paired_samples = np.array(all_samples)\n\n    def _select_kpt(self, obj, kpt_id):\n        obj['joints_3d'] = obj['joints_3d'][kpt_id:kpt_id + 1]\n        obj['joints_3d_visible'] = obj['joints_3d_visible'][kpt_id:kpt_id + 1]\n        obj['kpt_id'] = kpt_id\n\n        return obj\n\n    @staticmethod\n    def _get_mapping_id_name(imgs):\n        \"\"\"\n        Args:\n            imgs (dict): dict of image info.\n\n        Returns:\n            tuple: Image name & id mapping dicts.\n\n            - id2name (dict): Mapping image id to name.\n            - name2id (dict): Mapping image name to id.\n        \"\"\"\n        id2name = {}\n        name2id = {}\n        for image_id, image in imgs.items():\n            file_name = image['file_name']\n            id2name[image_id] = file_name\n            name2id[file_name] = image_id\n\n        return id2name, name2id\n\n    def _get_db(self):\n        \"\"\"Ground truth bbox and keypoints.\"\"\"\n        self.obj_id = 0\n\n        self.cat2obj = {}\n        for i in self.coco.getCatIds():\n            self.cat2obj.update({i: []})\n\n        gt_db = []\n        for img_id in self.img_ids:\n            gt_db.extend(self._load_coco_keypoint_annotation_kernel(img_id))\n        return gt_db\n\n    def _load_coco_keypoint_annotation_kernel(self, img_id):\n        \"\"\"load annotation from COCOAPI.\n\n        Note:\n            bbox:[x1, y1, w, h]\n        Args:\n            img_id: coco image id\n        Returns:\n            dict: db entry\n        \"\"\"\n        img_ann = self.coco.loadImgs(img_id)[0]\n        width = img_ann['width']\n        height = img_ann['height']\n\n        ann_ids = self.coco.getAnnIds(imgIds=img_id, iscrowd=False)\n        objs = self.coco.loadAnns(ann_ids)\n\n        # sanitize bboxes\n        valid_objs = []\n        for obj in objs:\n            if 'bbox' not in obj:\n                continue\n            x, y, w, h = obj['bbox']\n            x1 = max(0, x)\n            y1 = max(0, y)\n            x2 = min(width - 1, x1 + max(0, w - 1))\n            y2 = min(height - 1, y1 + max(0, h - 1))\n            if ('area' not in obj or obj['area'] > 0) and x2 > x1 and y2 > y1:\n                obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1]\n                valid_objs.append(obj)\n        objs = valid_objs\n\n        bbox_id = 0\n        rec = []\n        for obj in objs:\n            if 'keypoints' not in obj:\n                continue\n            if max(obj['keypoints']) == 0:\n                continue\n            if 'num_keypoints' in obj and obj['num_keypoints'] == 0:\n                continue\n\n            category_id = obj['category_id']\n            # the number of keypoint for this specific category\n            cat_kpt_num = int(len(obj['keypoints']) / 3)\n            if self.max_kpt_num is None:\n                kpt_num = cat_kpt_num\n            else:\n                kpt_num = self.max_kpt_num\n\n            joints_3d = np.zeros((kpt_num, 3), dtype=np.float32)\n            joints_3d_visible = np.zeros((kpt_num, 3), dtype=np.float32)\n\n            keypoints = np.array(obj['keypoints']).reshape(-1, 3)\n            joints_3d[:cat_kpt_num, :2] = keypoints[:, :2]\n            joints_3d_visible[:cat_kpt_num, :2] = np.minimum(\n                1, keypoints[:, 2:3])\n\n            center, scale = self._xywh2cs(*obj['clean_bbox'][:4])\n\n            image_file = os.path.join(self.img_prefix, self.id2name[img_id])\n\n            self.cat2obj[category_id].append(self.obj_id)\n\n            rec.append({\n                'image_file':\n                image_file,\n                'center':\n                center,\n                'scale':\n                scale,\n                'rotation':\n                0,\n                'bbox':\n                obj['clean_bbox'][:4],\n                'bbox_score':\n                1,\n                'joints_3d':\n                joints_3d,\n                'joints_3d_visible':\n                joints_3d_visible,\n                'category_id':\n                category_id,\n                'cat_kpt_num':\n                cat_kpt_num,\n                'bbox_id':\n                self.obj_id,\n                'skeleton':\n                self.coco.cats[obj['category_id']]['skeleton'],\n            })\n            bbox_id = bbox_id + 1\n            self.obj_id += 1\n\n        return rec\n\n    def _xywh2cs(self, x, y, w, h):\n        \"\"\"This encodes bbox(x,y,w,w) into (center, scale)\n\n        Args:\n            x, y, w, h\n\n        Returns:\n            tuple: A tuple containing center and scale.\n\n            - center (np.ndarray[float32](2,)): center of the bbox (x, y).\n            - scale (np.ndarray[float32](2,)): scale of the bbox w & h.\n        \"\"\"\n        aspect_ratio = self.ann_info['image_size'][0] / self.ann_info[\n            'image_size'][1]\n        center = np.array([x + w * 0.5, y + h * 0.5], dtype=np.float32)\n        #\n        # if (not self.test_mode) and np.random.rand() < 0.3:\n        #     center += 0.4 * (np.random.rand(2) - 0.5) * [w, h]\n\n        if w > aspect_ratio * h:\n            h = w * 1.0 / aspect_ratio\n        elif w < aspect_ratio * h:\n            w = h * aspect_ratio\n\n        # pixel std is 200.0\n        scale = np.array([w / 200.0, h / 200.0], dtype=np.float32)\n        # padding to include proper amount of context\n        scale = scale * 1.25\n\n        return center, scale\n\n    def evaluate(self, outputs, res_folder, metric='PCK', **kwargs):\n        \"\"\"Evaluate interhand2d keypoint results. The pose prediction results\n        will be saved in `${res_folder}/result_keypoints.json`.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n            heatmap height: H\n            heatmap width: W\n\n        Args:\n            outputs (list(preds, boxes, image_path, output_heatmap))\n                :preds (np.ndarray[N,K,3]): The first two dimensions are\n                    coordinates, score is the third dimension of the array.\n                :boxes (np.ndarray[N,6]): [center[0], center[1], scale[0]\n                    , scale[1],area, score]\n                :image_paths (list[str]): For example, ['C', 'a', 'p', 't',\n                    'u', 'r', 'e', '1', '2', '/', '0', '3', '9', '0', '_',\n                    'd', 'h', '_', 't', 'o', 'u', 'c', 'h', 'R', 'O', 'M',\n                    '/', 'c', 'a', 'm', '4', '1', '0', '2', '0', '9', '/',\n                    'i', 'm', 'a', 'g', 'e', '6', '2', '4', '3', '4', '.',\n                    'j', 'p', 'g']\n                :output_heatmap (np.ndarray[N, K, H, W]): model outputs.\n\n            res_folder (str): Path of directory to save the results.\n            metric (str | list[str]): Metric to be performed.\n                Options: 'PCK', 'AUC', 'EPE'.\n\n        Returns:\n            dict: Evaluation results for evaluation metric.\n        \"\"\"\n        metrics = metric if isinstance(metric, list) else [metric]\n        allowed_metrics = ['PCK', 'AUC', 'EPE', 'NME']\n        for metric in metrics:\n            if metric not in allowed_metrics:\n                raise KeyError(f'metric {metric} is not supported')\n\n        res_file = os.path.join(res_folder, 'result_keypoints.json')\n\n        kpts = []\n        for output in outputs:\n            preds = output['preds']\n            boxes = output['boxes']\n            image_paths = output['image_paths']\n            bbox_ids = output['bbox_ids']\n\n            batch_size = len(image_paths)\n            for i in range(batch_size):\n                image_id = self.name2id[image_paths[i][len(self.img_prefix):]]\n\n                kpts.append({\n                    'keypoints': preds[i].tolist(),\n                    'center': boxes[i][0:2].tolist(),\n                    'scale': boxes[i][2:4].tolist(),\n                    'area': float(boxes[i][4]),\n                    'score': float(boxes[i][5]),\n                    'image_id': image_id,\n                    'bbox_id': bbox_ids[i]\n                })\n        kpts = self._sort_and_unique_bboxes(kpts)\n\n        self._write_keypoint_results(kpts, res_file)\n        info_str = self._report_metric(res_file, metrics)\n        name_value = OrderedDict(info_str)\n\n        return name_value\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/transformer_base_dataset.py",
    "content": "import copy\nfrom abc import ABCMeta, abstractmethod\n\nimport json_tricks as json\nimport numpy as np\nfrom mmcv.parallel import DataContainer as DC\nfrom mmengine.dataset import Compose\nfrom torch.utils.data import Dataset\n\nfrom mmpose.core.evaluation.top_down_eval import keypoint_pck_accuracy\nfrom mmpose.datasets import DATASETS\n\n\n@DATASETS.register_module()\nclass TransformerBaseDataset(Dataset, metaclass=ABCMeta):\n\n    def __init__(self,\n                 ann_file,\n                 img_prefix,\n                 data_cfg,\n                 pipeline,\n                 test_mode=False):\n        self.image_info = {}\n        self.ann_info = {}\n\n        self.annotations_path = ann_file\n        if not img_prefix.endswith('/'):\n            img_prefix = img_prefix + '/'\n        self.img_prefix = img_prefix\n        self.pipeline = pipeline\n        self.test_mode = test_mode\n\n        self.ann_info['image_size'] = np.array(data_cfg['image_size'])\n        self.ann_info['heatmap_size'] = np.array(data_cfg['heatmap_size'])\n        self.ann_info['num_joints'] = data_cfg['num_joints']\n\n        self.ann_info['flip_pairs'] = None\n\n        self.ann_info['inference_channel'] = data_cfg['inference_channel']\n        self.ann_info['num_output_channels'] = data_cfg['num_output_channels']\n        self.ann_info['dataset_channel'] = data_cfg['dataset_channel']\n\n        self.db = []\n        self.num_shots = 1\n        self.paired_samples = []\n        self.pipeline = Compose(self.pipeline)\n\n    @abstractmethod\n    def _get_db(self):\n        \"\"\"Load dataset.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    def _select_kpt(self, obj, kpt_id):\n        \"\"\"Select kpt.\"\"\"\n        raise NotImplementedError\n\n    @abstractmethod\n    def evaluate(self, cfg, preds, output_dir, *args, **kwargs):\n        \"\"\"Evaluate keypoint results.\"\"\"\n        raise NotImplementedError\n\n    @staticmethod\n    def _write_keypoint_results(keypoints, res_file):\n        \"\"\"Write results into a json file.\"\"\"\n\n        with open(res_file, 'w') as f:\n            json.dump(keypoints, f, sort_keys=True, indent=4)\n\n    def _report_metric(self,\n                       res_file,\n                       metrics,\n                       pck_thr=0.2,\n                       pckh_thr=0.7,\n                       auc_nor=30):\n        \"\"\"Keypoint evaluation.\n\n        Args:\n            res_file (str): Json file stored prediction results.\n            metrics (str | list[str]): Metric to be performed.\n                Options: 'PCK', 'PCKh', 'AUC', 'EPE'.\n            pck_thr (float): PCK threshold, default as 0.2.\n            pckh_thr (float): PCKh threshold, default as 0.7.\n            auc_nor (float): AUC normalization factor, default as 30 pixel.\n\n        Returns:\n            List: Evaluation results for evaluation metric.\n        \"\"\"\n        info_str = []\n\n        with open(res_file, 'r') as fin:\n            preds = json.load(fin)\n        assert len(preds) == len(self.paired_samples)\n\n        outputs = []\n        gts = []\n        masks = []\n        threshold_bbox = []\n        threshold_head_box = []\n\n        for pred, pair in zip(preds, self.paired_samples):\n            item = self.db[pair[-1]]\n            outputs.append(np.array(pred['keypoints'])[:, :-1])\n            gts.append(np.array(item['joints_3d'])[:, :-1])\n\n            mask_query = ((np.array(item['joints_3d_visible'])[:, 0]) > 0)\n            mask_sample = ((np.array(\n                self.db[pair[0]]['joints_3d_visible'])[:, 0]) > 0)\n            for id_s in pair[:-1]:\n                mask_sample = np.bitwise_and(\n                    mask_sample,\n                    ((np.array(self.db[id_s]['joints_3d_visible'])[:, 0]) > 0))\n            masks.append(np.bitwise_and(mask_query, mask_sample))\n\n            if 'PCK' in metrics:\n                bbox = np.array(item['bbox'])\n                bbox_thr = np.max(bbox[2:])\n                threshold_bbox.append(np.array([bbox_thr, bbox_thr]))\n            if 'PCKh' in metrics:\n                head_box_thr = item['head_size']\n                threshold_head_box.append(\n                    np.array([head_box_thr, head_box_thr]))\n\n        if 'PCK' in metrics:\n            pck_avg = []\n            for (output, gt, mask, thr_bbox) in zip(outputs, gts, masks,\n                                                    threshold_bbox):\n                _, pck, _ = keypoint_pck_accuracy(\n                    np.expand_dims(output, 0), np.expand_dims(gt, 0),\n                    np.expand_dims(mask, 0), pck_thr,\n                    np.expand_dims(thr_bbox, 0))\n                pck_avg.append(pck)\n            info_str.append(('PCK', np.mean(pck_avg)))\n\n        return info_str\n\n    def _merge_obj(self, Xs_list, Xq, idx):\n        \"\"\"merge Xs_list and Xq.\n\n        :param Xs_list: N-shot samples X\n        :param Xq: query X\n        :param idx: id of paired_samples\n        :return: Xall\n        \"\"\"\n        Xall = dict()\n        Xall['img_s'] = [Xs['img'] for Xs in Xs_list]\n        Xall['target_s'] = [Xs['target'] for Xs in Xs_list]\n        Xall['target_weight_s'] = [Xs['target_weight'] for Xs in Xs_list]\n        xs_img_metas = [Xs['img_metas'].data for Xs in Xs_list]\n\n        Xall['img_q'] = Xq['img']\n        Xall['target_q'] = Xq['target']\n        Xall['target_weight_q'] = Xq['target_weight']\n        xq_img_metas = Xq['img_metas'].data\n\n        img_metas = dict()\n        for key in xq_img_metas.keys():\n            img_metas['sample_' + key] = [\n                xs_img_meta[key] for xs_img_meta in xs_img_metas\n            ]\n            img_metas['query_' + key] = xq_img_metas[key]\n        img_metas['bbox_id'] = idx\n\n        Xall['img_metas'] = DC(img_metas, cpu_only=True)\n\n        return Xall\n\n    def __len__(self):\n        \"\"\"Get the size of the dataset.\"\"\"\n        return len(self.paired_samples)\n\n    def __getitem__(self, idx):\n        \"\"\"Get the sample given index.\"\"\"\n\n        pair_ids = self.paired_samples[idx]  # [supported id * shots, query id]\n        assert len(pair_ids) == self.num_shots + 1\n        sample_id_list = pair_ids[:self.num_shots]\n        query_id = pair_ids[-1]\n\n        sample_obj_list = []\n        for sample_id in sample_id_list:\n            sample_obj = copy.deepcopy(self.db[sample_id])\n            sample_obj['ann_info'] = copy.deepcopy(self.ann_info)\n            sample_obj_list.append(sample_obj)\n\n        query_obj = copy.deepcopy(self.db[query_id])\n        query_obj['ann_info'] = copy.deepcopy(self.ann_info)\n\n        Xs_list = []\n        for sample_obj in sample_obj_list:\n            Xs = self.pipeline(\n                sample_obj\n            )  # dict with ['img', 'target', 'target_weight', 'img_metas'],\n            Xs_list.append(Xs)  # Xs['target'] is of shape [100, map_h, map_w]\n        Xq = self.pipeline(query_obj)\n\n        Xall = self._merge_obj(Xs_list, Xq, idx)\n        Xall['skeleton'] = self.db[query_id]['skeleton']\n        return Xall\n\n    def _sort_and_unique_bboxes(self, kpts, key='bbox_id'):\n        \"\"\"sort kpts and remove the repeated ones.\"\"\"\n        kpts = sorted(kpts, key=lambda x: x[key])\n        num = len(kpts)\n        for i in range(num - 1, 0, -1):\n            if kpts[i][key] == kpts[i - 1][key]:\n                del kpts[i]\n\n        return kpts\n"
  },
  {
    "path": "projects/pose_anything/datasets/datasets/mp100/transformer_dataset.py",
    "content": "import os\nimport random\nfrom collections import OrderedDict\n\nimport numpy as np\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets import DATASETS\nfrom .transformer_base_dataset import TransformerBaseDataset\n\n\n@DATASETS.register_module()\nclass TransformerPoseDataset(TransformerBaseDataset):\n\n    def __init__(self,\n                 ann_file,\n                 img_prefix,\n                 data_cfg,\n                 pipeline,\n                 valid_class_ids,\n                 max_kpt_num=None,\n                 num_shots=1,\n                 num_queries=100,\n                 num_episodes=1,\n                 test_mode=False):\n        super().__init__(\n            ann_file, img_prefix, data_cfg, pipeline, test_mode=test_mode)\n\n        self.ann_info['flip_pairs'] = []\n\n        self.ann_info['upper_body_ids'] = []\n        self.ann_info['lower_body_ids'] = []\n\n        self.ann_info['use_different_joint_weights'] = False\n        self.ann_info['joint_weights'] = np.array([\n            1.,\n        ], dtype=np.float32).reshape((self.ann_info['num_joints'], 1))\n\n        self.coco = COCO(ann_file)\n\n        self.id2name, self.name2id = self._get_mapping_id_name(self.coco.imgs)\n        self.img_ids = self.coco.getImgIds()\n        self.classes = [\n            cat['name'] for cat in self.coco.loadCats(self.coco.getCatIds())\n        ]\n\n        self.num_classes = len(self.classes)\n        self._class_to_ind = dict(zip(self.classes, self.coco.getCatIds()))\n        self._ind_to_class = dict(zip(self.coco.getCatIds(), self.classes))\n\n        if valid_class_ids is not None:  # None by default\n            self.valid_class_ids = valid_class_ids\n        else:\n            self.valid_class_ids = self.coco.getCatIds()\n        self.valid_classes = [\n            self._ind_to_class[ind] for ind in self.valid_class_ids\n        ]\n\n        self.cats = self.coco.cats\n        self.max_kpt_num = max_kpt_num\n\n        # Also update self.cat2obj\n        self.db = self._get_db()\n\n        self.num_shots = num_shots\n\n        if not test_mode:\n            # Update every training epoch\n            self.random_paired_samples()\n        else:\n            self.num_queries = num_queries\n            self.num_episodes = num_episodes\n            self.make_paired_samples()\n\n    def random_paired_samples(self):\n        num_datas = [\n            len(self.cat2obj[self._class_to_ind[cls]])\n            for cls in self.valid_classes\n        ]\n\n        # balance the dataset\n        max_num_data = max(num_datas)\n\n        all_samples = []\n        for cls in self.valid_class_ids:\n            for i in range(max_num_data):\n                shot = random.sample(self.cat2obj[cls], self.num_shots + 1)\n                all_samples.append(shot)\n\n        self.paired_samples = np.array(all_samples)\n        np.random.shuffle(self.paired_samples)\n\n    def make_paired_samples(self):\n        random.seed(1)\n        np.random.seed(0)\n\n        all_samples = []\n        for cls in self.valid_class_ids:\n            for _ in range(self.num_episodes):\n                shots = random.sample(self.cat2obj[cls],\n                                      self.num_shots + self.num_queries)\n                sample_ids = shots[:self.num_shots]\n                query_ids = shots[self.num_shots:]\n                for query_id in query_ids:\n                    all_samples.append(sample_ids + [query_id])\n\n        self.paired_samples = np.array(all_samples)\n\n    def _select_kpt(self, obj, kpt_id):\n        obj['joints_3d'] = obj['joints_3d'][kpt_id:kpt_id + 1]\n        obj['joints_3d_visible'] = obj['joints_3d_visible'][kpt_id:kpt_id + 1]\n        obj['kpt_id'] = kpt_id\n\n        return obj\n\n    @staticmethod\n    def _get_mapping_id_name(imgs):\n        \"\"\"\n        Args:\n            imgs (dict): dict of image info.\n\n        Returns:\n            tuple: Image name & id mapping dicts.\n\n            - id2name (dict): Mapping image id to name.\n            - name2id (dict): Mapping image name to id.\n        \"\"\"\n        id2name = {}\n        name2id = {}\n        for image_id, image in imgs.items():\n            file_name = image['file_name']\n            id2name[image_id] = file_name\n            name2id[file_name] = image_id\n\n        return id2name, name2id\n\n    def _get_db(self):\n        \"\"\"Ground truth bbox and keypoints.\"\"\"\n        self.obj_id = 0\n\n        self.cat2obj = {}\n        for i in self.coco.getCatIds():\n            self.cat2obj.update({i: []})\n\n        gt_db = []\n        for img_id in self.img_ids:\n            gt_db.extend(self._load_coco_keypoint_annotation_kernel(img_id))\n\n        return gt_db\n\n    def _load_coco_keypoint_annotation_kernel(self, img_id):\n        \"\"\"load annotation from COCOAPI.\n\n        Note:\n            bbox:[x1, y1, w, h]\n        Args:\n            img_id: coco image id\n        Returns:\n            dict: db entry\n        \"\"\"\n        img_ann = self.coco.loadImgs(img_id)[0]\n        width = img_ann['width']\n        height = img_ann['height']\n\n        ann_ids = self.coco.getAnnIds(imgIds=img_id, iscrowd=False)\n        objs = self.coco.loadAnns(ann_ids)\n\n        # sanitize bboxes\n        valid_objs = []\n        for obj in objs:\n            if 'bbox' not in obj:\n                continue\n            x, y, w, h = obj['bbox']\n            x1 = max(0, x)\n            y1 = max(0, y)\n            x2 = min(width - 1, x1 + max(0, w - 1))\n            y2 = min(height - 1, y1 + max(0, h - 1))\n            if ('area' not in obj or obj['area'] > 0) and x2 > x1 and y2 > y1:\n                obj['clean_bbox'] = [x1, y1, x2 - x1, y2 - y1]\n                valid_objs.append(obj)\n        objs = valid_objs\n\n        bbox_id = 0\n        rec = []\n        for obj in objs:\n            if 'keypoints' not in obj:\n                continue\n            if max(obj['keypoints']) == 0:\n                continue\n            if 'num_keypoints' in obj and obj['num_keypoints'] == 0:\n                continue\n\n            category_id = obj['category_id']\n            # the number of keypoint for this specific category\n            cat_kpt_num = int(len(obj['keypoints']) / 3)\n            if self.max_kpt_num is None:\n                kpt_num = cat_kpt_num\n            else:\n                kpt_num = self.max_kpt_num\n\n            joints_3d = np.zeros((kpt_num, 3), dtype=np.float32)\n            joints_3d_visible = np.zeros((kpt_num, 3), dtype=np.float32)\n\n            keypoints = np.array(obj['keypoints']).reshape(-1, 3)\n            joints_3d[:cat_kpt_num, :2] = keypoints[:, :2]\n            joints_3d_visible[:cat_kpt_num, :2] = np.minimum(\n                1, keypoints[:, 2:3])\n\n            center, scale = self._xywh2cs(*obj['clean_bbox'][:4])\n\n            image_file = os.path.join(self.img_prefix, self.id2name[img_id])\n            if os.path.exists(image_file):\n                self.cat2obj[category_id].append(self.obj_id)\n\n                rec.append({\n                    'image_file':\n                    image_file,\n                    'center':\n                    center,\n                    'scale':\n                    scale,\n                    'rotation':\n                    0,\n                    'bbox':\n                    obj['clean_bbox'][:4],\n                    'bbox_score':\n                    1,\n                    'joints_3d':\n                    joints_3d,\n                    'joints_3d_visible':\n                    joints_3d_visible,\n                    'category_id':\n                    category_id,\n                    'cat_kpt_num':\n                    cat_kpt_num,\n                    'bbox_id':\n                    self.obj_id,\n                    'skeleton':\n                    self.coco.cats[obj['category_id']]['skeleton'],\n                })\n                bbox_id = bbox_id + 1\n                self.obj_id += 1\n\n        return rec\n\n    def _xywh2cs(self, x, y, w, h):\n        \"\"\"This encodes bbox(x,y,w,w) into (center, scale)\n\n        Args:\n            x, y, w, h\n\n        Returns:\n            tuple: A tuple containing center and scale.\n\n            - center (np.ndarray[float32](2,)): center of the bbox (x, y).\n            - scale (np.ndarray[float32](2,)): scale of the bbox w & h.\n        \"\"\"\n        aspect_ratio = self.ann_info['image_size'][0] / self.ann_info[\n            'image_size'][1]\n        center = np.array([x + w * 0.5, y + h * 0.5], dtype=np.float32)\n        #\n        # if (not self.test_mode) and np.random.rand() < 0.3:\n        #     center += 0.4 * (np.random.rand(2) - 0.5) * [w, h]\n\n        if w > aspect_ratio * h:\n            h = w * 1.0 / aspect_ratio\n        elif w < aspect_ratio * h:\n            w = h * aspect_ratio\n\n        # pixel std is 200.0\n        scale = np.array([w / 200.0, h / 200.0], dtype=np.float32)\n        # padding to include proper amount of context\n        scale = scale * 1.25\n\n        return center, scale\n\n    def evaluate(self, outputs, res_folder, metric='PCK', **kwargs):\n        \"\"\"Evaluate interhand2d keypoint results. The pose prediction results\n        will be saved in `${res_folder}/result_keypoints.json`.\n\n        Note:\n            batch_size: N\n            num_keypoints: K\n            heatmap height: H\n            heatmap width: W\n\n        Args:\n            outputs (list(preds, boxes, image_path, output_heatmap))\n                :preds (np.ndarray[N,K,3]): The first two dimensions are\n                    coordinates, score is the third dimension of the array.\n                :boxes (np.ndarray[N,6]): [center[0], center[1], scale[0]\n                    , scale[1],area, score]\n                :image_paths (list[str]): For example, ['C', 'a', 'p', 't',\n                    'u', 'r', 'e', '1', '2', '/', '0', '3', '9', '0', '_',\n                    'd', 'h', '_', 't', 'o', 'u', 'c', 'h', 'R', 'O', 'M',\n                    '/', 'c', 'a', 'm', '4', '1', '0', '2', '0', '9', '/',\n                    'i', 'm', 'a', 'g', 'e', '6', '2', '4', '3', '4', '.',\n                    'j', 'p', 'g']\n                :output_heatmap (np.ndarray[N, K, H, W]): model outputs.\n\n            res_folder (str): Path of directory to save the results.\n            metric (str | list[str]): Metric to be performed.\n                Options: 'PCK', 'AUC', 'EPE'.\n\n        Returns:\n            dict: Evaluation results for evaluation metric.\n        \"\"\"\n        metrics = metric if isinstance(metric, list) else [metric]\n        allowed_metrics = ['PCK', 'AUC', 'EPE', 'NME']\n        for metric in metrics:\n            if metric not in allowed_metrics:\n                raise KeyError(f'metric {metric} is not supported')\n\n        res_file = os.path.join(res_folder, 'result_keypoints.json')\n\n        kpts = []\n        for output in outputs:\n            preds = output['preds']\n            boxes = output['boxes']\n            image_paths = output['image_paths']\n            bbox_ids = output['bbox_ids']\n\n            batch_size = len(image_paths)\n            for i in range(batch_size):\n                image_id = self.name2id[image_paths[i][len(self.img_prefix):]]\n\n                kpts.append({\n                    'keypoints': preds[i].tolist(),\n                    'center': boxes[i][0:2].tolist(),\n                    'scale': boxes[i][2:4].tolist(),\n                    'area': float(boxes[i][4]),\n                    'score': float(boxes[i][5]),\n                    'image_id': image_id,\n                    'bbox_id': bbox_ids[i]\n                })\n        kpts = self._sort_and_unique_bboxes(kpts)\n\n        self._write_keypoint_results(kpts, res_file)\n        info_str = self._report_metric(res_file, metrics)\n        name_value = OrderedDict(info_str)\n\n        return name_value\n"
  },
  {
    "path": "projects/pose_anything/datasets/pipelines/__init__.py",
    "content": "from .top_down_transform import TopDownGenerateTargetFewShot\n\n__all__ = ['TopDownGenerateTargetFewShot']\n"
  },
  {
    "path": "projects/pose_anything/datasets/pipelines/post_transforms.py",
    "content": ""
  },
  {
    "path": "projects/pose_anything/datasets/pipelines/top_down_transform.py",
    "content": "import numpy as np\n\n\nclass TopDownGenerateTargetFewShot:\n    \"\"\"Generate the target heatmap.\n\n    Required keys: 'joints_3d', 'joints_3d_visible', 'ann_info'.\n    Modified keys: 'target', and 'target_weight'.\n\n    Args:\n        sigma: Sigma of heatmap gaussian for 'MSRA' approach.\n        kernel: Kernel of heatmap gaussian for 'Megvii' approach.\n        encoding (str): Approach to generate target heatmaps.\n            Currently supported approaches: 'MSRA', 'Megvii', 'UDP'.\n            Default:'MSRA'\n\n        unbiased_encoding (bool): Option to use unbiased\n            encoding methods.\n            Paper ref: Zhang et al. Distribution-Aware Coordinate\n            Representation for Human Pose Estimation (CVPR 2020).\n        keypoint_pose_distance: Keypoint pose distance for UDP.\n            Paper ref: Huang et al. The Devil is in the Details: Delving into\n            Unbiased Data Processing for Human Pose Estimation (CVPR 2020).\n        target_type (str): supported targets: 'GaussianHeatMap',\n            'CombinedTarget'. Default:'GaussianHeatMap'\n            CombinedTarget: The combination of classification target\n            (response map) and regression target (offset map).\n            Paper ref: Huang et al. The Devil is in the Details: Delving into\n            Unbiased Data Processing for Human Pose Estimation (CVPR 2020).\n    \"\"\"\n\n    def __init__(self,\n                 sigma=2,\n                 kernel=(11, 11),\n                 valid_radius_factor=0.0546875,\n                 target_type='GaussianHeatMap',\n                 encoding='MSRA',\n                 unbiased_encoding=False):\n        self.sigma = sigma\n        self.unbiased_encoding = unbiased_encoding\n        self.kernel = kernel\n        self.valid_radius_factor = valid_radius_factor\n        self.target_type = target_type\n        self.encoding = encoding\n\n    def _msra_generate_target(self, cfg, joints_3d, joints_3d_visible, sigma):\n        \"\"\"Generate the target heatmap via \"MSRA\" approach.\n\n        Args:\n            cfg (dict): data config\n            joints_3d: np.ndarray ([num_joints, 3])\n            joints_3d_visible: np.ndarray ([num_joints, 3])\n            sigma: Sigma of heatmap gaussian\n        Returns:\n            tuple: A tuple containing targets.\n\n            - target: Target heatmaps.\n            - target_weight: (1: visible, 0: invisible)\n        \"\"\"\n        num_joints = len(joints_3d)\n        image_size = cfg['image_size']\n        W, H = cfg['heatmap_size']\n        joint_weights = cfg['joint_weights']\n        use_different_joint_weights = cfg['use_different_joint_weights']\n        assert not use_different_joint_weights\n\n        target_weight = np.zeros((num_joints, 1), dtype=np.float32)\n        target = np.zeros((num_joints, H, W), dtype=np.float32)\n\n        # 3-sigma rule\n        tmp_size = sigma * 3\n\n        if self.unbiased_encoding:\n            for joint_id in range(num_joints):\n                target_weight[joint_id] = joints_3d_visible[joint_id, 0]\n\n                feat_stride = image_size / [W, H]\n                mu_x = joints_3d[joint_id][0] / feat_stride[0]\n                mu_y = joints_3d[joint_id][1] / feat_stride[1]\n                # Check that any part of the gaussian is in-bounds\n                ul = [mu_x - tmp_size, mu_y - tmp_size]\n                br = [mu_x + tmp_size + 1, mu_y + tmp_size + 1]\n                if ul[0] >= W or ul[1] >= H or br[0] < 0 or br[1] < 0:\n                    target_weight[joint_id] = 0\n\n                if target_weight[joint_id] == 0:\n                    continue\n\n                x = np.arange(0, W, 1, np.float32)\n                y = np.arange(0, H, 1, np.float32)\n                y = y[:, None]\n\n                if target_weight[joint_id] > 0.5:\n                    target[joint_id] = np.exp(-((x - mu_x)**2 +\n                                                (y - mu_y)**2) /\n                                              (2 * sigma**2))\n        else:\n            for joint_id in range(num_joints):\n                target_weight[joint_id] = joints_3d_visible[joint_id, 0]\n\n                feat_stride = image_size / [W, H]\n                mu_x = int(joints_3d[joint_id][0] / feat_stride[0] + 0.5)\n                mu_y = int(joints_3d[joint_id][1] / feat_stride[1] + 0.5)\n                # Check that any part of the gaussian is in-bounds\n                ul = [int(mu_x - tmp_size), int(mu_y - tmp_size)]\n                br = [int(mu_x + tmp_size + 1), int(mu_y + tmp_size + 1)]\n                if ul[0] >= W or ul[1] >= H or br[0] < 0 or br[1] < 0:\n                    target_weight[joint_id] = 0\n\n                if target_weight[joint_id] > 0.5:\n                    size = 2 * tmp_size + 1\n                    x = np.arange(0, size, 1, np.float32)\n                    y = x[:, None]\n                    x0 = y0 = size // 2\n                    # The gaussian is not normalized,\n                    # we want the center value to equal 1\n                    g = np.exp(-((x - x0)**2 + (y - y0)**2) / (2 * sigma**2))\n\n                    # Usable gaussian range\n                    g_x = max(0, -ul[0]), min(br[0], W) - ul[0]\n                    g_y = max(0, -ul[1]), min(br[1], H) - ul[1]\n                    # Image range\n                    img_x = max(0, ul[0]), min(br[0], W)\n                    img_y = max(0, ul[1]), min(br[1], H)\n\n                    target[joint_id][img_y[0]:img_y[1], img_x[0]:img_x[1]] = \\\n                        g[g_y[0]:g_y[1], g_x[0]:g_x[1]]\n\n        if use_different_joint_weights:\n            target_weight = np.multiply(target_weight, joint_weights)\n\n        return target, target_weight\n\n    def _udp_generate_target(self, cfg, joints_3d, joints_3d_visible, factor,\n                             target_type):\n        \"\"\"Generate the target heatmap via 'UDP' approach. Paper ref: Huang et\n        al. The Devil is in the Details: Delving into Unbiased Data Processing\n        for Human Pose Estimation (CVPR 2020).\n\n        Note:\n            num keypoints: K\n            heatmap height: H\n            heatmap width: W\n            num target channels: C\n            C = K if target_type=='GaussianHeatMap'\n            C = 3*K if target_type=='CombinedTarget'\n\n        Args:\n            cfg (dict): data config\n            joints_3d (np.ndarray[K, 3]): Annotated keypoints.\n            joints_3d_visible (np.ndarray[K, 3]): Visibility of keypoints.\n            factor (float): kernel factor for GaussianHeatMap target or\n                valid radius factor for CombinedTarget.\n            target_type (str): 'GaussianHeatMap' or 'CombinedTarget'.\n                GaussianHeatMap: Heatmap target with gaussian distribution.\n                CombinedTarget: The combination of classification target\n                (response map) and regression target (offset map).\n\n        Returns:\n            tuple: A tuple containing targets.\n\n            - target (np.ndarray[C, H, W]): Target heatmaps.\n            - target_weight (np.ndarray[K, 1]): (1: visible, 0: invisible)\n        \"\"\"\n        num_joints = len(joints_3d)\n        image_size = cfg['image_size']\n        heatmap_size = cfg['heatmap_size']\n        joint_weights = cfg['joint_weights']\n        use_different_joint_weights = cfg['use_different_joint_weights']\n        assert not use_different_joint_weights\n\n        target_weight = np.ones((num_joints, 1), dtype=np.float32)\n        target_weight[:, 0] = joints_3d_visible[:, 0]\n\n        assert target_type in ['GaussianHeatMap', 'CombinedTarget']\n\n        if target_type == 'GaussianHeatMap':\n            target = np.zeros((num_joints, heatmap_size[1], heatmap_size[0]),\n                              dtype=np.float32)\n\n            tmp_size = factor * 3\n\n            # prepare for gaussian\n            size = 2 * tmp_size + 1\n            x = np.arange(0, size, 1, np.float32)\n            y = x[:, None]\n\n            for joint_id in range(num_joints):\n                feat_stride = (image_size - 1.0) / (heatmap_size - 1.0)\n                mu_x = int(joints_3d[joint_id][0] / feat_stride[0] + 0.5)\n                mu_y = int(joints_3d[joint_id][1] / feat_stride[1] + 0.5)\n                # Check that any part of the gaussian is in-bounds\n                ul = [int(mu_x - tmp_size), int(mu_y - tmp_size)]\n                br = [int(mu_x + tmp_size + 1), int(mu_y + tmp_size + 1)]\n                if ul[0] >= heatmap_size[0] or ul[1] >= heatmap_size[1] \\\n                        or br[0] < 0 or br[1] < 0:\n                    # If not, just return the image as is\n                    target_weight[joint_id] = 0\n                    continue\n\n                # # Generate gaussian\n                mu_x_ac = joints_3d[joint_id][0] / feat_stride[0]\n                mu_y_ac = joints_3d[joint_id][1] / feat_stride[1]\n                x0 = y0 = size // 2\n                x0 += mu_x_ac - mu_x\n                y0 += mu_y_ac - mu_y\n                g = np.exp(-((x - x0)**2 + (y - y0)**2) / (2 * factor**2))\n\n                # Usable gaussian range\n                g_x = max(0, -ul[0]), min(br[0], heatmap_size[0]) - ul[0]\n                g_y = max(0, -ul[1]), min(br[1], heatmap_size[1]) - ul[1]\n                # Image range\n                img_x = max(0, ul[0]), min(br[0], heatmap_size[0])\n                img_y = max(0, ul[1]), min(br[1], heatmap_size[1])\n\n                v = target_weight[joint_id]\n                if v > 0.5:\n                    target[joint_id][img_y[0]:img_y[1], img_x[0]:img_x[1]] = \\\n                        g[g_y[0]:g_y[1], g_x[0]:g_x[1]]\n        elif target_type == 'CombinedTarget':\n            target = np.zeros(\n                (num_joints, 3, heatmap_size[1] * heatmap_size[0]),\n                dtype=np.float32)\n            feat_width = heatmap_size[0]\n            feat_height = heatmap_size[1]\n            feat_x_int = np.arange(0, feat_width)\n            feat_y_int = np.arange(0, feat_height)\n            feat_x_int, feat_y_int = np.meshgrid(feat_x_int, feat_y_int)\n            feat_x_int = feat_x_int.flatten()\n            feat_y_int = feat_y_int.flatten()\n            # Calculate the radius of the positive area in classification\n            #   heatmap.\n            valid_radius = factor * heatmap_size[1]\n            feat_stride = (image_size - 1.0) / (heatmap_size - 1.0)\n            for joint_id in range(num_joints):\n                mu_x = joints_3d[joint_id][0] / feat_stride[0]\n                mu_y = joints_3d[joint_id][1] / feat_stride[1]\n                x_offset = (mu_x - feat_x_int) / valid_radius\n                y_offset = (mu_y - feat_y_int) / valid_radius\n                dis = x_offset**2 + y_offset**2\n                keep_pos = np.where(dis <= 1)[0]\n                v = target_weight[joint_id]\n                if v > 0.5:\n                    target[joint_id, 0, keep_pos] = 1\n                    target[joint_id, 1, keep_pos] = x_offset[keep_pos]\n                    target[joint_id, 2, keep_pos] = y_offset[keep_pos]\n            target = target.reshape(num_joints * 3, heatmap_size[1],\n                                    heatmap_size[0])\n\n        if use_different_joint_weights:\n            target_weight = np.multiply(target_weight, joint_weights)\n\n        return target, target_weight\n\n    def __call__(self, results):\n        \"\"\"Generate the target heatmap.\"\"\"\n        joints_3d = results['joints_3d']\n        joints_3d_visible = results['joints_3d_visible']\n\n        assert self.encoding in ['MSRA', 'UDP']\n\n        if self.encoding == 'MSRA':\n            if isinstance(self.sigma, list):\n                num_sigmas = len(self.sigma)\n                cfg = results['ann_info']\n                num_joints = len(joints_3d)\n                heatmap_size = cfg['heatmap_size']\n\n                target = np.empty(\n                    (0, num_joints, heatmap_size[1], heatmap_size[0]),\n                    dtype=np.float32)\n                target_weight = np.empty((0, num_joints, 1), dtype=np.float32)\n                for i in range(num_sigmas):\n                    target_i, target_weight_i = self._msra_generate_target(\n                        cfg, joints_3d, joints_3d_visible, self.sigma[i])\n                    target = np.concatenate([target, target_i[None]], axis=0)\n                    target_weight = np.concatenate(\n                        [target_weight, target_weight_i[None]], axis=0)\n            else:\n                target, target_weight = self._msra_generate_target(\n                    results['ann_info'], joints_3d, joints_3d_visible,\n                    self.sigma)\n        elif self.encoding == 'UDP':\n            if self.target_type == 'CombinedTarget':\n                factors = self.valid_radius_factor\n                channel_factor = 3\n            elif self.target_type == 'GaussianHeatMap':\n                factors = self.sigma\n                channel_factor = 1\n            if isinstance(factors, list):\n                num_factors = len(factors)\n                cfg = results['ann_info']\n                num_joints = len(joints_3d)\n                W, H = cfg['heatmap_size']\n\n                target = np.empty((0, channel_factor * num_joints, H, W),\n                                  dtype=np.float32)\n                target_weight = np.empty((0, num_joints, 1), dtype=np.float32)\n                for i in range(num_factors):\n                    target_i, target_weight_i = self._udp_generate_target(\n                        cfg, joints_3d, joints_3d_visible, factors[i],\n                        self.target_type)\n                    target = np.concatenate([target, target_i[None]], axis=0)\n                    target_weight = np.concatenate(\n                        [target_weight, target_weight_i[None]], axis=0)\n            else:\n                target, target_weight = self._udp_generate_target(\n                    results['ann_info'], joints_3d, joints_3d_visible, factors,\n                    self.target_type)\n        else:\n            raise ValueError(\n                f'Encoding approach {self.encoding} is not supported!')\n\n        results['target'] = target\n        results['target_weight'] = target_weight\n\n        return results\n"
  },
  {
    "path": "projects/pose_anything/demo.py",
    "content": "import argparse\nimport copy\nimport os\nimport random\n\nimport cv2\nimport numpy as np\nimport torch\nimport torchvision.transforms.functional as F\nfrom datasets.pipelines import TopDownGenerateTargetFewShot\nfrom mmcv.cnn import fuse_conv_bn\nfrom mmengine.config import Config, DictAction\nfrom mmengine.runner import load_checkpoint\nfrom torchvision import transforms\n\nfrom mmpose.models import build_pose_estimator\nfrom tools.visualization import COLORS, plot_results\n\n\nclass ResizePad:\n\n    def __init__(self, w=256, h=256):\n        self.w = w\n        self.h = h\n\n    def __call__(self, image):\n        _, w_1, h_1 = image.shape\n        ratio_1 = w_1 / h_1\n        # check if the original and final aspect ratios are the same within a\n        # margin\n        if round(ratio_1, 2) != 1:\n            # padding to preserve aspect ratio\n            if ratio_1 > 1:  # Make the image higher\n                hp = int(w_1 - h_1)\n                hp = hp // 2\n                image = F.pad(image, (hp, 0, hp, 0), 0, 'constant')\n                return F.resize(image, [self.h, self.w])\n            else:\n                wp = int(h_1 - w_1)\n                wp = wp // 2\n                image = F.pad(image, (0, wp, 0, wp), 0, 'constant')\n                return F.resize(image, [self.h, self.w])\n        else:\n            return F.resize(image, [self.h, self.w])\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Pose Anything Demo')\n    parser.add_argument('--support', help='Image file')\n    parser.add_argument('--query', help='Image file')\n    parser.add_argument(\n        '--config', default='configs/demo.py', help='test config file path')\n    parser.add_argument(\n        '--checkpoint', default='pretrained', help='checkpoint file')\n    parser.add_argument('--outdir', default='output', help='checkpoint file')\n\n    parser.add_argument(\n        '--fuse-conv-bn',\n        action='store_true',\n        help='Whether to fuse conv and bn, this will slightly increase'\n        'the inference speed')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        default={},\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. For example, '\n        \"'--cfg-options model.backbone.depth=18 \"\n        \"model.backbone.with_cp=True'\")\n    args = parser.parse_args()\n    return args\n\n\ndef merge_configs(cfg1, cfg2):\n    # Merge cfg2 into cfg1\n    # Overwrite cfg1 if repeated, ignore if value is None.\n    cfg1 = {} if cfg1 is None else cfg1.copy()\n    cfg2 = {} if cfg2 is None else cfg2\n    for k, v in cfg2.items():\n        if v:\n            cfg1[k] = v\n    return cfg1\n\n\ndef main():\n    random.seed(0)\n    np.random.seed(0)\n    torch.manual_seed(0)\n\n    args = parse_args()\n    cfg = Config.fromfile(args.config)\n\n    if args.cfg_options is not None:\n        cfg.merge_from_dict(args.cfg_options)\n    # set cudnn_benchmark\n    if cfg.get('cudnn_benchmark', False):\n        torch.backends.cudnn.benchmark = True\n    cfg.data.test.test_mode = True\n\n    os.makedirs(args.outdir, exist_ok=True)\n\n    # Load data\n    support_img = cv2.imread(args.support)\n    query_img = cv2.imread(args.query)\n    if support_img is None or query_img is None:\n        raise ValueError('Fail to read images')\n\n    preprocess = transforms.Compose([\n        transforms.ToTensor(),\n        ResizePad(cfg.model.encoder_config.img_size,\n                  cfg.model.encoder_config.img_size)\n    ])\n\n    # frame = copy.deepcopy(support_img)\n    padded_support_img = preprocess(support_img).cpu().numpy().transpose(\n        1, 2, 0) * 255\n    frame = copy.deepcopy(padded_support_img.astype(np.uint8).copy())\n    kp_src = []\n    skeleton = []\n    count = 0\n    prev_pt = None\n    prev_pt_idx = None\n    color_idx = 0\n\n    def selectKP(event, x, y, flags, param):\n        nonlocal kp_src, frame\n        # if we are in points selection mode, the mouse was clicked,\n        # list of  points with the (x, y) location of the click\n        # and draw the circle\n\n        if event == cv2.EVENT_LBUTTONDOWN:\n            kp_src.append((x, y))\n            cv2.circle(frame, (x, y), 2, (0, 0, 255), 1)\n            cv2.imshow('Source', frame)\n\n        if event == cv2.EVENT_RBUTTONDOWN:\n            kp_src = []\n            frame = copy.deepcopy(support_img)\n            cv2.imshow('Source', frame)\n\n    def draw_line(event, x, y, flags, param):\n        nonlocal skeleton, kp_src, frame, count, prev_pt, prev_pt_idx, \\\n            marked_frame, color_idx\n        if event == cv2.EVENT_LBUTTONDOWN:\n            closest_point = min(\n                kp_src, key=lambda p: (p[0] - x)**2 + (p[1] - y)**2)\n            closest_point_index = kp_src.index(closest_point)\n            if color_idx < len(COLORS):\n                c = COLORS[color_idx]\n            else:\n                c = random.choices(range(256), k=3)\n\n            cv2.circle(frame, closest_point, 2, c, 1)\n            if count == 0:\n                prev_pt = closest_point\n                prev_pt_idx = closest_point_index\n                count = count + 1\n                cv2.imshow('Source', frame)\n            else:\n                cv2.line(frame, prev_pt, closest_point, c, 2)\n                cv2.imshow('Source', frame)\n                count = 0\n                skeleton.append((prev_pt_idx, closest_point_index))\n                color_idx = color_idx + 1\n        elif event == cv2.EVENT_RBUTTONDOWN:\n            frame = copy.deepcopy(marked_frame)\n            cv2.imshow('Source', frame)\n            count = 0\n            color_idx = 0\n            skeleton = []\n            prev_pt = None\n\n    cv2.namedWindow('Source', cv2.WINDOW_NORMAL)\n    cv2.resizeWindow('Source', 800, 600)\n    cv2.setMouseCallback('Source', selectKP)\n    cv2.imshow('Source', frame)\n\n    # keep looping until points have been selected\n    print('Press any key when finished marking the points!! ')\n    while True:\n        if cv2.waitKey(1) > 0:\n            break\n\n    marked_frame = copy.deepcopy(frame)\n    cv2.setMouseCallback('Source', draw_line)\n    print('Press any key when finished creating skeleton!!')\n    while True:\n        if cv2.waitKey(1) > 0:\n            break\n\n    cv2.destroyAllWindows()\n    kp_src = torch.tensor(kp_src).float()\n    preprocess = transforms.Compose([\n        transforms.ToTensor(),\n        transforms.Normalize((0.485, 0.456, 0.406), (0.229, 0.224, 0.225)),\n        ResizePad(cfg.model.encoder_config.img_size,\n                  cfg.model.encoder_config.img_size)\n    ])\n\n    if len(skeleton) == 0:\n        skeleton = [(0, 0)]\n\n    support_img = preprocess(support_img).flip(0)[None]\n    query_img = preprocess(query_img).flip(0)[None]\n    # Create heatmap from keypoints\n    genHeatMap = TopDownGenerateTargetFewShot()\n    data_cfg = cfg.data_cfg\n    data_cfg['image_size'] = np.array(\n        [cfg.model.encoder_config.img_size, cfg.model.encoder_config.img_size])\n    data_cfg['joint_weights'] = None\n    data_cfg['use_different_joint_weights'] = False\n    kp_src_3d = torch.cat((kp_src, torch.zeros(kp_src.shape[0], 1)), dim=-1)\n    kp_src_3d_weight = torch.cat(\n        (torch.ones_like(kp_src), torch.zeros(kp_src.shape[0], 1)), dim=-1)\n    target_s, target_weight_s = genHeatMap._msra_generate_target(\n        data_cfg, kp_src_3d, kp_src_3d_weight, sigma=2)\n    target_s = torch.tensor(target_s).float()[None]\n    target_weight_s = torch.tensor(target_weight_s).float()[None]\n\n    data = {\n        'img_s': [support_img],\n        'img_q':\n        query_img,\n        'target_s': [target_s],\n        'target_weight_s': [target_weight_s],\n        'target_q':\n        None,\n        'target_weight_q':\n        None,\n        'return_loss':\n        False,\n        'img_metas': [{\n            'sample_skeleton': [skeleton],\n            'query_skeleton':\n            skeleton,\n            'sample_joints_3d': [kp_src_3d],\n            'query_joints_3d':\n            kp_src_3d,\n            'sample_center': [kp_src.mean(dim=0)],\n            'query_center':\n            kp_src.mean(dim=0),\n            'sample_scale': [kp_src.max(dim=0)[0] - kp_src.min(dim=0)[0]],\n            'query_scale':\n            kp_src.max(dim=0)[0] - kp_src.min(dim=0)[0],\n            'sample_rotation': [0],\n            'query_rotation':\n            0,\n            'sample_bbox_score': [1],\n            'query_bbox_score':\n            1,\n            'query_image_file':\n            '',\n            'sample_image_file': [''],\n        }]\n    }\n\n    # Load model\n    model = build_pose_estimator(cfg.model)\n    load_checkpoint(model, args.checkpoint, map_location='cpu')\n    if args.fuse_conv_bn:\n        model = fuse_conv_bn(model)\n    model.eval()\n\n    with torch.no_grad():\n        outputs = model(**data)\n\n    # visualize results\n    vis_s_weight = target_weight_s[0]\n    vis_q_weight = target_weight_s[0]\n    vis_s_image = support_img[0].detach().cpu().numpy().transpose(1, 2, 0)\n    vis_q_image = query_img[0].detach().cpu().numpy().transpose(1, 2, 0)\n    support_kp = kp_src_3d\n\n    plot_results(\n        vis_s_image,\n        vis_q_image,\n        support_kp,\n        vis_s_weight,\n        None,\n        vis_q_weight,\n        skeleton,\n        None,\n        torch.tensor(outputs['points']).squeeze(0),\n        out_dir=args.outdir)\n\n    print('Output saved to output dir: {}'.format(args.outdir))\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "projects/pose_anything/models/__init__.py",
    "content": "from .backbones import *  # noqa\nfrom .detectors import *  # noqa\nfrom .keypoint_heads import *  # noqa\nfrom .utils import *  # noqa\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/__init__.py",
    "content": "from .swin_transformer_v2 import SwinTransformerV2  # noqa\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/simmim.py",
    "content": "# --------------------------------------------------------\n# SimMIM\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Zhenda Xie\n# --------------------------------------------------------\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom timm.models.layers import trunc_normal_\n\nfrom .swin_transformer import SwinTransformer\nfrom .swin_transformer_v2 import SwinTransformerV2\n\n\ndef norm_targets(targets, patch_size):\n    assert patch_size % 2 == 1\n\n    targets_ = targets\n    targets_count = torch.ones_like(targets)\n\n    targets_square = targets**2.\n\n    targets_mean = F.avg_pool2d(\n        targets,\n        kernel_size=patch_size,\n        stride=1,\n        padding=patch_size // 2,\n        count_include_pad=False)\n    targets_square_mean = F.avg_pool2d(\n        targets_square,\n        kernel_size=patch_size,\n        stride=1,\n        padding=patch_size // 2,\n        count_include_pad=False)\n    targets_count = F.avg_pool2d(\n        targets_count,\n        kernel_size=patch_size,\n        stride=1,\n        padding=patch_size // 2,\n        count_include_pad=True) * (\n            patch_size**2)\n\n    targets_var = (targets_square_mean - targets_mean**2.) * (\n        targets_count / (targets_count - 1))\n    targets_var = torch.clamp(targets_var, min=0.)\n\n    targets_ = (targets_ - targets_mean) / (targets_var + 1.e-6)**0.5\n\n    return targets_\n\n\nclass SwinTransformerForSimMIM(SwinTransformer):\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n\n        assert self.num_classes == 0\n\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, self.embed_dim))\n        trunc_normal_(self.mask_token, mean=0., std=.02)\n\n    def forward(self, x, mask):\n        x = self.patch_embed(x)\n\n        assert mask is not None\n        B, L, _ = x.shape\n\n        mask_tokens = self.mask_token.expand(B, L, -1)\n        w = mask.flatten(1).unsqueeze(-1).type_as(mask_tokens)\n        x = x * (1. - w) + mask_tokens * w\n\n        if self.ape:\n            x = x + self.absolute_pos_embed\n        x = self.pos_drop(x)\n\n        for layer in self.layers:\n            x = layer(x)\n        x = self.norm(x)\n\n        x = x.transpose(1, 2)\n        B, C, L = x.shape\n        H = W = int(L**0.5)\n        x = x.reshape(B, C, H, W)\n        return x\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return super().no_weight_decay() | {'mask_token'}\n\n\nclass SwinTransformerV2ForSimMIM(SwinTransformerV2):\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n\n        assert self.num_classes == 0\n\n        self.mask_token = nn.Parameter(torch.zeros(1, 1, self.embed_dim))\n        trunc_normal_(self.mask_token, mean=0., std=.02)\n\n    def forward(self, x, mask):\n        x = self.patch_embed(x)\n\n        assert mask is not None\n        B, L, _ = x.shape\n\n        mask_tokens = self.mask_token.expand(B, L, -1)\n        w = mask.flatten(1).unsqueeze(-1).type_as(mask_tokens)\n        x = x * (1. - w) + mask_tokens * w\n\n        if self.ape:\n            x = x + self.absolute_pos_embed\n        x = self.pos_drop(x)\n\n        for layer in self.layers:\n            x = layer(x)\n        x = self.norm(x)\n\n        x = x.transpose(1, 2)\n        B, C, L = x.shape\n        H = W = int(L**0.5)\n        x = x.reshape(B, C, H, W)\n        return x\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return super().no_weight_decay() | {'mask_token'}\n\n\nclass SimMIM(nn.Module):\n\n    def __init__(self, config, encoder, encoder_stride, in_chans, patch_size):\n        super().__init__()\n        self.config = config\n        self.encoder = encoder\n        self.encoder_stride = encoder_stride\n\n        self.decoder = nn.Sequential(\n            nn.Conv2d(\n                in_channels=self.encoder.num_features,\n                out_channels=self.encoder_stride**2 * 3,\n                kernel_size=1),\n            nn.PixelShuffle(self.encoder_stride),\n        )\n\n        self.in_chans = in_chans\n        self.patch_size = patch_size\n\n    def forward(self, x, mask):\n        z = self.encoder(x, mask)\n        x_rec = self.decoder(z)\n\n        mask = mask.repeat_interleave(self.patch_size, 1).repeat_interleave(\n            self.patch_size, 2).unsqueeze(1).contiguous()\n\n        # norm target as prompted\n        if self.config.NORM_TARGET.ENABLE:\n            x = norm_targets(x, self.config.NORM_TARGET.PATCH_SIZE)\n\n        loss_recon = F.l1_loss(x, x_rec, reduction='none')\n        loss = (loss_recon * mask).sum() / (mask.sum() + 1e-5) / self.in_chans\n        return loss\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        if hasattr(self.encoder, 'no_weight_decay'):\n            return {'encoder.' + i for i in self.encoder.no_weight_decay()}\n        return {}\n\n    @torch.jit.ignore\n    def no_weight_decay_keywords(self):\n        if hasattr(self.encoder, 'no_weight_decay_keywords'):\n            return {\n                'encoder.' + i\n                for i in self.encoder.no_weight_decay_keywords()\n            }\n        return {}\n\n\ndef build_simmim(config):\n    model_type = config.MODEL.TYPE\n    if model_type == 'swin':\n        encoder = SwinTransformerForSimMIM(\n            img_size=config.DATA.IMG_SIZE,\n            patch_size=config.MODEL.SWIN.PATCH_SIZE,\n            in_chans=config.MODEL.SWIN.IN_CHANS,\n            num_classes=0,\n            embed_dim=config.MODEL.SWIN.EMBED_DIM,\n            depths=config.MODEL.SWIN.DEPTHS,\n            num_heads=config.MODEL.SWIN.NUM_HEADS,\n            window_size=config.MODEL.SWIN.WINDOW_SIZE,\n            mlp_ratio=config.MODEL.SWIN.MLP_RATIO,\n            qkv_bias=config.MODEL.SWIN.QKV_BIAS,\n            qk_scale=config.MODEL.SWIN.QK_SCALE,\n            drop_rate=config.MODEL.DROP_RATE,\n            drop_path_rate=config.MODEL.DROP_PATH_RATE,\n            ape=config.MODEL.SWIN.APE,\n            patch_norm=config.MODEL.SWIN.PATCH_NORM,\n            use_checkpoint=config.TRAIN.USE_CHECKPOINT)\n        encoder_stride = 32\n        in_chans = config.MODEL.SWIN.IN_CHANS\n        patch_size = config.MODEL.SWIN.PATCH_SIZE\n    elif model_type == 'swinv2':\n        encoder = SwinTransformerV2ForSimMIM(\n            img_size=config.DATA.IMG_SIZE,\n            patch_size=config.MODEL.SWINV2.PATCH_SIZE,\n            in_chans=config.MODEL.SWINV2.IN_CHANS,\n            num_classes=0,\n            embed_dim=config.MODEL.SWINV2.EMBED_DIM,\n            depths=config.MODEL.SWINV2.DEPTHS,\n            num_heads=config.MODEL.SWINV2.NUM_HEADS,\n            window_size=config.MODEL.SWINV2.WINDOW_SIZE,\n            mlp_ratio=config.MODEL.SWINV2.MLP_RATIO,\n            qkv_bias=config.MODEL.SWINV2.QKV_BIAS,\n            drop_rate=config.MODEL.DROP_RATE,\n            drop_path_rate=config.MODEL.DROP_PATH_RATE,\n            ape=config.MODEL.SWINV2.APE,\n            patch_norm=config.MODEL.SWINV2.PATCH_NORM,\n            use_checkpoint=config.TRAIN.USE_CHECKPOINT)\n        encoder_stride = 32\n        in_chans = config.MODEL.SWINV2.IN_CHANS\n        patch_size = config.MODEL.SWINV2.PATCH_SIZE\n    else:\n        raise NotImplementedError(f'Unknown pre-train model: {model_type}')\n\n    model = SimMIM(\n        config=config.MODEL.SIMMIM,\n        encoder=encoder,\n        encoder_stride=encoder_stride,\n        in_chans=in_chans,\n        patch_size=patch_size)\n\n    return model\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/swin_mlp.py",
    "content": "# --------------------------------------------------------\n# Swin Transformer\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ze Liu\n# --------------------------------------------------------\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as checkpoint\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\n\n\nclass Mlp(nn.Module):\n\n    def __init__(self,\n                 in_features,\n                 hidden_features=None,\n                 out_features=None,\n                 act_layer=nn.GELU,\n                 drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\ndef window_partition(x, window_size):\n    \"\"\"\n    Args:\n        x: (B, H, W, C)\n        window_size (int): window size\n\n    Returns:\n        windows: (num_windows*B, window_size, window_size, C)\n    \"\"\"\n    B, H, W, C = x.shape\n    x = x.view(B, H // window_size, window_size, W // window_size, window_size,\n               C)\n    windows = x.permute(0, 1, 3, 2, 4,\n                        5).contiguous().view(-1, window_size, window_size, C)\n    return windows\n\n\ndef window_reverse(windows, window_size, H, W):\n    \"\"\"\n    Args:\n        windows: (num_windows*B, window_size, window_size, C)\n        window_size (int): Window size\n        H (int): Height of image\n        W (int): Width of image\n\n    Returns:\n        x: (B, H, W, C)\n    \"\"\"\n    B = int(windows.shape[0] / (H * W / window_size / window_size))\n    x = windows.view(B, H // window_size, W // window_size, window_size,\n                     window_size, -1)\n    x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)\n    return x\n\n\nclass SwinMLPBlock(nn.Module):\n    r\"\"\" Swin MLP Block.\n\n    Args: dim (int): Number of input channels. input_resolution (tuple[int]):\n    Input resolution. num_heads (int): Number of attention heads. window_size\n    (int): Window size. shift_size (int): Shift size for SW-MSA. mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. drop (float, optional):\n    Dropout rate. Default: 0.0 drop_path (float, optional): Stochastic depth\n    rate. Default: 0.0 act_layer (nn.Module, optional): Activation layer.\n    Default: nn.GELU norm_layer (nn.Module, optional): Normalization layer.\n    Default: nn.LayerNorm\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 num_heads,\n                 window_size=7,\n                 shift_size=0,\n                 mlp_ratio=4.,\n                 drop=0.,\n                 drop_path=0.,\n                 act_layer=nn.GELU,\n                 norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.num_heads = num_heads\n        self.window_size = window_size\n        self.shift_size = shift_size\n        self.mlp_ratio = mlp_ratio\n        if min(self.input_resolution) <= self.window_size:\n            # if window size is larger than input resolution, we don't\n            # partition windows\n            self.shift_size = 0\n            self.window_size = min(self.input_resolution)\n        assert 0 <= self.shift_size < self.window_size, ('shift_size must in '\n                                                         '0-window_size')\n\n        self.padding = [\n            self.window_size - self.shift_size, self.shift_size,\n            self.window_size - self.shift_size, self.shift_size\n        ]  # P_l,P_r,P_t,P_b\n\n        self.norm1 = norm_layer(dim)\n        # use group convolution to implement multi-head MLP\n        self.spatial_mlp = nn.Conv1d(\n            self.num_heads * self.window_size**2,\n            self.num_heads * self.window_size**2,\n            kernel_size=1,\n            groups=self.num_heads)\n\n        self.drop_path = DropPath(\n            drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(\n            in_features=dim,\n            hidden_features=mlp_hidden_dim,\n            act_layer=act_layer,\n            drop=drop)\n\n    def forward(self, x):\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n\n        shortcut = x\n        x = self.norm1(x)\n        x = x.view(B, H, W, C)\n\n        # shift\n        if self.shift_size > 0:\n            P_l, P_r, P_t, P_b = self.padding\n            shifted_x = F.pad(x, [0, 0, P_l, P_r, P_t, P_b], 'constant', 0)\n        else:\n            shifted_x = x\n        _, _H, _W, _ = shifted_x.shape\n\n        # partition windows\n        x_windows = window_partition(\n            shifted_x, self.window_size)  # nW*B, window_size, window_size, C\n        x_windows = x_windows.view(-1, self.window_size * self.window_size,\n                                   C)  # nW*B, window_size*window_size, C\n\n        # Window/Shifted-Window Spatial MLP\n        x_windows_heads = x_windows.view(-1,\n                                         self.window_size * self.window_size,\n                                         self.num_heads, C // self.num_heads)\n        x_windows_heads = x_windows_heads.transpose(\n            1, 2)  # nW*B, nH, window_size*window_size, C//nH\n        x_windows_heads = x_windows_heads.reshape(\n            -1, self.num_heads * self.window_size * self.window_size,\n            C // self.num_heads)\n        spatial_mlp_windows = self.spatial_mlp(\n            x_windows_heads)  # nW*B, nH*window_size*window_size, C//nH\n        spatial_mlp_windows = spatial_mlp_windows.view(\n            -1, self.num_heads, self.window_size * self.window_size,\n            C // self.num_heads).transpose(1, 2)\n        spatial_mlp_windows = spatial_mlp_windows.reshape(\n            -1, self.window_size * self.window_size, C)\n\n        # merge windows\n        spatial_mlp_windows = spatial_mlp_windows.reshape(\n            -1, self.window_size, self.window_size, C)\n        shifted_x = window_reverse(spatial_mlp_windows, self.window_size, _H,\n                                   _W)  # B H' W' C\n\n        # reverse shift\n        if self.shift_size > 0:\n            P_l, P_r, P_t, P_b = self.padding\n            x = shifted_x[:, P_t:-P_b, P_l:-P_r, :].contiguous()\n        else:\n            x = shifted_x\n        x = x.view(B, H * W, C)\n\n        # FFN\n        x = shortcut + self.drop_path(x)\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, input_resolution={self.input_resolution}, '\n                f'num_heads={self.num_heads}, '\n                f'window_size={self.window_size}, '\n                f'shift_size={self.shift_size}, '\n                f'mlp_ratio={self.mlp_ratio}')\n\n    def flops(self):\n        flops = 0\n        H, W = self.input_resolution\n        # norm1\n        flops += self.dim * H * W\n\n        # Window/Shifted-Window Spatial MLP\n        if self.shift_size > 0:\n            nW = (H / self.window_size + 1) * (W / self.window_size + 1)\n        else:\n            nW = H * W / self.window_size / self.window_size\n        flops += nW * self.dim * (self.window_size * self.window_size) * (\n            self.window_size * self.window_size)\n        # mlp\n        flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio\n        # norm2\n        flops += self.dim * H * W\n        return flops\n\n\nclass PatchMerging(nn.Module):\n    r\"\"\" Patch Merging Layer.\n\n    Args:\n        input_resolution (tuple[int]): Resolution of input feature.\n        dim (int): Number of input channels.\n        norm_layer (nn.Module, optional): Normalization layer.  Default:\n        nn.LayerNorm\n    \"\"\"\n\n    def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.input_resolution = input_resolution\n        self.dim = dim\n        self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)\n        self.norm = norm_layer(4 * dim)\n\n    def forward(self, x):\n        \"\"\"\n        x: B, H*W, C\n        \"\"\"\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n        assert H % 2 == 0 and W % 2 == 0, f'x size ({H}*{W}) are not even.'\n\n        x = x.view(B, H, W, C)\n\n        x0 = x[:, 0::2, 0::2, :]  # B H/2 W/2 C\n        x1 = x[:, 1::2, 0::2, :]  # B H/2 W/2 C\n        x2 = x[:, 0::2, 1::2, :]  # B H/2 W/2 C\n        x3 = x[:, 1::2, 1::2, :]  # B H/2 W/2 C\n        x = torch.cat([x0, x1, x2, x3], -1)  # B H/2 W/2 4*C\n        x = x.view(B, -1, 4 * C)  # B H/2*W/2 4*C\n\n        x = self.norm(x)\n        x = self.reduction(x)\n\n        return x\n\n    def extra_repr(self) -> str:\n        return f'input_resolution={self.input_resolution}, dim={self.dim}'\n\n    def flops(self):\n        H, W = self.input_resolution\n        flops = H * W * self.dim\n        flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim\n        return flops\n\n\nclass BasicLayer(nn.Module):\n    \"\"\"A basic Swin MLP layer for one stage.\n\n    Args:\n        dim (int): Number of input channels.\n        input_resolution (tuple[int]): Input resolution.\n        depth (int): Number of blocks.\n        num_heads (int): Number of attention heads.\n        window_size (int): Local window size.\n        mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.\n        drop (float, optional): Dropout rate. Default: 0.0\n        drop_path (float | tuple[float], optional): Stochastic depth rate.\n        Default: 0.0\n        norm_layer (nn.Module, optional): Normalization layer. Default:\n        nn.LayerNorm\n        downsample (nn.Module | None, optional): Downsample layer at the end\n        of the layer. Default: None\n        use_checkpoint (bool): Whether to use checkpointing to save memory.\n        Default: False.\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 depth,\n                 num_heads,\n                 window_size,\n                 mlp_ratio=4.,\n                 drop=0.,\n                 drop_path=0.,\n                 norm_layer=nn.LayerNorm,\n                 downsample=None,\n                 use_checkpoint=False):\n\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.depth = depth\n        self.use_checkpoint = use_checkpoint\n\n        # build blocks\n        self.blocks = nn.ModuleList([\n            SwinMLPBlock(\n                dim=dim,\n                input_resolution=input_resolution,\n                num_heads=num_heads,\n                window_size=window_size,\n                shift_size=0 if (i % 2 == 0) else window_size // 2,\n                mlp_ratio=mlp_ratio,\n                drop=drop,\n                drop_path=drop_path[i]\n                if isinstance(drop_path, list) else drop_path,\n                norm_layer=norm_layer) for i in range(depth)\n        ])\n\n        # patch merging layer\n        if downsample is not None:\n            self.downsample = downsample(\n                input_resolution, dim=dim, norm_layer=norm_layer)\n        else:\n            self.downsample = None\n\n    def forward(self, x):\n        for blk in self.blocks:\n            if self.use_checkpoint:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        if self.downsample is not None:\n            x = self.downsample(x)\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, input_resolution={self.input_resolution}, '\n                f'depth={self.depth}')\n\n    def flops(self):\n        flops = 0\n        for blk in self.blocks:\n            flops += blk.flops()\n        if self.downsample is not None:\n            flops += self.downsample.flops()\n        return flops\n\n\nclass PatchEmbed(nn.Module):\n    r\"\"\" Image to Patch Embedding\n\n    Args:\n        img_size (int): Image size.  Default: 224.\n        patch_size (int): Patch token size. Default: 4.\n        in_chans (int): Number of input image channels. Default: 3.\n        embed_dim (int): Number of linear projection output channels.\n        Default: 96.\n        norm_layer (nn.Module, optional): Normalization layer. Default: None\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 embed_dim=96,\n                 norm_layer=None):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        patches_resolution = [\n            img_size[0] // patch_size[0], img_size[1] // patch_size[1]\n        ]\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.patches_resolution = patches_resolution\n        self.num_patches = patches_resolution[0] * patches_resolution[1]\n\n        self.in_chans = in_chans\n        self.embed_dim = embed_dim\n\n        self.proj = nn.Conv2d(\n            in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n        if norm_layer is not None:\n            self.norm = norm_layer(embed_dim)\n        else:\n            self.norm = None\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            (f\"Input image size ({H}*{W}) doesn't match model (\"\n             f'{self.img_size[0]}*{self.img_size[1]}).')\n        x = self.proj(x).flatten(2).transpose(1, 2)  # B Ph*Pw C\n        if self.norm is not None:\n            x = self.norm(x)\n        return x\n\n    def flops(self):\n        Ho, Wo = self.patches_resolution\n        flops = Ho * Wo * self.embed_dim * self.in_chans * (\n            self.patch_size[0] * self.patch_size[1])\n        if self.norm is not None:\n            flops += Ho * Wo * self.embed_dim\n        return flops\n\n\nclass SwinMLP(nn.Module):\n    r\"\"\" Swin MLP\n\n    Args:\n        img_size (int | tuple(int)): Input image size. Default 224\n        patch_size (int | tuple(int)): Patch size. Default: 4\n        in_chans (int): Number of input image channels. Default: 3\n        num_classes (int): Number of classes for classification head.\n        Default: 1000\n        embed_dim (int): Patch embedding dimension. Default: 96\n        depths (tuple(int)): Depth of each Swin MLP layer.\n        num_heads (tuple(int)): Number of attention heads in different layers.\n        window_size (int): Window size. Default: 7\n        mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4\n        drop_rate (float): Dropout rate. Default: 0\n        drop_path_rate (float): Stochastic depth rate. Default: 0.1\n        norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm.\n        ape (bool): If True, add absolute position embedding to the patch\n        embedding. Default: False\n        patch_norm (bool): If True, add normalization after patch embedding.\n        Default: True\n        use_checkpoint (bool): Whether to use checkpointing to save memory.\n        Default: False\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 num_classes=1000,\n                 embed_dim=96,\n                 depths=[2, 2, 6, 2],\n                 num_heads=[3, 6, 12, 24],\n                 window_size=7,\n                 mlp_ratio=4.,\n                 drop_rate=0.,\n                 drop_path_rate=0.1,\n                 norm_layer=nn.LayerNorm,\n                 ape=False,\n                 patch_norm=True,\n                 use_checkpoint=False,\n                 **kwargs):\n        super().__init__()\n\n        self.num_classes = num_classes\n        self.num_layers = len(depths)\n        self.embed_dim = embed_dim\n        self.ape = ape\n        self.patch_norm = patch_norm\n        self.num_features = int(embed_dim * 2**(self.num_layers - 1))\n        self.mlp_ratio = mlp_ratio\n\n        # split image into non-overlapping patches\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n            norm_layer=norm_layer if self.patch_norm else None)\n        num_patches = self.patch_embed.num_patches\n        patches_resolution = self.patch_embed.patches_resolution\n        self.patches_resolution = patches_resolution\n\n        # absolute position embedding\n        if self.ape:\n            self.absolute_pos_embed = nn.Parameter(\n                torch.zeros(1, num_patches, embed_dim))\n            trunc_normal_(self.absolute_pos_embed, std=.02)\n\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        # stochastic depth\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))\n        ]  # stochastic depth decay rule\n\n        # build layers\n        self.layers = nn.ModuleList()\n        for i_layer in range(self.num_layers):\n            layer = BasicLayer(\n                dim=int(embed_dim * 2**i_layer),\n                input_resolution=(patches_resolution[0] // (2**i_layer),\n                                  patches_resolution[1] // (2**i_layer)),\n                depth=depths[i_layer],\n                num_heads=num_heads[i_layer],\n                window_size=window_size,\n                mlp_ratio=self.mlp_ratio,\n                drop=drop_rate,\n                drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])],\n                norm_layer=norm_layer,\n                downsample=PatchMerging if\n                (i_layer < self.num_layers - 1) else None,\n                use_checkpoint=use_checkpoint)\n            self.layers.append(layer)\n\n        self.norm = norm_layer(self.num_features)\n        self.avgpool = nn.AdaptiveAvgPool1d(1)\n        self.head = nn.Linear(\n            self.num_features,\n            num_classes) if num_classes > 0 else nn.Identity()\n\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, (nn.Linear, nn.Conv1d)):\n            trunc_normal_(m.weight, std=.02)\n            if m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'absolute_pos_embed'}\n\n    @torch.jit.ignore\n    def no_weight_decay_keywords(self):\n        return {'relative_position_bias_table'}\n\n    def forward_features(self, x):\n        x = self.patch_embed(x)\n        if self.ape:\n            x = x + self.absolute_pos_embed\n        x = self.pos_drop(x)\n\n        for layer in self.layers:\n            x = layer(x)\n\n        x = self.norm(x)  # B L C\n        x = self.avgpool(x.transpose(1, 2))  # B C 1\n        x = torch.flatten(x, 1)\n        return x\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        x = self.head(x)\n        return x\n\n    def flops(self):\n        flops = 0\n        flops += self.patch_embed.flops()\n        for i, layer in enumerate(self.layers):\n            flops += layer.flops()\n        flops += self.num_features * self.patches_resolution[\n            0] * self.patches_resolution[1] // (2**self.num_layers)\n        flops += self.num_features * self.num_classes\n        return flops\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/swin_transformer.py",
    "content": "# --------------------------------------------------------\n# Swin Transformer\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ze Liu\n# --------------------------------------------------------\n\nimport torch\nimport torch.nn as nn\nimport torch.utils.checkpoint as checkpoint\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\n\ntry:\n    import os\n    import sys\n\n    kernel_path = os.path.abspath(os.path.join('..'))\n    sys.path.append(kernel_path)\n    from kernels.window_process.window_process import (WindowProcess,\n                                                       WindowProcessReverse)\n\nexcept ImportError:\n    WindowProcess = None\n    WindowProcessReverse = None\n    print(\n        '[Warning] Fused window process have not been installed. Please refer '\n        'to get_started.md for installation.')\n\n\nclass Mlp(nn.Module):\n\n    def __init__(self,\n                 in_features,\n                 hidden_features=None,\n                 out_features=None,\n                 act_layer=nn.GELU,\n                 drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\ndef window_partition(x, window_size):\n    \"\"\"\n    Args:\n        x: (B, H, W, C)\n        window_size (int): window size\n\n    Returns:\n        windows: (num_windows*B, window_size, window_size, C)\n    \"\"\"\n    B, H, W, C = x.shape\n    x = x.view(B, H // window_size, window_size, W // window_size, window_size,\n               C)\n    windows = x.permute(0, 1, 3, 2, 4,\n                        5).contiguous().view(-1, window_size, window_size, C)\n    return windows\n\n\ndef window_reverse(windows, window_size, H, W):\n    \"\"\"\n    Args:\n        windows: (num_windows*B, window_size, window_size, C)\n        window_size (int): Window size\n        H (int): Height of image\n        W (int): Width of image\n\n    Returns:\n        x: (B, H, W, C)\n    \"\"\"\n    B = int(windows.shape[0] / (H * W / window_size / window_size))\n    x = windows.view(B, H // window_size, W // window_size, window_size,\n                     window_size, -1)\n    x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)\n    return x\n\n\nclass WindowAttention(nn.Module):\n    r\"\"\" Window based multi-head self attention (W-MSA) module with relative\n    position bias. It supports both of shifted and non-shifted window.\n\n    Args: dim (int): Number of input channels. window_size (tuple[int]): The\n    height and width of the window. num_heads (int): Number of attention\n    heads. qkv_bias (bool, optional):  If True, add a learnable bias to\n    query, key, value. Default: True qk_scale (float | None, optional):\n    Override default qk scale of head_dim ** -0.5 if set attn_drop (float,\n    optional): Dropout ratio of attention weight. Default: 0.0 proj_drop (\n    float, optional): Dropout ratio of output. Default: 0.0\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 window_size,\n                 num_heads,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 attn_drop=0.,\n                 proj_drop=0.):\n\n        super().__init__()\n        self.dim = dim\n        self.window_size = window_size  # Wh, Ww\n        self.num_heads = num_heads\n        head_dim = dim // num_heads\n        self.scale = qk_scale or head_dim**-0.5\n\n        # define a parameter table of relative position bias\n        self.relative_position_bias_table = nn.Parameter(\n            torch.zeros((2 * window_size[0] - 1) * (2 * window_size[1] - 1),\n                        num_heads))  # 2*Wh-1 * 2*Ww-1, nH\n\n        # get pair-wise relative position index for each token inside the\n        # window\n        coords_h = torch.arange(self.window_size[0])\n        coords_w = torch.arange(self.window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = (coords_flatten[:, :, None] -\n                           coords_flatten[:, None, :])  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(\n            1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += self.window_size[0] - 1\n        relative_coords[:, :, 1] += self.window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1\n        relative_position_index = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        self.register_buffer('relative_position_index',\n                             relative_position_index)\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n\n        trunc_normal_(self.relative_position_bias_table, std=.02)\n        self.softmax = nn.Softmax(dim=-1)\n\n    def forward(self, x, mask=None):\n        \"\"\"\n        Args: x: input features with shape of (num_windows*B, N, C) mask: (\n        0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None\n        \"\"\"\n        B_, N, C = x.shape\n        qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads,\n                                  C // self.num_heads).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[\n            2]  # make torch script happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        relative_position_bias = self.relative_position_bias_table[\n            self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1],\n                self.window_size[0] * self.window_size[1],\n                -1)  # Wh*Ww,Wh*Ww,nH\n        relative_position_bias = relative_position_bias.permute(\n            2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n        attn = attn + relative_position_bias.unsqueeze(0)\n\n        if mask is not None:\n            nW = mask.shape[0]\n            attn = attn.view(B_ // nW, nW, self.num_heads, N,\n                             N) + mask.unsqueeze(1).unsqueeze(0)\n            attn = attn.view(-1, self.num_heads, N, N)\n            attn = self.softmax(attn)\n        else:\n            attn = self.softmax(attn)\n\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B_, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, window_size={self.window_size}, num_heads='\n                f'{self.num_heads}')\n\n    def flops(self, N):\n        # calculate flops for 1 window with token length of N\n        flops = 0\n        # qkv = self.qkv(x)\n        flops += N * self.dim * 3 * self.dim\n        # attn = (q @ k.transpose(-2, -1))\n        flops += self.num_heads * N * (self.dim // self.num_heads) * N\n        #  x = (attn @ v)\n        flops += self.num_heads * N * N * (self.dim // self.num_heads)\n        # x = self.proj(x)\n        flops += N * self.dim * self.dim\n        return flops\n\n\nclass SwinTransformerBlock(nn.Module):\n    r\"\"\" Swin Transformer Block.\n\n    Args: dim (int): Number of input channels. input_resolution (tuple[int]):\n    Input resolution. num_heads (int): Number of attention heads. window_size\n    (int): Window size. shift_size (int): Shift size for SW-MSA. mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. qkv_bias (bool,\n    optional): If True, add a learnable bias to query, key, value. Default:\n    True qk_scale (float | None, optional): Override default qk scale of\n    head_dim ** -0.5 if set. drop (float, optional): Dropout rate. Default:\n    0.0 attn_drop (float, optional): Attention dropout rate. Default: 0.0\n    drop_path (float, optional): Stochastic depth rate. Default: 0.0\n    act_layer (nn.Module, optional): Activation layer. Default: nn.GELU\n    norm_layer (nn.Module, optional): Normalization layer.  Default:\n    nn.LayerNorm fused_window_process (bool, optional): If True, use one\n    kernel to fused window shift & window partition for acceleration, similar\n    for the reversed part. Default: False\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 num_heads,\n                 window_size=7,\n                 shift_size=0,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 act_layer=nn.GELU,\n                 norm_layer=nn.LayerNorm,\n                 fused_window_process=False):\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.num_heads = num_heads\n        self.window_size = window_size\n        self.shift_size = shift_size\n        self.mlp_ratio = mlp_ratio\n        if min(self.input_resolution) <= self.window_size:\n            # if window size is larger than input resolution, we don't\n            # partition windows\n            self.shift_size = 0\n            self.window_size = min(self.input_resolution)\n        assert 0 <= self.shift_size < self.window_size, ('shift_size must in '\n                                                         '0-window_size')\n\n        self.norm1 = norm_layer(dim)\n        self.attn = WindowAttention(\n            dim,\n            window_size=to_2tuple(self.window_size),\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop=attn_drop,\n            proj_drop=drop)\n\n        self.drop_path = DropPath(\n            drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(\n            in_features=dim,\n            hidden_features=mlp_hidden_dim,\n            act_layer=act_layer,\n            drop=drop)\n\n        if self.shift_size > 0:\n            # calculate attention mask for SW-MSA\n            H, W = self.input_resolution\n            img_mask = torch.zeros((1, H, W, 1))  # 1 H W 1\n            h_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            w_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            cnt = 0\n            for h in h_slices:\n                for w in w_slices:\n                    img_mask[:, h, w, :] = cnt\n                    cnt += 1\n\n            mask_windows = window_partition(\n                img_mask, self.window_size)  # nW, window_size, window_size, 1\n            mask_windows = mask_windows.view(\n                -1, self.window_size * self.window_size)\n            attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)\n            attn_mask = attn_mask.masked_fill(attn_mask != 0,\n                                              float(-100.0)).masked_fill(\n                                                  attn_mask == 0, float(0.0))\n        else:\n            attn_mask = None\n\n        self.register_buffer('attn_mask', attn_mask)\n        self.fused_window_process = fused_window_process\n\n    def forward(self, x):\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n\n        shortcut = x\n        x = self.norm1(x)\n        x = x.view(B, H, W, C)\n\n        # cyclic shift\n        if self.shift_size > 0:\n            if not self.fused_window_process:\n                shifted_x = torch.roll(\n                    x,\n                    shifts=(-self.shift_size, -self.shift_size),\n                    dims=(1, 2))\n                # partition windows\n                x_windows = window_partition(\n                    shifted_x,\n                    self.window_size)  # nW*B, window_size, window_size, C\n            else:\n                x_windows = WindowProcess.apply(x, B, H, W, C,\n                                                -self.shift_size,\n                                                self.window_size)\n        else:\n            shifted_x = x\n            # partition windows\n            x_windows = window_partition(\n                shifted_x,\n                self.window_size)  # nW*B, window_size, window_size, C\n\n        x_windows = x_windows.view(-1, self.window_size * self.window_size,\n                                   C)  # nW*B, window_size*window_size, C\n\n        # W-MSA/SW-MSA\n        attn_windows = self.attn(\n            x_windows, mask=self.attn_mask)  # nW*B, window_size*window_size, C\n\n        # merge windows\n        attn_windows = attn_windows.view(-1, self.window_size,\n                                         self.window_size, C)\n\n        # reverse cyclic shift\n        if self.shift_size > 0:\n            if not self.fused_window_process:\n                shifted_x = window_reverse(attn_windows, self.window_size, H,\n                                           W)  # B H' W' C\n                x = torch.roll(\n                    shifted_x,\n                    shifts=(self.shift_size, self.shift_size),\n                    dims=(1, 2))\n            else:\n                x = WindowProcessReverse.apply(attn_windows, B, H, W, C,\n                                               self.shift_size,\n                                               self.window_size)\n        else:\n            shifted_x = window_reverse(attn_windows, self.window_size, H,\n                                       W)  # B H' W' C\n            x = shifted_x\n        x = x.view(B, H * W, C)\n        x = shortcut + self.drop_path(x)\n\n        # FFN\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, '\n                f'input_resolution={self.input_resolution}, '\n                f'num_heads={self.num_heads}, '\n                f'window_size={self.window_size}, '\n                f'shift_size={self.shift_size}, '\n                f'mlp_ratio={self.mlp_ratio}')\n\n    def flops(self):\n        flops = 0\n        H, W = self.input_resolution\n        # norm1\n        flops += self.dim * H * W\n        # W-MSA/SW-MSA\n        nW = H * W / self.window_size / self.window_size\n        flops += nW * self.attn.flops(self.window_size * self.window_size)\n        # mlp\n        flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio\n        # norm2\n        flops += self.dim * H * W\n        return flops\n\n\nclass PatchMerging(nn.Module):\n    r\"\"\" Patch Merging Layer.\n\n    Args: input_resolution (tuple[int]): Resolution of input feature. dim (\n    int): Number of input channels. norm_layer (nn.Module, optional):\n    Normalization layer.  Default: nn.LayerNorm\n    \"\"\"\n\n    def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.input_resolution = input_resolution\n        self.dim = dim\n        self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)\n        self.norm = norm_layer(4 * dim)\n\n    def forward(self, x):\n        \"\"\"\n        x: B, H*W, C\n        \"\"\"\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n        assert H % 2 == 0 and W % 2 == 0, f'x size ({H}*{W}) are not even.'\n\n        x = x.view(B, H, W, C)\n\n        x0 = x[:, 0::2, 0::2, :]  # B H/2 W/2 C\n        x1 = x[:, 1::2, 0::2, :]  # B H/2 W/2 C\n        x2 = x[:, 0::2, 1::2, :]  # B H/2 W/2 C\n        x3 = x[:, 1::2, 1::2, :]  # B H/2 W/2 C\n        x = torch.cat([x0, x1, x2, x3], -1)  # B H/2 W/2 4*C\n        x = x.view(B, -1, 4 * C)  # B H/2*W/2 4*C\n\n        x = self.norm(x)\n        x = self.reduction(x)\n\n        return x\n\n    def extra_repr(self) -> str:\n        return f'input_resolution={self.input_resolution}, dim={self.dim}'\n\n    def flops(self):\n        H, W = self.input_resolution\n        flops = H * W * self.dim\n        flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim\n        return flops\n\n\nclass BasicLayer(nn.Module):\n    \"\"\"A basic Swin Transformer layer for one stage.\n\n    Args: dim (int): Number of input channels. input_resolution (tuple[int]):\n    Input resolution. depth (int): Number of blocks. num_heads (int): Number\n    of attention heads. window_size (int): Local window size. mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. qkv_bias (bool,\n    optional): If True, add a learnable bias to query, key, value. Default:\n    True qk_scale (float | None, optional): Override default qk scale of\n    head_dim ** -0.5 if set. drop (float, optional): Dropout rate. Default:\n    0.0 attn_drop (float, optional): Attention dropout rate. Default: 0.0\n    drop_path (float | tuple[float], optional): Stochastic depth rate.\n    Default: 0.0 norm_layer (nn.Module, optional): Normalization layer.\n    Default: nn.LayerNorm downsample (nn.Module | None, optional): Downsample\n    layer at the end of the layer. Default: None use_checkpoint (bool):\n    Whether to use checkpointing to save memory. Default: False.\n    fused_window_process (bool, optional): If True, use one kernel to fused\n    window shift & window partition for acceleration, similar for the\n    reversed part. Default: False\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 depth,\n                 num_heads,\n                 window_size,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 norm_layer=nn.LayerNorm,\n                 downsample=None,\n                 use_checkpoint=False,\n                 fused_window_process=False):\n\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.depth = depth\n        self.use_checkpoint = use_checkpoint\n\n        # build blocks\n        self.blocks = nn.ModuleList([\n            SwinTransformerBlock(\n                dim=dim,\n                input_resolution=input_resolution,\n                num_heads=num_heads,\n                window_size=window_size,\n                shift_size=0 if (i % 2 == 0) else window_size // 2,\n                mlp_ratio=mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop=drop,\n                attn_drop=attn_drop,\n                drop_path=drop_path[i]\n                if isinstance(drop_path, list) else drop_path,\n                norm_layer=norm_layer,\n                fused_window_process=fused_window_process)\n            for i in range(depth)\n        ])\n\n        # patch merging layer\n        if downsample is not None:\n            self.downsample = downsample(\n                input_resolution, dim=dim, norm_layer=norm_layer)\n        else:\n            self.downsample = None\n\n    def forward(self, x):\n        for blk in self.blocks:\n            if self.use_checkpoint:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        if self.downsample is not None:\n            x = self.downsample(x)\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, input_resolution={self.input_resolution}, '\n                f'depth={self.depth}')\n\n    def flops(self):\n        flops = 0\n        for blk in self.blocks:\n            flops += blk.flops()\n        if self.downsample is not None:\n            flops += self.downsample.flops()\n        return flops\n\n\nclass PatchEmbed(nn.Module):\n    r\"\"\" Image to Patch Embedding\n\n    Args: img_size (int): Image size.  Default: 224. patch_size (int): Patch\n    token size. Default: 4. in_chans (int): Number of input image channels.\n    Default: 3. embed_dim (int): Number of linear projection output channels.\n    Default: 96. norm_layer (nn.Module, optional): Normalization layer.\n    Default: None\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 embed_dim=96,\n                 norm_layer=None):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        patches_resolution = [\n            img_size[0] // patch_size[0], img_size[1] // patch_size[1]\n        ]\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.patches_resolution = patches_resolution\n        self.num_patches = patches_resolution[0] * patches_resolution[1]\n\n        self.in_chans = in_chans\n        self.embed_dim = embed_dim\n\n        self.proj = nn.Conv2d(\n            in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n        if norm_layer is not None:\n            self.norm = norm_layer(embed_dim)\n        else:\n            self.norm = None\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            (f\"Input image size ({H}*{W}) doesn't match model \"\n             f'({self.img_size[0]}*{self.img_size[1]}).')\n        x = self.proj(x).flatten(2).transpose(1, 2)  # B Ph*Pw C\n        if self.norm is not None:\n            x = self.norm(x)\n        return x\n\n    def flops(self):\n        Ho, Wo = self.patches_resolution\n        flops = Ho * Wo * self.embed_dim * self.in_chans * (\n            self.patch_size[0] * self.patch_size[1])\n        if self.norm is not None:\n            flops += Ho * Wo * self.embed_dim\n        return flops\n\n\nclass SwinTransformer(nn.Module):\n    r\"\"\" Swin Transformer A PyTorch impl of : `Swin Transformer: Hierarchical\n    Vision Transformer using Shifted Windows`  -\n    https://arxiv.org/pdf/2103.14030\n\n    Args: img_size (int | tuple(int)): Input image size. Default 224\n    patch_size (int | tuple(int)): Patch size. Default: 4 in_chans (int):\n    Number of input image channels. Default: 3 num_classes (int): Number of\n    classes for classification head. Default: 1000 embed_dim (int): Patch\n    embedding dimension. Default: 96 depths (tuple(int)): Depth of each Swin\n    Transformer layer. num_heads (tuple(int)): Number of attention heads in\n    different layers. window_size (int): Window size. Default: 7 mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. Default: 4 qkv_bias (\n    bool): If True, add a learnable bias to query, key, value. Default: True\n    qk_scale (float): Override default qk scale of head_dim ** -0.5 if set.\n    Default: None drop_rate (float): Dropout rate. Default: 0 attn_drop_rate\n    (float): Attention dropout rate. Default: 0 drop_path_rate (float):\n    Stochastic depth rate. Default: 0.1 norm_layer (nn.Module): Normalization\n    layer. Default: nn.LayerNorm. ape (bool): If True, add absolute position\n    embedding to the patch embedding. Default: False patch_norm (bool): If\n    True, add normalization after patch embedding. Default: True\n    use_checkpoint (bool): Whether to use checkpointing to save memory.\n    Default: False fused_window_process (bool, optional): If True, use one\n    kernel to fused window shift & window partition for acceleration, similar\n    for the reversed part. Default: False\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 num_classes=1000,\n                 embed_dim=96,\n                 depths=[2, 2, 6, 2],\n                 num_heads=[3, 6, 12, 24],\n                 window_size=7,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.1,\n                 norm_layer=nn.LayerNorm,\n                 ape=False,\n                 patch_norm=True,\n                 use_checkpoint=False,\n                 fused_window_process=False,\n                 **kwargs):\n        super().__init__()\n\n        self.num_classes = num_classes\n        self.num_layers = len(depths)\n        self.embed_dim = embed_dim\n        self.ape = ape\n        self.patch_norm = patch_norm\n        self.num_features = int(embed_dim * 2**(self.num_layers - 1))\n        self.mlp_ratio = mlp_ratio\n\n        # split image into non-overlapping patches\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n            norm_layer=norm_layer if self.patch_norm else None)\n        num_patches = self.patch_embed.num_patches\n        patches_resolution = self.patch_embed.patches_resolution\n        self.patches_resolution = patches_resolution\n\n        # absolute position embedding\n        if self.ape:\n            self.absolute_pos_embed = nn.Parameter(\n                torch.zeros(1, num_patches, embed_dim))\n            trunc_normal_(self.absolute_pos_embed, std=.02)\n\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        # stochastic depth\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))\n        ]  # stochastic depth decay rule\n\n        # build layers\n        self.layers = nn.ModuleList()\n        for i_layer in range(self.num_layers):\n            layer = BasicLayer(\n                dim=int(embed_dim * 2**i_layer),\n                input_resolution=(patches_resolution[0] // (2**i_layer),\n                                  patches_resolution[1] // (2**i_layer)),\n                depth=depths[i_layer],\n                num_heads=num_heads[i_layer],\n                window_size=window_size,\n                mlp_ratio=self.mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop=drop_rate,\n                attn_drop=attn_drop_rate,\n                drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])],\n                norm_layer=norm_layer,\n                downsample=PatchMerging if\n                (i_layer < self.num_layers - 1) else None,\n                use_checkpoint=use_checkpoint,\n                fused_window_process=fused_window_process)\n            self.layers.append(layer)\n\n        self.norm = norm_layer(self.num_features)\n        self.avgpool = nn.AdaptiveAvgPool1d(1)\n        self.head = nn.Linear(\n            self.num_features,\n            num_classes) if num_classes > 0 else nn.Identity()\n\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'absolute_pos_embed'}\n\n    @torch.jit.ignore\n    def no_weight_decay_keywords(self):\n        return {'relative_position_bias_table'}\n\n    def forward_features(self, x):\n        x = self.patch_embed(x)\n        if self.ape:\n            x = x + self.absolute_pos_embed\n        x = self.pos_drop(x)\n\n        for layer in self.layers:\n            x = layer(x)\n\n        x = self.norm(x)  # B L C\n        x = self.avgpool(x.transpose(1, 2))  # B C 1\n        x = torch.flatten(x, 1)\n        return x\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        x = self.head(x)\n        return x\n\n    def flops(self):\n        flops = 0\n        flops += self.patch_embed.flops()\n        for i, layer in enumerate(self.layers):\n            flops += layer.flops()\n        flops += self.num_features * self.patches_resolution[\n            0] * self.patches_resolution[1] // (2**self.num_layers)\n        flops += self.num_features * self.num_classes\n        return flops\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/swin_transformer_moe.py",
    "content": "# --------------------------------------------------------\n# Swin Transformer MoE\n# Copyright (c) 2022 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ze Liu\n# --------------------------------------------------------\n\nimport numpy as np\nimport torch\nimport torch.distributed as dist\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as checkpoint\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\n\ntry:\n    from tutel import moe as tutel_moe\nexcept ImportError:\n    tutel_moe = None\n    print(\n        'Tutel has not been installed. To use Swin-MoE, please install Tutel;'\n        'otherwise, just ignore this.')\n\n\nclass Mlp(nn.Module):\n\n    def __init__(self,\n                 in_features,\n                 hidden_features=None,\n                 out_features=None,\n                 act_layer=nn.GELU,\n                 drop=0.,\n                 mlp_fc2_bias=True):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features, bias=mlp_fc2_bias)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\nclass MoEMlp(nn.Module):\n\n    def __init__(self,\n                 in_features,\n                 hidden_features,\n                 num_local_experts,\n                 top_value,\n                 capacity_factor=1.25,\n                 cosine_router=False,\n                 normalize_gate=False,\n                 use_bpr=True,\n                 is_gshard_loss=True,\n                 gate_noise=1.0,\n                 cosine_router_dim=256,\n                 cosine_router_init_t=0.5,\n                 moe_drop=0.0,\n                 init_std=0.02,\n                 mlp_fc2_bias=True):\n        super().__init__()\n\n        self.in_features = in_features\n        self.hidden_features = hidden_features\n        self.num_local_experts = num_local_experts\n        self.top_value = top_value\n        self.capacity_factor = capacity_factor\n        self.cosine_router = cosine_router\n        self.normalize_gate = normalize_gate\n        self.use_bpr = use_bpr\n        self.init_std = init_std\n        self.mlp_fc2_bias = mlp_fc2_bias\n\n        self.dist_rank = dist.get_rank()\n\n        self._dropout = nn.Dropout(p=moe_drop)\n\n        _gate_type = {\n            'type': 'cosine_top' if cosine_router else 'top',\n            'k': top_value,\n            'capacity_factor': capacity_factor,\n            'gate_noise': gate_noise,\n            'fp32_gate': True\n        }\n        if cosine_router:\n            _gate_type['proj_dim'] = cosine_router_dim\n            _gate_type['init_t'] = cosine_router_init_t\n        self._moe_layer = tutel_moe.moe_layer(\n            gate_type=_gate_type,\n            model_dim=in_features,\n            experts={\n                'type': 'ffn',\n                'count_per_node': num_local_experts,\n                'hidden_size_per_expert': hidden_features,\n                'activation_fn': lambda x: self._dropout(F.gelu(x))\n            },\n            scan_expert_func=lambda name, param: setattr(\n                param, 'skip_allreduce', True),\n            seeds=(1, self.dist_rank + 1, self.dist_rank + 1),\n            batch_prioritized_routing=use_bpr,\n            normalize_gate=normalize_gate,\n            is_gshard_loss=is_gshard_loss,\n        )\n        if not self.mlp_fc2_bias:\n            self._moe_layer.experts.batched_fc2_bias.requires_grad = False\n\n    def forward(self, x):\n        x = self._moe_layer(x)\n        return x, x.l_aux\n\n    def extra_repr(self) -> str:\n        return (f'[Statistics-{self.dist_rank}] param count for MoE, '\n                f'in_features = {self.in_features}, '\n                f'hidden_features = {self.hidden_features}, '\n                f'num_local_experts = {self.num_local_experts}, '\n                f'top_value = {self.top_value}, '\n                f'cosine_router={self.cosine_router} '\n                f'normalize_gate={self.normalize_gate}, '\n                f'use_bpr = {self.use_bpr}')\n\n    def _init_weights(self):\n        if hasattr(self._moe_layer, 'experts'):\n            trunc_normal_(\n                self._moe_layer.experts.batched_fc1_w, std=self.init_std)\n            trunc_normal_(\n                self._moe_layer.experts.batched_fc2_w, std=self.init_std)\n            nn.init.constant_(self._moe_layer.experts.batched_fc1_bias, 0)\n            nn.init.constant_(self._moe_layer.experts.batched_fc2_bias, 0)\n\n\ndef window_partition(x, window_size):\n    \"\"\"\n    Args:\n        x: (B, H, W, C)\n        window_size (int): window size\n\n    Returns:\n        windows: (num_windows*B, window_size, window_size, C)\n    \"\"\"\n    B, H, W, C = x.shape\n    x = x.view(B, H // window_size, window_size, W // window_size, window_size,\n               C)\n    windows = x.permute(0, 1, 3, 2, 4,\n                        5).contiguous().view(-1, window_size, window_size, C)\n    return windows\n\n\ndef window_reverse(windows, window_size, H, W):\n    \"\"\"\n    Args:\n        windows: (num_windows*B, window_size, window_size, C)\n        window_size (int): Window size\n        H (int): Height of image\n        W (int): Width of image\n\n    Returns:\n        x: (B, H, W, C)\n    \"\"\"\n    B = int(windows.shape[0] / (H * W / window_size / window_size))\n    x = windows.view(B, H // window_size, W // window_size, window_size,\n                     window_size, -1)\n    x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)\n    return x\n\n\nclass WindowAttention(nn.Module):\n    r\"\"\" Window based multi-head self attention (W-MSA) module with relative\n    position bias.\n    It supports both of shifted and non-shifted window.\n\n    Args:\n        dim (int): Number of input channels.\n        window_size (tuple[int]): The height and width of the window.\n        num_heads (int): Number of attention heads.\n        qkv_bias (bool, optional):  If True, add a learnable bias to query,\n        key, value. Default: True\n        qk_scale (float | None, optional): Override default qk scale of\n        head_dim ** -0.5 if set\n        attn_drop (float, optional): Dropout ratio of attention weight.\n        Default: 0.0\n        proj_drop (float, optional): Dropout ratio of output. Default: 0.0\n        pretrained_window_size (tuple[int]): The height and width of the\n        window in pretraining.\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 window_size,\n                 num_heads,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 attn_drop=0.,\n                 proj_drop=0.,\n                 pretrained_window_size=[0, 0]):\n\n        super().__init__()\n        self.dim = dim\n        self.window_size = window_size  # Wh, Ww\n        self.pretrained_window_size = pretrained_window_size\n        self.num_heads = num_heads\n\n        head_dim = dim // num_heads\n        self.scale = qk_scale or head_dim**-0.5\n\n        # mlp to generate continuous relative position bias\n        self.cpb_mlp = nn.Sequential(\n            nn.Linear(2, 512, bias=True), nn.ReLU(inplace=True),\n            nn.Linear(512, num_heads, bias=False))\n\n        # get relative_coords_table\n        relative_coords_h = torch.arange(\n            -(self.window_size[0] - 1),\n            self.window_size[0],\n            dtype=torch.float32)\n        relative_coords_w = torch.arange(\n            -(self.window_size[1] - 1),\n            self.window_size[1],\n            dtype=torch.float32)\n        relative_coords_table = torch.stack(\n            torch.meshgrid([relative_coords_h, relative_coords_w])).permute(\n                1, 2, 0).contiguous().unsqueeze(0)  # 1, 2*Wh-1, 2*Ww-1, 2\n        if pretrained_window_size[0] > 0:\n            relative_coords_table[:, :, :, 0] /= (\n                pretrained_window_size[0] - 1)\n            relative_coords_table[:, :, :, 1] /= (\n                pretrained_window_size[1] - 1)\n        else:\n            relative_coords_table[:, :, :, 0] /= (self.window_size[0] - 1)\n            relative_coords_table[:, :, :, 1] /= (self.window_size[1] - 1)\n        relative_coords_table *= 8  # normalize to -8, 8\n        relative_coords_table = torch.sign(relative_coords_table) * torch.log2(\n            torch.abs(relative_coords_table) + 1.0) / np.log2(8)\n\n        self.register_buffer('relative_coords_table', relative_coords_table)\n\n        # get pair-wise relative position index for each token inside the\n        # window\n        coords_h = torch.arange(self.window_size[0])\n        coords_w = torch.arange(self.window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = (coords_flatten[:, :, None] -\n                           coords_flatten[:, None, :])  # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(\n            1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :, 0] += self.window_size[0] - 1\n        relative_coords[:, :, 1] += self.window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1\n        relative_position_index = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        self.register_buffer('relative_position_index',\n                             relative_position_index)\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n        self.softmax = nn.Softmax(dim=-1)\n\n    def forward(self, x, mask=None):\n        \"\"\"\n        Args:\n            x: input features with shape of (num_windows*B, N, C)\n            mask: (0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or\n            None\n        \"\"\"\n        B_, N, C = x.shape\n        qkv = self.qkv(x).reshape(B_, N, 3, self.num_heads,\n                                  C // self.num_heads).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[\n            2]  # make torchscript happy (cannot use tensor as tuple)\n\n        q = q * self.scale\n        attn = (q @ k.transpose(-2, -1))\n\n        relative_position_bias_table = self.cpb_mlp(\n            self.relative_coords_table).view(-1, self.num_heads)\n        relative_position_bias = relative_position_bias_table[\n            self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1],\n                self.window_size[0] * self.window_size[1],\n                -1)  # Wh*Ww,Wh*Ww,nH\n        relative_position_bias = relative_position_bias.permute(\n            2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n        attn = attn + relative_position_bias.unsqueeze(0)\n\n        if mask is not None:\n            nW = mask.shape[0]\n            attn = attn.view(B_ // nW, nW, self.num_heads, N,\n                             N) + mask.unsqueeze(1).unsqueeze(0)\n            attn = attn.view(-1, self.num_heads, N, N)\n            attn = self.softmax(attn)\n        else:\n            attn = self.softmax(attn)\n\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B_, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n    def extra_repr(self) -> str:\n        return f'dim={self.dim}, window_size={self.window_size}, ' \\\n            (f'pretrained_window_size={self.pretrained_window_size}, '\n             f'num_heads={self.num_heads}')\n\n    def flops(self, N):\n        # calculate flops for 1 window with token length of N\n        flops = 0\n        # qkv = self.qkv(x)\n        flops += N * self.dim * 3 * self.dim\n        # attn = (q @ k.transpose(-2, -1))\n        flops += self.num_heads * N * (self.dim // self.num_heads) * N\n        #  x = (attn @ v)\n        flops += self.num_heads * N * N * (self.dim // self.num_heads)\n        # x = self.proj(x)\n        flops += N * self.dim * self.dim\n        return flops\n\n\nclass SwinTransformerBlock(nn.Module):\n    r\"\"\" Swin Transformer Block.\n\n    Args:\n        dim (int): Number of input channels.\n        input_resolution (tuple[int]): Input resolution.\n        num_heads (int): Number of attention heads.\n        window_size (int): Window size.\n        shift_size (int): Shift size for SW-MSA.\n        mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.\n        qkv_bias (bool, optional): If True, add a learnable bias to query,\n        key, value. Default: True\n        qk_scale (float | None, optional): Override default qk scale of\n        head_dim ** -0.5 if set.\n        drop (float, optional): Dropout rate. Default: 0.0\n        attn_drop (float, optional): Attention dropout rate. Default: 0.0\n        drop_path (float, optional): Stochastic depth rate. Default: 0.0\n        act_layer (nn.Module, optional): Activation layer. Default: nn.GELU\n        norm_layer (nn.Module, optional): Normalization layer.  Default:\n        nn.LayerNorm\n        mlp_fc2_bias (bool): Whether to add bias in fc2 of Mlp. Default: True\n        init_std: Initialization std. Default: 0.02\n        pretrained_window_size (int): Window size in pretraining.\n        is_moe (bool): If True, this block is a MoE block.\n        num_local_experts (int): number of local experts in each device (\n        GPU). Default: 1\n        top_value (int): the value of k in top-k gating. Default: 1\n        capacity_factor (float): the capacity factor in MoE. Default: 1.25\n        cosine_router (bool): Whether to use cosine router. Default: False\n        normalize_gate (bool): Whether to normalize the gating score in top-k\n        gating. Default: False\n        use_bpr (bool): Whether to use batch-prioritized-routing. Default: True\n        is_gshard_loss (bool): If True, use Gshard balance loss.\n                               If False, use the load loss and importance\n                               loss in \"arXiv:1701.06538\". Default: False\n        gate_noise (float): the noise ratio in top-k gating. Default: 1.0\n        cosine_router_dim (int): Projection dimension in cosine router.\n        cosine_router_init_t (float): Initialization temperature in cosine\n        router.\n        moe_drop (float): Dropout rate in MoE. Default: 0.0\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 num_heads,\n                 window_size=7,\n                 shift_size=0,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 act_layer=nn.GELU,\n                 norm_layer=nn.LayerNorm,\n                 mlp_fc2_bias=True,\n                 init_std=0.02,\n                 pretrained_window_size=0,\n                 is_moe=False,\n                 num_local_experts=1,\n                 top_value=1,\n                 capacity_factor=1.25,\n                 cosine_router=False,\n                 normalize_gate=False,\n                 use_bpr=True,\n                 is_gshard_loss=True,\n                 gate_noise=1.0,\n                 cosine_router_dim=256,\n                 cosine_router_init_t=0.5,\n                 moe_drop=0.0):\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.num_heads = num_heads\n        self.window_size = window_size\n        self.shift_size = shift_size\n        self.mlp_ratio = mlp_ratio\n        self.is_moe = is_moe\n        self.capacity_factor = capacity_factor\n        self.top_value = top_value\n\n        if min(self.input_resolution) <= self.window_size:\n            # if window size is larger than input resolution, we don't\n            # partition windows\n            self.shift_size = 0\n            self.window_size = min(self.input_resolution)\n        assert 0 <= self.shift_size < self.window_size, ('shift_size must in '\n                                                         '0-window_size')\n\n        self.norm1 = norm_layer(dim)\n        self.attn = WindowAttention(\n            dim,\n            window_size=to_2tuple(self.window_size),\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop=attn_drop,\n            proj_drop=drop,\n            pretrained_window_size=to_2tuple(pretrained_window_size))\n\n        self.drop_path = DropPath(\n            drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        if self.is_moe:\n            self.mlp = MoEMlp(\n                in_features=dim,\n                hidden_features=mlp_hidden_dim,\n                num_local_experts=num_local_experts,\n                top_value=top_value,\n                capacity_factor=capacity_factor,\n                cosine_router=cosine_router,\n                normalize_gate=normalize_gate,\n                use_bpr=use_bpr,\n                is_gshard_loss=is_gshard_loss,\n                gate_noise=gate_noise,\n                cosine_router_dim=cosine_router_dim,\n                cosine_router_init_t=cosine_router_init_t,\n                moe_drop=moe_drop,\n                mlp_fc2_bias=mlp_fc2_bias,\n                init_std=init_std)\n        else:\n            self.mlp = Mlp(\n                in_features=dim,\n                hidden_features=mlp_hidden_dim,\n                act_layer=act_layer,\n                drop=drop,\n                mlp_fc2_bias=mlp_fc2_bias)\n\n        if self.shift_size > 0:\n            # calculate attention mask for SW-MSA\n            H, W = self.input_resolution\n            img_mask = torch.zeros((1, H, W, 1))  # 1 H W 1\n            h_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            w_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            cnt = 0\n            for h in h_slices:\n                for w in w_slices:\n                    img_mask[:, h, w, :] = cnt\n                    cnt += 1\n\n            mask_windows = window_partition(\n                img_mask, self.window_size)  # nW, window_size, window_size, 1\n            mask_windows = mask_windows.view(\n                -1, self.window_size * self.window_size)\n            attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)\n            attn_mask = attn_mask.masked_fill(attn_mask != 0,\n                                              float(-100.0)).masked_fill(\n                                                  attn_mask == 0, float(0.0))\n        else:\n            attn_mask = None\n\n        self.register_buffer('attn_mask', attn_mask)\n\n    def forward(self, x):\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n\n        shortcut = x\n        x = self.norm1(x)\n        x = x.view(B, H, W, C)\n\n        # cyclic shift\n        if self.shift_size > 0:\n            shifted_x = torch.roll(\n                x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))\n        else:\n            shifted_x = x\n\n        # partition windows\n        x_windows = window_partition(\n            shifted_x, self.window_size)  # nW*B, window_size, window_size, C\n        x_windows = x_windows.view(-1, self.window_size * self.window_size,\n                                   C)  # nW*B, window_size*window_size, C\n\n        # W-MSA/SW-MSA\n        attn_windows = self.attn(\n            x_windows, mask=self.attn_mask)  # nW*B, window_size*window_size, C\n\n        # merge windows\n        attn_windows = attn_windows.view(-1, self.window_size,\n                                         self.window_size, C)\n        shifted_x = window_reverse(attn_windows, self.window_size, H,\n                                   W)  # B H' W' C\n\n        # reverse cyclic shift\n        if self.shift_size > 0:\n            x = torch.roll(\n                shifted_x,\n                shifts=(self.shift_size, self.shift_size),\n                dims=(1, 2))\n        else:\n            x = shifted_x\n        x = x.view(B, H * W, C)\n        x = shortcut + self.drop_path(x)\n\n        # FFN\n        shortcut = x\n        x = self.norm2(x)\n        if self.is_moe:\n            x, l_aux = self.mlp(x)\n            x = shortcut + self.drop_path(x)\n            return x, l_aux\n        else:\n            x = shortcut + self.drop_path(self.mlp(x))\n            return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, '\n                f'input_resolution={self.input_resolution}, '\n                f'num_heads={self.num_heads}, '\n                f'window_size={self.window_size}, '\n                f'shift_size={self.shift_size}, '\n                f'mlp_ratio={self.mlp_ratio}')\n\n    def flops(self):\n        flops = 0\n        H, W = self.input_resolution\n        # norm1\n        flops += self.dim * H * W\n        # W-MSA/SW-MSA\n        nW = H * W / self.window_size / self.window_size\n        flops += nW * self.attn.flops(self.window_size * self.window_size)\n        # mlp\n        if self.is_moe:\n            flops += (2 * H * W * self.dim * self.dim * self.mlp_ratio *\n                      self.capacity_factor * self.top_value)\n        else:\n            flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio\n        # norm2\n        flops += self.dim * H * W\n        return flops\n\n\nclass PatchMerging(nn.Module):\n    r\"\"\" Patch Merging Layer.\n\n    Args:\n        input_resolution (tuple[int]): Resolution of input feature.\n        dim (int): Number of input channels.\n        norm_layer (nn.Module, optional): Normalization layer.  Default:\n        nn.LayerNorm\n    \"\"\"\n\n    def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.input_resolution = input_resolution\n        self.dim = dim\n        self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)\n        self.norm = norm_layer(4 * dim)\n\n    def forward(self, x):\n        \"\"\"\n        x: B, H*W, C\n        \"\"\"\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n        assert H % 2 == 0 and W % 2 == 0, f'x size ({H}*{W}) are not even.'\n\n        x = x.view(B, H, W, C)\n\n        x0 = x[:, 0::2, 0::2, :]  # B H/2 W/2 C\n        x1 = x[:, 1::2, 0::2, :]  # B H/2 W/2 C\n        x2 = x[:, 0::2, 1::2, :]  # B H/2 W/2 C\n        x3 = x[:, 1::2, 1::2, :]  # B H/2 W/2 C\n        x = torch.cat([x0, x1, x2, x3], -1)  # B H/2 W/2 4*C\n        x = x.view(B, -1, 4 * C)  # B H/2*W/2 4*C\n\n        x = self.norm(x)\n        x = self.reduction(x)\n\n        return x\n\n    def extra_repr(self) -> str:\n        return f'input_resolution={self.input_resolution}, dim={self.dim}'\n\n    def flops(self):\n        H, W = self.input_resolution\n        flops = H * W * self.dim\n        flops += (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim\n        return flops\n\n\nclass BasicLayer(nn.Module):\n    \"\"\"A basic Swin Transformer layer for one stage.\n\n    Args:\n        dim (int): Number of input channels.\n        input_resolution (tuple[int]): Input resolution.\n        depth (int): Number of blocks.\n        num_heads (int): Number of attention heads.\n        window_size (int): Local window size.\n        mlp_ratio (float): Ratio of mlp hidden dim to embedding dim.\n        qkv_bias (bool, optional): If True, add a learnable bias to query,\n        key, value. Default: True\n        qk_scale (float | None, optional): Override default qk scale of\n        head_dim ** -0.5 if set.\n        drop (float, optional): Dropout rate. Default: 0.0\n        attn_drop (float, optional): Attention dropout rate. Default: 0.0\n        drop_path (float | tuple[float], optional): Stochastic depth rate.\n        Default: 0.0\n        norm_layer (nn.Module, optional): Normalization layer. Default:\n        nn.LayerNorm\n        downsample (nn.Module | None, optional): Downsample layer at the end\n        of the layer. Default: None\n        mlp_fc2_bias (bool): Whether to add bias in fc2 of Mlp. Default: True\n        init_std: Initialization std. Default: 0.02\n        use_checkpoint (bool): Whether to use checkpointing to save memory.\n        Default: False.\n        pretrained_window_size (int): Local window size in pretraining.\n        moe_blocks (tuple(int)): The index of each MoE block.\n        num_local_experts (int): number of local experts in each device (\n        GPU). Default: 1\n        top_value (int): the value of k in top-k gating. Default: 1\n        capacity_factor (float): the capacity factor in MoE. Default: 1.25\n        cosine_router (bool): Whether to use cosine router Default: False\n        normalize_gate (bool): Whether to normalize the gating score in top-k\n        gating. Default: False\n        use_bpr (bool): Whether to use batch-prioritized-routing. Default: True\n        is_gshard_loss (bool): If True, use Gshard balance loss.\n                               If False, use the load loss and importance\n                               loss in \"arXiv:1701.06538\". Default: False\n        gate_noise (float): the noise ratio in top-k gating. Default: 1.0\n        cosine_router_dim (int): Projection dimension in cosine router.\n        cosine_router_init_t (float): Initialization temperature in cosine\n        router.\n        moe_drop (float): Dropout rate in MoE. Default: 0.0\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 depth,\n                 num_heads,\n                 window_size,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 norm_layer=nn.LayerNorm,\n                 downsample=None,\n                 mlp_fc2_bias=True,\n                 init_std=0.02,\n                 use_checkpoint=False,\n                 pretrained_window_size=0,\n                 moe_block=[-1],\n                 num_local_experts=1,\n                 top_value=1,\n                 capacity_factor=1.25,\n                 cosine_router=False,\n                 normalize_gate=False,\n                 use_bpr=True,\n                 is_gshard_loss=True,\n                 cosine_router_dim=256,\n                 cosine_router_init_t=0.5,\n                 gate_noise=1.0,\n                 moe_drop=0.0):\n\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.depth = depth\n        self.use_checkpoint = use_checkpoint\n\n        # build blocks\n        self.blocks = nn.ModuleList([\n            SwinTransformerBlock(\n                dim=dim,\n                input_resolution=input_resolution,\n                num_heads=num_heads,\n                window_size=window_size,\n                shift_size=0 if (i % 2 == 0) else window_size // 2,\n                mlp_ratio=mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop=drop,\n                attn_drop=attn_drop,\n                drop_path=drop_path[i]\n                if isinstance(drop_path, list) else drop_path,\n                norm_layer=norm_layer,\n                mlp_fc2_bias=mlp_fc2_bias,\n                init_std=init_std,\n                pretrained_window_size=pretrained_window_size,\n                is_moe=True if i in moe_block else False,\n                num_local_experts=num_local_experts,\n                top_value=top_value,\n                capacity_factor=capacity_factor,\n                cosine_router=cosine_router,\n                normalize_gate=normalize_gate,\n                use_bpr=use_bpr,\n                is_gshard_loss=is_gshard_loss,\n                gate_noise=gate_noise,\n                cosine_router_dim=cosine_router_dim,\n                cosine_router_init_t=cosine_router_init_t,\n                moe_drop=moe_drop) for i in range(depth)\n        ])\n\n        # patch merging layer\n        if downsample is not None:\n            self.downsample = downsample(\n                input_resolution, dim=dim, norm_layer=norm_layer)\n        else:\n            self.downsample = None\n\n    def forward(self, x):\n        l_aux = 0.0\n        for blk in self.blocks:\n            if self.use_checkpoint:\n                out = checkpoint.checkpoint(blk, x)\n            else:\n                out = blk(x)\n            if isinstance(out, tuple):\n                x = out[0]\n                cur_l_aux = out[1]\n                l_aux = cur_l_aux + l_aux\n            else:\n                x = out\n\n        if self.downsample is not None:\n            x = self.downsample(x)\n        return x, l_aux\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, input_resolution={self.input_resolution}, '\n                f'depth={self.depth}')\n\n    def flops(self):\n        flops = 0\n        for blk in self.blocks:\n            flops += blk.flops()\n        if self.downsample is not None:\n            flops += self.downsample.flops()\n        return flops\n\n\nclass PatchEmbed(nn.Module):\n    r\"\"\" Image to Patch Embedding\n\n    Args:\n        img_size (int): Image size.  Default: 224.\n        patch_size (int): Patch token size. Default: 4.\n        in_chans (int): Number of input image channels. Default: 3.\n        embed_dim (int): Number of linear projection output channels.\n        Default: 96.\n        norm_layer (nn.Module, optional): Normalization layer. Default: None\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 embed_dim=96,\n                 norm_layer=None):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        patches_resolution = [\n            img_size[0] // patch_size[0], img_size[1] // patch_size[1]\n        ]\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.patches_resolution = patches_resolution\n        self.num_patches = patches_resolution[0] * patches_resolution[1]\n\n        self.in_chans = in_chans\n        self.embed_dim = embed_dim\n\n        self.proj = nn.Conv2d(\n            in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n        if norm_layer is not None:\n            self.norm = norm_layer(embed_dim)\n        else:\n            self.norm = None\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            (f\"Input image size ({H}*{W}) doesn't match model (\"\n             f'{self.img_size[0]}*{self.img_size[1]}).')\n        x = self.proj(x).flatten(2).transpose(1, 2)  # B Ph*Pw C\n        if self.norm is not None:\n            x = self.norm(x)\n        return x\n\n    def flops(self):\n        Ho, Wo = self.patches_resolution\n        flops = Ho * Wo * self.embed_dim * self.in_chans * (\n            self.patch_size[0] * self.patch_size[1])\n        if self.norm is not None:\n            flops += Ho * Wo * self.embed_dim\n        return flops\n\n\nclass SwinTransformerMoE(nn.Module):\n    r\"\"\" Swin Transformer\n        A PyTorch impl of : `Swin Transformer: Hierarchical Vision\n        Transformer using Shifted Windows`  -\n          https://arxiv.org/pdf/2103.14030\n\n    Args:\n        img_size (int | tuple(int)): Input image size. Default 224\n        patch_size (int | tuple(int)): Patch size. Default: 4\n        in_chans (int): Number of input image channels. Default: 3\n        num_classes (int): Number of classes for classification head.\n        Default: 1000\n        embed_dim (int): Patch embedding dimension. Default: 96\n        depths (tuple(int)): Depth of each Swin Transformer layer.\n        num_heads (tuple(int)): Number of attention heads in different layers.\n        window_size (int): Window size. Default: 7\n        mlp_ratio (float): Ratio of mlp hidden dim to embedding dim. Default: 4\n        qkv_bias (bool): If True, add a learnable bias to query, key, value.\n        Default: True\n        qk_scale (float): Override default qk scale of head_dim ** -0.5 if\n        set. Default: None\n        drop_rate (float): Dropout rate. Default: 0\n        attn_drop_rate (float): Attention dropout rate. Default: 0\n        drop_path_rate (float): Stochastic depth rate. Default: 0.1\n        norm_layer (nn.Module): Normalization layer. Default: nn.LayerNorm.\n        ape (bool): If True, add absolute position embedding to the patch\n        embedding. Default: False\n        patch_norm (bool): If True, add normalization after patch embedding.\n        Default: True\n        mlp_fc2_bias (bool): Whether to add bias in fc2 of Mlp. Default: True\n        init_std: Initialization std. Default: 0.02\n        use_checkpoint (bool): Whether to use checkpointing to save memory.\n        Default: False\n        pretrained_window_sizes (tuple(int)): Pretrained window sizes of each\n        layer.\n        moe_blocks (tuple(tuple(int))): The index of each MoE block in each\n        layer.\n        num_local_experts (int): number of local experts in each device (\n        GPU). Default: 1\n        top_value (int): the value of k in top-k gating. Default: 1\n        capacity_factor (float): the capacity factor in MoE. Default: 1.25\n        cosine_router (bool): Whether to use cosine router Default: False\n        normalize_gate (bool): Whether to normalize the gating score in top-k\n        gating. Default: False\n        use_bpr (bool): Whether to use batch-prioritized-routing. Default: True\n        is_gshard_loss (bool): If True, use Gshard balance loss.\n                               If False, use the load loss and importance\n                               loss in \"arXiv:1701.06538\". Default: False\n        gate_noise (float): the noise ratio in top-k gating. Default: 1.0\n        cosine_router_dim (int): Projection dimension in cosine router.\n        cosine_router_init_t (float): Initialization temperature in cosine\n        router.\n        moe_drop (float): Dropout rate in MoE. Default: 0.0\n        aux_loss_weight (float): auxiliary loss weight. Default: 0.1\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 num_classes=1000,\n                 embed_dim=96,\n                 depths=[2, 2, 6, 2],\n                 num_heads=[3, 6, 12, 24],\n                 window_size=7,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 qk_scale=None,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.1,\n                 norm_layer=nn.LayerNorm,\n                 ape=False,\n                 patch_norm=True,\n                 mlp_fc2_bias=True,\n                 init_std=0.02,\n                 use_checkpoint=False,\n                 pretrained_window_sizes=[0, 0, 0, 0],\n                 moe_blocks=[[-1], [-1], [-1], [-1]],\n                 num_local_experts=1,\n                 top_value=1,\n                 capacity_factor=1.25,\n                 cosine_router=False,\n                 normalize_gate=False,\n                 use_bpr=True,\n                 is_gshard_loss=True,\n                 gate_noise=1.0,\n                 cosine_router_dim=256,\n                 cosine_router_init_t=0.5,\n                 moe_drop=0.0,\n                 aux_loss_weight=0.01,\n                 **kwargs):\n        super().__init__()\n        self._ddp_params_and_buffers_to_ignore = list()\n\n        self.num_classes = num_classes\n        self.num_layers = len(depths)\n        self.embed_dim = embed_dim\n        self.ape = ape\n        self.patch_norm = patch_norm\n        self.num_features = int(embed_dim * 2**(self.num_layers - 1))\n        self.mlp_ratio = mlp_ratio\n        self.init_std = init_std\n        self.aux_loss_weight = aux_loss_weight\n        self.num_local_experts = num_local_experts\n        self.global_experts = num_local_experts * dist.get_world_size() if (\n                num_local_experts > 0) \\\n            else dist.get_world_size() // (-num_local_experts)\n        self.sharded_count = (\n            1.0 / num_local_experts) if num_local_experts > 0 else (\n                -num_local_experts)\n\n        # split image into non-overlapping patches\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n            norm_layer=norm_layer if self.patch_norm else None)\n        num_patches = self.patch_embed.num_patches\n        patches_resolution = self.patch_embed.patches_resolution\n        self.patches_resolution = patches_resolution\n\n        # absolute position embedding\n        if self.ape:\n            self.absolute_pos_embed = nn.Parameter(\n                torch.zeros(1, num_patches, embed_dim))\n            trunc_normal_(self.absolute_pos_embed, std=self.init_std)\n\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        # stochastic depth\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))\n        ]  # stochastic depth decay rule\n\n        # build layers\n        self.layers = nn.ModuleList()\n        for i_layer in range(self.num_layers):\n            layer = BasicLayer(\n                dim=int(embed_dim * 2**i_layer),\n                input_resolution=(patches_resolution[0] // (2**i_layer),\n                                  patches_resolution[1] // (2**i_layer)),\n                depth=depths[i_layer],\n                num_heads=num_heads[i_layer],\n                window_size=window_size,\n                mlp_ratio=self.mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop=drop_rate,\n                attn_drop=attn_drop_rate,\n                drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])],\n                norm_layer=norm_layer,\n                downsample=PatchMerging if\n                (i_layer < self.num_layers - 1) else None,\n                mlp_fc2_bias=mlp_fc2_bias,\n                init_std=init_std,\n                use_checkpoint=use_checkpoint,\n                pretrained_window_size=pretrained_window_sizes[i_layer],\n                moe_block=moe_blocks[i_layer],\n                num_local_experts=num_local_experts,\n                top_value=top_value,\n                capacity_factor=capacity_factor,\n                cosine_router=cosine_router,\n                normalize_gate=normalize_gate,\n                use_bpr=use_bpr,\n                is_gshard_loss=is_gshard_loss,\n                gate_noise=gate_noise,\n                cosine_router_dim=cosine_router_dim,\n                cosine_router_init_t=cosine_router_init_t,\n                moe_drop=moe_drop)\n            self.layers.append(layer)\n\n        self.norm = norm_layer(self.num_features)\n        self.avgpool = nn.AdaptiveAvgPool1d(1)\n        self.head = nn.Linear(\n            self.num_features,\n            num_classes) if num_classes > 0 else nn.Identity()\n\n        self.apply(self._init_weights)\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=self.init_std)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n        elif isinstance(m, MoEMlp):\n            m._init_weights()\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'absolute_pos_embed'}\n\n    @torch.jit.ignore\n    def no_weight_decay_keywords(self):\n        return {\n            'cpb_mlp', 'relative_position_bias_table', 'fc1_bias', 'fc2_bias',\n            'temperature', 'cosine_projector', 'sim_matrix'\n        }\n\n    def forward_features(self, x):\n        x = self.patch_embed(x)\n        if self.ape:\n            x = x + self.absolute_pos_embed\n        x = self.pos_drop(x)\n        l_aux = 0.0\n        for layer in self.layers:\n            x, cur_l_aux = layer(x)\n            l_aux = cur_l_aux + l_aux\n\n        x = self.norm(x)  # B L C\n        x = self.avgpool(x.transpose(1, 2))  # B C 1\n        x = torch.flatten(x, 1)\n        return x, l_aux\n\n    def forward(self, x):\n        x, l_aux = self.forward_features(x)\n        x = self.head(x)\n        return x, l_aux * self.aux_loss_weight\n\n    def add_param_to_skip_allreduce(self, param_name):\n        self._ddp_params_and_buffers_to_ignore.append(param_name)\n\n    def flops(self):\n        flops = 0\n        flops += self.patch_embed.flops()\n        for i, layer in enumerate(self.layers):\n            flops += layer.flops()\n        flops += self.num_features * self.patches_resolution[\n            0] * self.patches_resolution[1] // (2**self.num_layers)\n        flops += self.num_features * self.num_classes\n        return flops\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/swin_transformer_v2.py",
    "content": "# --------------------------------------------------------\n# Swin Transformer V2\n# Copyright (c) 2022 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ze Liu\n# --------------------------------------------------------\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nimport torch.utils.checkpoint as checkpoint\nfrom timm.models.layers import DropPath, to_2tuple, trunc_normal_\n\nfrom mmpose.models.builder import BACKBONES\n\n\nclass Mlp(nn.Module):\n\n    def __init__(self,\n                 in_features,\n                 hidden_features=None,\n                 out_features=None,\n                 act_layer=nn.GELU,\n                 drop=0.):\n        super().__init__()\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = act_layer()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop)\n\n    def forward(self, x):\n        x = self.fc1(x)\n        x = self.act(x)\n        x = self.drop(x)\n        x = self.fc2(x)\n        x = self.drop(x)\n        return x\n\n\ndef window_partition(x, window_size):\n    \"\"\"\n    Args:\n        x: (B, H, W, C)\n        window_size (int): window size\n\n    Returns:\n        windows: (num_windows*B, window_size, window_size, C)\n    \"\"\"\n    B, H, W, C = x.shape\n    x = x.view(B, H // window_size, window_size, W // window_size, window_size,\n               C)\n    windows = x.permute(0, 1, 3, 2, 4,\n                        5).contiguous().view(-1, window_size, window_size, C)\n    return windows\n\n\ndef window_reverse(windows, window_size, H, W):\n    \"\"\"\n    Args:\n        windows: (num_windows*B, window_size, window_size, C)\n        window_size (int): Window size\n        H (int): Height of image\n        W (int): Width of image\n\n    Returns:\n        x: (B, H, W, C)\n    \"\"\"\n    B = int(windows.shape[0] / (H * W / window_size / window_size))\n    x = windows.view(B, H // window_size, W // window_size, window_size,\n                     window_size, -1)\n    x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)\n    return x\n\n\nclass WindowAttention(nn.Module):\n    r\"\"\" Window based multi-head self attention (W-MSA) module with relative\n    position bias. It supports both of shifted and non-shifted window.\n\n    Args: dim (int): Number of input channels. window_size (tuple[int]): The\n    height and width of the window. num_heads (int): Number of attention\n    heads. qkv_bias (bool, optional):  If True, add a learnable bias to\n    query, key, value. Default: True attn_drop (float, optional): Dropout\n    ratio of attention weight. Default: 0.0 proj_drop (float, optional):\n    Dropout ratio of output. Default: 0.0 pretrained_window_size (tuple[\n    int]): The height and width of the window in pre-training.\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 window_size,\n                 num_heads,\n                 qkv_bias=True,\n                 attn_drop=0.,\n                 proj_drop=0.,\n                 pretrained_window_size=[0, 0]):\n\n        super().__init__()\n        self.dim = dim\n        self.window_size = window_size  # Wh, Ww\n        self.pretrained_window_size = pretrained_window_size\n        self.num_heads = num_heads\n\n        self.logit_scale = nn.Parameter(\n            torch.log(10 * torch.ones((num_heads, 1, 1))), requires_grad=True)\n\n        # mlp to generate continuous relative position bias\n        self.cpb_mlp = nn.Sequential(\n            nn.Linear(2, 512, bias=True), nn.ReLU(inplace=True),\n            nn.Linear(512, num_heads, bias=False))\n\n        # get relative_coords_table\n        relative_coords_h = torch.arange(\n            -(self.window_size[0] - 1),\n            self.window_size[0],\n            dtype=torch.float32)\n        relative_coords_w = torch.arange(\n            -(self.window_size[1] - 1),\n            self.window_size[1],\n            dtype=torch.float32)\n        relative_coords_table = torch.stack(\n            torch.meshgrid([relative_coords_h, relative_coords_w])).permute(\n                1, 2, 0).contiguous().unsqueeze(0)  # 1, 2*Wh-1, 2*Ww-1, 2\n        if pretrained_window_size[0] > 0:\n            relative_coords_table[:, :, :, 0] /= (\n                pretrained_window_size[0] - 1)\n            relative_coords_table[:, :, :, 1] /= (\n                pretrained_window_size[1] - 1)\n        else:\n            relative_coords_table[:, :, :, 0] /= (self.window_size[0] - 1)\n            relative_coords_table[:, :, :, 1] /= (self.window_size[1] - 1)\n        relative_coords_table *= 8  # normalize to -8, 8\n        relative_coords_table = torch.sign(relative_coords_table) * torch.log2(\n            torch.abs(relative_coords_table) + 1.0) / np.log2(8)\n\n        self.register_buffer('relative_coords_table', relative_coords_table)\n\n        # get pair-wise relative position index for each token inside the\n        # window\n        coords_h = torch.arange(self.window_size[0])\n        coords_w = torch.arange(self.window_size[1])\n        coords = torch.stack(torch.meshgrid([coords_h, coords_w]))  # 2, Wh, Ww\n        coords_flatten = torch.flatten(coords, 1)  # 2, Wh*Ww\n        relative_coords = coords_flatten[:, :,\n                                         None] - coords_flatten[:, None, :]  #\n        # 2, Wh*Ww, Wh*Ww\n        relative_coords = relative_coords.permute(\n            1, 2, 0).contiguous()  # Wh*Ww, Wh*Ww, 2\n        relative_coords[:, :,\n                        0] += self.window_size[0] - 1  # shift to start from 0\n        relative_coords[:, :, 1] += self.window_size[1] - 1\n        relative_coords[:, :, 0] *= 2 * self.window_size[1] - 1\n        relative_position_index = relative_coords.sum(-1)  # Wh*Ww, Wh*Ww\n        self.register_buffer('relative_position_index',\n                             relative_position_index)\n\n        self.qkv = nn.Linear(dim, dim * 3, bias=False)\n        if qkv_bias:\n            self.q_bias = nn.Parameter(torch.zeros(dim))\n            self.v_bias = nn.Parameter(torch.zeros(dim))\n        else:\n            self.q_bias = None\n            self.v_bias = None\n        self.attn_drop = nn.Dropout(attn_drop)\n        self.proj = nn.Linear(dim, dim)\n        self.proj_drop = nn.Dropout(proj_drop)\n        self.softmax = nn.Softmax(dim=-1)\n\n    def forward(self, x, mask=None):\n        \"\"\"\n        Args: x: input features with shape of (num_windows*B, N, C) mask: (\n        0/-inf) mask with shape of (num_windows, Wh*Ww, Wh*Ww) or None\n        \"\"\"\n        B_, N, C = x.shape\n        qkv_bias = None\n        if self.q_bias is not None:\n            qkv_bias = torch.cat(\n                (self.q_bias,\n                 torch.zeros_like(self.v_bias,\n                                  requires_grad=False), self.v_bias))\n        qkv = F.linear(input=x, weight=self.qkv.weight, bias=qkv_bias)\n        qkv = qkv.reshape(B_, N, 3, self.num_heads, -1).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[\n            2]  # make torchscript happy (cannot use tensor as tuple)\n\n        # cosine attention\n        attn = (\n            F.normalize(q, dim=-1) @ F.normalize(k, dim=-1).transpose(-2, -1))\n        logit_scale = torch.clamp(\n            self.logit_scale,\n            max=torch.log(torch.tensor(1. / 0.01, device=x.device))).exp()\n        attn = attn * logit_scale\n\n        relative_position_bias_table = self.cpb_mlp(\n            self.relative_coords_table).view(-1, self.num_heads)\n        relative_position_bias = relative_position_bias_table[\n            self.relative_position_index.view(-1)].view(\n                self.window_size[0] * self.window_size[1],\n                self.window_size[0] * self.window_size[1],\n                -1)  # Wh*Ww,Wh*Ww,nH\n        relative_position_bias = relative_position_bias.permute(\n            2, 0, 1).contiguous()  # nH, Wh*Ww, Wh*Ww\n        relative_position_bias = 16 * torch.sigmoid(relative_position_bias)\n        attn = attn + relative_position_bias.unsqueeze(0)\n\n        if mask is not None:\n            nW = mask.shape[0]\n            attn = attn.view(B_ // nW, nW, self.num_heads, N,\n                             N) + mask.unsqueeze(1).unsqueeze(0)\n            attn = attn.view(-1, self.num_heads, N, N)\n            attn = self.softmax(attn)\n        else:\n            attn = self.softmax(attn)\n\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B_, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n    def extra_repr(self) -> str:\n        return f'dim={self.dim}, window_size={self.window_size}, ' \\\n               (f'pretrained_window_size={self.pretrained_window_size}, '\n                f'num_heads={self.num_heads}')\n\n    def flops(self, N):\n        # calculate flops for 1 window with token length of N\n        flops = 0\n        # qkv = self.qkv(x)\n        flops += N * self.dim * 3 * self.dim\n        # attn = (q @ k.transpose(-2, -1))\n        flops += self.num_heads * N * (self.dim // self.num_heads) * N\n        #  x = (attn @ v)\n        flops += self.num_heads * N * N * (self.dim // self.num_heads)\n        # x = self.proj(x)\n        flops += N * self.dim * self.dim\n        return flops\n\n\nclass SwinTransformerBlock(nn.Module):\n    r\"\"\" Swin Transformer Block.\n\n    Args: dim (int): Number of input channels. input_resolution (tuple[int]):\n    Input resolution. num_heads (int): Number of attention heads. window_size\n    (int): Window size. shift_size (int): Shift size for SW-MSA. mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. qkv_bias (bool,\n    optional): If True, add a learnable bias to query, key, value. Default:\n    True drop (float, optional): Dropout rate. Default: 0.0 attn_drop (float,\n    optional): Attention dropout rate. Default: 0.0 drop_path (float,\n    optional): Stochastic depth rate. Default: 0.0 act_layer (nn.Module,\n    optional): Activation layer. Default: nn.GELU norm_layer (nn.Module,\n    optional): Normalization layer.  Default: nn.LayerNorm\n    pretrained_window_size (int): Window size in pre-training.\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 num_heads,\n                 window_size=7,\n                 shift_size=0,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 act_layer=nn.GELU,\n                 norm_layer=nn.LayerNorm,\n                 pretrained_window_size=0):\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.num_heads = num_heads\n        self.window_size = window_size\n        self.shift_size = shift_size\n        self.mlp_ratio = mlp_ratio\n        if min(self.input_resolution) <= self.window_size:\n            # if window size is larger than input resolution, we don't\n            # partition windows\n            self.shift_size = 0\n            self.window_size = min(self.input_resolution)\n        assert 0 <= self.shift_size < self.window_size, ('shift_size must in '\n                                                         '0-window_size')\n\n        self.norm1 = norm_layer(dim)\n        self.attn = WindowAttention(\n            dim,\n            window_size=to_2tuple(self.window_size),\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            attn_drop=attn_drop,\n            proj_drop=drop,\n            pretrained_window_size=to_2tuple(pretrained_window_size))\n\n        self.drop_path = DropPath(\n            drop_path) if drop_path > 0. else nn.Identity()\n        self.norm2 = norm_layer(dim)\n        mlp_hidden_dim = int(dim * mlp_ratio)\n        self.mlp = Mlp(\n            in_features=dim,\n            hidden_features=mlp_hidden_dim,\n            act_layer=act_layer,\n            drop=drop)\n\n        if self.shift_size > 0:\n            # calculate attention mask for SW-MSA\n            H, W = self.input_resolution\n            img_mask = torch.zeros((1, H, W, 1))  # 1 H W 1\n            h_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            w_slices = (slice(0, -self.window_size),\n                        slice(-self.window_size,\n                              -self.shift_size), slice(-self.shift_size, None))\n            cnt = 0\n            for h in h_slices:\n                for w in w_slices:\n                    img_mask[:, h, w, :] = cnt\n                    cnt += 1\n\n            mask_windows = window_partition(\n                img_mask, self.window_size)  # nW, window_size, window_size, 1\n            mask_windows = mask_windows.view(\n                -1, self.window_size * self.window_size)\n            attn_mask = mask_windows.unsqueeze(1) - mask_windows.unsqueeze(2)\n            attn_mask = attn_mask.masked_fill(attn_mask != 0,\n                                              float(-100.0)).masked_fill(\n                                                  attn_mask == 0, float(0.0))\n        else:\n            attn_mask = None\n\n        self.register_buffer('attn_mask', attn_mask)\n\n    def forward(self, x):\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n\n        shortcut = x\n        x = x.view(B, H, W, C)\n\n        # cyclic shift\n        if self.shift_size > 0:\n            shifted_x = torch.roll(\n                x, shifts=(-self.shift_size, -self.shift_size), dims=(1, 2))\n        else:\n            shifted_x = x\n\n        # partition windows\n        x_windows = window_partition(\n            shifted_x, self.window_size)  # nW*B, window_size, window_size, C\n        x_windows = x_windows.view(-1, self.window_size * self.window_size,\n                                   C)  # nW*B, window_size*window_size, C\n\n        # W-MSA/SW-MSA\n        attn_windows = self.attn(\n            x_windows, mask=self.attn_mask)  # nW*B, window_size*window_size, C\n\n        # merge windows\n        attn_windows = attn_windows.view(-1, self.window_size,\n                                         self.window_size, C)\n        shifted_x = window_reverse(attn_windows, self.window_size, H,\n                                   W)  # B H' W' C\n\n        # reverse cyclic shift\n        if self.shift_size > 0:\n            x = torch.roll(\n                shifted_x,\n                shifts=(self.shift_size, self.shift_size),\n                dims=(1, 2))\n        else:\n            x = shifted_x\n        x = x.view(B, H * W, C)\n        x = shortcut + self.drop_path(self.norm1(x))\n\n        # FFN\n        x = x + self.drop_path(self.norm2(self.mlp(x)))\n\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, input_resolution={self.input_resolution}, '\n                f'num_heads={self.num_heads}, '\n                f'window_size={self.window_size}, '\n                f'shift_size={self.shift_size}, '\n                f'mlp_ratio={self.mlp_ratio}')\n\n    def flops(self):\n        flops = 0\n        H, W = self.input_resolution\n        # norm1\n        flops += self.dim * H * W\n        # W-MSA/SW-MSA\n        nW = H * W / self.window_size / self.window_size\n        flops += nW * self.attn.flops(self.window_size * self.window_size)\n        # mlp\n        flops += 2 * H * W * self.dim * self.dim * self.mlp_ratio\n        # norm2\n        flops += self.dim * H * W\n        return flops\n\n\nclass PatchMerging(nn.Module):\n    r\"\"\" Patch Merging Layer.\n\n    Args: input_resolution (tuple[int]): Resolution of input feature. dim (\n    int): Number of input channels. norm_layer (nn.Module, optional):\n    Normalization layer.  Default: nn.LayerNorm\n    \"\"\"\n\n    def __init__(self, input_resolution, dim, norm_layer=nn.LayerNorm):\n        super().__init__()\n        self.input_resolution = input_resolution\n        self.dim = dim\n        self.reduction = nn.Linear(4 * dim, 2 * dim, bias=False)\n        self.norm = norm_layer(2 * dim)\n\n    def forward(self, x):\n        \"\"\"\n        x: B, H*W, C\n        \"\"\"\n        H, W = self.input_resolution\n        B, L, C = x.shape\n        assert L == H * W, 'input feature has wrong size'\n        assert H % 2 == 0 and W % 2 == 0, f'x size ({H}*{W}) are not even.'\n\n        x = x.view(B, H, W, C)\n\n        x0 = x[:, 0::2, 0::2, :]  # B H/2 W/2 C\n        x1 = x[:, 1::2, 0::2, :]  # B H/2 W/2 C\n        x2 = x[:, 0::2, 1::2, :]  # B H/2 W/2 C\n        x3 = x[:, 1::2, 1::2, :]  # B H/2 W/2 C\n        x = torch.cat([x0, x1, x2, x3], -1)  # B H/2 W/2 4*C\n        x = x.view(B, -1, 4 * C)  # B H/2*W/2 4*C\n\n        x = self.reduction(x)\n        x = self.norm(x)\n\n        return x\n\n    def extra_repr(self) -> str:\n        return f'input_resolution={self.input_resolution}, dim={self.dim}'\n\n    def flops(self):\n        H, W = self.input_resolution\n        flops = (H // 2) * (W // 2) * 4 * self.dim * 2 * self.dim\n        flops += H * W * self.dim // 2\n        return flops\n\n\nclass BasicLayer(nn.Module):\n    \"\"\"A basic Swin Transformer layer for one stage.\n\n    Args: dim (int): Number of input channels. input_resolution (tuple[int]):\n    Input resolution. depth (int): Number of blocks. num_heads (int): Number\n    of attention heads. window_size (int): Local window size. mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. qkv_bias (bool,\n    optional): If True, add a learnable bias to query, key, value. Default:\n    True drop (float, optional): Dropout rate. Default: 0.0 attn_drop (float,\n    optional): Attention dropout rate. Default: 0.0 drop_path (float | tuple[\n    float], optional): Stochastic depth rate. Default: 0.0 norm_layer (\n    nn.Module, optional): Normalization layer. Default: nn.LayerNorm\n    downsample (nn.Module | None, optional): Downsample layer at the end of\n    the layer. Default: None use_checkpoint (bool): Whether to use\n    checkpointing to save memory. Default: False. pretrained_window_size (\n    int): Local window size in pre-training.\n    \"\"\"\n\n    def __init__(self,\n                 dim,\n                 input_resolution,\n                 depth,\n                 num_heads,\n                 window_size,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 drop=0.,\n                 attn_drop=0.,\n                 drop_path=0.,\n                 norm_layer=nn.LayerNorm,\n                 downsample=None,\n                 use_checkpoint=False,\n                 pretrained_window_size=0):\n\n        super().__init__()\n        self.dim = dim\n        self.input_resolution = input_resolution\n        self.depth = depth\n        self.use_checkpoint = use_checkpoint\n\n        # build blocks\n        self.blocks = nn.ModuleList([\n            SwinTransformerBlock(\n                dim=dim,\n                input_resolution=input_resolution,\n                num_heads=num_heads,\n                window_size=window_size,\n                shift_size=0 if (i % 2 == 0) else window_size // 2,\n                mlp_ratio=mlp_ratio,\n                qkv_bias=qkv_bias,\n                drop=drop,\n                attn_drop=attn_drop,\n                drop_path=drop_path[i]\n                if isinstance(drop_path, list) else drop_path,\n                norm_layer=norm_layer,\n                pretrained_window_size=pretrained_window_size)\n            for i in range(depth)\n        ])\n\n        # patch merging layer\n        if downsample is not None:\n            self.downsample = downsample(\n                input_resolution, dim=dim, norm_layer=norm_layer)\n        else:\n            self.downsample = None\n\n    def forward(self, x):\n        for blk in self.blocks:\n            if self.use_checkpoint:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        if self.downsample is not None:\n            x = self.downsample(x)\n        return x\n\n    def extra_repr(self) -> str:\n        return (f'dim={self.dim}, input_resolution={self.input_resolution}, '\n                f'depth={self.depth}')\n\n    def flops(self):\n        flops = 0\n        for blk in self.blocks:\n            flops += blk.flops()\n        if self.downsample is not None:\n            flops += self.downsample.flops()\n        return flops\n\n    def _init_respostnorm(self):\n        for blk in self.blocks:\n            nn.init.constant_(blk.norm1.bias, 0)\n            nn.init.constant_(blk.norm1.weight, 0)\n            nn.init.constant_(blk.norm2.bias, 0)\n            nn.init.constant_(blk.norm2.weight, 0)\n\n\nclass PatchEmbed(nn.Module):\n    r\"\"\" Image to Patch Embedding\n\n    Args: img_size (int): Image size.  Default: 224. patch_size (int): Patch\n    token size. Default: 4. in_chans (int): Number of input image channels.\n    Default: 3. embed_dim (int): Number of linear projection output channels.\n    Default: 96. norm_layer (nn.Module, optional): Normalization layer.\n    Default: None\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 embed_dim=96,\n                 norm_layer=None):\n        super().__init__()\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        patches_resolution = [\n            img_size[0] // patch_size[0], img_size[1] // patch_size[1]\n        ]\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.patches_resolution = patches_resolution\n        self.num_patches = patches_resolution[0] * patches_resolution[1]\n\n        self.in_chans = in_chans\n        self.embed_dim = embed_dim\n\n        self.proj = nn.Conv2d(\n            in_chans, embed_dim, kernel_size=patch_size, stride=patch_size)\n        if norm_layer is not None:\n            self.norm = norm_layer(embed_dim)\n        else:\n            self.norm = None\n\n    def forward(self, x):\n        B, C, H, W = x.shape\n        # FIXME look at relaxing size constraints\n        assert H == self.img_size[0] and W == self.img_size[1], \\\n            (f\"Input image size ({H}*{W}) doesn't match model \"\n             f'({self.img_size[0]}*{self.img_size[1]}).')\n        x = self.proj(x).flatten(2).transpose(1, 2)  # B Ph*Pw C\n        if self.norm is not None:\n            x = self.norm(x)\n        return x\n\n    def flops(self):\n        Ho, Wo = self.patches_resolution\n        flops = Ho * Wo * self.embed_dim * self.in_chans * (\n            self.patch_size[0] * self.patch_size[1])\n        if self.norm is not None:\n            flops += Ho * Wo * self.embed_dim\n        return flops\n\n\n@BACKBONES.register_module()\nclass SwinTransformerV2(nn.Module):\n    r\"\"\" Swin Transformer A PyTorch impl of : `Swin Transformer: Hierarchical\n    Vision Transformer using Shifted Windows`  -\n    https://arxiv.org/pdf/2103.14030\n\n    Args: img_size (int | tuple(int)): Input image size. Default 224\n    patch_size (int | tuple(int)): Patch size. Default: 4 in_chans (int):\n    Number of input image channels. Default: 3 num_classes (int): Number of\n    classes for classification head. Default: 1000 embed_dim (int): Patch\n    embedding dimension. Default: 96 depths (tuple(int)): Depth of each Swin\n    Transformer layer. num_heads (tuple(int)): Number of attention heads in\n    different layers. window_size (int): Window size. Default: 7 mlp_ratio (\n    float): Ratio of mlp hidden dim to embedding dim. Default: 4 qkv_bias (\n    bool): If True, add a learnable bias to query, key, value. Default: True\n    drop_rate (float): Dropout rate. Default: 0 attn_drop_rate (float):\n    Attention dropout rate. Default: 0 drop_path_rate (float): Stochastic\n    depth rate. Default: 0.1 norm_layer (nn.Module): Normalization layer.\n    Default: nn.LayerNorm. ape (bool): If True, add absolute position\n    embedding to the patch embedding. Default: False patch_norm (bool): If\n    True, add normalization after patch embedding. Default: True\n    use_checkpoint (bool): Whether to use checkpointing to save memory.\n    Default: False pretrained_window_sizes (tuple(int)): Pretrained window\n    sizes of each layer.\n    \"\"\"\n\n    def __init__(self,\n                 img_size=224,\n                 patch_size=4,\n                 in_chans=3,\n                 num_classes=1000,\n                 embed_dim=96,\n                 depths=[2, 2, 6, 2],\n                 num_heads=[3, 6, 12, 24],\n                 window_size=7,\n                 mlp_ratio=4.,\n                 qkv_bias=True,\n                 drop_rate=0.,\n                 attn_drop_rate=0.,\n                 drop_path_rate=0.1,\n                 norm_layer=nn.LayerNorm,\n                 ape=False,\n                 patch_norm=True,\n                 use_checkpoint=False,\n                 pretrained_window_sizes=[0, 0, 0, 0],\n                 multi_scale=False,\n                 upsample='deconv',\n                 **kwargs):\n        super().__init__()\n\n        self.num_classes = num_classes\n        self.num_layers = len(depths)\n        self.embed_dim = embed_dim\n        self.ape = ape\n        self.patch_norm = patch_norm\n        self.num_features = int(embed_dim * 2**(self.num_layers - 1))\n        self.mlp_ratio = mlp_ratio\n\n        # split image into non-overlapping patches\n        self.patch_embed = PatchEmbed(\n            img_size=img_size,\n            patch_size=patch_size,\n            in_chans=in_chans,\n            embed_dim=embed_dim,\n            norm_layer=norm_layer if self.patch_norm else None)\n        num_patches = self.patch_embed.num_patches\n        patches_resolution = self.patch_embed.patches_resolution\n        self.patches_resolution = patches_resolution\n\n        # absolute position embedding\n        if self.ape:\n            self.absolute_pos_embed = nn.Parameter(\n                torch.zeros(1, num_patches, embed_dim))\n            trunc_normal_(self.absolute_pos_embed, std=.02)\n\n        self.pos_drop = nn.Dropout(p=drop_rate)\n\n        # stochastic depth\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))\n        ]  # stochastic depth decay rule\n\n        # build layers\n        self.layers = nn.ModuleList()\n        for i_layer in range(self.num_layers):\n            layer = BasicLayer(\n                dim=int(embed_dim * 2**i_layer),\n                input_resolution=(patches_resolution[0] // (2**i_layer),\n                                  patches_resolution[1] // (2**i_layer)),\n                depth=depths[i_layer],\n                num_heads=num_heads[i_layer],\n                window_size=window_size,\n                mlp_ratio=self.mlp_ratio,\n                qkv_bias=qkv_bias,\n                drop=drop_rate,\n                attn_drop=attn_drop_rate,\n                drop_path=dpr[sum(depths[:i_layer]):sum(depths[:i_layer + 1])],\n                norm_layer=norm_layer,\n                downsample=PatchMerging if\n                (i_layer < self.num_layers - 1) else None,\n                use_checkpoint=use_checkpoint,\n                pretrained_window_size=pretrained_window_sizes[i_layer])\n            self.layers.append(layer)\n\n        self.norm = norm_layer(self.num_features)\n        self.avgpool = nn.AdaptiveAvgPool1d(1)\n        self.multi_scale = multi_scale\n        if self.multi_scale:\n            self.scales = [1, 2, 4, 4]\n            self.upsample = nn.ModuleList()\n            features = [\n                int(embed_dim * 2**i) for i in range(1, self.num_layers)\n            ] + [self.num_features]\n            self.multi_scale_fuse = nn.Conv2d(\n                sum(features), self.num_features, 1)\n            for i in range(self.num_layers):\n                self.upsample.append(nn.Upsample(scale_factor=self.scales[i]))\n        else:\n            if upsample == 'deconv':\n                self.upsample = nn.ConvTranspose2d(\n                    self.num_features, self.num_features, 2, stride=2)\n            elif upsample == 'new_deconv':\n                self.upsample = nn.Sequential(\n                    nn.Upsample(\n                        scale_factor=2, mode='bilinear', align_corners=False),\n                    nn.Conv2d(\n                        self.num_features,\n                        self.num_features,\n                        3,\n                        stride=1,\n                        padding=1), nn.BatchNorm2d(self.num_features),\n                    nn.ReLU(inplace=True))\n            elif upsample == 'new_deconv2':\n                self.upsample = nn.Sequential(\n                    nn.Upsample(scale_factor=2),\n                    nn.Conv2d(\n                        self.num_features,\n                        self.num_features,\n                        3,\n                        stride=1,\n                        padding=1), nn.BatchNorm2d(self.num_features),\n                    nn.ReLU(inplace=True))\n            elif upsample == 'bilinear':\n                self.upsample = nn.Upsample(\n                    scale_factor=2, mode='bilinear', align_corners=False)\n            else:\n                self.upsample = nn.Identity()\n        self.head = nn.Linear(\n            self.num_features,\n            num_classes) if num_classes > 0 else nn.Identity()\n\n        self.apply(self._init_weights)\n        for bly in self.layers:\n            bly._init_respostnorm()\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'absolute_pos_embed'}\n\n    @torch.jit.ignore\n    def no_weight_decay_keywords(self):\n        return {'cpb_mlp', 'logit_scale', 'relative_position_bias_table'}\n\n    def forward_features(self, x):\n        B, C, H, W = x.shape\n        x = self.patch_embed(x)\n        if self.ape:\n            x = x + self.absolute_pos_embed\n        x = self.pos_drop(x)\n\n        if self.multi_scale:\n            # x_2d = x.view(B, H // 4, W // 4, -1).permute(0, 3, 1, 2)  # B C\n            # H W features = [self.upsample[0](x_2d)]\n            features = []\n            for i, layer in enumerate(self.layers):\n                x = layer(x)\n                x_2d = x.view(B, H // (8 * self.scales[i]),\n                              W // (8 * self.scales[i]),\n                              -1).permute(0, 3, 1, 2)  # B C H W\n                features.append(self.upsample[i](x_2d))\n            x = torch.cat(features, dim=1)\n            x = self.multi_scale_fuse(x)\n            x = x.view(B, self.num_features, -1).permute(0, 2, 1)\n            x = self.norm(x)  # B L C\n            x = x.view(B, H // 8, W // 8,\n                       self.num_features).permute(0, 3, 1, 2)  # B C H W\n\n        else:\n            for layer in self.layers:\n                x = layer(x)\n            x = self.norm(x)  # B L C\n            x = x.view(B, H // 32, W // 32,\n                       self.num_features).permute(0, 3, 1, 2)  # B C H W\n            x = self.upsample(x)\n\n        return x\n\n    def forward(self, x):\n        x = self.forward_features(x)\n        x = self.head(x)\n        return x\n\n    def flops(self):\n        flops = 0\n        flops += self.patch_embed.flops()\n        for i, layer in enumerate(self.layers):\n            flops += layer.flops()\n        flops += self.num_features * self.patches_resolution[\n            0] * self.patches_resolution[1] // (2**self.num_layers)\n        flops += self.num_features * self.num_classes\n        return flops\n"
  },
  {
    "path": "projects/pose_anything/models/backbones/swin_utils.py",
    "content": "# --------------------------------------------------------\n# SimMIM\n# Copyright (c) 2021 Microsoft\n# Licensed under The MIT License [see LICENSE for details]\n# Written by Ze Liu\n# Modified by Zhenda Xie\n# --------------------------------------------------------\n\nimport numpy as np\nimport torch\nfrom scipy import interpolate\n\n\ndef load_pretrained(config, model, logger):\n    checkpoint = torch.load(config, map_location='cpu')\n    ckpt_model = checkpoint['model']\n    if any([True if 'encoder.' in k else False for k in ckpt_model.keys()]):\n        ckpt_model = {\n            k.replace('encoder.', ''): v\n            for k, v in ckpt_model.items() if k.startswith('encoder.')\n        }\n        print('Detect pre-trained model, remove [encoder.] prefix.')\n    else:\n        print('Detect non-pre-trained model, pass without doing anything.')\n\n    checkpoint = remap_pretrained_keys_swin(model, ckpt_model, logger)\n    msg = model.load_state_dict(ckpt_model, strict=False)\n    print(msg)\n\n    del checkpoint\n    torch.cuda.empty_cache()\n\n\ndef remap_pretrained_keys_swin(model, checkpoint_model, logger):\n    state_dict = model.state_dict()\n\n    # Geometric interpolation when pre-trained patch size mismatch with\n    # fine-tuned patch size\n    all_keys = list(checkpoint_model.keys())\n    for key in all_keys:\n        if 'relative_position_bias_table' in key:\n            relative_position_bias_table_pretrained = checkpoint_model[key]\n            relative_position_bias_table_current = state_dict[key]\n            L1, nH1 = relative_position_bias_table_pretrained.size()\n            L2, nH2 = relative_position_bias_table_current.size()\n            if nH1 != nH2:\n                print(f'Error in loading {key}, passing......')\n            else:\n                if L1 != L2:\n                    print(f'{key}: Interpolate relative_position_bias_table '\n                          f'using geo.')\n                    src_size = int(L1**0.5)\n                    dst_size = int(L2**0.5)\n\n                    def geometric_progression(a, r, n):\n                        return a * (1.0 - r**n) / (1.0 - r)\n\n                    left, right = 1.01, 1.5\n                    while right - left > 1e-6:\n                        q = (left + right) / 2.0\n                        gp = geometric_progression(1, q, src_size // 2)\n                        if gp > dst_size // 2:\n                            right = q\n                        else:\n                            left = q\n\n                    # if q > 1.090307:\n                    #     q = 1.090307\n\n                    dis = []\n                    cur = 1\n                    for i in range(src_size // 2):\n                        dis.append(cur)\n                        cur += q**(i + 1)\n\n                    r_ids = [-_ for _ in reversed(dis)]\n\n                    x = r_ids + [0] + dis\n                    y = r_ids + [0] + dis\n\n                    t = dst_size // 2.0\n                    dx = np.arange(-t, t + 0.1, 1.0)\n                    dy = np.arange(-t, t + 0.1, 1.0)\n\n                    print('Original positions = %s' % str(x))\n                    print('Target positions = %s' % str(dx))\n\n                    all_rel_pos_bias = []\n\n                    for i in range(nH1):\n                        z = relative_position_bias_table_pretrained[:, i].view(\n                            src_size, src_size).float().numpy()\n                        f_cubic = interpolate.interp2d(x, y, z, kind='cubic')\n                        all_rel_pos_bias.append(\n                            torch.Tensor(f_cubic(dx,\n                                                 dy)).contiguous().view(-1, 1).\n                            to(relative_position_bias_table_pretrained.device))\n\n                    new_rel_pos_bias = torch.cat(all_rel_pos_bias, dim=-1)\n                    checkpoint_model[key] = new_rel_pos_bias\n\n    # delete relative_position_index since we always re-init it\n    relative_position_index_keys = [\n        k for k in checkpoint_model.keys() if 'relative_position_index' in k\n    ]\n    for k in relative_position_index_keys:\n        del checkpoint_model[k]\n\n    # delete relative_coords_table since we always re-init it\n    relative_coords_table_keys = [\n        k for k in checkpoint_model.keys() if 'relative_coords_table' in k\n    ]\n    for k in relative_coords_table_keys:\n        del checkpoint_model[k]\n\n    # re-map keys due to name change\n    rpe_mlp_keys = [k for k in checkpoint_model.keys() if 'rpe_mlp' in k]\n    for k in rpe_mlp_keys:\n        checkpoint_model[k.replace('rpe_mlp',\n                                   'cpb_mlp')] = checkpoint_model.pop(k)\n\n    # delete attn_mask since we always re-init it\n    attn_mask_keys = [k for k in checkpoint_model.keys() if 'attn_mask' in k]\n    for k in attn_mask_keys:\n        del checkpoint_model[k]\n\n    return checkpoint_model\n"
  },
  {
    "path": "projects/pose_anything/models/detectors/__init__.py",
    "content": "from .pam import PoseAnythingModel\n\n__all__ = ['PoseAnythingModel']\n"
  },
  {
    "path": "projects/pose_anything/models/detectors/pam.py",
    "content": "import math\nfrom abc import ABCMeta\n\nimport cv2\nimport mmcv\nimport numpy as np\nimport torch\nfrom mmcv import imshow, imwrite\nfrom mmengine.model import BaseModel\n\nfrom mmpose.models import builder\nfrom mmpose.registry import MODELS\nfrom ..backbones.swin_utils import load_pretrained\n\n\n@MODELS.register_module()\nclass PoseAnythingModel(BaseModel, metaclass=ABCMeta):\n    \"\"\"Few-shot keypoint detectors.\n\n    Args:\n        keypoint_head (dict): Keypoint head to process feature.\n        encoder_config (dict): Config for encoder. Default: None.\n        pretrained (str): Path to the pretrained models.\n        train_cfg (dict): Config for training. Default: None.\n        test_cfg (dict): Config for testing. Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 keypoint_head,\n                 encoder_config,\n                 pretrained=False,\n                 train_cfg=None,\n                 test_cfg=None):\n        super().__init__()\n        self.backbone, self.backbone_type = self.init_backbone(\n            pretrained, encoder_config)\n        self.keypoint_head = builder.build_head(keypoint_head)\n        self.keypoint_head.init_weights()\n        self.train_cfg = train_cfg\n        self.test_cfg = test_cfg\n        self.target_type = test_cfg.get('target_type',\n                                        'GaussianHeatMap')  # GaussianHeatMap\n\n    def init_backbone(self, pretrained, encoder_config):\n        if 'swin' in pretrained:\n            encoder_sample = builder.build_backbone(encoder_config)\n            if '.pth' in pretrained:\n                load_pretrained(pretrained, encoder_sample, logger=None)\n            backbone = 'swin'\n        elif 'dino' in pretrained:\n            if 'dinov2' in pretrained:\n                repo = 'facebookresearch/dinov2'\n                backbone = 'dinov2'\n            else:\n                repo = 'facebookresearch/dino:main'\n                backbone = 'dino'\n            encoder_sample = torch.hub.load(repo, pretrained)\n        elif 'resnet' in pretrained:\n            pretrained = 'torchvision://resnet50'\n            encoder_config = dict(type='ResNet', depth=50, out_indices=(3, ))\n            encoder_sample = builder.build_backbone(encoder_config)\n            encoder_sample.init_weights(pretrained)\n            backbone = 'resnet50'\n        else:\n            raise NotImplementedError(f'backbone {pretrained} not supported')\n        return encoder_sample, backbone\n\n    @property\n    def with_keypoint(self):\n        \"\"\"Check if has keypoint_head.\"\"\"\n        return hasattr(self, 'keypoint_head')\n\n    def init_weights(self, pretrained=None):\n        \"\"\"Weight initialization for model.\"\"\"\n        self.backbone.init_weights(pretrained)\n        self.encoder_query.init_weights(pretrained)\n        self.keypoint_head.init_weights()\n\n    def forward(self,\n                img_s,\n                img_q,\n                target_s=None,\n                target_weight_s=None,\n                target_q=None,\n                target_weight_q=None,\n                img_metas=None,\n                return_loss=True,\n                **kwargs):\n        \"\"\"Defines the computation performed at every call.\"\"\"\n\n        if return_loss:\n            return self.forward_train(img_s, target_s, target_weight_s, img_q,\n                                      target_q, target_weight_q, img_metas,\n                                      **kwargs)\n        else:\n            return self.forward_test(img_s, target_s, target_weight_s, img_q,\n                                     target_q, target_weight_q, img_metas,\n                                     **kwargs)\n\n    def forward_dummy(self, img_s, target_s, target_weight_s, img_q, target_q,\n                      target_weight_q, img_metas, **kwargs):\n        return self.predict(img_s, target_s, target_weight_s, img_q, img_metas)\n\n    def forward_train(self, img_s, target_s, target_weight_s, img_q, target_q,\n                      target_weight_q, img_metas, **kwargs):\n        \"\"\"Defines the computation performed at every call when training.\"\"\"\n        bs, _, h, w = img_q.shape\n\n        output, initial_proposals, similarity_map, mask_s = self.predict(\n            img_s, target_s, target_weight_s, img_q, img_metas)\n\n        # parse the img meta to get the target keypoints\n        target_keypoints = self.parse_keypoints_from_img_meta(\n            img_metas, output.device, keyword='query')\n        target_sizes = torch.tensor([img_q.shape[-2],\n                                     img_q.shape[-1]]).unsqueeze(0).repeat(\n                                         img_q.shape[0], 1, 1)\n\n        # if return loss\n        losses = dict()\n        if self.with_keypoint:\n            keypoint_losses = self.keypoint_head.get_loss(\n                output, initial_proposals, similarity_map, target_keypoints,\n                target_q, target_weight_q * mask_s, target_sizes)\n            losses.update(keypoint_losses)\n            keypoint_accuracy = self.keypoint_head.get_accuracy(\n                output[-1],\n                target_keypoints,\n                target_weight_q * mask_s,\n                target_sizes,\n                height=h)\n            losses.update(keypoint_accuracy)\n\n        return losses\n\n    def forward_test(self,\n                     img_s,\n                     target_s,\n                     target_weight_s,\n                     img_q,\n                     target_q,\n                     target_weight_q,\n                     img_metas=None,\n                     **kwargs):\n        \"\"\"Defines the computation performed at every call when testing.\"\"\"\n        batch_size, _, img_height, img_width = img_q.shape\n\n        output, initial_proposals, similarity_map, _ = self.predict(\n            img_s, target_s, target_weight_s, img_q, img_metas)\n        predicted_pose = output[-1].detach().cpu().numpy(\n        )  # [bs, num_query, 2]\n\n        result = {}\n        if self.with_keypoint:\n            keypoint_result = self.keypoint_head.decode(\n                img_metas, predicted_pose, img_size=[img_width, img_height])\n            result.update(keypoint_result)\n\n        result.update({\n            'points':\n            torch.cat((initial_proposals, output.squeeze(1)),\n                      dim=0).cpu().numpy()\n        })\n        result.update({'sample_image_file': img_metas[0]['sample_image_file']})\n\n        return result\n\n    def predict(self, img_s, target_s, target_weight_s, img_q, img_metas=None):\n\n        batch_size, _, img_height, img_width = img_q.shape\n        assert [\n            i['sample_skeleton'][0] != i['query_skeleton'] for i in img_metas\n        ]\n        skeleton = [i['sample_skeleton'][0] for i in img_metas]\n\n        feature_q, feature_s = self.extract_features(img_s, img_q)\n\n        mask_s = target_weight_s[0]\n        for target_weight in target_weight_s:\n            mask_s = mask_s * target_weight\n\n        output, initial_proposals, similarity_map = self.keypoint_head(\n            feature_q, feature_s, target_s, mask_s, skeleton)\n\n        return output, initial_proposals, similarity_map, mask_s\n\n    def extract_features(self, img_s, img_q):\n        if self.backbone_type == 'swin':\n            feature_q = self.backbone.forward_features(img_q)  # [bs, C, h, w]\n            feature_s = [self.backbone.forward_features(img) for img in img_s]\n        elif self.backbone_type == 'dino':\n            batch_size, _, img_height, img_width = img_q.shape\n            feature_q = self.backbone.get_intermediate_layers(img_q, n=1)\n            ([0][:, 1:].reshape(batch_size, img_height // 8, img_width // 8,\n                                -1).permute(0, 3, 1, 2))  # [bs, 3, h, w]\n            feature_s = [\n                self.backbone.get_intermediate_layers(\n                    img, n=1)[0][:, 1:].reshape(batch_size, img_height // 8,\n                                                img_width // 8,\n                                                -1).permute(0, 3, 1, 2)\n                for img in img_s\n            ]\n        elif self.backbone_type == 'dinov2':\n            batch_size, _, img_height, img_width = img_q.shape\n            feature_q = self.backbone.get_intermediate_layers(\n                img_q, n=1, reshape=True)[0]  # [bs, c, h, w]\n            feature_s = [\n                self.backbone.get_intermediate_layers(img, n=1,\n                                                      reshape=True)[0]\n                for img in img_s\n            ]\n        else:\n            feature_s = [self.backbone(img) for img in img_s]\n            feature_q = self.encoder_query(img_q)\n\n        return feature_q, feature_s\n\n    def parse_keypoints_from_img_meta(self, img_meta, device, keyword='query'):\n        \"\"\"Parse keypoints from the img_meta.\n\n        Args:\n            img_meta (dict): Image meta info.\n            device (torch.device): Device of the output keypoints.\n            keyword (str): 'query' or 'sample'. Default: 'query'.\n\n        Returns:\n            Tensor: Keypoints coordinates of query images.\n        \"\"\"\n\n        if keyword == 'query':\n            query_kpt = torch.stack([\n                torch.tensor(info[f'{keyword}_joints_3d']).to(device)\n                for info in img_meta\n            ],\n                                    dim=0)[:, :, :2]  # [bs, num_query, 2]\n        else:\n            query_kpt = []\n            for info in img_meta:\n                if isinstance(info[f'{keyword}_joints_3d'][0], torch.Tensor):\n                    samples = torch.stack(info[f'{keyword}_joints_3d'])\n                else:\n                    samples = np.array(info[f'{keyword}_joints_3d'])\n                query_kpt.append(torch.tensor(samples).to(device)[:, :, :2])\n            query_kpt = torch.stack(\n                query_kpt, dim=0)  # [bs, , num_samples, num_query, 2]\n        return query_kpt\n\n    # UNMODIFIED\n    def show_result(self,\n                    img,\n                    result,\n                    skeleton=None,\n                    kpt_score_thr=0.3,\n                    bbox_color='green',\n                    pose_kpt_color=None,\n                    pose_limb_color=None,\n                    radius=4,\n                    text_color=(255, 0, 0),\n                    thickness=1,\n                    font_scale=0.5,\n                    win_name='',\n                    show=False,\n                    wait_time=0,\n                    out_file=None):\n        \"\"\"Draw `result` over `img`.\n\n        Args:\n            img (str or Tensor): The image to be displayed.\n            result (list[dict]): The results to draw over `img`\n                (bbox_result, pose_result).\n            kpt_score_thr (float, optional): Minimum score of keypoints\n                to be shown. Default: 0.3.\n            bbox_color (str or tuple or :obj:`Color`): Color of bbox lines.\n            pose_kpt_color (np.array[Nx3]`): Color of N keypoints.\n                If None, do not draw keypoints.\n            pose_limb_color (np.array[Mx3]): Color of M limbs.\n                If None, do not draw limbs.\n            text_color (str or tuple or :obj:`Color`): Color of texts.\n            thickness (int): Thickness of lines.\n            font_scale (float): Font scales of texts.\n            win_name (str): The window name.\n            wait_time (int): Value of waitKey param.\n                Default: 0.\n            out_file (str or None): The filename to write the image.\n                Default: None.\n\n        Returns:\n            Tensor: Visualized img, only if not `show` or `out_file`.\n        \"\"\"\n\n        img = mmcv.imread(img)\n        img = img.copy()\n        img_h, img_w, _ = img.shape\n\n        bbox_result = []\n        pose_result = []\n        for res in result:\n            bbox_result.append(res['bbox'])\n            pose_result.append(res['keypoints'])\n\n        if len(bbox_result) > 0:\n            bboxes = np.vstack(bbox_result)\n            # draw bounding boxes\n            mmcv.imshow_bboxes(\n                img,\n                bboxes,\n                colors=bbox_color,\n                top_k=-1,\n                thickness=thickness,\n                show=False,\n                win_name=win_name,\n                wait_time=wait_time,\n                out_file=None)\n\n            for person_id, kpts in enumerate(pose_result):\n                # draw each point on image\n                if pose_kpt_color is not None:\n                    assert len(pose_kpt_color) == len(kpts), (\n                        len(pose_kpt_color), len(kpts))\n                    for kid, kpt in enumerate(kpts):\n                        x_coord, y_coord, kpt_score = int(kpt[0]), int(\n                            kpt[1]), kpt[2]\n                        if kpt_score > kpt_score_thr:\n                            img_copy = img.copy()\n                            r, g, b = pose_kpt_color[kid]\n                            cv2.circle(img_copy, (int(x_coord), int(y_coord)),\n                                       radius, (int(r), int(g), int(b)), -1)\n                            transparency = max(0, min(1, kpt_score))\n                            cv2.addWeighted(\n                                img_copy,\n                                transparency,\n                                img,\n                                1 - transparency,\n                                0,\n                                dst=img)\n\n                # draw limbs\n                if skeleton is not None and pose_limb_color is not None:\n                    assert len(pose_limb_color) == len(skeleton)\n                    for sk_id, sk in enumerate(skeleton):\n                        pos1 = (int(kpts[sk[0] - 1, 0]), int(kpts[sk[0] - 1,\n                                                                  1]))\n                        pos2 = (int(kpts[sk[1] - 1, 0]), int(kpts[sk[1] - 1,\n                                                                  1]))\n                        if (0 < pos1[0] < img_w and 0 < pos1[1] < img_h\n                                and 0 < pos2[0] < img_w and 0 < pos2[1] < img_h\n                                and kpts[sk[0] - 1, 2] > kpt_score_thr\n                                and kpts[sk[1] - 1, 2] > kpt_score_thr):\n                            img_copy = img.copy()\n                            X = (pos1[0], pos2[0])\n                            Y = (pos1[1], pos2[1])\n                            mX = np.mean(X)\n                            mY = np.mean(Y)\n                            length = ((Y[0] - Y[1])**2 + (X[0] - X[1])**2)**0.5\n                            angle = math.degrees(\n                                math.atan2(Y[0] - Y[1], X[0] - X[1]))\n                            stickwidth = 2\n                            polygon = cv2.ellipse2Poly(\n                                (int(mX), int(mY)),\n                                (int(length / 2), int(stickwidth)), int(angle),\n                                0, 360, 1)\n\n                            r, g, b = pose_limb_color[sk_id]\n                            cv2.fillConvexPoly(img_copy, polygon,\n                                               (int(r), int(g), int(b)))\n                            transparency = max(\n                                0,\n                                min(\n                                    1, 0.5 *\n                                    (kpts[sk[0] - 1, 2] + kpts[sk[1] - 1, 2])))\n                            cv2.addWeighted(\n                                img_copy,\n                                transparency,\n                                img,\n                                1 - transparency,\n                                0,\n                                dst=img)\n\n        show, wait_time = 1, 1\n        if show:\n            height, width = img.shape[:2]\n            max_ = max(height, width)\n\n            factor = min(1, 800 / max_)\n            enlarge = cv2.resize(\n                img, (0, 0),\n                fx=factor,\n                fy=factor,\n                interpolation=cv2.INTER_CUBIC)\n            imshow(enlarge, win_name, wait_time)\n\n        if out_file is not None:\n            imwrite(img, out_file)\n\n        return img\n"
  },
  {
    "path": "projects/pose_anything/models/keypoint_heads/__init__.py",
    "content": "from .head import PoseHead\n\n__all__ = ['PoseHead']\n"
  },
  {
    "path": "projects/pose_anything/models/keypoint_heads/head.py",
    "content": "from copy import deepcopy\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn import Conv2d, Linear\nfrom mmengine.model import xavier_init\nfrom models.utils import build_positional_encoding, build_transformer\n\n# from mmcv.cnn.bricks.transformer import build_positional_encoding\nfrom mmpose.evaluation import keypoint_pck_accuracy\nfrom mmpose.models import HEADS\nfrom mmpose.models.utils.ops import resize\n\n\ndef transform_preds(coords, center, scale, output_size, use_udp=False):\n    \"\"\"Get final keypoint predictions from heatmaps and apply scaling and\n    translation to map them back to the image.\n\n    Note:\n        num_keypoints: K\n\n    Args:\n        coords (np.ndarray[K, ndims]):\n\n            * If ndims=2, corrds are predicted keypoint location.\n            * If ndims=4, corrds are composed of (x, y, scores, tags)\n            * If ndims=5, corrds are composed of (x, y, scores, tags,\n              flipped_tags)\n\n        center (np.ndarray[2, ]): Center of the bounding box (x, y).\n        scale (np.ndarray[2, ]): Scale of the bounding box\n            wrt [width, height].\n        output_size (np.ndarray[2, ] | list(2,)): Size of the\n            destination heatmaps.\n        use_udp (bool): Use unbiased data processing\n\n    Returns:\n        np.ndarray: Predicted coordinates in the images.\n    \"\"\"\n    assert coords.shape[1] in (2, 4, 5)\n    assert len(center) == 2\n    assert len(scale) == 2\n    assert len(output_size) == 2\n\n    # Recover the scale which is normalized by a factor of 200.\n    scale = scale * 200.0\n\n    if use_udp:\n        scale_x = scale[0] / (output_size[0] - 1.0)\n        scale_y = scale[1] / (output_size[1] - 1.0)\n    else:\n        scale_x = scale[0] / output_size[0]\n        scale_y = scale[1] / output_size[1]\n\n    target_coords = coords.copy()\n    target_coords[:, 0] = coords[:, 0] * scale_x + center[0] - scale[0] * 0.5\n    target_coords[:, 1] = coords[:, 1] * scale_y + center[1] - scale[1] * 0.5\n\n    return target_coords\n\n\ndef inverse_sigmoid(x, eps=1e-3):\n    x = x.clamp(min=0, max=1)\n    x1 = x.clamp(min=eps)\n    x2 = (1 - x).clamp(min=eps)\n    return torch.log(x1 / x2)\n\n\nclass TokenDecodeMLP(nn.Module):\n    \"\"\"The MLP used to predict coordinates from the support keypoints\n    tokens.\"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 hidden_channels,\n                 out_channels=2,\n                 num_layers=3):\n        super(TokenDecodeMLP, self).__init__()\n        layers = []\n        for i in range(num_layers):\n            if i == 0:\n                layers.append(nn.Linear(in_channels, hidden_channels))\n                layers.append(nn.GELU())\n            else:\n                layers.append(nn.Linear(hidden_channels, hidden_channels))\n                layers.append(nn.GELU())\n        layers.append(nn.Linear(hidden_channels, out_channels))\n        self.mlp = nn.Sequential(*layers)\n\n    def forward(self, x):\n        return self.mlp(x)\n\n\n@HEADS.register_module()\nclass PoseHead(nn.Module):\n    \"\"\"In two stage regression A3, the proposal generator are moved into\n    transformer.\n\n    All valid proposals will be added with an positional embedding to better\n    regress the location\n    \"\"\"\n\n    def __init__(self,\n                 in_channels,\n                 transformer=None,\n                 positional_encoding=dict(\n                     type='SinePositionalEncoding',\n                     num_feats=128,\n                     normalize=True),\n                 encoder_positional_encoding=dict(\n                     type='SinePositionalEncoding',\n                     num_feats=512,\n                     normalize=True),\n                 share_kpt_branch=False,\n                 num_decoder_layer=3,\n                 with_heatmap_loss=False,\n                 with_bb_loss=False,\n                 bb_temperature=0.2,\n                 heatmap_loss_weight=2.0,\n                 support_order_dropout=-1,\n                 extra=None,\n                 train_cfg=None,\n                 test_cfg=None):\n        super().__init__()\n\n        self.in_channels = in_channels\n        self.positional_encoding = build_positional_encoding(\n            positional_encoding)\n        self.encoder_positional_encoding = build_positional_encoding(\n            encoder_positional_encoding)\n        self.transformer = build_transformer(transformer)\n        self.embed_dims = self.transformer.d_model\n        self.with_heatmap_loss = with_heatmap_loss\n        self.with_bb_loss = with_bb_loss\n        self.bb_temperature = bb_temperature\n        self.heatmap_loss_weight = heatmap_loss_weight\n        self.support_order_dropout = support_order_dropout\n\n        assert 'num_feats' in positional_encoding\n        num_feats = positional_encoding['num_feats']\n        assert num_feats * 2 == self.embed_dims, 'embed_dims should' \\\n            (f' be exactly 2 times of '\n             f'num_feats. Found'\n             f' {self.embed_dims} '\n             f'and {num_feats}.')\n        if extra is not None and not isinstance(extra, dict):\n            raise TypeError('extra should be dict or None.')\n        \"\"\"Initialize layers of the transformer head.\"\"\"\n        self.input_proj = Conv2d(\n            self.in_channels, self.embed_dims, kernel_size=1)\n        self.query_proj = Linear(self.in_channels, self.embed_dims)\n        # Instantiate the proposal generator and subsequent keypoint branch.\n        kpt_branch = TokenDecodeMLP(\n            in_channels=self.embed_dims, hidden_channels=self.embed_dims)\n        if share_kpt_branch:\n            self.kpt_branch = nn.ModuleList(\n                [kpt_branch for i in range(num_decoder_layer)])\n        else:\n            self.kpt_branch = nn.ModuleList(\n                [deepcopy(kpt_branch) for i in range(num_decoder_layer)])\n\n        self.train_cfg = {} if train_cfg is None else train_cfg\n        self.test_cfg = {} if test_cfg is None else test_cfg\n        self.target_type = self.test_cfg.get('target_type', 'GaussianHeatMap')\n\n    def init_weights(self):\n        for m in self.modules():\n            if hasattr(m, 'weight') and m.weight.dim() > 1:\n                xavier_init(m, distribution='uniform')\n        \"\"\"Initialize weights of the transformer head.\"\"\"\n        # The initialization for transformer is important\n        self.transformer.init_weights()\n        # initialization for input_proj & prediction head\n        for mlp in self.kpt_branch:\n            nn.init.constant_(mlp.mlp[-1].weight.data, 0)\n            nn.init.constant_(mlp.mlp[-1].bias.data, 0)\n        nn.init.xavier_uniform_(self.input_proj.weight, gain=1)\n        nn.init.constant_(self.input_proj.bias, 0)\n\n        nn.init.xavier_uniform_(self.query_proj.weight, gain=1)\n        nn.init.constant_(self.query_proj.bias, 0)\n\n    def forward(self, x, feature_s, target_s, mask_s, skeleton):\n        \"\"\"\"Forward function for a single feature level.\n\n        Args:\n            x (Tensor): Input feature from backbone's single stage, shape\n                [bs, c, h, w].\n\n        Returns:\n            all_cls_scores (Tensor): Outputs from the classification head,\n                shape [nb_dec, bs, num_query, cls_out_channels]. Note\n                cls_out_channels should includes background.\n            all_bbox_preds (Tensor): Sigmoid outputs from the regression\n                head with normalized coordinate format (cx, cy, w, h).\n                Shape [nb_dec, bs, num_query, 4].\n        \"\"\"\n        # construct binary masks which used for the transformer.\n        # NOTE following the official DETR repo, non-zero values representing\n        # ignored positions, while zero values means valid positions.\n\n        # process query image feature\n        x = self.input_proj(x)\n        bs, dim, h, w = x.shape\n\n        # Disable the support keypoint positional embedding\n        support_order_embedding = x.new_zeros(\n            (bs, self.embed_dims, 1, target_s[0].shape[1])).to(torch.bool)\n\n        # Feature map pos embedding\n        masks = x.new_zeros(\n            (x.shape[0], x.shape[2], x.shape[3])).to(torch.bool)\n        pos_embed = self.positional_encoding(masks)\n\n        # process keypoint token feature\n        query_embed_list = []\n        for i, (feature, target) in enumerate(zip(feature_s, target_s)):\n            # resize the support feature back to the heatmap sizes.\n            resized_feature = resize(\n                input=feature,\n                size=target.shape[-2:],\n                mode='bilinear',\n                align_corners=False)\n            target = target / (\n                target.sum(dim=-1).sum(dim=-1)[:, :, None, None] + 1e-8)\n            support_keypoints = target.flatten(2) @ resized_feature.flatten(\n                2).permute(0, 2, 1)\n            query_embed_list.append(support_keypoints)\n\n        support_keypoints = torch.mean(torch.stack(query_embed_list, dim=0), 0)\n        support_keypoints = support_keypoints * mask_s\n        support_keypoints = self.query_proj(support_keypoints)\n        masks_query = (~mask_s.to(torch.bool)).squeeze(\n            -1)  # True indicating this query matched no actual joints.\n\n        # outs_dec: [nb_dec, bs, num_query, c]\n        # memory: [bs, c, h, w]\n        # x = Query image feature,\n        # support_keypoints = Support keypoint feature\n        outs_dec, initial_proposals, out_points, similarity_map = (\n            self.transformer(x, masks, support_keypoints, pos_embed,\n                             support_order_embedding, masks_query,\n                             self.positional_encoding, self.kpt_branch,\n                             skeleton))\n\n        output_kpts = []\n        for idx in range(outs_dec.shape[0]):\n            layer_delta_unsig = self.kpt_branch[idx](outs_dec[idx])\n            layer_outputs_unsig = layer_delta_unsig + inverse_sigmoid(\n                out_points[idx])\n            output_kpts.append(layer_outputs_unsig.sigmoid())\n\n        return torch.stack(\n            output_kpts, dim=0), initial_proposals, similarity_map\n\n    def get_loss(self, output, initial_proposals, similarity_map, target,\n                 target_heatmap, target_weight, target_sizes):\n        # Calculate top-down keypoint loss.\n        losses = dict()\n        # denormalize the predicted coordinates.\n        num_dec_layer, bs, nq = output.shape[:3]\n        target_sizes = target_sizes.to(output.device)  # [bs, 1, 2]\n        target = target / target_sizes\n        target = target[None, :, :, :].repeat(num_dec_layer, 1, 1, 1)\n\n        # set the weight for unset query point to be zero\n        normalizer = target_weight.squeeze(dim=-1).sum(dim=-1)  # [bs, ]\n        normalizer[normalizer == 0] = 1\n\n        # compute the heatmap loss\n        if self.with_heatmap_loss:\n            losses['heatmap_loss'] = self.heatmap_loss(\n                similarity_map, target_heatmap, target_weight,\n                normalizer) * self.heatmap_loss_weight\n\n        # compute l1 loss for initial_proposals\n        proposal_l1_loss = F.l1_loss(\n            initial_proposals, target[0], reduction='none')\n        proposal_l1_loss = proposal_l1_loss.sum(\n            dim=-1, keepdim=False) * target_weight.squeeze(dim=-1)\n        proposal_l1_loss = proposal_l1_loss.sum(\n            dim=-1, keepdim=False) / normalizer  # [bs, ]\n        losses['proposal_loss'] = proposal_l1_loss.sum() / bs\n\n        # compute l1 loss for each layer\n        for idx in range(num_dec_layer):\n            layer_output, layer_target = output[idx], target[idx]\n            l1_loss = F.l1_loss(\n                layer_output, layer_target, reduction='none')  # [bs, query, 2]\n            l1_loss = l1_loss.sum(\n                dim=-1, keepdim=False) * target_weight.squeeze(\n                    dim=-1)  # [bs, query]\n            # normalize the loss for each sample with the number of visible\n            # joints\n            l1_loss = l1_loss.sum(dim=-1, keepdim=False) / normalizer  # [bs, ]\n            losses['l1_loss' + '_layer' + str(idx)] = l1_loss.sum() / bs\n\n        return losses\n\n    def get_max_coords(self, heatmap, heatmap_size=64):\n        B, C, H, W = heatmap.shape\n        heatmap = heatmap.view(B, C, -1)\n        max_cor = heatmap.argmax(dim=2)\n        row, col = torch.floor(max_cor / heatmap_size), max_cor % heatmap_size\n        support_joints = torch.cat((row.unsqueeze(-1), col.unsqueeze(-1)),\n                                   dim=-1)\n        return support_joints\n\n    def heatmap_loss(self, similarity_map, target_heatmap, target_weight,\n                     normalizer):\n        # similarity_map: [bs, num_query, h, w]\n        # target_heatmap: [bs, num_query, sh, sw]\n        # target_weight: [bs, num_query, 1]\n\n        # preprocess the similarity_map\n        h, w = similarity_map.shape[-2:]\n        # similarity_map = torch.clamp(similarity_map, 0.0, None)\n        similarity_map = similarity_map.sigmoid()\n\n        target_heatmap = F.interpolate(\n            target_heatmap, size=(h, w), mode='bilinear')\n        target_heatmap = (target_heatmap /\n                          (target_heatmap.max(dim=-1)[0].max(dim=-1)[0] +\n                           1e-10)[:, :, None, None]\n                          )  # make sure sum of each query is 1\n\n        l2_loss = F.mse_loss(\n            similarity_map, target_heatmap, reduction='none')  # bs, nq, h, w\n        l2_loss = l2_loss * target_weight[:, :, :, None]  # bs, nq, h, w\n        l2_loss = l2_loss.flatten(2, 3).sum(-1) / (h * w)  # bs, nq\n        l2_loss = l2_loss.sum(-1) / normalizer  # bs,\n\n        return l2_loss.mean()\n\n    def get_accuracy(self,\n                     output,\n                     target,\n                     target_weight,\n                     target_sizes,\n                     height=256):\n        \"\"\"Calculate accuracy for top-down keypoint loss.\n\n        Args:\n            output (torch.Tensor[NxKx2]): estimated keypoints in ABSOLUTE\n            coordinates.\n            target (torch.Tensor[NxKx2]): gt keypoints in ABSOLUTE coordinates.\n            target_weight (torch.Tensor[NxKx1]): Weights across different\n            joint types.\n            target_sizes (torch.Tensor[Nx2): shapes of the image.\n        \"\"\"\n        # NOTE: In POMNet, PCK is estimated on 1/8 resolution, which is\n        # slightly different here.\n\n        accuracy = dict()\n        output = output * float(height)\n        output, target, target_weight, target_sizes = (\n            output.detach().cpu().numpy(), target.detach().cpu().numpy(),\n            target_weight.squeeze(-1).long().detach().cpu().numpy(),\n            target_sizes.squeeze(1).detach().cpu().numpy())\n\n        _, avg_acc, _ = keypoint_pck_accuracy(\n            output,\n            target,\n            target_weight.astype(np.bool8),\n            thr=0.2,\n            normalize=target_sizes)\n        accuracy['acc_pose'] = float(avg_acc)\n\n        return accuracy\n\n    def decode(self, img_metas, output, img_size, **kwargs):\n        \"\"\"Decode the predicted keypoints from prediction.\n\n        Args:\n            img_metas (list(dict)): Information about data augmentation\n                By default this includes:\n                - \"image_file: path to the image file\n                - \"center\": center of the bbox\n                - \"scale\": scale of the bbox\n                - \"rotation\": rotation of the bbox\n                - \"bbox_score\": score of bbox\n            output (np.ndarray[N, K, H, W]): model predicted heatmaps.\n        \"\"\"\n        batch_size = len(img_metas)\n        W, H = img_size\n        output = output * np.array([\n            W, H\n        ])[None, None, :]  # [bs, query, 2], coordinates with recovered shapes.\n\n        if 'bbox_id' or 'query_bbox_id' in img_metas[0]:\n            bbox_ids = []\n        else:\n            bbox_ids = None\n\n        c = np.zeros((batch_size, 2), dtype=np.float32)\n        s = np.zeros((batch_size, 2), dtype=np.float32)\n        image_paths = []\n        score = np.ones(batch_size)\n        for i in range(batch_size):\n            c[i, :] = img_metas[i]['query_center']\n            s[i, :] = img_metas[i]['query_scale']\n            image_paths.append(img_metas[i]['query_image_file'])\n\n            if 'query_bbox_score' in img_metas[i]:\n                score[i] = np.array(\n                    img_metas[i]['query_bbox_score']).reshape(-1)\n            if 'bbox_id' in img_metas[i]:\n                bbox_ids.append(img_metas[i]['bbox_id'])\n            elif 'query_bbox_id' in img_metas[i]:\n                bbox_ids.append(img_metas[i]['query_bbox_id'])\n\n        preds = np.zeros(output.shape)\n        for idx in range(output.shape[0]):\n            preds[i] = transform_preds(\n                output[i],\n                c[i],\n                s[i], [W, H],\n                use_udp=self.test_cfg.get('use_udp', False))\n\n        all_preds = np.zeros((batch_size, preds.shape[1], 3), dtype=np.float32)\n        all_boxes = np.zeros((batch_size, 6), dtype=np.float32)\n        all_preds[:, :, 0:2] = preds[:, :, 0:2]\n        all_preds[:, :, 2:3] = 1.0\n        all_boxes[:, 0:2] = c[:, 0:2]\n        all_boxes[:, 2:4] = s[:, 0:2]\n        all_boxes[:, 4] = np.prod(s * 200.0, axis=1)\n        all_boxes[:, 5] = score\n\n        result = {}\n\n        result['preds'] = all_preds\n        result['boxes'] = all_boxes\n        result['image_paths'] = image_paths\n        result['bbox_ids'] = bbox_ids\n\n        return result\n"
  },
  {
    "path": "projects/pose_anything/models/utils/__init__.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom .builder import (build_backbone, build_linear_layer,\n                      build_positional_encoding, build_transformer)\nfrom .encoder_decoder import EncoderDecoder\nfrom .positional_encoding import (LearnedPositionalEncoding,\n                                  SinePositionalEncoding)\nfrom .transformer import (DetrTransformerDecoder, DetrTransformerDecoderLayer,\n                          DetrTransformerEncoder, DynamicConv)\n\n__all__ = [\n    'build_transformer',\n    'build_backbone',\n    'build_linear_layer',\n    'build_positional_encoding',\n    'DetrTransformerDecoderLayer',\n    'DetrTransformerDecoder',\n    'DetrTransformerEncoder',\n    'LearnedPositionalEncoding',\n    'SinePositionalEncoding',\n    'EncoderDecoder',\n    'DynamicConv',\n]\n"
  },
  {
    "path": "projects/pose_anything/models/utils/builder.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport torch.nn as nn\nfrom mmengine import build_from_cfg\n\nfrom mmpose.registry import Registry\n\nTRANSFORMER = Registry('Transformer')\nBACKBONES = Registry('BACKBONES')\nPOSITIONAL_ENCODING = Registry('position encoding')\nLINEAR_LAYERS = Registry('linear layers')\n\n\ndef build_positional_encoding(cfg, default_args=None):\n    \"\"\"Build backbone.\"\"\"\n    return build_from_cfg(cfg, POSITIONAL_ENCODING, default_args)\n\n\ndef build_backbone(cfg, default_args=None):\n    \"\"\"Build backbone.\"\"\"\n    return build_from_cfg(cfg, BACKBONES, default_args)\n\n\ndef build_transformer(cfg, default_args=None):\n    \"\"\"Builder for Transformer.\"\"\"\n    return build_from_cfg(cfg, TRANSFORMER, default_args)\n\n\nLINEAR_LAYERS.register_module('Linear', module=nn.Linear)\n\n\ndef build_linear_layer(cfg, *args, **kwargs):\n    \"\"\"Build linear layer.\n    Args:\n        cfg (None or dict): The linear layer config, which should contain:\n            - type (str): Layer type.\n            - layer args: Args needed to instantiate an linear layer.\n        args (argument list): Arguments passed to the `__init__`\n            method of the corresponding linear layer.\n        kwargs (keyword arguments): Keyword arguments passed to the `__init__`\n            method of the corresponding linear layer.\n    Returns:\n        nn.Module: Created linear layer.\n    \"\"\"\n    if cfg is None:\n        cfg_ = dict(type='Linear')\n    else:\n        if not isinstance(cfg, dict):\n            raise TypeError('cfg must be a dict')\n        if 'type' not in cfg:\n            raise KeyError('the cfg dict must contain the key \"type\"')\n        cfg_ = cfg.copy()\n\n    layer_type = cfg_.pop('type')\n    if layer_type not in LINEAR_LAYERS:\n        raise KeyError(f'Unrecognized linear type {layer_type}')\n    else:\n        linear_layer = LINEAR_LAYERS.get(layer_type)\n\n    layer = linear_layer(*args, **kwargs, **cfg_)\n\n    return layer\n"
  },
  {
    "path": "projects/pose_anything/models/utils/encoder_decoder.py",
    "content": "import copy\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmengine.model import xavier_init\nfrom models.utils.builder import TRANSFORMER\nfrom torch import Tensor\n\n\ndef inverse_sigmoid(x, eps=1e-3):\n    x = x.clamp(min=0, max=1)\n    x1 = x.clamp(min=eps)\n    x2 = (1 - x).clamp(min=eps)\n    return torch.log(x1 / x2)\n\n\nclass MLP(nn.Module):\n    \"\"\"Very simple multi-layer perceptron (also called FFN)\"\"\"\n\n    def __init__(self, input_dim, hidden_dim, output_dim, num_layers):\n        super().__init__()\n        self.num_layers = num_layers\n        h = [hidden_dim] * (num_layers - 1)\n        self.layers = nn.ModuleList(\n            nn.Linear(n, k) for n, k in zip([input_dim] + h, h + [output_dim]))\n\n    def forward(self, x):\n        for i, layer in enumerate(self.layers):\n            x = F.gelu(layer(x)) if i < self.num_layers - 1 else layer(x)\n        return x\n\n\nclass ProposalGenerator(nn.Module):\n\n    def __init__(self, hidden_dim, proj_dim, dynamic_proj_dim):\n        super().__init__()\n        self.support_proj = nn.Linear(hidden_dim, proj_dim)\n        self.query_proj = nn.Linear(hidden_dim, proj_dim)\n        self.dynamic_proj = nn.Sequential(\n            nn.Linear(hidden_dim, dynamic_proj_dim), nn.ReLU(),\n            nn.Linear(dynamic_proj_dim, hidden_dim))\n        self.dynamic_act = nn.Tanh()\n\n    def forward(self, query_feat, support_feat, spatial_shape):\n        \"\"\"\n        Args:\n            support_feat: [query, bs, c]\n            query_feat: [hw, bs, c]\n            spatial_shape: h, w\n        \"\"\"\n        device = query_feat.device\n        _, bs, c = query_feat.shape\n        h, w = spatial_shape\n        side_normalizer = torch.tensor([w, h]).to(query_feat.device)[\n            None, None, :]  # [bs, query, 2], Normalize the coord to [0,1]\n\n        query_feat = query_feat.transpose(0, 1)\n        support_feat = support_feat.transpose(0, 1)\n        nq = support_feat.shape[1]\n\n        fs_proj = self.support_proj(support_feat)  # [bs, query, c]\n        fq_proj = self.query_proj(query_feat)  # [bs, hw, c]\n        pattern_attention = self.dynamic_act(\n            self.dynamic_proj(fs_proj))  # [bs, query, c]\n\n        fs_feat = (pattern_attention + 1) * fs_proj  # [bs, query, c]\n        similarity = torch.bmm(fq_proj,\n                               fs_feat.transpose(1, 2))  # [bs, hw, query]\n        similarity = similarity.transpose(1, 2).reshape(bs, nq, h, w)\n        grid_y, grid_x = torch.meshgrid(\n            torch.linspace(\n                0.5, h - 0.5, h, dtype=torch.float32, device=device),  # (h, w)\n            torch.linspace(\n                0.5, w - 0.5, w, dtype=torch.float32, device=device))\n\n        # compute softmax and sum up\n        coord_grid = torch.stack([grid_x, grid_y],\n                                 dim=0).unsqueeze(0).unsqueeze(0).repeat(\n                                     bs, nq, 1, 1, 1)  # [bs, query, 2, h, w]\n        coord_grid = coord_grid.permute(0, 1, 3, 4, 2)  # [bs, query, h, w, 2]\n        similarity_softmax = similarity.flatten(2, 3).softmax(\n            dim=-1)  # [bs, query, hw]\n        similarity_coord_grid = similarity_softmax[:, :, :,\n                                                   None] * coord_grid.flatten(\n                                                       2, 3)\n        proposal_for_loss = similarity_coord_grid.sum(\n            dim=2, keepdim=False)  # [bs, query, 2]\n        proposal_for_loss = proposal_for_loss / side_normalizer\n\n        max_pos = torch.argmax(\n            similarity.reshape(bs, nq, -1), dim=-1,\n            keepdim=True)  # (bs, nq, 1)\n        max_mask = F.one_hot(max_pos, num_classes=w * h)  # (bs, nq, 1, w*h)\n        max_mask = max_mask.reshape(bs, nq, w,\n                                    h).type(torch.float)  # (bs, nq, w, h)\n        local_max_mask = F.max_pool2d(\n            input=max_mask, kernel_size=3, stride=1,\n            padding=1).reshape(bs, nq, w * h, 1)  # (bs, nq, w*h, 1)\n        '''\n        proposal = (similarity_coord_grid * local_max_mask).sum(\n            dim=2, keepdim=False) / torch.count_nonzero(\n                local_max_mask, dim=2)\n        '''\n        # first, extract the local probability map with the mask\n        local_similarity_softmax = similarity_softmax[:, :, :,\n                                                      None] * local_max_mask\n\n        # then, re-normalize the local probability map\n        local_similarity_softmax = local_similarity_softmax / (\n            local_similarity_softmax.sum(dim=-2, keepdim=True) + 1e-10\n        )  # [bs, nq, w*h, 1]\n\n        # point-wise mulplication of local probability map and coord grid\n        proposals = local_similarity_softmax * coord_grid.flatten(\n            2, 3)  # [bs, nq, w*h, 2]\n\n        # sum the mulplication to obtain the final coord proposals\n        proposals = proposals.sum(dim=2) / side_normalizer  # [bs, nq, 2]\n\n        return proposal_for_loss, similarity, proposals\n\n\n@TRANSFORMER.register_module()\nclass EncoderDecoder(nn.Module):\n\n    def __init__(self,\n                 d_model=256,\n                 nhead=8,\n                 num_encoder_layers=3,\n                 num_decoder_layers=3,\n                 graph_decoder=None,\n                 dim_feedforward=2048,\n                 dropout=0.1,\n                 activation='relu',\n                 normalize_before=False,\n                 similarity_proj_dim=256,\n                 dynamic_proj_dim=128,\n                 return_intermediate_dec=True,\n                 look_twice=False,\n                 detach_support_feat=False):\n        super().__init__()\n\n        self.d_model = d_model\n        self.nhead = nhead\n\n        encoder_layer = TransformerEncoderLayer(d_model, nhead,\n                                                dim_feedforward, dropout,\n                                                activation, normalize_before)\n        encoder_norm = nn.LayerNorm(d_model) if normalize_before else None\n        self.encoder = TransformerEncoder(encoder_layer, num_encoder_layers,\n                                          encoder_norm)\n\n        decoder_layer = GraphTransformerDecoderLayer(d_model, nhead,\n                                                     dim_feedforward, dropout,\n                                                     activation,\n                                                     normalize_before,\n                                                     graph_decoder)\n        decoder_norm = nn.LayerNorm(d_model)\n        self.decoder = GraphTransformerDecoder(\n            d_model,\n            decoder_layer,\n            num_decoder_layers,\n            decoder_norm,\n            return_intermediate=return_intermediate_dec,\n            look_twice=look_twice,\n            detach_support_feat=detach_support_feat)\n\n        self.proposal_generator = ProposalGenerator(\n            hidden_dim=d_model,\n            proj_dim=similarity_proj_dim,\n            dynamic_proj_dim=dynamic_proj_dim)\n\n    def init_weights(self):\n        # follow the official DETR to init parameters\n        for m in self.modules():\n            if hasattr(m, 'weight') and m.weight.dim() > 1:\n                xavier_init(m, distribution='uniform')\n\n    def forward(self,\n                src,\n                mask,\n                support_embed,\n                pos_embed,\n                support_order_embed,\n                query_padding_mask,\n                position_embedding,\n                kpt_branch,\n                skeleton,\n                return_attn_map=False):\n\n        bs, c, h, w = src.shape\n\n        src = src.flatten(2).permute(2, 0, 1)\n        pos_embed = pos_embed.flatten(2).permute(2, 0, 1)\n        support_order_embed = support_order_embed.flatten(2).permute(2, 0, 1)\n        pos_embed = torch.cat((pos_embed, support_order_embed))\n        query_embed = support_embed.transpose(0, 1)\n        mask = mask.flatten(1)\n\n        query_embed, refined_support_embed = self.encoder(\n            src,\n            query_embed,\n            src_key_padding_mask=mask,\n            query_key_padding_mask=query_padding_mask,\n            pos=pos_embed)\n\n        # Generate initial proposals and corresponding positional embedding.\n        initial_proposals_for_loss, similarity_map, initial_proposals = (\n            self.proposal_generator(\n                query_embed, refined_support_embed, spatial_shape=[h, w]))\n        initial_position_embedding = position_embedding.forward_coordinates(\n            initial_proposals)\n\n        outs_dec, out_points, attn_maps = self.decoder(\n            refined_support_embed,\n            query_embed,\n            memory_key_padding_mask=mask,\n            pos=pos_embed,\n            query_pos=initial_position_embedding,\n            tgt_key_padding_mask=query_padding_mask,\n            position_embedding=position_embedding,\n            initial_proposals=initial_proposals,\n            kpt_branch=kpt_branch,\n            skeleton=skeleton,\n            return_attn_map=return_attn_map)\n\n        return outs_dec.transpose(\n            1, 2), initial_proposals_for_loss, out_points, similarity_map\n\n\nclass GraphTransformerDecoder(nn.Module):\n\n    def __init__(self,\n                 d_model,\n                 decoder_layer,\n                 num_layers,\n                 norm=None,\n                 return_intermediate=False,\n                 look_twice=False,\n                 detach_support_feat=False):\n        super().__init__()\n        self.layers = _get_clones(decoder_layer, num_layers)\n        self.num_layers = num_layers\n        self.norm = norm\n        self.return_intermediate = return_intermediate\n        self.ref_point_head = MLP(d_model, d_model, d_model, num_layers=2)\n        self.look_twice = look_twice\n        self.detach_support_feat = detach_support_feat\n\n    def forward(self,\n                support_feat,\n                query_feat,\n                tgt_mask=None,\n                memory_mask=None,\n                tgt_key_padding_mask=None,\n                memory_key_padding_mask=None,\n                pos=None,\n                query_pos=None,\n                position_embedding=None,\n                initial_proposals=None,\n                kpt_branch=None,\n                skeleton=None,\n                return_attn_map=False):\n        \"\"\"\n        position_embedding: Class used to compute positional embedding\n        initial_proposals: [bs, nq, 2], normalized coordinates of initial\n        proposals kpt_branch: MLP used to predict the offsets for each query.\n        \"\"\"\n\n        refined_support_feat = support_feat\n        intermediate = []\n        attn_maps = []\n        bi = initial_proposals.detach()\n        bi_tag = initial_proposals.detach()\n        query_points = [initial_proposals.detach()]\n\n        tgt_key_padding_mask_remove_all_true = tgt_key_padding_mask.clone().to(\n            tgt_key_padding_mask.device)\n        tgt_key_padding_mask_remove_all_true[\n            tgt_key_padding_mask.logical_not().sum(dim=-1) == 0, 0] = False\n\n        for layer_idx, layer in enumerate(self.layers):\n            if layer_idx == 0:  # use positional embedding form initial\n                # proposals\n                query_pos_embed = query_pos.transpose(0, 1)\n            else:\n                # recalculate the positional embedding\n                query_pos_embed = position_embedding.forward_coordinates(bi)\n                query_pos_embed = query_pos_embed.transpose(0, 1)\n            query_pos_embed = self.ref_point_head(query_pos_embed)\n\n            if self.detach_support_feat:\n                refined_support_feat = refined_support_feat.detach()\n\n            refined_support_feat, attn_map = layer(\n                refined_support_feat,\n                query_feat,\n                tgt_mask=tgt_mask,\n                memory_mask=memory_mask,\n                tgt_key_padding_mask=tgt_key_padding_mask_remove_all_true,\n                memory_key_padding_mask=memory_key_padding_mask,\n                pos=pos,\n                query_pos=query_pos_embed,\n                skeleton=skeleton)\n\n            if self.return_intermediate:\n                intermediate.append(self.norm(refined_support_feat))\n\n            if return_attn_map:\n                attn_maps.append(attn_map)\n\n            # update the query coordinates\n            delta_bi = kpt_branch[layer_idx](\n                refined_support_feat.transpose(0, 1))\n\n            # Prediction loss\n            if self.look_twice:\n                bi_pred = self.update(bi_tag, delta_bi)\n                bi_tag = self.update(bi, delta_bi)\n            else:\n                bi_tag = self.update(bi, delta_bi)\n                bi_pred = bi_tag\n\n            bi = bi_tag.detach()\n            query_points.append(bi_pred)\n\n        if self.norm is not None:\n            refined_support_feat = self.norm(refined_support_feat)\n            if self.return_intermediate:\n                intermediate.pop()\n                intermediate.append(refined_support_feat)\n\n        if self.return_intermediate:\n            return torch.stack(intermediate), query_points, attn_maps\n\n        return refined_support_feat.unsqueeze(0), query_points, attn_maps\n\n    def update(self, query_coordinates, delta_unsig):\n        query_coordinates_unsigmoid = inverse_sigmoid(query_coordinates)\n        new_query_coordinates = query_coordinates_unsigmoid + delta_unsig\n        new_query_coordinates = new_query_coordinates.sigmoid()\n        return new_query_coordinates\n\n\nclass GraphTransformerDecoderLayer(nn.Module):\n\n    def __init__(self,\n                 d_model,\n                 nhead,\n                 dim_feedforward=2048,\n                 dropout=0.1,\n                 activation='relu',\n                 normalize_before=False,\n                 graph_decoder=None):\n\n        super().__init__()\n        self.graph_decoder = graph_decoder\n        self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)\n        self.multihead_attn = nn.MultiheadAttention(\n            d_model * 2, nhead, dropout=dropout, vdim=d_model)\n        self.choker = nn.Linear(in_features=2 * d_model, out_features=d_model)\n        # Implementation of Feedforward model\n        if self.graph_decoder is None:\n            self.ffn1 = nn.Linear(d_model, dim_feedforward)\n            self.ffn2 = nn.Linear(dim_feedforward, d_model)\n        elif self.graph_decoder == 'pre':\n            self.ffn1 = GCNLayer(d_model, dim_feedforward, batch_first=False)\n            self.ffn2 = nn.Linear(dim_feedforward, d_model)\n        elif self.graph_decoder == 'post':\n            self.ffn1 = nn.Linear(d_model, dim_feedforward)\n            self.ffn2 = GCNLayer(dim_feedforward, d_model, batch_first=False)\n        else:\n            self.ffn1 = GCNLayer(d_model, dim_feedforward, batch_first=False)\n            self.ffn2 = GCNLayer(dim_feedforward, d_model, batch_first=False)\n\n        self.dropout = nn.Dropout(dropout)\n        self.norm1 = nn.LayerNorm(d_model)\n        self.norm2 = nn.LayerNorm(d_model)\n        self.norm3 = nn.LayerNorm(d_model)\n        self.dropout1 = nn.Dropout(dropout)\n        self.dropout2 = nn.Dropout(dropout)\n        self.dropout3 = nn.Dropout(dropout)\n\n        self.activation = _get_activation_fn(activation)\n        self.normalize_before = normalize_before\n\n    def with_pos_embed(self, tensor, pos: Optional[Tensor]):\n        return tensor if pos is None else tensor + pos\n\n    def forward(self,\n                refined_support_feat,\n                refined_query_feat,\n                tgt_mask: Optional[Tensor] = None,\n                memory_mask: Optional[Tensor] = None,\n                tgt_key_padding_mask: Optional[Tensor] = None,\n                memory_key_padding_mask: Optional[Tensor] = None,\n                pos: Optional[Tensor] = None,\n                query_pos: Optional[Tensor] = None,\n                skeleton: Optional[list] = None):\n\n        q = k = self.with_pos_embed(\n            refined_support_feat,\n            query_pos + pos[refined_query_feat.shape[0]:])\n        tgt2 = self.self_attn(\n            q,\n            k,\n            value=refined_support_feat,\n            attn_mask=tgt_mask,\n            key_padding_mask=tgt_key_padding_mask)[0]\n\n        refined_support_feat = refined_support_feat + self.dropout1(tgt2)\n        refined_support_feat = self.norm1(refined_support_feat)\n\n        # concatenate the positional embedding with the content feature,\n        # instead of direct addition\n        cross_attn_q = torch.cat(\n            (refined_support_feat,\n             query_pos + pos[refined_query_feat.shape[0]:]),\n            dim=-1)\n        cross_attn_k = torch.cat(\n            (refined_query_feat, pos[:refined_query_feat.shape[0]]), dim=-1)\n\n        tgt2, attn_map = self.multihead_attn(\n            query=cross_attn_q,\n            key=cross_attn_k,\n            value=refined_query_feat,\n            attn_mask=memory_mask,\n            key_padding_mask=memory_key_padding_mask)\n\n        refined_support_feat = refined_support_feat + self.dropout2(\n            self.choker(tgt2))\n        refined_support_feat = self.norm2(refined_support_feat)\n        if self.graph_decoder is not None:\n            num_pts, b, c = refined_support_feat.shape\n            adj = adj_from_skeleton(\n                num_pts=num_pts,\n                skeleton=skeleton,\n                mask=tgt_key_padding_mask,\n                device=refined_support_feat.device)\n            if self.graph_decoder == 'pre':\n                tgt2 = self.ffn2(\n                    self.dropout(\n                        self.activation(self.ffn1(refined_support_feat, adj))))\n            elif self.graph_decoder == 'post':\n                tgt2 = self.ffn2(\n                    self.dropout(\n                        self.activation(self.ffn1(refined_support_feat))), adj)\n            else:\n                tgt2 = self.ffn2(\n                    self.dropout(\n                        self.activation(self.ffn1(refined_support_feat, adj))),\n                    adj)\n        else:\n            tgt2 = self.ffn2(\n                self.dropout(self.activation(self.ffn1(refined_support_feat))))\n        refined_support_feat = refined_support_feat + self.dropout3(tgt2)\n        refined_support_feat = self.norm3(refined_support_feat)\n\n        return refined_support_feat, attn_map\n\n\nclass TransformerEncoder(nn.Module):\n\n    def __init__(self, encoder_layer, num_layers, norm=None):\n        super().__init__()\n        self.layers = _get_clones(encoder_layer, num_layers)\n        self.num_layers = num_layers\n        self.norm = norm\n\n    def forward(self,\n                src,\n                query,\n                mask: Optional[Tensor] = None,\n                src_key_padding_mask: Optional[Tensor] = None,\n                query_key_padding_mask: Optional[Tensor] = None,\n                pos: Optional[Tensor] = None):\n        # src: [hw, bs, c]\n        # query: [num_query, bs, c]\n        # mask: None by default\n        # src_key_padding_mask: [bs, hw]\n        # query_key_padding_mask: [bs, nq]\n        # pos: [hw, bs, c]\n\n        # organize the input\n        # implement the attention mask to mask out the useless points\n        n, bs, c = src.shape\n        src_cat = torch.cat((src, query), dim=0)  # [hw + nq, bs, c]\n        mask_cat = torch.cat((src_key_padding_mask, query_key_padding_mask),\n                             dim=1)  # [bs, hw+nq]\n        output = src_cat\n\n        for layer in self.layers:\n            output = layer(\n                output,\n                query_length=n,\n                src_mask=mask,\n                src_key_padding_mask=mask_cat,\n                pos=pos)\n\n        if self.norm is not None:\n            output = self.norm(output)\n\n        # resplit the output into src and query\n        refined_query = output[n:, :, :]  # [nq, bs, c]\n        output = output[:n, :, :]  # [n, bs, c]\n\n        return output, refined_query\n\n\nclass TransformerEncoderLayer(nn.Module):\n\n    def __init__(self,\n                 d_model,\n                 nhead,\n                 dim_feedforward=2048,\n                 dropout=0.1,\n                 activation='relu',\n                 normalize_before=False):\n        super().__init__()\n        self.self_attn = nn.MultiheadAttention(d_model, nhead, dropout=dropout)\n        # Implementation of Feedforward model\n        self.linear1 = nn.Linear(d_model, dim_feedforward)\n        self.dropout = nn.Dropout(dropout)\n        self.linear2 = nn.Linear(dim_feedforward, d_model)\n\n        self.norm1 = nn.LayerNorm(d_model)\n        self.norm2 = nn.LayerNorm(d_model)\n        self.dropout1 = nn.Dropout(dropout)\n        self.dropout2 = nn.Dropout(dropout)\n\n        self.activation = _get_activation_fn(activation)\n        self.normalize_before = normalize_before\n\n    def with_pos_embed(self, tensor, pos: Optional[Tensor]):\n        return tensor if pos is None else tensor + pos\n\n    def forward(self,\n                src,\n                query_length,\n                src_mask: Optional[Tensor] = None,\n                src_key_padding_mask: Optional[Tensor] = None,\n                pos: Optional[Tensor] = None):\n        src = self.with_pos_embed(src, pos)\n        q = k = src\n        # NOTE: compared with original implementation, we add positional\n        # embedding into the VALUE.\n        src2 = self.self_attn(\n            q,\n            k,\n            value=src,\n            attn_mask=src_mask,\n            key_padding_mask=src_key_padding_mask)[0]\n        src = src + self.dropout1(src2)\n        src = self.norm1(src)\n        src2 = self.linear2(self.dropout(self.activation(self.linear1(src))))\n        src = src + self.dropout2(src2)\n        src = self.norm2(src)\n        return src\n\n\ndef adj_from_skeleton(num_pts, skeleton, mask, device='cuda'):\n    adj_mx = torch.empty(0, device=device)\n    batch_size = len(skeleton)\n    for b in range(batch_size):\n        edges = torch.tensor(skeleton[b])\n        adj = torch.zeros(num_pts, num_pts, device=device)\n        adj[edges[:, 0], edges[:, 1]] = 1\n        adj_mx = torch.cat((adj_mx, adj.unsqueeze(0)), dim=0)\n    trans_adj_mx = torch.transpose(adj_mx, 1, 2)\n    cond = (trans_adj_mx > adj_mx).float()\n    adj = adj_mx + trans_adj_mx * cond - adj_mx * cond\n    adj = adj * ~mask[..., None] * ~mask[:, None]\n    adj = torch.nan_to_num(adj / adj.sum(dim=-1, keepdim=True))\n    adj = torch.stack((torch.diag_embed(~mask), adj), dim=1)\n    return adj\n\n\nclass GCNLayer(nn.Module):\n\n    def __init__(self,\n                 in_features,\n                 out_features,\n                 kernel_size=2,\n                 use_bias=True,\n                 activation=nn.ReLU(inplace=True),\n                 batch_first=True):\n        super(GCNLayer, self).__init__()\n        self.conv = nn.Conv1d(\n            in_features,\n            out_features * kernel_size,\n            kernel_size=1,\n            padding=0,\n            stride=1,\n            dilation=1,\n            bias=use_bias)\n        self.kernel_size = kernel_size\n        self.activation = activation\n        self.batch_first = batch_first\n\n    def forward(self, x, adj):\n        assert adj.size(1) == self.kernel_size\n        if not self.batch_first:\n            x = x.permute(1, 2, 0)\n        else:\n            x = x.transpose(1, 2)\n        x = self.conv(x)\n        b, kc, v = x.size()\n        x = x.view(b, self.kernel_size, kc // self.kernel_size, v)\n        x = torch.einsum('bkcv,bkvw->bcw', (x, adj))\n        if self.activation is not None:\n            x = self.activation(x)\n        if not self.batch_first:\n            x = x.permute(2, 0, 1)\n        else:\n            x = x.transpose(1, 2)\n        return x\n\n\ndef _get_clones(module, N):\n    return nn.ModuleList([copy.deepcopy(module) for i in range(N)])\n\n\ndef _get_activation_fn(activation):\n    \"\"\"Return an activation function given a string.\"\"\"\n    if activation == 'relu':\n        return F.relu\n    if activation == 'gelu':\n        return F.gelu\n    if activation == 'glu':\n        return F.glu\n    raise RuntimeError(F'activation should be relu/gelu, not {activation}.')\n\n\ndef clones(module, N):\n    return nn.ModuleList([copy.deepcopy(module) for _ in range(N)])\n"
  },
  {
    "path": "projects/pose_anything/models/utils/positional_encoding.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport math\n\nimport torch\nimport torch.nn as nn\nfrom mmengine.model import BaseModule\nfrom models.utils.builder import POSITIONAL_ENCODING\n\n\n# TODO: add an SinePositionalEncoding for coordinates input\n@POSITIONAL_ENCODING.register_module()\nclass SinePositionalEncoding(BaseModule):\n    \"\"\"Position encoding with sine and cosine functions.\n\n    See `End-to-End Object Detection with Transformers\n    <https://arxiv.org/pdf/2005.12872>`_ for details.\n\n    Args:\n        num_feats (int): The feature dimension for each position\n            along x-axis or y-axis. Note the final returned dimension\n            for each position is 2 times of this value.\n        temperature (int, optional): The temperature used for scaling\n            the position embedding. Defaults to 10000.\n        normalize (bool, optional): Whether to normalize the position\n            embedding. Defaults to False.\n        scale (float, optional): A scale factor that scales the position\n            embedding. The scale will be used only when `normalize` is True.\n            Defaults to 2*pi.\n        eps (float, optional): A value added to the denominator for\n            numerical stability. Defaults to 1e-6.\n        offset (float): offset add to embed when do the normalization.\n            Defaults to 0.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n            Default: None\n    \"\"\"\n\n    def __init__(self,\n                 num_feats,\n                 temperature=10000,\n                 normalize=False,\n                 scale=2 * math.pi,\n                 eps=1e-6,\n                 offset=0.,\n                 init_cfg=None):\n        super(SinePositionalEncoding, self).__init__(init_cfg)\n        if normalize:\n            assert isinstance(scale, (float, int)), \\\n                (f'when normalize is set, '\n                 f'scale should be provided and in float or int type, '\n                 f'found {type(scale)}')\n        self.num_feats = num_feats\n        self.temperature = temperature\n        self.normalize = normalize\n        self.scale = scale\n        self.eps = eps\n        self.offset = offset\n\n    def forward(self, mask):\n        \"\"\"Forward function for `SinePositionalEncoding`.\n\n        Args:\n            mask (Tensor): ByteTensor mask. Non-zero values representing\n                ignored positions, while zero values means valid positions\n                for this image. Shape [bs, h, w].\n\n        Returns:\n            pos (Tensor): Returned position embedding with shape\n                [bs, num_feats*2, h, w].\n        \"\"\"\n        # For convenience of exporting to ONNX, it's required to convert\n        # `masks` from bool to int.\n        mask = mask.to(torch.int)\n        not_mask = 1 - mask  # logical_not\n        y_embed = not_mask.cumsum(\n            1, dtype=torch.float32\n        )  # [bs, h, w], recording the y coordinate of each pixel\n        x_embed = not_mask.cumsum(2, dtype=torch.float32)\n        if self.normalize:  # default True\n            y_embed = (y_embed + self.offset) / \\\n                      (y_embed[:, -1:, :] + self.eps) * self.scale\n            x_embed = (x_embed + self.offset) / \\\n                      (x_embed[:, :, -1:] + self.eps) * self.scale\n        dim_t = torch.arange(\n            self.num_feats, dtype=torch.float32, device=mask.device)\n        dim_t = self.temperature**(2 * (dim_t // 2) / self.num_feats)\n        pos_x = x_embed[:, :, :, None] / dim_t  # [bs, h, w, num_feats]\n        pos_y = y_embed[:, :, :, None] / dim_t\n        # use `view` instead of `flatten` for dynamically exporting to ONNX\n        B, H, W = mask.size()\n        pos_x = torch.stack(\n            (pos_x[:, :, :, 0::2].sin(), pos_x[:, :, :, 1::2].cos()),\n            dim=4).view(B, H, W, -1)  # [bs, h, w, num_feats]\n        pos_y = torch.stack(\n            (pos_y[:, :, :, 0::2].sin(), pos_y[:, :, :, 1::2].cos()),\n            dim=4).view(B, H, W, -1)\n        pos = torch.cat((pos_y, pos_x), dim=3).permute(0, 3, 1, 2)\n        return pos\n\n    def forward_coordinates(self, coord):\n        \"\"\"Forward function for normalized coordinates input with the shape of.\n\n        [ bs, kpt, 2] return: pos (Tensor): position embedding with the shape\n        of.\n\n        [bs, kpt, num_feats*2]\n        \"\"\"\n        x_embed, y_embed = coord[:, :, 0], coord[:, :, 1]  # [bs, kpt]\n        x_embed = x_embed * self.scale  # [bs, kpt]\n        y_embed = y_embed * self.scale\n\n        dim_t = torch.arange(\n            self.num_feats, dtype=torch.float32, device=coord.device)\n        dim_t = self.temperature**(2 * (dim_t // 2) / self.num_feats)\n\n        pos_x = x_embed[:, :, None] / dim_t  # [bs, kpt, num_feats]\n        pos_y = y_embed[:, :, None] / dim_t  # [bs, kpt, num_feats]\n        bs, kpt, _ = pos_x.shape\n\n        pos_x = torch.stack((pos_x[:, :, 0::2].sin(), pos_x[:, :, 1::2].cos()),\n                            dim=3).view(bs, kpt, -1)  # [bs, kpt, num_feats]\n        pos_y = torch.stack((pos_y[:, :, 0::2].sin(), pos_y[:, :, 1::2].cos()),\n                            dim=3).view(bs, kpt, -1)  # [bs, kpt, num_feats]\n        pos = torch.cat((pos_y, pos_x), dim=2)  # [bs, kpt, num_feats * 2]\n\n        return pos\n\n    def __repr__(self):\n        \"\"\"str: a string that describes the module\"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(num_feats={self.num_feats}, '\n        repr_str += f'temperature={self.temperature}, '\n        repr_str += f'normalize={self.normalize}, '\n        repr_str += f'scale={self.scale}, '\n        repr_str += f'eps={self.eps})'\n        return repr_str\n\n\n@POSITIONAL_ENCODING.register_module()\nclass LearnedPositionalEncoding(BaseModule):\n    \"\"\"Position embedding with learnable embedding weights.\n\n    Args:\n        num_feats (int): The feature dimension for each position\n            along x-axis or y-axis. The final returned dimension for\n            each position is 2 times of this value.\n        row_num_embed (int, optional): The dictionary size of row embeddings.\n            Default 50.\n        col_num_embed (int, optional): The dictionary size of col embeddings.\n            Default 50.\n        init_cfg (dict or list[dict], optional): Initialization config dict.\n    \"\"\"\n\n    def __init__(self,\n                 num_feats,\n                 row_num_embed=50,\n                 col_num_embed=50,\n                 init_cfg=dict(type='Uniform', layer='Embedding')):\n        super(LearnedPositionalEncoding, self).__init__(init_cfg)\n        self.row_embed = nn.Embedding(row_num_embed, num_feats)\n        self.col_embed = nn.Embedding(col_num_embed, num_feats)\n        self.num_feats = num_feats\n        self.row_num_embed = row_num_embed\n        self.col_num_embed = col_num_embed\n\n    def forward(self, mask):\n        \"\"\"Forward function for `LearnedPositionalEncoding`.\n\n        Args:\n            mask (Tensor): ByteTensor mask. Non-zero values representing\n                ignored positions, while zero values means valid positions\n                for this image. Shape [bs, h, w].\n\n        Returns:\n            pos (Tensor): Returned position embedding with shape\n                [bs, num_feats*2, h, w].\n        \"\"\"\n        h, w = mask.shape[-2:]\n        x = torch.arange(w, device=mask.device)\n        y = torch.arange(h, device=mask.device)\n        x_embed = self.col_embed(x)\n        y_embed = self.row_embed(y)\n        pos = torch.cat(\n            (x_embed.unsqueeze(0).repeat(h, 1, 1), y_embed.unsqueeze(1).repeat(\n                1, w, 1)),\n            dim=-1).permute(2, 0,\n                            1).unsqueeze(0).repeat(mask.shape[0], 1, 1, 1)\n        return pos\n\n    def __repr__(self):\n        \"\"\"str: a string that describes the module\"\"\"\n        repr_str = self.__class__.__name__\n        repr_str += f'(num_feats={self.num_feats}, '\n        repr_str += f'row_num_embed={self.row_num_embed}, '\n        repr_str += f'col_num_embed={self.col_num_embed})'\n        return repr_str\n"
  },
  {
    "path": "projects/pose_anything/models/utils/transformer.py",
    "content": "import torch\nimport torch.nn as nn\nfrom mmcv.cnn import build_activation_layer, build_norm_layer\nfrom mmcv.cnn.bricks.transformer import (BaseTransformerLayer,\n                                         TransformerLayerSequence,\n                                         build_transformer_layer_sequence)\nfrom mmengine.model import BaseModule, xavier_init\nfrom mmengine.registry import MODELS\n\n\n@MODELS.register_module()\nclass Transformer(BaseModule):\n    \"\"\"Implements the DETR transformer. Following the official DETR\n    implementation, this module copy-paste from torch.nn.Transformer with\n    modifications:\n\n        * positional encodings are passed in MultiheadAttention\n        * extra LN at the end of encoder is removed\n        * decoder returns a stack of activations from all decoding layers\n    See `paper: End-to-End Object Detection with Transformers\n    <https://arxiv.org/pdf/2005.12872>`_ for details.\n    Args:\n        encoder (`mmcv.ConfigDict` | Dict): Config of\n            TransformerEncoder. Defaults to None.\n        decoder ((`mmcv.ConfigDict` | Dict)): Config of\n            TransformerDecoder. Defaults to None\n        init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self, encoder=None, decoder=None, init_cfg=None):\n        super(Transformer, self).__init__(init_cfg=init_cfg)\n        self.encoder = build_transformer_layer_sequence(encoder)\n        self.decoder = build_transformer_layer_sequence(decoder)\n        self.embed_dims = self.encoder.embed_dims\n\n    def init_weights(self):\n        # follow the official DETR to init parameters\n        for m in self.modules():\n            if hasattr(m, 'weight') and m.weight.dim() > 1:\n                xavier_init(m, distribution='uniform')\n        self._is_init = True\n\n    def forward(self, x, mask, query_embed, pos_embed, mask_query):\n        \"\"\"Forward function for `Transformer`.\n        Args:\n            x (Tensor): Input query with shape [bs, c, h, w] where\n                c = embed_dims.\n            mask (Tensor): The key_padding_mask used for encoder and decoder,\n                with shape [bs, h, w].\n            query_embed (Tensor): The query embedding for decoder, with shape\n                [num_query, c].\n            pos_embed (Tensor): The positional encoding for encoder and\n                decoder, with the same shape as `x`.\n        Returns:\n            tuple[Tensor]: results of decoder containing the following tensor.\n                - out_dec: Output from decoder. If return_intermediate_dec \\\n                      is True output has shape [num_dec_layers, bs,\n                      num_query, embed_dims], else has shape [1, bs, \\\n                      num_query, embed_dims].\n                - memory: Output results from encoder, with shape \\\n                      [bs, embed_dims, h, w].\n\n        Notes:\n            x: query image features with shape [bs, c, h, w]\n            mask: mask for x with shape [bs, h, w]\n            pos_embed: positional embedding for x with shape [bs, c, h, w]\n            query_embed: sample keypoint features with shape [bs, num_query, c]\n            mask_query: mask for query_embed with shape [bs, num_query]\n        Outputs:\n            out_dec: [num_layers, bs, num_query, c]\n            memory: [bs, c, h, w]\n\n        \"\"\"\n        bs, c, h, w = x.shape\n        # use `view` instead of `flatten` for dynamically exporting to ONNX\n        x = x.view(bs, c, -1).permute(2, 0, 1)  # [bs, c, h, w] -> [h*w, bs, c]\n        mask = mask.view(\n            bs, -1\n        )  # [bs, h, w] -> [bs, h*w] Note: this mask should be filled with\n        # False, since all images are with the same shape.\n        pos_embed = pos_embed.view(bs, c, -1).permute(\n            2, 0, 1)  # positional embeding for memory, i.e., the query.\n        memory = self.encoder(\n            query=x,\n            key=None,\n            value=None,\n            query_pos=pos_embed,\n            query_key_padding_mask=mask)  # output memory: [hw, bs, c]\n\n        query_embed = query_embed.permute(\n            1, 0, 2)  # [bs, num_query, c] -> [num_query, bs, c]\n        # target = torch.zeros_like(query_embed)\n        # out_dec: [num_layers, num_query, bs, c]\n        out_dec = self.decoder(\n            query=query_embed,\n            key=memory,\n            value=memory,\n            key_pos=pos_embed,\n            # query_pos=query_embed,\n            query_key_padding_mask=mask_query,\n            key_padding_mask=mask)\n        out_dec = out_dec.transpose(1, 2)  # [decoder_layer, bs, num_query, c]\n        memory = memory.permute(1, 2, 0).reshape(bs, c, h, w)\n        return out_dec, memory\n\n\n@MODELS.register_module()\nclass DetrTransformerDecoderLayer(BaseTransformerLayer):\n    \"\"\"Implements decoder layer in DETR transformer.\n\n    Args:\n        attn_cfgs (list[`mmcv.ConfigDict`] | list[dict] | dict )):\n            Configs for self_attention or cross_attention, the order\n            should be consistent with it in `operation_order`. If it is\n            a dict, it would be expand to the number of attention in\n            `operation_order`.\n        feedforward_channels (int): The hidden dimension for FFNs.\n        ffn_dropout (float): Probability of an element to be zeroed\n            in ffn. Default 0.0.\n        operation_order (tuple[str]): The execution order of operation\n            in transformer. Such as ('self_attn', 'norm', 'ffn', 'norm').\n            Default：None\n        act_cfg (dict): The activation config for FFNs. Default: `LN`\n        norm_cfg (dict): Config dict for normalization layer.\n            Default: `LN`.\n        ffn_num_fcs (int): The number of fully-connected layers in FFNs.\n            Default：2.\n    \"\"\"\n\n    def __init__(self,\n                 attn_cfgs,\n                 feedforward_channels,\n                 ffn_dropout=0.0,\n                 operation_order=None,\n                 act_cfg=dict(type='ReLU', inplace=True),\n                 norm_cfg=dict(type='LN'),\n                 ffn_num_fcs=2,\n                 **kwargs):\n        super(DetrTransformerDecoderLayer, self).__init__(\n            attn_cfgs=attn_cfgs,\n            feedforward_channels=feedforward_channels,\n            ffn_dropout=ffn_dropout,\n            operation_order=operation_order,\n            act_cfg=act_cfg,\n            norm_cfg=norm_cfg,\n            ffn_num_fcs=ffn_num_fcs,\n            **kwargs)\n        # assert len(operation_order) == 6\n        # assert set(operation_order) == set(\n        #     ['self_attn', 'norm', 'cross_attn', 'ffn'])\n\n\n@MODELS.register_module()\nclass DetrTransformerEncoder(TransformerLayerSequence):\n    \"\"\"TransformerEncoder of DETR.\n\n    Args:\n        post_norm_cfg (dict): Config of last normalization layer. Default：\n            `LN`. Only used when `self.pre_norm` is `True`\n    \"\"\"\n\n    def __init__(self, *args, post_norm_cfg=dict(type='LN'), **kwargs):\n        super(DetrTransformerEncoder, self).__init__(*args, **kwargs)\n        if post_norm_cfg is not None:\n            self.post_norm = build_norm_layer(\n                post_norm_cfg, self.embed_dims)[1] if self.pre_norm else None\n        else:\n            # assert not self.pre_norm, f'Use prenorm in ' \\\n            #                           f'{self.__class__.__name__},' \\\n            #                           f'Please specify post_norm_cfg'\n            self.post_norm = None\n\n    def forward(self, *args, **kwargs):\n        \"\"\"Forward function for `TransformerCoder`.\n\n        Returns:\n            Tensor: forwarded results with shape [num_query, bs, embed_dims].\n        \"\"\"\n        x = super(DetrTransformerEncoder, self).forward(*args, **kwargs)\n        if self.post_norm is not None:\n            x = self.post_norm(x)\n        return x\n\n\n@MODELS.register_module()\nclass DetrTransformerDecoder(TransformerLayerSequence):\n    \"\"\"Implements the decoder in DETR transformer.\n\n    Args:\n        return_intermediate (bool): Whether to return intermediate outputs.\n        post_norm_cfg (dict): Config of last normalization layer. Default：\n            `LN`.\n    \"\"\"\n\n    def __init__(self,\n                 *args,\n                 post_norm_cfg=dict(type='LN'),\n                 return_intermediate=False,\n                 **kwargs):\n\n        super(DetrTransformerDecoder, self).__init__(*args, **kwargs)\n        self.return_intermediate = return_intermediate\n        if post_norm_cfg is not None:\n            self.post_norm = build_norm_layer(post_norm_cfg,\n                                              self.embed_dims)[1]\n        else:\n            self.post_norm = None\n\n    def forward(self, query, *args, **kwargs):\n        \"\"\"Forward function for `TransformerDecoder`.\n        Args:\n            query (Tensor): Input query with shape\n                `(num_query, bs, embed_dims)`.\n        Returns:\n            Tensor: Results with shape [1, num_query, bs, embed_dims] when\n                return_intermediate is `False`, otherwise it has shape\n                [num_layers, num_query, bs, embed_dims].\n        \"\"\"\n        if not self.return_intermediate:\n            x = super().forward(query, *args, **kwargs)\n            if self.post_norm:\n                x = self.post_norm(x)[None]\n            return x\n\n        intermediate = []\n        for layer in self.layers:\n            query = layer(query, *args, **kwargs)\n            if self.return_intermediate:\n                if self.post_norm is not None:\n                    intermediate.append(self.post_norm(query))\n                else:\n                    intermediate.append(query)\n        return torch.stack(intermediate)\n\n\n@MODELS.register_module()\nclass DynamicConv(BaseModule):\n    \"\"\"Implements Dynamic Convolution.\n\n    This module generate parameters for each sample and\n    use bmm to implement 1*1 convolution. Code is modified\n    from the `official github repo <https://github.com/PeizeSun/\n    SparseR-CNN/blob/main/projects/SparseRCNN/sparsercnn/head.py#L258>`_ .\n    Args:\n        in_channels (int): The input feature channel.\n            Defaults to 256.\n        feat_channels (int): The inner feature channel.\n            Defaults to 64.\n        out_channels (int, optional): The output feature channel.\n            When not specified, it will be set to `in_channels`\n            by default\n        input_feat_shape (int): The shape of input feature.\n            Defaults to 7.\n        with_proj (bool): Project two-dimentional feature to\n            one-dimentional feature. Default to True.\n        act_cfg (dict): The activation config for DynamicConv.\n        norm_cfg (dict): Config dict for normalization layer. Default\n            layer normalization.\n        init_cfg (obj:`mmcv.ConfigDict`): The Config for initialization.\n            Default: None.\n    \"\"\"\n\n    def __init__(self,\n                 in_channels=256,\n                 feat_channels=64,\n                 out_channels=None,\n                 input_feat_shape=7,\n                 with_proj=True,\n                 act_cfg=dict(type='ReLU', inplace=True),\n                 norm_cfg=dict(type='LN'),\n                 init_cfg=None):\n        super(DynamicConv, self).__init__(init_cfg)\n        self.in_channels = in_channels\n        self.feat_channels = feat_channels\n        self.out_channels_raw = out_channels\n        self.input_feat_shape = input_feat_shape\n        self.with_proj = with_proj\n        self.act_cfg = act_cfg\n        self.norm_cfg = norm_cfg\n        self.out_channels = out_channels if out_channels else in_channels\n\n        self.num_params_in = self.in_channels * self.feat_channels\n        self.num_params_out = self.out_channels * self.feat_channels\n        self.dynamic_layer = nn.Linear(\n            self.in_channels, self.num_params_in + self.num_params_out)\n\n        self.norm_in = build_norm_layer(norm_cfg, self.feat_channels)[1]\n        self.norm_out = build_norm_layer(norm_cfg, self.out_channels)[1]\n\n        self.activation = build_activation_layer(act_cfg)\n\n        num_output = self.out_channels * input_feat_shape**2\n        if self.with_proj:\n            self.fc_layer = nn.Linear(num_output, self.out_channels)\n            self.fc_norm = build_norm_layer(norm_cfg, self.out_channels)[1]\n\n    def forward(self, param_feature, input_feature):\n        \"\"\"Forward function for `DynamicConv`.\n\n        Args:\n            param_feature (Tensor): The feature can be used\n                to generate the parameter, has shape\n                (num_all_proposals, in_channels).\n            input_feature (Tensor): Feature that\n                interact with parameters, has shape\n                (num_all_proposals, in_channels, H, W).\n        Returns:\n            Tensor: The output feature has shape\n            (num_all_proposals, out_channels).\n        \"\"\"\n        input_feature = input_feature.flatten(2).permute(2, 0, 1)\n\n        input_feature = input_feature.permute(1, 0, 2)\n        parameters = self.dynamic_layer(param_feature)\n\n        param_in = parameters[:, :self.num_params_in].view(\n            -1, self.in_channels, self.feat_channels)\n        param_out = parameters[:, -self.num_params_out:].view(\n            -1, self.feat_channels, self.out_channels)\n\n        # input_feature has shape (num_all_proposals, H*W, in_channels)\n        # param_in has shape (num_all_proposals, in_channels, feat_channels)\n        # feature has shape (num_all_proposals, H*W, feat_channels)\n        features = torch.bmm(input_feature, param_in)\n        features = self.norm_in(features)\n        features = self.activation(features)\n\n        # param_out has shape (batch_size, feat_channels, out_channels)\n        features = torch.bmm(features, param_out)\n        features = self.norm_out(features)\n        features = self.activation(features)\n\n        if self.with_proj:\n            features = features.flatten(1)\n            features = self.fc_layer(features)\n            features = self.fc_norm(features)\n            features = self.activation(features)\n\n        return features\n"
  },
  {
    "path": "projects/pose_anything/tools/visualization.py",
    "content": "import os\nimport random\n\nimport matplotlib.pyplot as plt\nimport numpy as np\n\nCOLORS = ([255, 0, 0], [255, 85, 0], [255, 170, 0], [255, 255,\n                                                     0], [170, 255,\n                                                          0], [85, 255,\n                                                               0], [0, 255, 0],\n          [0, 255, 85], [0, 255, 170], [0, 255,\n                                        255], [0, 170,\n                                               255], [0, 85, 255], [0, 0, 255],\n          [85, 0, 255], [170, 0, 255], [255, 0, 255], [255, 0,\n                                                       170], [255, 0,\n                                                              85], [255, 0, 0])\n\n\ndef plot_results(support_img,\n                 query_img,\n                 support_kp,\n                 support_w,\n                 query_kp,\n                 query_w,\n                 skeleton,\n                 initial_proposals,\n                 prediction,\n                 radius=6,\n                 out_dir='./heatmaps'):\n    img_names = [\n        img.split('_')[0] for img in os.listdir(out_dir)\n        if str_is_int(img.split('_')[0])\n    ]\n    if len(img_names) > 0:\n        name_idx = max([int(img_name) for img_name in img_names]) + 1\n    else:\n        name_idx = 0\n\n    h, w, c = support_img.shape\n    prediction = prediction[-1].cpu().numpy() * h\n    support_img = (support_img - np.min(support_img)) / (\n        np.max(support_img) - np.min(support_img))\n    query_img = (query_img - np.min(query_img)) / (\n        np.max(query_img) - np.min(query_img))\n\n    for index, (img, w, keypoint) in enumerate(\n            zip([support_img, query_img], [support_w, query_w],\n                [support_kp, prediction])):\n        f, axes = plt.subplots()\n        plt.imshow(img)\n        for k in range(keypoint.shape[0]):\n            if w[k] > 0:\n                kp = keypoint[k, :2]\n                c = (1, 0, 0, 0.75) if w[k] == 1 else (0, 0, 1, 0.6)\n                patch = plt.Circle(kp, radius, color=c)\n                axes.add_patch(patch)\n                axes.text(kp[0], kp[1], k)\n                plt.draw()\n        for limb_index, limb in enumerate(skeleton):\n            kp = keypoint[:, :2]\n            if limb_index > len(COLORS) - 1:\n                c = [x / 255 for x in random.sample(range(0, 255), 3)]\n            else:\n                c = [x / 255 for x in COLORS[limb_index]]\n            if w[limb[0]] > 0 and w[limb[1]] > 0:\n                patch = plt.Line2D([kp[limb[0], 0], kp[limb[1], 0]],\n                                   [kp[limb[0], 1], kp[limb[1], 1]],\n                                   linewidth=6,\n                                   color=c,\n                                   alpha=0.6)\n                axes.add_artist(patch)\n        plt.axis('off')  # command for hiding the axis.\n        name = 'support' if index == 0 else 'query'\n        plt.savefig(\n            f'./{out_dir}/{str(name_idx)}_{str(name)}.png',\n            bbox_inches='tight',\n            pad_inches=0)\n        if index == 1:\n            plt.show()\n        plt.clf()\n        plt.close('all')\n\n\ndef str_is_int(s):\n    try:\n        int(s)\n        return True\n    except ValueError:\n        return False\n"
  },
  {
    "path": "projects/rtmo/README.md",
    "content": "# RTMO: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/cc2b3657-ba2b-478a-b61d-2c0fb310515c\" style=\"width:350px\" /> <img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/94db75b7-3215-45b0-9f7e-203f31fcb263\" style=\"width:350px\" />\n\nRTMO is a one-stage pose estimation model that achieves performance comparable to RTMPose. It has the following key advantages:\n\n- **Faster inference speed when multiple people are present** - RTMO runs faster than RTMPose on images with more than 4 persons. This makes it well-suited for real-time multi-person pose estimation.\n- **No dependency on human detectors** - Since RTMO is a one-stage model, it does not rely on an auxiliary human detector. This simplifies the pipeline and deployment.\n\n👉🏼 TRY RTMO NOW\n\n```bash\npython demo/inferencer_demo.py $IMAGE --pose2d rtmo --vis-out-dir vis_results\n```\n\n**rtmlib demo**\n\n[rtmlib](https://github.com/Tau-J/rtmlib/tree/main) provides simple and easy-to-use API for inference with RTMPose models.\n\n- Support OpenCV/ONNXRuntime/OpenVINO inference and does not require Pytorch or MMCV.\n- Super user-friendly API for inference and visualization.\n- Support both CPU and GPU inference.\n- Automatically download onnx models from OpenMMLab model zoo.\n- Support all series of RTMPose models (RTMPose, DWPose, RTMO, RTMW etc.)\n\n## 📜 Introduction\n\nReal-time multi-person pose estimation presents significant challenges in balancing speed and precision. While two-stage top-down methods slow down as the number of people in the image increases, existing one-stage methods often fail to simultaneously deliver high accuracy and real-time performance. This paper introduces RTMO, a one-stage pose estimation framework that seamlessly integrates coordinate classification by representing keypoints using dual 1-D heatmaps within the YOLO architecture, achieving accuracy comparable to top-down methods while maintaining high speed. We propose a dynamic coordinate classifier and a tailored loss function for heatmap learning, specifically designed to address the incompatibilities between coordinate classification and dense prediction models. RTMO outperforms state-of-the-art one-stage pose estimators, achieving 1.1% higher AP on COCO while operating about 9 times faster with the same backbone. Our largest model, RTMO-l, attains 74.8% AP on COCO val2017 and 141 FPS on a single V100 GPU, demonstrating its efficiency and accuracy.\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/26127467/ad94c097-7d51-4b91-b885-d8605e22a0e6\" height=\"360px\" alt><br>\n\nRefer to [our paper](https://arxiv.org/abs/2312.07526) for more details.\n\n## 🎉 News\n\n- **`2023/12/13`**: The RTMO paper and models are released!\n\n## 🗂️ Model Zoo\n\n### Results on COCO val2017 dataset\n\n| Model                                                        | Train Set | Latency (ms) |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                             Download                             |\n| :----------------------------------------------------------- | :-------: | :----------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :--------------------------------------------------------------: |\n| [RTMO-s](/configs/body_2d_keypoint/rtmo/coco/rtmo-s_8xb32-600e_coco-640x640.py) |   COCO    |     8.9      | 0.677 |      0.878      |      0.737      | 0.715 |      0.908      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_coco-640x640-8db55a59_20231211.pth) |\n| [RTMO-m](/configs/body_2d_keypoint/rtmo/coco/rtmo-m_16xb16-600e_coco-640x640.py) |   COCO    |     12.4     | 0.709 |      0.890      |      0.778      | 0.747 |      0.920      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_coco-640x640-6f4e0306_20231211.pth) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/coco/rtmo-l_16xb16-600e_coco-640x640.py) |   COCO    |     19.1     | 0.724 |      0.899      |      0.788      | 0.762 |      0.927      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_coco-640x640-516a421f_20231211.pth) |\n| [RTMO-t](/configs/body_2d_keypoint/rtmo/body7/rtmo-t_8xb32-600e_body7-416x416.py) |   body7   |      -       | 0.574 |      0.803      |      0.613      | 0.611 |      0.836      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-t_8xb32-600e_body7-416x416-f48f75cb_20231219.pth) \\| [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-t_8xb32-600e_body7-416x416-f48f75cb_20231219.zip) |\n| [RTMO-s](/configs/body_2d_keypoint/rtmo/body7/rtmo-s_8xb32-600e_body7-640x640.py) |   body7   |     8.9      | 0.686 |      0.879      |      0.744      | 0.723 |      0.908      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-600e_body7-640x640-dac2bf74_20231211.pth) \\| [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-s_8xb32-600e_body7-640x640-dac2bf74_20231211.zip) |\n| [RTMO-m](/configs/body_2d_keypoint/rtmo/body7/rtmo-m_16xb16-600e_body7-640x640.py) |   body7   |     12.4     | 0.726 |      0.899      |      0.790      | 0.763 |      0.926      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-m_16xb16-600e_body7-640x640-39e78cc4_20231211.pth)  \\| [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-m_16xb16-600e_body7-640x640-39e78cc4_20231211.zip) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/body7/rtmo-l_16xb16-600e_body7-640x640.py) |   body7   |     19.1     | 0.748 |      0.911      |      0.813      | 0.786 |      0.939      | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-600e_body7-640x640-b37118ce_20231211.pth) \\| [onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmo/onnx_sdk/rtmo-l_16xb16-600e_body7-640x640-b37118ce_20231211.zip) |\n\n- The latency is evaluated on a single V100 GPU with ONNXRuntime backend.\n- \"body7\" refers to a combined dataset composed of [AI Challenger](https://github.com/AIChallenger/AI_Challenger_2017), [COCO](http://cocodataset.org/), [CrowdPose](https://github.com/Jeff-sjtu/CrowdPose), [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/), [MPII](http://human-pose.mpi-inf.mpg.de/), [PoseTrack18](https://posetrack.net/users/download.php) and [sub-JHMDB](http://jhmdb.is.tue.mpg.de/dataset).\n\n### Results on CrowdPose test dataset\n\n| Model                                                               | Train Set |  AP   | AP<sup>50</sup> | AP<sup>75</sup> | AP (E) | AP (M) | AP (H) |                                Download                                 |\n| :------------------------------------------------------------------ | :-------: | :---: | :-------------: | :-------------: | :----: | :----: | :----: | :---------------------------------------------------------------------: |\n| [RTMO-s](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-s_8xb32-700e_crowdpose-640x640.py) | CrowdPose | 0.673 |      0.882      |      0.729      | 0.737  | 0.682  | 0.591  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-s_8xb32-700e_crowdpose-640x640-79f81c0d_20231211.pth) |\n| [RTMO-m](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-m_16xb16-700e_crowdpose-640x640.py) | CrowdPose | 0.711 |      0.897      |      0.771      | 0.774  | 0.719  | 0.634  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rrtmo-m_16xb16-700e_crowdpose-640x640-0eaf670d_20231211.pth) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_crowdpose-640x640.py) | CrowdPose | 0.732 |      0.907      |      0.793      | 0.792  | 0.741  | 0.653  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_crowdpose-640x640-1008211f_20231211.pth) |\n| [RTMO-l](/configs/body_2d_keypoint/rtmo/crowdpose/rtmo-l_16xb16-700e_body7-crowdpose-640x640.py) |   body7   | 0.838 |      0.947      |      0.893      | 0.888  | 0.847  | 0.772  | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/rtmo/rtmo-l_16xb16-700e_body7-crowdpose-640x640-5bafdc11_20231219.pth) |\n\n## 🖥️ Train and Evaluation\n\n### Dataset Preparation\n\nPlease follow [this instruction](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html) to prepare the training and testing datasets.\n\n### Train\n\nUnder the root directory of mmpose, run the following command to train models:\n\n```sh\nsh tools/dist_train.sh $CONFIG $NUM_GPUS --work-dir $WORK_DIR --amp\n```\n\n- Automatic Mixed Precision (AMP) technique is used to reduce GPU memory consumption during training.\n\n### Evaluation\n\nUnder the root directory of mmpose, run the following command to evaluate models:\n\n```sh\nsh tools/dist_test.sh $CONFIG $PATH_TO_CHECKPOINT $NUM_GPUS\n```\n\nSee [here](https://mmpose.readthedocs.io/en/latest/user_guides/train_and_test.html) for more training and evaluation details.\n\n## 🛞 Deployment\n\n[MMDeploy](https://github.com/open-mmlab/mmdeploy) provides tools for easy deployment of RTMO models. [\\[Install Now\\]](https://mmdeploy.readthedocs.io/en/latest/get_started.html#installation)\n\n**⭕ Notice**:\n\n- PyTorch **1.12+** is required to export the ONNX model of RTMO!\n\n- MMDeploy v1.3.1+ is required to deploy RTMO.\n\n### ONNX Model Export\n\nUnder mmdeploy root, run:\n\n```sh\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_rtmo_onnxruntime_dynamic-640x640.py \\\n    $RTMO_CONFIG $RTMO_CHECKPOINT \\\n    $MMPOSE_ROOT/tests/data/coco/000000197388.jpg \\\n    --work-dir $WORK_DIR --dump-info \\\n    [--show] [--device $DEVICE]\n```\n\n### TensorRT Model Export\n\n[Install TensorRT](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/tensorrt.html#install-tensorrt) and [build custom ops](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/tensorrt.html#build-custom-ops) first.\n\nThen under mmdeploy root, run:\n\n```sh\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_rtmo_tensorrt-fp16_dynamic-640x640.py \\\n    $RTMO_CONFIG $RTMO_CHECKPOINT \\\n    $MMPOSE_ROOT/tests/data/coco/000000197388.jpg \\\n    --work-dir $WORK_DIR --dump-info \\\n    --device cuda:0 [--show]\n```\n\nThis conversion takes several minutes. GPU is required for TensorRT model exportation.\n\n## ⭐ Citation\n\nIf this project benefits your work, please kindly consider citing the original paper and MMPose:\n\n```bibtex\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n"
  },
  {
    "path": "projects/rtmpose/README.md",
    "content": "<div align=\"center\">\n  <img width=\"100%\" src=\"https://github.com/open-mmlab/mmpose/assets/13503330/5b637d76-41dd-4376-9a7f-854cd120799d\"/>\n</div>\n\n# RTMPose: Real-Time Multi-Person Pose Estimation toolkit based on MMPose\n\n> [RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose](https://arxiv.org/abs/2303.07399)\n\n<div align=\"center\">\n\nEnglish | [简体中文](README_CN.md)\n\n</div>\n\n______________________________________________________________________\n\n## Abstract\n\nRecent studies on 2D pose estimation have achieved excellent performance on public benchmarks, yet its application in the industrial community still suffers from heavy model parameters and high latency.\nIn order to bridge this gap, we empirically study five aspects that affect the performance of multi-person pose estimation algorithms: paradigm, backbone network, localization algorithm, training strategy, and deployment inference, and present a high-performance real-time multi-person pose estimation framework, **RTMPose**, based on MMPose.\nOur RTMPose-m achieves **75.8% AP** on COCO with **90+ FPS** on an Intel i7-11700 CPU and **430+ FPS** on an NVIDIA GTX 1660 Ti GPU.\nTo further evaluate RTMPose's capability in critical real-time applications, we also report the performance after deploying on the mobile device. Our RTMPose-s achieves **72.2% AP** on COCO with **70+ FPS** on a Snapdragon 865 chip, outperforming existing open-source libraries.\nWith the help of MMDeploy, our project supports various platforms like CPU, GPU, NVIDIA Jetson, and mobile devices and multiple inference backends such as ONNXRuntime, TensorRT, ncnn, etc.\n\n![rtmpose_intro](https://user-images.githubusercontent.com/13503330/219269619-935499e5-bdd9-49ea-8104-3c7796dbd862.png)\n\n______________________________________________________________________\n\n## 📄 Table of Contents\n\n- [🥳 🚀 What's New](#--whats-new-)\n- [📖 Introduction](#-introduction-)\n- [🙌 Community](#-community-)\n- [⚡ Pipeline Performance](#-pipeline-performance-)\n- [📊 Model Zoo](#-model-zoo-)\n- [👀 Visualization](#-visualization-)\n- [😎 Get Started](#-get-started-)\n- [👨‍🏫 How to Train](#-how-to-train-)\n- [🏗️ How to Deploy](#️-how-to-deploy-)\n- [📚 Common Usage](#️-common-usage-)\n  - [🚀 Inference Speed Test](#-inference-speed-test-)\n  - [📊 Model Test](#-model-test-)\n- [📜 Citation](#-citation-)\n\n## 🥳 🚀 What's New [🔝](#-table-of-contents)\n\n- Dec. 2023:\n  - Update RTMW models. The RTMW-l model achieves 70.1 mAP on COCO-Wholebody val set.\n- Sep. 2023:\n  - Add RTMW models trained on combined datasets. The alpha version of RTMW-x model achieves 70.2 mAP on COCO-Wholebody val set. You can try it [Here](https://openxlab.org.cn/apps/detail/mmpose/RTMPose). The technical report will be released soon.\n  - Add YOLOX and RTMDet models trained on HumanArt dataset.\n- Aug. 2023:\n  - Support distilled 133-keypoint WholeBody models powered by [DWPose](https://github.com/IDEA-Research/DWPose/tree/main).\n    - You can try DWPose/RTMPose with [sd-webui-controlnet](https://github.com/Mikubill/sd-webui-controlnet) now! Just update your sd-webui-controlnet >= v1.1237, then choose `dw_openpose_full` as preprocessor.\n    - You can try our DWPose with this [Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose) by choosing `wholebody`!\n- Jul. 2023:\n  - Add [Online RTMPose Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose).\n  - Support 17-keypoint Body models trained on Human-Art.\n- Jun. 2023:\n  - Release 26-keypoint Body models trained on combined datasets.\n- May. 2023:\n  - Exported SDK models (ONNX, TRT, ncnn, etc.) can be downloaded from [OpenMMLab Deploee](https://platform.openmmlab.com/deploee).\n  - [Online Conversion](https://platform.openmmlab.com/deploee/task-convert-list) of `.pth` models into SDK models (ONNX, TensorRT, ncnn, etc.).\n  - Add [code examples](./examples/) of RTMPose, such as:\n    - Pure Python inference without MMDeploy, MMCV etc.\n    - C++ examples with ONNXRuntime and TensorRT backends.\n    - Android examples with ncnn backend.\n  - Release Hand, Face, Body models trained on combined datasets.\n- Mar. 2023: RTMPose is released. RTMPose-m runs at 430+ FPS and achieves 75.8 mAP on COCO val set.\n\n## 📖 Introduction [🔝](#-table-of-contents)\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/221138554-110240d8-e887-4b9a-90b1-2fbdc982e9de.gif\" width=400 height=300/><img src=\"https://user-images.githubusercontent.com/13503330/221125176-85015a13-9648-4f0d-a17c-1cbb469efacf.gif\" width=250 height=300/><img src=\"https://user-images.githubusercontent.com/13503330/221125310-7eeb2212-907e-427f-97af-af799d70a4c5.gif\" width=250 height=300/>\n</div>\n\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/38aa345e-4ceb-4e73-bc37-5e082735e336\" width=450 height=300/><img src=\"https://user-images.githubusercontent.com/13503330/221125888-15c20faf-0ad5-4afb-828b-a71ccb064582.gif\" width=450 height=300/>\n</div>\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/2ecbf9f4-6963-4a14-9801-da10c0a65dac\" width=300 height=350/><img src=\"https://user-images.githubusercontent.com/13503330/221138017-10431ab4-e515-4c32-8fa7-8748e2d17a58.gif\" width=600 height=350/>\n</div>\n\n### ✨ Major Features\n\n- 🚀 **High efficiency and high accuracy**\n\n  | Model | AP(COCO) | CPU-FPS | GPU-FPS |\n  | :---: | :------: | :-----: | :-----: |\n  |   t   |   68.5   |  300+   |  940+   |\n  |   s   |   72.2   |  200+   |  710+   |\n  |   m   |   75.8   |   90+   |  430+   |\n  |   l   |   76.5   |   50+   |  280+   |\n  | l-384 |   78.3   |    -    |  160+   |\n\n- 🛠️ **Easy to deploy**\n\n  - Step-by-step deployment tutorials.\n  - Support various backends including\n    - ONNX\n    - TensorRT\n    - ncnn\n    - OpenVINO\n    - etc.\n  - Support various platforms including\n    - Linux\n    - Windows\n    - NVIDIA Jetson\n    - ARM\n    - etc.\n\n- 🏗️ **Design for practical applications**\n\n  - Pipeline inference API and SDK for\n    - Python\n    - C++\n    - C#\n    - JAVA\n    - etc.\n\n## 🙌 Community [🔝](#-table-of-contents)\n\nRTMPose is a long-term project dedicated to the training, optimization and deployment of high-performance real-time pose estimation algorithms in practical scenarios, so we are looking forward to the power from the community. Welcome to share the training configurations and tricks based on RTMPose in different business applications to help more community users!\n\n✨ ✨ ✨\n\n- **If you are a new user of RTMPose, we eagerly hope you can fill out this [Google Questionnaire](https://docs.google.com/forms/d/e/1FAIpQLSfzwWr3eNlDzhU98qzk2Eph44Zio6hi5r0iSwfO9wSARkHdWg/viewform?usp=sf_link)/[Chinese version](https://uua478.fanqier.cn/f/xxmynrki), it's very important for our work!**\n\n✨ ✨ ✨\n\nFeel free to join our community group for more help:\n\n- WeChat Group:\n\n<div align=left>\n<img src=\"https://user-images.githubusercontent.com/13503330/222647056-875bed70-85ec-455c-9016-c024772915c4.jpg\" width=200 />\n</div>\n\n- Discord Group:\n  - 🙌 https://discord.gg/raweFPmdzG 🙌\n\n## ⚡ Pipeline Performance [🔝](#-table-of-contents)\n\n**Notes**\n\n- Pipeline latency is tested under skip-frame settings, the detection interval is 5 frames by defaults.\n- Flip test is NOT used.\n- Env Setup:\n  - torch >= 1.7.1\n  - onnxruntime 1.12.1\n  - TensorRT 8.4.3.1\n  - ncnn 20221128\n  - cuDNN 8.3.2\n  - CUDA 11.3\n- **Updates**: We recommend you to try `Body8` models trained on combined datasets, see [here](#body-2d).\n\n| Detection Config                                                    | Pose Config                                                                   | Input Size<sup><br>(Det/Pose) | Model AP<sup><br>(COCO) | Pipeline AP<sup><br>(COCO) | Params (M)<sup><br>(Det/Pose) | Flops (G)<sup><br>(Det/Pose) | ORT-Latency(ms)<sup><br>(i7-11700) | TRT-FP16-Latency(ms)<sup><br>(GTX 1660Ti) |                                                                                                                                  Download                                                                                                                                  |\n| :------------------------------------------------------------------ | :---------------------------------------------------------------------------- | :---------------------------: | :---------------------: | :------------------------: | :---------------------------: | :--------------------------: | :--------------------------------: | :---------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-t](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>67.1       |            64.4            |         0.99<br/>3.34         |        0.31<br/>0.36         |               12.403               |                   2.467                   | [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.pth) |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-s](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>71.1       |            68.5            |         0.99<br/>5.47         |        0.31<br/>0.68         |               16.658               |                   2.730                   |  [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth)   |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>75.3       |            73.2            |        0.99<br/>13.59         |        0.31<br/>1.93         |               26.613               |                   4.312                   |  [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth)   |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>76.3       |            74.2            |        0.99<br/>27.66         |        0.31<br/>4.16         |               36.311               |                   4.644                   |  [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth)   |\n| [RTMDet-m](./rtmdet/person/rtmdet_m_640-8xb32_coco-person.py)       | [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |      640x640<br>256x192       |      62.5<br>75.3       |            75.7            |        24.66<br/>13.59        |        38.95<br/>1.93        |                 -                  |                   6.923                   |    [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth)    |\n| [RTMDet-m](./rtmdet/person/rtmdet_m_640-8xb32_coco-person.py)       | [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |      640x640<br>256x192       |      62.5<br>76.3       |            76.6            |        24.66<br/>27.66        |        38.95<br/>4.16        |                 -                  |                   7.204                   |    [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth)    |\n\n## 📊 Model Zoo [🔝](#-table-of-contents)\n\n**Notes**\n\n- Since all models are trained on multi-domain combined datasets for practical applications, results are **not** suitable for academic comparison.\n- More results of RTMPose on public benchmarks can refer to [Model Zoo](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html)\n- Flip test is used.\n- Inference speed measured on more hardware platforms can refer to [Benchmark](./benchmark/README.md)\n- If you have datasets you would like us to support, feel free to [contact us](https://docs.google.com/forms/d/e/1FAIpQLSfzwWr3eNlDzhU98qzk2Eph44Zio6hi5r0iSwfO9wSARkHdWg/viewform?usp=sf_link)/[联系我们](https://uua478.fanqier.cn/f/xxmynrki).\n\n### Body 2d\n\n#### 17 Keypoints\n\n- Keypoints are defined as [COCO](http://cocodataset.org/). For details please refer to the [meta info](/configs/_base_/datasets/coco.py).\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/2417e4f7-2203-468f-bad0-e7a6a6bf8251\" height=\"300px\">\n\n<details close>\n<summary><b>AIC+COCO</b></summary>\n\n|                                    Config                                     | Input Size | AP<sup><br>(COCO) | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                   Download                                                                    |\n| :---------------------------------------------------------------------------: | :--------: | :---------------: | :---------------------: | :-----------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   |       68.5        |          91.28          |        63.38        |        3.34        |       0.36        |                    3.20                     |                        1.06                        |                          9.02                           | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.pth) |\n| [RTMPose-s](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |       72.2        |          92.95          |        66.19        |        5.47        |       0.68        |                    4.48                     |                        1.39                        |                          13.89                          |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth)   |\n| [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |       75.8        |          94.13          |        68.53        |       13.59        |       1.93        |                    11.06                    |                        2.29                        |                          26.44                          |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth)   |\n| [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |       76.5        |          94.35          |        68.98        |       27.66        |       4.16        |                    18.85                    |                        3.46                        |                          45.37                          |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth)   |\n| [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py) |  384x288   |       77.0        |          94.32          |        69.85        |       13.72        |       4.33        |                    24.78                    |                        3.66                        |                            -                            |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-384x288-a62a0b32_20230228.pth)   |\n| [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py) |  384x288   |       77.3        |          94.54          |        70.14        |       27.79        |       9.35        |                      -                      |                        6.05                        |                            -                            |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-384x288-97d6cb0f_20230228.pth)   |\n\n</details>\n\n<details open>\n<summary><b>Body8</b></summary>\n\n- `*` denotes model trained on 7 public datasets:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [MS COCO](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n- `Body8` denotes the addition of the [OCHuman](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#ochuman) dataset, in addition to the 7 datasets mentioned above, for evaluation.\n\n|                                     Config                                      | Input Size | AP<sup><br>(COCO) | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                                                                                        Download                                                                                                                                        |\n| :-----------------------------------------------------------------------------: | :--------: | :---------------: | :---------------------: | :-----------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   |       65.9        |          91.44          |        63.18        |        3.34        |       0.36        |                    3.20                     |                        1.06                        |                          9.02                           | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7_420e-256x192-026a1439_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-body7_pt-body7_420e-256x192-026a1439_20230504.zip) |\n| [RTMPose-s\\*](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |       69.7        |          92.45          |        65.15        |        5.47        |       0.68        |                    4.48                     |                        1.39                        |                          13.89                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |       74.9        |          94.25          |        68.59        |       13.59        |       1.93        |                    11.06                    |                        2.29                        |                          26.44                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |       76.7        |          95.08          |        70.14        |       27.66        |       4.16        |                    18.85                    |                        3.46                        |                          45.37                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py) |  384x288   |       76.6        |          94.64          |        70.38        |       13.72        |       4.33        |                    24.78                    |                        3.66                        |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py) |  384x288   |       78.3        |          95.36          |        71.58        |       27.79        |       9.35        |                      -                      |                        6.05                        |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.zip) |\n| [RTMPose-x\\*](./rtmpose/body_2d_keypoint/rtmpose-x_8xb256-700e_coco-384x288.py) |  384x288   |       78.8        |            -            |          -          |       49.43        |       17.22       |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-body7_pt-body7_700e-384x288-71d7b7e9_20230629.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-x_simcc-body7_pt-body7_700e-384x288-71d7b7e9_20230629.zip) |\n\n</details>\n\n<details open>\n<summary><b>Human-Art</b></summary>\n\n- RTMPose for Human-Centric Artificial Scenes is supported by  [Human-Art](https://github.com/IDEA-Research/HumanArt)\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/685bc610-dd9e-4e6f-9c41-dbc8220584f4\" height=\"300px\">\n\nDetetors:\n\n|       Detection Config        | Input Size | Model AP<sup><br>(OneHand10K) | Flops<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |        Download        |\n| :---------------------------: | :--------: | :---------------------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :--------------------: |\n| [RTMDet-tiny](./rtmdet/person/rtmdet_tiny_8xb32-300e_humanart.py) |  640x640   |             46.6              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_tiny_8xb32-300e_humanart-7da5554e.pth) |\n| [RTMDet-s](./rtmdet/person/rtmdet_s_8xb32-300e_humanart.py) |  640x640   |             50.6              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_s_8xb32-300e_humanart-af5bd52d.pth) |\n| [YOLOX-nano](./yolox/humanart/yolox_nano_8xb8-300e_humanart.py) |  640x640   |             38.9              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_nano_8xb8-300e_humanart-40f6f0d0.pth) |\n| [YOLOX-tiny](./yolox/humanart/yolox_tiny_8xb8-300e_humanart.py) |  640x640   |             47.7              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_tiny_8xb8-300e_humanart-6f3252f9.pth) |\n| [YOLOX-s](./yolox/humanart/yolox_s_8xb8-300e_humanart.py) |  640x640   |             54.6              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_s_8xb8-300e_humanart-3ef259a7.pth) |\n| [YOLOX-m](./yolox/humanart/yolox_m_8xb8-300e_humanart.py) |  640x640   |             59.1              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_m_8xb8-300e_humanart-c2c7a14a.pth) |\n| [YOLOX-l](./yolox/humanart/yolox_l_8xb8-300e_humanart.py) |  640x640   |             60.2              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_l_8xb8-300e_humanart-ce1d7a62.pth) |\n| [YOLOX-x](./yolox/humanart/yolox_x_8xb8-300e_humanart.py) |  640x640   |             61.3              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_x_8xb8-300e_humanart-a39d44ed.pth) |\n\nPose Estimators:\n\n|                                     Config                                      | Input Size | AP<sup><br>(Human-Art GT) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                                                                                   Download                                                                                                                                   |\n| :-----------------------------------------------------------------------------: | :--------: | :-----------------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   |           65.5            |        3.34        |       0.36        |                    3.20                     |                        1.06                        |                          9.02                           | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.zip) |\n| [RTMPose-s\\*](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |           69.8            |        5.47        |       0.68        |                    4.48                     |                        1.39                        |                          13.89                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |           72.8            |       13.59        |       1.93        |                    11.06                    |                        2.29                        |                          26.44                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |           75.3            |       27.66        |       4.16        |                    18.85                    |                        3.46                        |                          45.37                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.zip) |\n\n</details>\n\n#### 26 Keypoints\n\n- Keypoints are defined as [Halpe26](https://github.com/Fang-Haoshu/Halpe-FullBody/). For details please refer to the [meta info](/configs/_base_/datasets/halpe26.py).\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/f28ab3ba-833d-4ca7-8739-f97e6cafbab7\" height=\"300px\">\n- Models are trained and evaluated on `Body8`.\n\n|                                          Config                                           | Input Size | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params(M) | FLOPS(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                                                                                                Download                                                                                                                                                |\n| :---------------------------------------------------------------------------------------: | :--------: | :---------------------: | :-----------------: | :-------: | :------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/body_2d_keypoint/rtmpose-t_8xb1024-700e_body8-halpe26-256x192.py) |  256x192   |          91.89          |        66.35        |   3.51    |   0.37   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7-halpe26_700e-256x192-6020f8a6_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-body7_pt-body7-halpe26_700e-256x192-6020f8a6_20230605.zip) |\n| [RTMPose-s\\*](./rtmpose/body_2d_keypoint/rtmpose-s_8xb1024-700e_body8-halpe26-256x192.py) |  256x192   |          93.01          |        68.62        |   5.70    |   0.70   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb512-700e_body8-halpe26-256x192.py)  |  256x192   |          94.75          |        71.91        |   13.93   |   1.95   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb512-700e_body8-halpe26-256x192.py)  |  256x192   |          95.37          |        73.19        |   28.11   |   4.19   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-256x192-2abb7558_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-256x192-2abb7558_20230605.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb512-700e_body8-halpe26-384x288.py)  |  384x288   |          95.15          |        73.56        |   14.06   |   4.37   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-384x288-89e6428b_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-384x288-89e6428b_20230605.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb512-700e_body8-halpe26-384x288.py)  |  384x288   |          95.56          |        74.38        |   28.24   |   9.40   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-384x288-734182ce_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-384x288-734182ce_20230605.zip) |\n| [RTMPose-x\\*](./rtmpose/body_2d_keypoint/rtmpose-x_8xb256-700e_body8-halpe26-384x288.py)  |  384x288   |          95.74          |        74.82        |   50.00   |  17.29   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-body7_pt-body7-halpe26_700e-384x288-7fb6e239_20230606.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-x_simcc-body7_pt-body7-halpe26_700e-384x288-7fb6e239_20230606.zip) |\n\n#### Model Pruning\n\n**Notes**\n\n- Model pruning is supported by [MMRazor](https://github.com/open-mmlab/mmrazor)\n\n|          Config           | Input Size | AP<sup><br>(COCO) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                     Download                                                                     |\n| :-----------------------: | :--------: | :---------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: |\n| RTMPose-s-aic-coco-pruned |  256x192   |       69.4        |        3.43        |       0.35        |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth) |\n\nFor more details, please refer to [GroupFisher Pruning for RTMPose](./rtmpose/pruning/README.md).\n\n### WholeBody 2d (133 Keypoints)\n\n- Keypoints are defined as [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/). For details please refer to the [meta info](/configs/_base_/datasets/coco_wholebody.py).\n- <img src=\"https://user-images.githubusercontent.com/100993824/227770977-c8f00355-c43a-467e-8444-d307789cf4b2.png\" height=\"300px\">\n\n<details close>\n<summary><b>COCO-WholeBody</b></summary>\n\n| Config                          | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download              |\n| :------------------------------ | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-------------------------------: |\n| [RTMPose-m](./rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   58.2   |   67.4   |       2.22        |                    13.50                    |                        4.00                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.pth) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   61.1   |   70.0   |       4.52        |                    23.41                    |                        5.67                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-256x192-6f206314_20230124.pth) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   64.8   |   73.0   |       10.07       |                    44.58                    |                        7.68                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-384x288-eaeb96c8_20230125.pth) |\n| [RTMPose-x](./rtmpose/wholebody_2d_keypoint/rtmpose-x_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   65.3   |   73.3   |       18.1        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-coco-wholebody_pt-body7_270e-384x288-401dfc90_20230629.pth) |\n\n</details>\n\n<details open>\n<summary><b>Cocktail14</b></summary>\n\n- `Cocktail14` denotes model trained on 14 public datasets:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n  - [COCO-Wholebody](https://github.com/jin-s13/COCO-WholeBody/)\n  - [UBody](https://github.com/IDEA-Research/OSX)\n  - [Human-Art](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#human-art-dataset)\n  - [WFLW](https://wywu.github.io/projects/LAB/WFLW.html)\n  - [300W](https://ibug.doc.ic.ac.uk/resources/300-W/)\n  - [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/)\n  - [LaPa](https://github.com/JDAI-CV/lapa-dataset)\n  - [InterHand](https://mks0601.github.io/InterHand2.6M/)\n\n| Config                          | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download              |\n| :------------------------------ | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-------------------------------: |\n| [RTMW-m](./rtmpose/wholebody_2d_keypoint/rtmw-m_8xb1024-270e_cocktail14-256x192.py) |  256x192   |   58.2   |   67.3   |        4.3        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-l-m_simcc-cocktail14_270e-256x192-20231122.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmw/onnx_sdk/rtmw-dw-m-s_simcc-cocktail14_270e-256x192_20231122.zip) |\n| [RTMW-l](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb704-270e_cocktail14-256x192.py) |  256x192   |   66.0   |   74.6   |        7.9        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-256x192-20231122.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmw/onnx_sdk/rtmw-dw-x-l_simcc-cocktail14_270e-256x192_20231122.zip) |\n| [RTMW-x](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb704-270e_cocktail14-256x192.py) |  256x192   |   67.2   |   75.2   |       13.1        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-256x192-13a2546d_20231208.pth) |\n| [RTMW-l](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb320-270e_cocktail14-384x288.py) |  384x288   |   70.1   |   78.0   |       17.7        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-384x288-20231122.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmw/onnx_sdk/rtmw-dw-x-l_simcc-cocktail14_270e-384x288_20231122.zip) |\n| [RTMW-x](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb320-270e_cocktail14-384x288.py) |  384x288   |   70.2   |   78.1   |       29.3        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-384x288-f840f204_20231122.pth) |\n\n</details>\n\n<details open>\n<summary><b>COCO+UBody</b></summary>\n\n- DWPose Models are supported by [DWPose](https://github.com/IDEA-Research/DWPose)\n- Models are trained and distilled on:\n  - [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/)\n  - [UBody](https://github.com/IDEA-Research/OSX)\n\n| Config                          | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download              |\n| :------------------------------ | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-------------------------------: |\n| [RTMPose-t](./rtmpose/wholebody_2d_keypoint/rtmpose-t_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   48.5   |   58.4   |        0.5        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-ucoco_dw-ucoco_270e-256x192-dcf277bf_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-ucoco_dw-ucoco_270e-256x192-dcf277bf_20230728.zip) |\n| [RTMPose-s](./rtmpose/wholebody_2d_keypoint/rtmpose-s_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   53.8   |   63.2   |        0.9        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-ucoco_dw-ucoco_270e-256x192-3fd922c8_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-ucoco_dw-ucoco_270e-256x192-3fd922c8_20230728.zip) |\n| [RTMPose-m](./rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   60.6   |   69.5   |       2.22        |                    13.50                    |                        4.00                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.zip) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   63.1   |   71.7   |       4.52        |                    23.41                    |                        5.67                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.zip) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   66.5   |   74.3   |       10.07       |                    44.58                    |                        7.68                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.zip) |\n\n</details>\n\n### Animal 2d (17 Keypoints)\n\n- Keypoints are defined as [AP-10K](https://github.com/AlexTheBad/AP-10K/). For details please refer to the [meta info](/configs/_base_/datasets/ap10k.py).\n- <img src=\"https://user-images.githubusercontent.com/100993824/227797151-091dc21a-d944-49c9-8b62-cc47fa89e69f.png\" height=\"300px\">\n\n|             Config             | Input Size | AP<sup><br>(AP10K) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download             |\n| :----------------------------: | :--------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :------------------------------: |\n| [RTMPose-m](./rtmpose/animal_2d_keypoint/rtmpose-m_8xb64-210e_ap10k-256x256.py) |  256x256   |        72.2        |       2.57        |                   14.157                    |                       2.404                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.zip) |\n\n### Face 2d (106 Keypoints)\n\n- Keypoints are defined as [LaPa](https://github.com/JDAI-CV/lapa-dataset). For details please refer to the [meta info](/configs/_base_/datasets/lapa.py).\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/30fa583e-500c-4356-ac5a-7e9d7d18381a\" height=\"300px\">\n\n<details open>\n<summary><b>Face6</b></summary>\n\n- `Face6` and `*` denote model trained on 6 public datasets:\n  - [COCO-Wholebody-Face](https://github.com/jin-s13/COCO-WholeBody/)\n  - [WFLW](https://wywu.github.io/projects/LAB/WFLW.html)\n  - [300W](https://ibug.doc.ic.ac.uk/resources/300-W/)\n  - [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/)\n  - [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/)\n  - [LaPa](https://github.com/JDAI-CV/lapa-dataset)\n\n|             Config             | Input Size | NME<sup><br>(LaPa) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download             |\n| :----------------------------: | :--------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :------------------------------: |\n| [RTMPose-t\\*](./rtmpose/face_2d_keypoint/rtmpose-t_8xb256-120e_lapa-256x256.py) |  256x256   |        1.67        |       0.652       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-face6_pt-in1k_120e-256x256-df79d9a5_20230529.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-face6_pt-in1k_120e-256x256-df79d9a5_20230529.zip) |\n| [RTMPose-s\\*](./rtmpose/face_2d_keypoint/rtmpose-s_8xb256-120e_lapa-256x256.py) |  256x256   |        1.59        |       1.119       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-face6_pt-in1k_120e-256x256-d779fdef_20230529.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-face6_pt-in1k_120e-256x256-d779fdef_20230529.zip) |\n| [RTMPose-m\\*](./rtmpose/face_2d_keypoint/rtmpose-m_8xb256-120e_lapa-256x256.py) |  256x256   |        1.44        |       2.852       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.zip) |\n\n</details>\n\n### Hand 2d (21 Keypoints)\n\n- Keypoints are defined as [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/). For details please refer to the [meta info](/configs/_base_/datasets/coco_wholebody_hand.py).\n- <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"300px\">\n\n|       Detection Config        | Input Size | Model AP<sup><br>(OneHand10K) | Flops<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |        Download        |\n| :---------------------------: | :--------: | :---------------------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :--------------------: |\n| [RTMDet-nano<sup><br>(alpha version)](./rtmdet/hand/rtmdet_nano_320-8xb32_hand.py) |  320x320   |             76.0              |       0.31        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmdet_nano_8xb32-300e_hand-267f9c8f.zip) |\n\n<details open>\n<summary><b>Hand5</b></summary>\n\n- `Hand5` and `*` denote model trained on 5 public datasets:\n  - [COCO-Wholebody-Hand](https://github.com/jin-s13/COCO-WholeBody/)\n  - [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\n  - [FreiHand2d](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\n  - [RHD2d](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html)\n  - [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/)\n\n|                                                        Config                                                         | Input Size | PCK@0.2<sup><br>(COCO-Wholebody-Hand) | PCK@0.2<sup><br>(Hand5) | AUC<sup><br>(Hand5) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |                                                                                                                                          Download                                                                                                                                          |\n| :-------------------------------------------------------------------------------------------------------------------: | :--------: | :-----------------------------------: | :---------------------: | :-----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-m\\*<sup><br>(alpha version)](./rtmpose/hand_2d_keypoint/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |                 81.5                  |          96.4           |        83.9         |       2.581       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.zip) |\n\n</details>\n\n### Pretrained Models\n\nWe provide the UDP pretraining configs of the CSPNeXt backbone. Find more details in the [pretrain_cspnext_udp folder](./rtmpose/pretrain_cspnext_udp/).\n\n<details close>\n<summary><b>AIC+COCO</b></summary>\n\n|    Model     | Input Size | Params<sup><br>(M) | Flops<sup><br>(G) | AP<sup><br>(GT) | AR<sup><br>(GT) |                                                     Download                                                      |\n| :----------: | :--------: | :----------------: | :---------------: | :-------------: | :-------------: | :---------------------------------------------------------------------------------------------------------------: |\n| CSPNeXt-tiny |  256x192   |        6.03        |       1.43        |      65.5       |      68.9       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth) |\n|  CSPNeXt-s   |  256x192   |        8.58        |       1.78        |      70.0       |      73.3       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth) |\n|  CSPNeXt-m   |  256x192   |       17.53        |       3.05        |      74.8       |      77.7       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth) |\n|  CSPNeXt-l   |  256x192   |       32.44        |       5.32        |      77.2       |      79.9       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth) |\n\n</details>\n\n<details open>\n<summary><b>Body8</b></summary>\n\n- `*` denotes model trained on 7 public datasets:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [MS COCO](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n- `Body8` denotes the addition of the [OCHuman](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#ochuman) dataset, in addition to the 7 datasets mentioned above, for evaluation.\n\n|     Model      | Input Size | Params<sup><br>(M) | Flops<sup><br>(G) | AP<sup><br>(COCO) | PCK@0.2<sup><br>(Body8) | AUC<sup><br>(Body8) |                                      Download                                      |\n| :------------: | :--------: | :----------------: | :---------------: | :---------------: | :---------------------: | :-----------------: | :--------------------------------------------------------------------------------: |\n| CSPNeXt-tiny\\* |  256x192   |        6.03        |       1.43        |       65.9        |          96.34          |        63.80        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-body7_210e-256x192-a3775292_20230504.pth) |\n|  CSPNeXt-s\\*   |  256x192   |        8.58        |       1.78        |       68.7        |          96.59          |        64.92        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-body7_210e-256x192-8c9ccbdb_20230504.pth) |\n|  CSPNeXt-m\\*   |  256x192   |       17.53        |       3.05        |       73.7        |          97.42          |        68.19        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-body7_210e-256x192-e0c9327b_20230504.pth) |\n|  CSPNeXt-l\\*   |  256x192   |       32.44        |       5.32        |       75.7        |          97.76          |        69.57        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-body7_210e-256x192-5e9558ef_20230504.pth) |\n|  CSPNeXt-m\\*   |  384x288   |       17.53        |       6.86        |       75.8        |          97.60          |        70.18        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-body7_210e-384x288-b9bc2b57_20230504.pth) |\n|  CSPNeXt-l\\*   |  384x288   |       32.44        |       11.96       |       77.2        |          97.89          |        71.23        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-body7_210e-384x288-b15bc30d_20230504.pth) |\n|  CSPNeXt-x\\*   |  384x288   |       54.92        |       19.96       |       78.1        |          98.00          |        71.79        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth) |\n\n</details>\n\n#### ImageNet\n\nWe also provide the ImageNet classification pre-trained weights of the CSPNeXt backbone. Find more details in [RTMDet](https://github.com/open-mmlab/mmdetection/blob/latest/configs/rtmdet/README.md#classification).\n\n|    Model     | Input Size | Params<sup><br>(M) | Flops<sup><br>(G) | Top-1 (%) | Top-5 (%) |                                                           Download                                                            |\n| :----------: | :--------: | :----------------: | :---------------: | :-------: | :-------: | :---------------------------------------------------------------------------------------------------------------------------: |\n| CSPNeXt-tiny |  224x224   |        2.73        |       0.34        |   69.44   |   89.45   |  [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-tiny_imagenet_600e-3a2dd350.pth)   |\n|  CSPNeXt-s   |  224x224   |        4.89        |       0.66        |   74.41   |   92.23   |    [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-s_imagenet_600e-ea671761.pth)    |\n|  CSPNeXt-m   |  224x224   |       13.05        |       1.93        |   79.27   |   94.79   | [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth) |\n|  CSPNeXt-l   |  224x224   |       27.16        |       4.19        |   81.30   |   95.62   | [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth) |\n|  CSPNeXt-x   |  224x224   |       48.85        |       7.76        |   82.10   |   95.69   | [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-x_8xb256-rsb-a1-600e_in1k-b3f78edd.pth) |\n\n## 👀 Visualization [🔝](#-table-of-contents)\n\n<div align=center>\n<img src='https://user-images.githubusercontent.com/13503330/221795678-2c4ae2ec-ac23-4368-8083-0ebeb29f0d3c.gif' width=900/>\n<img src=\"https://user-images.githubusercontent.com/13503330/219270443-421d9b02-fcec-46de-90f2-ce769c67575a.png\" width=900 />\n</div>\n\n## 😎 Get Started [🔝](#-table-of-contents)\n\nWe provide following appoaches to try RTMPose:\n\n- [Online RTMPose Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose)\n- [Examples](https://github.com/open-mmlab/mmpose/tree/dev-1.x/projects/rtmpose/examples/onnxruntime) based on Python and ONNXRuntime (without mmcv)\n- [rtmlib](https://github.com/Tau-J/rtmlib/tree/main) （without mmcv, pytorch）\n- MMPose demo scripts (based on Pytorch)\n- Pre-compiled MMDeploy SDK (Recommended, 6-10 times faster)\n\n## rtmlib\n\n[rtmlib](https://github.com/Tau-J/rtmlib/tree/main) provides simple and easy-to-use API for inference with RTMPose models.\n\n- Support OpenCV/ONNXRuntime/OpenVINO inference and does not require Pytorch or MMCV.\n- Super user-friendly API for inference and visualization.\n- Support both CPU and GPU inference.\n- Automatically download onnx models from OpenMMLab model zoo.\n- Support all series of RTMPose models (RTMPose, DWPose, RTMO, RTMW etc.)\n\n### MMPose demo scripts\n\nMMPose provides demo scripts to conduct [inference with existing models](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html).\n\n**Note:**\n\n- Inferencing with Pytorch can not reach the maximum speed of RTMPose, just for verification.\n- Model file can be either a local path or a download link\n\n```shell\n# go to the mmpose folder\ncd ${PATH_TO_MMPOSE}\n\n# inference with rtmdet\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input {YOUR_TEST_IMG_or_VIDEO} \\\n    --show\n\n# inference with webcam\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input webcam \\\n    --show\n```\n\nResult is as follows:\n\n![topdown_inference_with_rtmdet](https://user-images.githubusercontent.com/13503330/220005020-06bdf37f-6817-4681-a2c8-9dd55e4fbf1e.png)\n\n### Pre-compiled MMDeploy SDK (Recommended)\n\nMMDeploy provides a precompiled SDK for Pipeline reasoning on RTMPose projects, where the model used for reasoning is the SDK version.\n\n- All models must by exported by `tools/deploy.py` before PoseTracker can be used for inference.\n- For the tutorial of exporting the SDK version model, see [SDK Reasoning](#%EF%B8%8F-step3-inference-with-sdk), and for detailed parameter settings of inference, see [Pipeline Reasoning](#-step4-pipeline-inference).\n- Exported SDK models (ONNX, TRT, ncnn, etc.) can be downloaded from [OpenMMLab Deploee](https://platform.openmmlab.com/deploee).\n- You can also convert `.pth` models into SDK [online](https://platform.openmmlab.com/deploee/task-convert-list).\n\n#### Linux\n\nEnv Requirements:\n\n- GCC >= 7.5\n- cmake >= 3.20\n\n##### Python Inference\n\n1. Install mmdeploy_runtime or mmdeploy_runtime_gpu\n\n```shell\n# for onnxruntime\npip install mmdeploy-runtime\n\n# for onnxruntime-gpu / tensorrt\npip install mmdeploy-runtime-gpu\n```\n\n2. Download Pre-compiled files.\n\n```shell\n# onnxruntime\n# for ubuntu\nwget -c  https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n# unzip then add third party runtime libraries to the PATH\n\n# for centos7 and lower\nwget -c https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64.tar.gz\n# unzip then add third party runtime libraries to the PATH\n\n# onnxruntime-gpu / tensorrt\n# for ubuntu\nwget -c  https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3.tar.gz\n# unzip then add third party runtime libraries to the PATH\n\n# for centos7 and lower\nwget -c https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cuda11.3.tar.gz\n# unzip then add third party runtime libraries to the PATH\n```\n\n3. Download the sdk models and unzip to `./example/python`. (If you need other models, please export sdk models refer to [SDK Reasoning](#%EF%B8%8F-step3-inference-with-sdk))\n\n```shell\n# rtmdet-nano + rtmpose-m for cpu sdk\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-cpu.zip\n\nunzip rtmpose-cpu.zip\n```\n\n4. Inference with `pose_tracker.py`:\n\n```shell\n# go to ./example/python\n\n# Please pass the folder of the model, not the model file\n# Format:\n# python pose_tracker.py cpu {det work-dir} {pose work-dir} {your_video.mp4}\n\n# Example:\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4\n\n# webcam\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0\n```\n\n##### ONNX\n\n```shell\n# Download pre-compiled files\nwget https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n\n# Unzip files\ntar -xzvf mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n\n# Go to the sdk folder\ncd mmdeploy-1.0.0-linux-x86_64-cxx11abi\n\n# Init environment\nsource set_env.sh\n\n# If opencv 3+ is not installed on your system, execute the following command.\n# If it is installed, skip this command\nbash install_opencv.sh\n\n# Compile executable programs\nbash build_sdk.sh\n\n# Inference for an image\n# Please pass the folder of the model, not the model file\n./bin/det_pose rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_img.jpg --device cpu\n\n# Inference for a video\n# Please pass the folder of the model, not the model file\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4 --device cpu\n\n# Inference using webcam\n# Please pass the folder of the model, not the model file\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0 --device cpu\n```\n\n##### TensorRT\n\n```shell\n# Download pre-compiled files\nwget https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3.tar.gz\n\n# Unzip files\ntar -xzvf mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3.tar.gz\n\n# Go to the sdk folder\ncd mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3\n\n# Init environment\nsource set_env.sh\n\n# If opencv 3+ is not installed on your system, execute the following command.\n# If it is installed, skip this command\nbash install_opencv.sh\n\n# Compile executable programs\nbash build_sdk.sh\n\n# Inference for an image\n# Please pass the folder of the model, not the model file\n./bin/det_pose rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_img.jpg --device cuda\n\n# Inference for a video\n# Please pass the folder of the model, not the model file\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4 --device cuda\n\n# Inference using webcam\n# Please pass the folder of the model, not the model file\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0 --device cuda\n```\n\nFor details, see [Pipeline Inference](#-step4-pipeline-inference).\n\n#### Windows\n\n##### Python Inference\n\n1. Install mmdeploy_runtime or mmdeploy_runtime_gpu\n\n```shell\n# for onnxruntime\npip install mmdeploy-runtime\n# download [sdk](https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-windows-amd64.zip) add third party runtime libraries to the PATH\n\n# for onnxruntime-gpu / tensorrt\npip install mmdeploy-runtime-gpu\n# download [sdk](https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-windows-amd64-cuda11.3.zip) add third party runtime libraries to the PATH\n```\n\n2. Download the sdk models and unzip to `./example/python`. (If you need other models, please export sdk models refer to [SDK Reasoning](#%EF%B8%8F-step3-inference-with-sdk))\n\n```shell\n# rtmdet-nano + rtmpose-m for cpu sdk\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-cpu.zip\n\nunzip rtmpose-cpu.zip\n```\n\n3. Inference with `pose_tracker.py`:\n\n```shell\n# go to ./example/python\n# Please pass the folder of the model, not the model file\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4\n\n# Inference using webcam\n# Please pass the folder of the model, not the model file\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0\n```\n\n##### Executable Inference\n\n1. Install [CMake](https://cmake.org/download/).\n2. Download the [pre-compiled SDK](https://github.com/open-mmlab/mmdeploy/releases).\n3. Unzip the SDK and go to the `sdk` folder.\n4. open windows powerShell with administrator privileges\n\n```shell\nset-ExecutionPolicy RemoteSigned\n```\n\n5. Install OpenCV:\n\n```shell\n# in sdk folder:\n.\\install_opencv.ps1\n```\n\n6. Set environment variables:\n\n```shell\n# in sdk folder:\n. .\\set_env.ps1\n```\n\n7. Compile the SDK:\n\n```shell\n# in sdk folder:\n# (if you installed opencv by .\\install_opencv.ps1)\n.\\build_sdk.ps1\n# (if you installed opencv yourself)\n.\\build_sdk.ps1 \"path/to/folder/of/OpenCVConfig.cmake\"\n```\n\n8. the executable will be generated in:\n\n```shell\nexample\\cpp\\build\\Release\n```\n\n### MMPose demo scripts\n\nMMPose provides demo scripts to conduct [inference with existing models](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html).\n\n**Note:**\n\n- Inferencing with Pytorch can not reach the maximum speed of RTMPose, just for verification.\n\n```shell\n# go to the mmpose folder\ncd ${PATH_TO_MMPOSE}\n\n# inference with rtmdet\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    {PATH_TO_CHECKPOINT}/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    {PATH_TO_CHECKPOINT}/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input {YOUR_TEST_IMG_or_VIDEO} \\\n    --show\n\n# inference with webcam\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    {PATH_TO_CHECKPOINT}/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    {PATH_TO_CHECKPOINT}/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input webcam \\\n    --show\n```\n\nResult is as follows:\n\n![topdown_inference_with_rtmdet](https://user-images.githubusercontent.com/13503330/220005020-06bdf37f-6817-4681-a2c8-9dd55e4fbf1e.png)\n\n## 👨‍🏫 How to Train [🔝](#-table-of-contents)\n\nPlease refer to [Train and Test](https://mmpose.readthedocs.io/en/latest/user_guides/train_and_test.html).\n\n**Tips**:\n\n- Please accordinally reduce `batch_size` and `base_lr` when your dataset is small.\n- Guidelines to choose a model\n  - m: Recommended and Preferred Use\n  - t/s: For mobile devices with extremely low computing power, or scenarios with stringent inference speed requirements\n  - l: Suitable for scenarios with strong computing power and not sensitive to speed\n\n## 🏗️ How to Deploy [🔝](#-table-of-contents)\n\nHere is a basic example of deploy RTMPose with [MMDeploy](https://github.com/open-mmlab/mmdeploy/tree/main).\n\n- Exported SDK models (ONNX, TRT, ncnn, etc.) can be downloaded from [OpenMMLab Deploee](https://platform.openmmlab.com/deploee).\n- You can also convert `.pth` models into SDK [online](https://platform.openmmlab.com/deploee/task-convert-list).\n\n### 🧩 Step1. Install MMDeploy\n\nBefore starting the deployment, please make sure you install MMPose and MMDeploy correctly.\n\n- Install MMPose, please refer to the [MMPose installation guide](https://mmpose.readthedocs.io/en/latest/installation.html).\n- Install MMDeploy, please refer to the [MMDeploy installation guide](https://mmdeploy.readthedocs.io/en/latest/get_started.html#installation).\n\nDepending on the deployment backend, some backends require compilation of custom operators, so please refer to the corresponding document to ensure the environment is built correctly according to your needs:\n\n- [ONNX](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/onnxruntime.html)\n- [TensorRT](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/tensorrt.html)\n- [OpenVINO](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/openvino.html)\n- [TorchScript](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/torchscript.html)\n- [More](https://github.com/open-mmlab/mmdeploy/tree/main/docs/en/05-supported-backends)\n\n### 🛠️ Step2. Convert Model\n\nAfter the installation, you can enjoy the model deployment journey starting from converting PyTorch model to backend model by running MMDeploy's `tools/deploy.py`.\n\nThe detailed model conversion tutorial please refer to the [MMDeploy document](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/convert_model.html). Here we only give the example of converting RTMPose.\n\nHere we take converting RTMDet-nano and RTMPose-m to ONNX/TensorRT as an example.\n\n- ONNX\n  - [`detection_onnxruntime_static.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmdet/detection/detection_onnxruntime_static.py) for RTMDet.\n  - [`pose-detection_simcc_onnxruntime_dynamic.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py) for RTMPose.\n- TensorRT\n  - [`detection_tensorrt_static-320x320.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmdet/detection/detection_tensorrt_static-320x320.py) for RTMDet.\n  - [`pose-detection_simcc_tensorrt_dynamic-256x192.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py) for RTMPose.\n- More\n  |   Backend   |                                                                                Config                                                                                |\n  | :---------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n  |  ncnn-fp16  | [pose-detection_simcc_ncnn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_ncnn-fp16_static-256x192.py) |\n  |   CoreML    |    [pose-detection_simcc_coreml_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_coreml_static-256x192.py)    |\n  |  OpenVINO   |  [pose-detection_simcc_openvino_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_openvino_static-256x192.py)  |\n  |    RKNN     | [pose-detection_simcc_rknn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_rknn-fp16_static-256x192.py) |\n  | TorchScript |                    [pose-detection_torchscript.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_torchscript.py)                    |\n\nIf you want to customize the settings in the deployment config for your requirements, please refer to [MMDeploy config tutorial](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/write_config.html).\n\nIn this tutorial, we organize files as follows:\n\n```shell\n|----mmdeploy\n|----mmdetection\n|----mmpose\n```\n\n#### ONNX\n\n```shell\n# go to the mmdeploy folder\ncd ${PATH_TO_MMDEPLOY}\n\n# run the command to convert RTMDet\n# Model file can be either a local path or a download link\npython tools/deploy.py \\\n    configs/mmdet/detection/detection_onnxruntime_static.py \\\n    ../mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmdet-nano \\\n    --device cpu \\\n    --show \\\n    --dump-info  # dump sdk info\n\n# run the command to convert RTMPose\n# Model file can be either a local path or a download link\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmpose-m \\\n    --device cpu \\\n    --show \\\n    --dump-info  # dump sdk info\n```\n\nThe converted model file is `{work-dir}/end2end.onnx` by defaults.\n\n#### TensorRT\n\n```shell\n# go to the mmdeploy folder\ncd ${PATH_TO_MMDEPLOY}\n\n# run the command to convert RTMDet\n# Model file can be either a local path or a download link\npython tools/deploy.py \\\n    configs/mmdet/detection/detection_tensorrt_static-320x320.py \\\n    ../mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-trt/rtmdet-nano \\\n    --device cuda:0 \\\n    --show \\\n    --dump-info  # dump sdk info\n\n# run the command to convert RTMPose\n# Model file can be either a local path or a download link\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-trt/rtmpose-m \\\n    --device cuda:0 \\\n    --show \\\n    --dump-info  # dump sdk info\n```\n\nThe converted model file is `{work-dir}/end2end.engine` by defaults.\n\n🎊 If the script runs successfully, you will see the following files:\n\n![convert_models](https://user-images.githubusercontent.com/13503330/217726963-7815dd01-561a-4605-b0c6-07b6fe1956c3.png)\n\n#### Advanced Setting\n\nTo convert the model with TRT-FP16, you can enable the fp16 mode in your deploy config:\n\n```Python\n# in MMDeploy config\nbackend_config = dict(\n    type='tensorrt',\n    common_config=dict(\n        fp16_mode=True  # enable fp16\n    ))\n```\n\n### 🕹️ Step3. Inference with SDK\n\nWe provide both Python and C++ inference API with MMDeploy SDK.\n\nTo use SDK, you need to dump the required info during converting the model. Just add --dump-info to the model conversion command.\n\n```shell\n# RTMDet\n# Model file can be either a local path or a download link\npython tools/deploy.py \\\n    configs/mmdet/detection/detection_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmdet-nano \\\n    --device cpu \\\n    --show \\\n    --dump-info  # dump sdk info\n\n# RTMPose\n# Model file can be either a local path or a download link\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmpose-m \\\n    --device cpu \\\n    --show \\\n    --dump-info  # dump sdk info\n```\n\nAfter running the command, it will dump 3 json files additionally for the SDK:\n\n```shell\n|----{work-dir}\n     |----end2end.onnx    # ONNX model\n     |----end2end.engine  # TensorRT engine file\n\n     |----pipeline.json   #\n     |----deploy.json     # json files for the SDK\n     |----detail.json     #\n```\n\n#### Python API\n\nHere is a basic example of SDK Python API:\n\n```Python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\n\nimport cv2\nimport numpy as np\nfrom mmdeploy_runtime import PoseDetector\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='show how to use sdk python api')\n    parser.add_argument('device_name', help='name of device, cuda or cpu')\n    parser.add_argument(\n        'model_path',\n        help='path of mmdeploy SDK model dumped by model converter')\n    parser.add_argument('image_path', help='path of an image')\n    parser.add_argument(\n        '--bbox',\n        default=None,\n        nargs='+',\n        type=int,\n        help='bounding box of an object in format (x, y, w, h)')\n    args = parser.parse_args()\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    img = cv2.imread(args.image_path)\n\n    detector = PoseDetector(\n        model_path=args.model_path, device_name=args.device_name, device_id=0)\n\n    if args.bbox is None:\n        result = detector(img)\n    else:\n        # converter (x, y, w, h) -> (left, top, right, bottom)\n        print(args.bbox)\n        bbox = np.array(args.bbox, dtype=int)\n        bbox[2:] += bbox[:2]\n        result = detector(img, bbox)\n    print(result)\n\n    _, point_num, _ = result.shape\n    points = result[:, :, :2].reshape(point_num, 2)\n    for [x, y] in points.astype(int):\n        cv2.circle(img, (x, y), 1, (0, 255, 0), 2)\n\n    cv2.imwrite('output_pose.png', img)\n\n\nif __name__ == '__main__':\n    main()\n```\n\n#### C++ API\n\nHere is a basic example of SDK C++ API:\n\n```C++\n#include \"mmdeploy/pose_detector.hpp\"\n#include \"opencv2/imgcodecs.hpp\"\n#include \"opencv2/imgproc.hpp\"\n#include \"utils/argparse.h\" // See: https://github.com/open-mmlab/mmdeploy/blob/main/demo/csrc/cpp/utils/argparse.h\n\nDEFINE_ARG_string(model_path, \"Model path\");\nDEFINE_ARG_string(image_path, \"Input image path\");\nDEFINE_string(device_name, \"cpu\", R\"(Device name, e.g. \"cpu\", \"cuda\")\");\nDEFINE_int32(bbox_x, -1, R\"(x position of the bounding box)\");\nDEFINE_int32(bbox_y, -1, R\"(y position of the bounding box)\");\nDEFINE_int32(bbox_w, -1, R\"(width of the bounding box)\");\nDEFINE_int32(bbox_h, -1, R\"(height of the bounding box)\");\n\nint main(int argc, char* argv[]) {\n  if (!utils::ParseArguments(argc, argv)) {\n    return -1;\n  }\n\n  cv::Mat img = cv::imread(ARGS_image_path);\n\n  mmdeploy::PoseDetector detector(mmdeploy::Model{ARGS_model_path}, mmdeploy::Device{FLAGS_device_name, 0});\n\n  mmdeploy::PoseDetector::Result result{0, 0, nullptr};\n\n  if (FLAGS_bbox_x == -1 || FLAGS_bbox_y == -1 || FLAGS_bbox_w == -1 || FLAGS_bbox_h == -1) {\n    result = detector.Apply(img);\n  } else {\n    // convert (x, y, w, h) -> (left, top, right, bottom)\n    mmdeploy::cxx::Rect rect;\n    rect.left = FLAGS_bbox_x;\n    rect.top = FLAGS_bbox_y;\n    rect.right = FLAGS_bbox_x + FLAGS_bbox_w;\n    rect.bottom = FLAGS_bbox_y + FLAGS_bbox_h;\n    result = detector.Apply(img, {rect});\n  }\n\n  // Draw circles at detected keypoints\n  for (size_t i = 0; i < result[0].length; ++i) {\n    cv::Point keypoint(result[0].point[i].x, result[0].point[i].y);\n    cv::circle(img, keypoint, 1, cv::Scalar(0, 255, 0), 2);  // Draw filled circle\n  }\n\n  // Save the output image\n  cv::imwrite(\"output_pose.png\", img);\n\n  return 0;\n}\n```\n\nTo build C++ example, please add MMDeploy package in your CMake project as following:\n\n```CMake\nfind_package(MMDeploy REQUIRED)\ntarget_link_libraries(${name} PRIVATE mmdeploy ${OpenCV_LIBS})\n```\n\n#### Other languages\n\n- [C# API Examples](https://github.com/open-mmlab/mmdeploy/tree/main/demo/csharp)\n- [JAVA API Examples](https://github.com/open-mmlab/mmdeploy/tree/main/demo/java)\n\n## 🚀 Step4. Pipeline Inference\n\n### Inference for images\n\nIf the user has MMDeploy compiled correctly, you will see the `det_pose` executable under the `mmdeploy/build/bin/`.\n\n```shell\n# go to the mmdeploy folder\ncd ${PATH_TO_MMDEPLOY}/build/bin/\n\n# inference for an image\n./det_pose rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_img.jpg --device cpu\n\nrequired arguments:\n  det_model           Object detection model path [string]\n  pose_model          Pose estimation model path [string]\n  image               Input image path [string]\n\noptional arguments:\n  --device            Device name, e.g. \"cpu\", \"cuda\" [string = \"cpu\"]\n  --output            Output image path [string = \"det_pose_output.jpg\"]\n  --skeleton          Path to skeleton data or name of predefined skeletons:\n                      \"coco\" [string = \"coco\", \"coco-wholoebody\"]\n  --det_label         Detection label use for pose estimation [int32 = 0]\n                      (0 refers to 'person' in coco)\n  --det_thr           Detection score threshold [double = 0.5]\n  --det_min_bbox_size Detection minimum bbox size [double = -1]\n  --pose_thr          Pose key-point threshold [double = 0]\n```\n\n#### API Example\n\n- [`det_pose.py`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/python/det_pose.py)\n- [`det_pose.cxx`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/csrc/cpp/det_pose.cxx)\n\n### Inference for a video\n\nIf the user has MMDeploy compiled correctly, you will see the `pose_tracker` executable under the `mmdeploy/build/bin/`.\n\n- pass `0` to `input` can inference from a webcam\n\n```shell\n# go to the mmdeploy folder\ncd ${PATH_TO_MMDEPLOY}/build/bin/\n\n# inference for a video\n./pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4 --device cpu\n\nrequired arguments:\n  det_model             Object detection model path [string]\n  pose_model            Pose estimation model path [string]\n  input                 Input video path or camera index [string]\n\noptional arguments:\n  --device              Device name, e.g. \"cpu\", \"cuda\" [string = \"cpu\"]\n  --output              Output video path or format string [string = \"\"]\n  --output_size         Long-edge of output frames [int32 = 0]\n  --flip                Set to 1 for flipping the input horizontally [int32 = 0]\n  --show                Delay passed to `cv::waitKey` when using `cv::imshow`;\n                        -1: disable [int32 = 1]\n  --skeleton            Path to skeleton data or name of predefined skeletons:\n                        \"coco\", \"coco-wholebody\" [string = \"coco\"]\n  --background          Output background, \"default\": original image, \"black\":\n                        black background [string = \"default\"]\n  --det_interval        Detection interval [int32 = 1]\n  --det_label           Detection label use for pose estimation [int32 = 0]\n                        (0 refers to 'person' in coco)\n  --det_thr             Detection score threshold [double = 0.5]\n  --det_min_bbox_size   Detection minimum bbox size [double = -1]\n  --det_nms_thr         NMS IOU threshold for merging detected bboxes and\n                        bboxes from tracked targets [double = 0.7]\n  --pose_max_num_bboxes Max number of bboxes used for pose estimation per frame\n                        [int32 = -1]\n  --pose_kpt_thr        Threshold for visible key-points [double = 0.5]\n  --pose_min_keypoints  Min number of key-points for valid poses, -1 indicates\n                        ceil(n_kpts/2) [int32 = -1]\n  --pose_bbox_scale     Scale for expanding key-points to bbox [double = 1.25]\n  --pose_min_bbox_size  Min pose bbox size, tracks with bbox size smaller than\n                        the threshold will be dropped [double = -1]\n  --pose_nms_thr        NMS OKS/IOU threshold for suppressing overlapped poses,\n                        useful when multiple pose estimations collapse to the\n                        same target [double = 0.5]\n  --track_iou_thr       IOU threshold for associating missing tracks\n                        [double = 0.4]\n  --track_max_missing   Max number of missing frames before a missing tracks is\n                        removed [int32 = 10]\n```\n\n#### API Example\n\n- [`pose_tracker.py`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/python/pose_tracker.py)\n- [`pose_tracker.cxx`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/csrc/cpp/pose_tracker.cxx)\n\n## 📚 Common Usage [🔝](#-table-of-contents)\n\n### 🚀 Inference Speed Test [🔝](#-table-of-contents)\n\nIf you need to test the inference speed of the model under the deployment framework, MMDeploy provides a convenient `tools/profiler.py` script.\n\nThe user needs to prepare a folder for the test images `./test_images`, the profiler will randomly read images from this directory for the model speed test.\n\n```shell\npython tools/profiler.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    {RTMPOSE_PROJECT}/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    ../test_images \\\n    --model {WORK_DIR}/end2end.onnx \\\n    --shape 256x192 \\\n    --device cpu \\\n    --warmup 50 \\\n    --num-iter 200\n```\n\nThe result is as follows:\n\n```shell\n01/30 15:06:35 - mmengine - INFO - [onnxruntime]-70 times per count: 8.73 ms, 114.50 FPS\n01/30 15:06:36 - mmengine - INFO - [onnxruntime]-90 times per count: 9.05 ms, 110.48 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-110 times per count: 9.87 ms, 101.32 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-130 times per count: 9.99 ms, 100.10 FPS\n01/30 15:06:38 - mmengine - INFO - [onnxruntime]-150 times per count: 10.39 ms, 96.29 FPS\n01/30 15:06:39 - mmengine - INFO - [onnxruntime]-170 times per count: 10.77 ms, 92.86 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-190 times per count: 10.98 ms, 91.05 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-210 times per count: 11.19 ms, 89.33 FPS\n01/30 15:06:41 - mmengine - INFO - [onnxruntime]-230 times per count: 11.16 ms, 89.58 FPS\n01/30 15:06:42 - mmengine - INFO - [onnxruntime]-250 times per count: 11.06 ms, 90.41 FPS\n----- Settings:\n+------------+---------+\n| batch size |    1    |\n|   shape    | 256x192 |\n| iterations |   200   |\n|   warmup   |    50   |\n+------------+---------+\n----- Results:\n+--------+------------+---------+\n| Stats  | Latency/ms |   FPS   |\n+--------+------------+---------+\n|  Mean  |   11.060   |  90.412 |\n| Median |   11.852   |  84.375 |\n|  Min   |   7.812    | 128.007 |\n|  Max   |   13.690   |  73.044 |\n+--------+------------+---------+\n```\n\nIf you want to learn more details of profiler, you can refer to the [Profiler Docs](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/useful_tools.html#profiler).\n\n### 📊 Model Test [🔝](#-table-of-contents)\n\nIf you need to test the inference accuracy of the model on the deployment backend, MMDeploy provides a convenient `tools/test.py` script.\n\n```shell\npython tools/test.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    {RTMPOSE_PROJECT}/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    --model {PATH_TO_MODEL}/rtmpose_m.pth \\\n    --device cpu\n```\n\nYou can also refer to [MMDeploy Docs](https://github.com/open-mmlab/mmdeploy/blob/main/docs/en/02-how-to-run/profile_model.md) for more details.\n\n## 📜 Citation [🔝](#-table-of-contents)\n\nIf you find RTMPose useful in your research, please consider cite:\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n\nif you used the whole-body model RTMW, please also cite:\n\n```bibtex\n@article{jiang2024rtmw,\n  title={RTMW: Real-Time Multi-Person 2D and 3D Whole-body Pose Estimation},\n  author={Jiang, Tao and Xie, Xinchen and Li, Yining},\n  journal={arXiv preprint arXiv:2407.08634},\n  year={2024}\n}\n```\n"
  },
  {
    "path": "projects/rtmpose/README_CN.md",
    "content": "<div align=\"center\">\n  <img width=\"100%\" src=\"https://github.com/open-mmlab/mmpose/assets/13503330/5b637d76-41dd-4376-9a7f-854cd120799d\"/>\n</div>\n\n# RTMPose: Real-Time Multi-Person Pose Estimation toolkit based on MMPose\n\n> [RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose](https://arxiv.org/abs/2303.07399)\n\n<div align=\"center\">\n\n[English](README.md) | 简体中文\n\n</div>\n\n______________________________________________________________________\n\n## Abstract\n\n近年来，2D 姿态估计的研究在公开数据集上取得了出色的成绩，但是它在工业界的应用仍然受到笨重的模型参数和高推理延迟的影响。为了让前沿姿态估计算法在工业界落地，我们通过实验研究了多人姿态估计算法的五个方面：范式、骨干网络、定位算法、训练策略和部署推理，基于 MMPose 提出了一个高性能的实时多人姿态估计框架 **RTMPose**。我们的 RTMPose-m 模型在 COCO 上取得 **75.8％AP**，在 Intel i7-11700 CPU 上达到 **90+FPS**，在 NVIDIA GTX 1660 Ti GPU 上达到 **430+FPS**。我们同样验证了在算力有限的设备上做实时姿态估计，RTMPose-s 在移动端骁龙865芯片上可以达到 **COCO 72.2%AP**，**70+FPS**。在 MMDeploy 的帮助下，我们的项目支持 CPU、GPU、Jetson、移动端等多种部署环境。\n\n![rtmpose_intro](https://user-images.githubusercontent.com/13503330/219269619-935499e5-bdd9-49ea-8104-3c7796dbd862.png)\n\n______________________________________________________________________\n\n## 📄 Table of Contents\n\n- [🥳 🚀 最新进展](#--最新进展-)\n- [📖 简介](#-简介-)\n- [🙌 社区共建](#-社区共建-)\n- [⚡ Pipeline 性能](#-pipeline-性能-)\n- [📊 模型库](#-模型库-)\n- [👀 可视化](#-可视化-)\n- [😎 快速尝试](#-快速尝试-)\n- [👨‍🏫 模型训练](#-模型训练-)\n- [🏗️ 部署教程](#️-部署教程-)\n- [📚 常用功能](#️-常用功能-)\n  - [🚀 模型测速](#-模型测速-)\n  - [📊 精度验证](#-精度验证-)\n- [📜 引用](#-引用-)\n\n## 🥳 最新进展 [🔝](#-table-of-contents)\n\n- 2023 年 12 月：\n  - 更新 RTMW 模型，RTMW-l 在 COCO-Wholebody 验证集上去的 70.1 mAP。\n- 2023 年 9 月：\n  - 发布混合数据集上训练的 RTMW 模型。Alpha 版本的 RTMW-x 在 COCO-Wholebody 验证集上取得了 70.2 mAP。[在线 Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose) 已支持 RTMW。技术报告正在撰写中。\n  - 增加 HumanArt 上训练的 YOLOX 和 RTMDet 模型。\n- 2023 年 8 月：\n  - 支持基于 RTMPose 模型蒸馏的 133 点 WholeBody 模型（由 [DWPose](https://github.com/IDEA-Research/DWPose/tree/main) 提供）。\n    - 你可以在 [sd-webui-controlnet](https://github.com/Mikubill/sd-webui-controlnet) 中使用 DWPose/RTMPose 作为姿态估计后端进行人物图像生成。升级 sd-webui-controlnet >= v1.1237 并选择 `dw_openpose_full` 即可使用。\n    - [在线 Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose) 已支持 DWPose，试玩请选择 `wholebody`。\n- 2023 年 7 月：\n  - 在线 RTMPose 试玩 [Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose)。\n  - 支持面向艺术图片人体姿态估计的 17 点 Body 模型。\n- 2023 年 6 月：\n  - 发布混合数据集训练的 26 点 Body 模型。\n- 2023 年 5 月：\n  - 已导出的 SDK 模型（ONNX、TRT、ncnn 等）可以从 [OpenMMLab Deploee](https://platform.openmmlab.com/deploee) 直接下载。\n  - [在线导出](https://platform.openmmlab.com/deploee/task-convert-list) SDK 模型（ONNX、TRT、ncnn 等）。\n  - 添加 [代码示例](./examples/)，包括：\n    - 纯 Python 推理代码示例，无 MMDeploy、MMCV 依赖\n    - C++ 代码示例：ONNXRuntime、TensorRT\n    - Android 项目示例：基于 ncnn\n  - 发布混合数据集训练的 Hand, Face, Body 模型。\n- 2023 年 3 月：发布 RTMPose。RTMPose-m 取得 COCO 验证集 75.8 mAP，推理速度达到 430+ FPS 。\n\n## 📖 简介 [🔝](#-table-of-contents)\n\n<div align=center>\n<img src=\"https://user-images.githubusercontent.com/13503330/221138554-110240d8-e887-4b9a-90b1-2fbdc982e9de.gif\" width=400 height=300/><img src=\"https://user-images.githubusercontent.com/13503330/221125176-85015a13-9648-4f0d-a17c-1cbb469efacf.gif\" width=250 height=300/><img src=\"https://user-images.githubusercontent.com/13503330/221125310-7eeb2212-907e-427f-97af-af799d70a4c5.gif\" width=250 height=300/>\n</div>\n\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/38aa345e-4ceb-4e73-bc37-5e082735e336\" width=450 height=300/><img src=\"https://user-images.githubusercontent.com/13503330/221125888-15c20faf-0ad5-4afb-828b-a71ccb064582.gif\" width=450 height=300/>\n</div>\n<div align=center>\n<img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/2ecbf9f4-6963-4a14-9801-da10c0a65dac\" width=300 height=350/><img src=\"https://user-images.githubusercontent.com/13503330/221138017-10431ab4-e515-4c32-8fa7-8748e2d17a58.gif\" width=600 height=350/>\n</div>\n\n### ✨ 主要特性\n\n- 🚀 **高精度，低延迟**\n\n  | Model | AP(COCO) | CPU-FPS | GPU-FPS |\n  | :---: | :------: | :-----: | :-----: |\n  |   t   |   68.5   |  300+   |  940+   |\n  |   s   |   72.2   |  200+   |  710+   |\n  |   m   |   75.8   |   90+   |  430+   |\n  |   l   |   76.5   |   50+   |  280+   |\n  | l-384 |   78.3   |    -    |  160+   |\n\n- 🛠️ **易部署**\n\n  - 详细的部署代码教程，手把手教你模型部署\n  - MMDeploy 助力\n  - 支持多种部署后端\n    - ONNX\n    - TensorRT\n    - ncnn\n    - OpenVINO 等\n  - 支持多种平台\n    - Linux\n    - Windows\n    - NVIDIA Jetson\n    - ARM 等\n\n- 🏗️ **为实际业务设计**\n\n  - 提供多种 Pipeline 推理接口和 SDK\n    - Python\n    - C++\n    - C#\n    - JAVA 等\n\n## 🙌 社区共建 [🔝](#-table-of-contents)\n\nRTMPose 是一个长期优化迭代的项目，致力于业务场景下的高性能实时姿态估计算法的训练、优化和部署，因此我们十分期待来自社区的力量，欢迎分享不同业务场景中 RTMPose 的训练配置与技巧，助力更多的社区用户！\n\n✨ ✨ ✨\n\n- **如果你是 RTMPose 的新用户，我们热切希望你能参与[这份问卷](https://uua478.fanqier.cn/f/xxmynrki)/[Google Questionnaire](https://docs.google.com/forms/d/e/1FAIpQLSfzwWr3eNlDzhU98qzk2Eph44Zio6hi5r0iSwfO9wSARkHdWg/viewform?usp=sf_link)，这对于我们的工作非常重要！**\n\n✨ ✨ ✨\n\n欢迎加入我们的社区交流群获得更多帮助：\n\n- 微信用户群\n\n<div align=left>\n<img src=\"https://user-images.githubusercontent.com/13503330/222647056-875bed70-85ec-455c-9016-c024772915c4.jpg\" width=200 />\n\n- Discord Group:\n  - 🙌 https://discord.gg/raweFPmdzG 🙌\n\n## ⚡ Pipeline 性能 [🔝](#-table-of-contents)\n\n**说明**\n\n- Pipeline 速度测试时开启了隔帧检测策略，默认检测间隔为 5 帧。\n- 环境配置:\n  - torch >= 1.7.1\n  - onnxruntime 1.12.1\n  - TensorRT 8.4.3.1\n  - cuDNN 8.3.2\n  - CUDA 11.3\n- **更新**：我们推荐你使用混合数据集训练的 `Body8` 模型，性能高于下表中提供的模型，[传送门](#人体-2d-关键点)。\n\n| Detection Config                                                    | Pose Config                                                                   | Input Size<sup><br>(Det/Pose) | Model AP<sup><br>(COCO) | Pipeline AP<sup><br>(COCO) | Params (M)<sup><br>(Det/Pose) | Flops (G)<sup><br>(Det/Pose) | ORT-Latency(ms)<sup><br>(i7-11700) | TRT-FP16-Latency(ms)<sup><br>(GTX 1660Ti) |                                                                                                                                  Download                                                                                                                                  |\n| :------------------------------------------------------------------ | :---------------------------------------------------------------------------- | :---------------------------: | :---------------------: | :------------------------: | :---------------------------: | :--------------------------: | :--------------------------------: | :---------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-t](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>67.1       |            64.4            |         0.99<br/>3.34         |        0.31<br/>0.36         |               12.403               |                   2.467                   | [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.pth) |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-s](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>71.1       |            68.5            |         0.99<br/>5.47         |        0.31<br/>0.68         |               16.658               |                   2.730                   |  [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth)   |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>75.3       |            73.2            |        0.99<br/>13.59         |        0.31<br/>1.93         |               26.613               |                   4.312                   |  [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth)   |\n| [RTMDet-nano](./rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py) | [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |      320x320<br>256x192       |      40.3<br>76.3       |            74.2            |        0.99<br/>27.66         |        0.31<br/>4.16         |               36.311               |                   4.644                   |  [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth)   |\n| [RTMDet-m](./rtmdet/person/rtmdet_m_640-8xb32_coco-person.py)       | [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |      640x640<br>256x192       |      62.5<br>75.3       |            75.7            |        24.66<br/>13.59        |        38.95<br/>1.93        |                 -                  |                   6.923                   |    [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth)    |\n| [RTMDet-m](./rtmdet/person/rtmdet_m_640-8xb32_coco-person.py)       | [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |      640x640<br>256x192       |      62.5<br>76.3       |            76.6            |        24.66<br/>27.66        |        38.95<br/>4.16        |                 -                  |                   7.204                   |    [det](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth)<br/>[pose](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth)    |\n\n## 📊 模型库 [🔝](#-table-of-contents)\n\n**说明**\n\n- 此处提供的模型采用了多数据集联合训练以提高性能，模型指标不适用于学术比较。\n- 表格中为开启了 Flip Test 的测试结果。\n- RTMPose 在更多公开数据集上的性能指标可以前往 [Model Zoo](https://mmpose.readthedocs.io/en/latest/model_zoo_papers/algorithms.html) 查看。\n- RTMPose 在更多硬件平台上的推理速度可以前往 [Benchmark](./benchmark/README_CN.md) 查看。\n- 如果你有希望我们支持的数据集，欢迎[联系我们](https://uua478.fanqier.cn/f/xxmynrki)/[Google Questionnaire](https://docs.google.com/forms/d/e/1FAIpQLSfzwWr3eNlDzhU98qzk2Eph44Zio6hi5r0iSwfO9wSARkHdWg/viewform?usp=sf_link)！\n\n### 人体 2d 关键点\n\n#### 17 Keypoints\n\n- 关键点骨架定义遵循 [COCO](http://cocodataset.org/). 详情见 [meta info](/configs/_base_/datasets/coco.py).\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/2417e4f7-2203-468f-bad0-e7a6a6bf8251\" height=\"300px\">\n\n<details close>\n<summary><b>AIC+COCO</b></summary>\n\n|                                    Config                                     | Input Size | AP<sup><br>(COCO) | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                   Download                                                                    |\n| :---------------------------------------------------------------------------: | :--------: | :---------------: | :---------------------: | :-----------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :-------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   |       68.5        |          91.28          |        63.38        |        3.34        |       0.36        |                    3.20                     |                        1.06                        |                          9.02                           | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-tiny_simcc-aic-coco_pt-aic-coco_420e-256x192-cfc8f33d_20230126.pth) |\n| [RTMPose-s](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |       72.2        |          92.95          |        66.19        |        5.47        |       0.68        |                    4.48                     |                        1.39                        |                          13.89                          |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth)   |\n| [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |       75.8        |          94.13          |        68.53        |       13.59        |       1.93        |                    11.06                    |                        2.29                        |                          26.44                          |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth)   |\n| [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |       76.5        |          94.35          |        68.98        |       27.66        |       4.16        |                    18.85                    |                        3.46                        |                          45.37                          |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-256x192-f016ffe0_20230126.pth)   |\n| [RTMPose-m](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py) |  384x288   |       77.0        |          94.32          |        69.85        |       13.72        |       4.33        |                    24.78                    |                        3.66                        |                            -                            |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-384x288-a62a0b32_20230228.pth)   |\n| [RTMPose-l](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py) |  384x288   |       77.3        |          94.54          |        70.14        |       27.79        |       9.35        |                      -                      |                        6.05                        |                            -                            |  [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-aic-coco_pt-aic-coco_420e-384x288-97d6cb0f_20230228.pth)   |\n\n</details>\n\n<details open>\n<summary><b>Body8</b></summary>\n\n- `*` 代表模型在 7 个开源数据集上训练得到：\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [MS COCO](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n- `Body8` 代表除了以上提到的 7 个数据集，再加上 [OCHuman](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#ochuman) 合并后一起进行评测得到的指标。\n\n|                                     Config                                      | Input Size | AP<sup><br>(COCO) | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                                                                                        Download                                                                                                                                        |\n| :-----------------------------------------------------------------------------: | :--------: | :---------------: | :---------------------: | :-----------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   |       65.9        |          91.44          |        63.18        |        3.34        |       0.36        |                    3.20                     |                        1.06                        |                          9.02                           | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7_420e-256x192-026a1439_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-body7_pt-body7_420e-256x192-026a1439_20230504.zip) |\n| [RTMPose-s\\*](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |       69.7        |          92.45          |        65.15        |        5.47        |       0.68        |                    4.48                     |                        1.39                        |                          13.89                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |       74.9        |          94.25          |        68.59        |       13.59        |       1.93        |                    11.06                    |                        2.29                        |                          26.44                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |       76.7        |          95.08          |        70.14        |       27.66        |       4.16        |                    18.85                    |                        3.46                        |                          45.37                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py) |  384x288   |       76.6        |          94.64          |        70.38        |       13.72        |       4.33        |                    24.78                    |                        3.66                        |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py) |  384x288   |       78.3        |          95.36          |        71.58        |       27.79        |       9.35        |                      -                      |                        6.05                        |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.zip) |\n| [RTMPose-x\\*](./rtmpose/body_2d_keypoint/rtmpose-x_8xb256-700e_coco-384x288.py) |  384x288   |       78.8        |            -            |          -          |       49.43        |       17.22       |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-body7_pt-body7_700e-384x288-71d7b7e9_20230629.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-x_simcc-body7_pt-body7_700e-384x288-71d7b7e9_20230629.zip) |\n\n</details>\n\n<details open>\n<summary><b>Human-Art</b></summary>\n\n- 面向艺术图片的人体姿态估计 RTMPose 模型由 [Human-Art](https://github.com/IDEA-Research/HumanArt) 提供。\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/685bc610-dd9e-4e6f-9c41-dbc8220584f4\" height=\"300px\">\n\n人体检测模型：\n\n|       Detection Config        | Input Size | Model AP<sup><br>(OneHand10K) | Flops<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |        Download        |\n| :---------------------------: | :--------: | :---------------------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :--------------------: |\n| [RTMDet-tiny](./rtmdet/person/rtmdet_tiny_8xb32-300e_humanart.py) |  640x640   |             46.6              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_tiny_8xb32-300e_humanart-7da5554e.pth) |\n| [RTMDet-s](./rtmdet/person/rtmdet_s_8xb32-300e_humanart.py) |  640x640   |             50.6              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_s_8xb32-300e_humanart-af5bd52d.pth) |\n| [YOLOX-nano](./yolox/humanart/yolox_nano_8xb8-300e_humanart.py) |  640x640   |             38.9              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_nano_8xb8-300e_humanart-40f6f0d0.pth) |\n| [YOLOX-tiny](./yolox/humanart/yolox_tiny_8xb8-300e_humanart.py) |  640x640   |             47.7              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_tiny_8xb8-300e_humanart-6f3252f9.pth) |\n| [YOLOX-s](./yolox/humanart/yolox_s_8xb8-300e_humanart.py) |  640x640   |             54.6              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_s_8xb8-300e_humanart-3ef259a7.pth) |\n| [YOLOX-m](./yolox/humanart/yolox_m_8xb8-300e_humanart.py) |  640x640   |             59.1              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_m_8xb8-300e_humanart-c2c7a14a.pth) |\n| [YOLOX-l](./yolox/humanart/yolox_l_8xb8-300e_humanart.py) |  640x640   |             60.2              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_l_8xb8-300e_humanart-ce1d7a62.pth) |\n| [YOLOX-x](./yolox/humanart/yolox_x_8xb8-300e_humanart.py) |  640x640   |             61.3              |         -         |                      -                      |                         -                          | [Det Model](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/yolox_x_8xb8-300e_humanart-a39d44ed.pth) |\n\n人体姿态估计模型：\n\n|                                     Config                                      | Input Size | AP<sup><br>(Human-Art GT) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                                                                                   Download                                                                                                                                   |\n| :-----------------------------------------------------------------------------: | :--------: | :-----------------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py) |  256x192   |           65.5            |        3.34        |       0.36        |                    3.20                     |                        1.06                        |                          9.02                           | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_8xb256-420e_humanart-256x192-60b68c98_20230612.zip) |\n| [RTMPose-s\\*](./rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |           69.8            |        5.47        |       0.68        |                    4.48                     |                        1.39                        |                          13.89                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_8xb256-420e_humanart-256x192-5a3ac943_20230611.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |           72.8            |       13.59        |       1.93        |                    11.06                    |                        2.29                        |                          26.44                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_8xb256-420e_humanart-256x192-8430627b_20230611.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |           75.3            |       27.66        |       4.16        |                    18.85                    |                        3.46                        |                          45.37                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_8xb256-420e_humanart-256x192-389f2cb0_20230611.zip) |\n\n</details>\n\n#### 26 Keypoints\n\n- 关键点骨架定义遵循 [Halpe26](https://github.com/Fang-Haoshu/Halpe-FullBody/)，详情见 [meta info](/configs/_base_/datasets/halpe26.py)。\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/f28ab3ba-833d-4ca7-8739-f97e6cafbab7\" height=\"300px\">\n- 模型在 `Body8` 上进行训练和评估。\n\n|                                          Config                                           | Input Size | PCK@0.1<sup><br>(Body8) | AUC<sup><br>(Body8) | Params(M) | FLOPS(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                                                                                                Download                                                                                                                                                |\n| :---------------------------------------------------------------------------------------: | :--------: | :---------------------: | :-----------------: | :-------: | :------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-t\\*](./rtmpose/body_2d_keypoint/rtmpose-t_8xb1024-700e_body8-halpe26-256x192.py) |  256x192   |          91.89          |        66.35        |   3.51    |   0.37   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-body7_pt-body7-halpe26_700e-256x192-6020f8a6_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-body7_pt-body7-halpe26_700e-256x192-6020f8a6_20230605.zip) |\n| [RTMPose-s\\*](./rtmpose/body_2d_keypoint/rtmpose-s_8xb1024-700e_body8-halpe26-256x192.py) |  256x192   |          93.01          |        68.62        |   5.70    |   0.70   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-body7_pt-body7-halpe26_700e-256x192-7f134165_20230605.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb512-700e_body8-halpe26-256x192.py)  |  256x192   |          94.75          |        71.91        |   13.93   |   1.95   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-256x192-4d3e73dd_20230605.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb512-700e_body8-halpe26-256x192.py)  |  256x192   |          95.37          |        73.19        |   28.11   |   4.19   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-256x192-2abb7558_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-256x192-2abb7558_20230605.zip) |\n| [RTMPose-m\\*](./rtmpose/body_2d_keypoint/rtmpose-m_8xb512-700e_body8-halpe26-384x288.py)  |  384x288   |          95.15          |        73.56        |   14.06   |   4.37   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-384x288-89e6428b_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-body7_pt-body7-halpe26_700e-384x288-89e6428b_20230605.zip) |\n| [RTMPose-l\\*](./rtmpose/body_2d_keypoint/rtmpose-l_8xb512-700e_body8-halpe26-384x288.py)  |  384x288   |          95.56          |        74.38        |   28.24   |   9.40   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-384x288-734182ce_20230605.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-body7_pt-body7-halpe26_700e-384x288-734182ce_20230605.zip) |\n| [RTMPose-x\\*](./rtmpose/body_2d_keypoint/rtmpose-x_8xb256-700e_body8-halpe26-384x288.py)  |  384x288   |          95.74          |        74.82        |   50.00   |  17.29   |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-body7_pt-body7-halpe26_700e-384x288-7fb6e239_20230606.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-x_simcc-body7_pt-body7-halpe26_700e-384x288-7fb6e239_20230606.zip) |\n\n#### 模型剪枝\n\n**说明**\n\n- 模型剪枝由 [MMRazor](https://github.com/open-mmlab/mmrazor) 提供\n\n|          Config           | Input Size | AP<sup><br>(COCO) | Params<sup><br>(M) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) | ncnn-FP16-Latency<sup><br>(ms)<sup><br>(Snapdragon 865) |                                                                     Download                                                                     |\n| :-----------------------: | :--------: | :---------------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-----------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------: |\n| RTMPose-s-aic-coco-pruned |  256x192   |       69.4        |        3.43        |       0.35        |                      -                      |                         -                          |                            -                            | [pth](https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth) |\n\n更多信息，请参考 [GroupFisher Pruning for RTMPose](./rtmpose/pruning/README.md).\n\n### 人体全身 2d 关键点 (133 Keypoints)\n\n- 关键点骨架定义遵循 [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/)，详情见 [meta info](/configs/_base_/datasets/coco_wholebody.py)。\n- <img src=\"https://user-images.githubusercontent.com/100993824/227770977-c8f00355-c43a-467e-8444-d307789cf4b2.png\" height=\"300px\">\n\n<details close>\n<summary><b>COCO-WholeBody</b></summary>\n\n| Config                          | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download              |\n| :------------------------------ | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-------------------------------: |\n| [RTMPose-m](./rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   58.2   |   67.4   |       2.22        |                    13.50                    |                        4.00                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.pth) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   61.1   |   70.0   |       4.52        |                    23.41                    |                        5.67                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-256x192-6f206314_20230124.pth) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   64.8   |   73.0   |       10.07       |                    44.58                    |                        7.68                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-coco-wholebody_pt-aic-coco_270e-384x288-eaeb96c8_20230125.pth) |\n| [RTMPose-x](./rtmpose/wholebody_2d_keypoint/rtmpose-x_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   65.3   |   73.3   |       18.1        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-x_simcc-coco-wholebody_pt-body7_270e-384x288-401dfc90_20230629.pth) |\n\n</details>\n\n<details open>\n<summary><b>Cocktail14</b></summary>\n\n- `Cocktail13` 代表模型在 13 个开源数据集上训练得到:\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n  - [COCO-Wholebody](https://github.com/jin-s13/COCO-WholeBody/)\n  - [UBody](https://github.com/IDEA-Research/OSX)\n  - [Human-Art](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#human-art-dataset)\n  - [WFLW](https://wywu.github.io/projects/LAB/WFLW.html)\n  - [300W](https://ibug.doc.ic.ac.uk/resources/300-W/)\n  - [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/)\n  - [LaPa](https://github.com/JDAI-CV/lapa-dataset)\n  - [InterHand](https://mks0601.github.io/InterHand2.6M/)\n\n| Config                          | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download              |\n| :------------------------------ | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-------------------------------: |\n| [RTMW-m](./rtmpose/wholebody_2d_keypoint/rtmw-m_8xb1024-270e_cocktail14-256x192.py) |  256x192   |   58.2   |   67.3   |        4.3        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-l-m_simcc-cocktail14_270e-256x192-20231122.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmw/onnx_sdk/rtmw-dw-m-s_simcc-cocktail14_270e-256x192_20231122.zip) |\n| [RTMW-l](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb704-270e_cocktail14-256x192.py) |  256x192   |   66.0   |   74.6   |        7.9        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-256x192-20231122.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmw/onnx_sdk/rtmw-dw-x-l_simcc-cocktail14_270e-256x192_20231122.zip) |\n| [RTMW-x](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb704-270e_cocktail14-256x192.py) |  256x192   |   67.2   |   75.2   |       13.1        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-256x192-13a2546d_20231208.pth) |\n| [RTMW-l](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb320-270e_cocktail14-384x288.py) |  384x288   |   70.1   |   78.0   |       17.7        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-384x288-20231122.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmw/onnx_sdk/rtmw-dw-x-l_simcc-cocktail14_270e-384x288_20231122.zip) |\n| [RTMW-x](./rtmpose/wholebody_2d_keypoint/rtmw-x_8xb320-270e_cocktail14-384x288.py) |  384x288   |   70.2   |   78.1   |       29.3        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmw/rtmw-x_simcc-cocktail14_pt-ucoco_270e-384x288-f840f204_20231122.pth) |\n\n</details>\n\n<details open>\n<summary><b>COCO+UBody</b></summary>\n\n- DWPose 模型由 [DWPose](https://github.com/IDEA-Research/DWPose) 项目提供\n- 模型在以下数据集上训练并蒸馏:\n  - [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/)\n  - [UBody](https://github.com/IDEA-Research/OSX)\n\n| Config                          | Input Size | Whole AP | Whole AR | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download              |\n| :------------------------------ | :--------: | :------: | :------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :-------------------------------: |\n| [RTMPose-t](./rtmpose/wholebody_2d_keypoint/rtmpose-t_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   48.5   |   58.4   |        0.5        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-ucoco_dw-ucoco_270e-256x192-dcf277bf_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-ucoco_dw-ucoco_270e-256x192-dcf277bf_20230728.zip) |\n| [RTMPose-s](./rtmpose/wholebody_2d_keypoint/rtmpose-s_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   53.8   |   63.2   |        0.9        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-ucoco_dw-ucoco_270e-256x192-3fd922c8_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-ucoco_dw-ucoco_270e-256x192-3fd922c8_20230728.zip) |\n| [RTMPose-m](./rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   60.6   |   69.5   |       2.22        |                    13.50                    |                        4.00                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.zip) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   63.1   |   71.7   |       4.52        |                    23.41                    |                        5.67                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.zip) |\n| [RTMPose-l](./rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   66.5   |   74.3   |       10.07       |                    44.58                    |                        7.68                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-l_simcc-ucoco_dw-ucoco_270e-384x288-2438fd99_20230728.zip) |\n\n</details>\n\n### 动物 2d 关键点 (17 Keypoints)\n\n- 关键点骨架定义遵循 [AP-10K](https://github.com/AlexTheBad/AP-10K/)，详情见 [meta info](/configs/_base_/datasets/ap10k.py)。\n- <img src=\"https://user-images.githubusercontent.com/100993824/227797151-091dc21a-d944-49c9-8b62-cc47fa89e69f.png\" height=\"300px\">\n\n|             Config             | Input Size | AP<sup><br>(AP10K) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download             |\n| :----------------------------: | :--------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :------------------------------: |\n| [RTMPose-m](./rtmpose/animal_2d_keypoint/rtmpose-m_8xb64-210e_ap10k-256x256.py) |  256x256   |        72.2        |       2.57        |                   14.157                    |                       2.404                        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-ap10k_pt-aic-coco_210e-256x256-7a041aa1_20230206.zip) |\n\n### 脸部 2d 关键点 (106 Keypoints)\n\n- 关键点骨架定义遵循 [LaPa](https://github.com/JDAI-CV/lapa-dataset)，详情见 [meta info](/configs/_base_/datasets/lapa.py)。\n- <img src=\"https://github.com/open-mmlab/mmpose/assets/13503330/30fa583e-500c-4356-ac5a-7e9d7d18381a\" height=\"300px\">\n\n<details open>\n<summary><b>Face6</b></summary>\n\n- `Face6` and `*` 代表模型在 6 个开源数据集上训练得到：\n  - [COCO-Wholebody-Face](https://github.com/jin-s13/COCO-WholeBody/)\n  - [WFLW](https://wywu.github.io/projects/LAB/WFLW.html)\n  - [300W](https://ibug.doc.ic.ac.uk/resources/300-W/)\n  - [COFW](http://www.vision.caltech.edu/xpburgos/ICCV13/)\n  - [Halpe](https://github.com/Fang-Haoshu/Halpe-FullBody/)\n  - [LaPa](https://github.com/JDAI-CV/lapa-dataset)\n\n|             Config             | Input Size | NME<sup><br>(LaPa) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |             Download             |\n| :----------------------------: | :--------: | :----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :------------------------------: |\n| [RTMPose-t\\*](./rtmpose/face_2d_keypoint/rtmpose-t_8xb256-120e_lapa-256x256.py) |  256x256   |        1.67        |       0.652       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-t_simcc-face6_pt-in1k_120e-256x256-df79d9a5_20230529.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-t_simcc-face6_pt-in1k_120e-256x256-df79d9a5_20230529.zip) |\n| [RTMPose-s\\*](./rtmpose/face_2d_keypoint/rtmpose-s_8xb256-120e_lapa-256x256.py) |  256x256   |        1.59        |       1.119       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-s_simcc-face6_pt-in1k_120e-256x256-d779fdef_20230529.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-s_simcc-face6_pt-in1k_120e-256x256-d779fdef_20230529.zip) |\n| [RTMPose-m\\*](./rtmpose/face_2d_keypoint/rtmpose-m_8xb256-120e_lapa-256x256.py) |  256x256   |        1.44        |       2.852       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-face6_pt-in1k_120e-256x256-72a37400_20230529.zip) |\n\n</details>\n\n### 手部 2d 关键点 (21 Keypoints)\n\n- 关键点骨架定义遵循 [COCO-WholeBody](https://github.com/jin-s13/COCO-WholeBody/)，详情见 [meta info](/configs/_base_/datasets/coco_wholebody_hand.py)。\n- <img src=\"https://user-images.githubusercontent.com/100993824/227771101-03a27bd8-ccc0-4eb9-a111-660f191a7a16.png\" height=\"300px\">\n\n|       Detection Config        | Input Size | Model AP<sup><br>(OneHand10K) | Flops<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |        Download        |\n| :---------------------------: | :--------: | :---------------------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :--------------------: |\n| [RTMDet-nano<sup><br>(alpha version)](./rtmdet/hand/rtmdet_nano_320-8xb32_hand.py) |  320x320   |             76.0              |       0.31        |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmdet_nano_8xb32-300e_hand-267f9c8f.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmdet_nano_8xb32-300e_hand-267f9c8f.zip) |\n\n<details open>\n<summary><b>Hand5</b></summary>\n\n- `Hand5` and `*` 代表模型在 5 个开源数据集上训练得到：\n  - [COCO-Wholebody-Hand](https://github.com/jin-s13/COCO-WholeBody/)\n  - [OneHand10K](https://www.yangangwang.com/papers/WANG-MCC-2018-10.html)\n  - [FreiHand2d](https://lmb.informatik.uni-freiburg.de/projects/freihand/)\n  - [RHD2d](https://lmb.informatik.uni-freiburg.de/resources/datasets/RenderedHandposeDataset.en.html)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n\n|                                                        Config                                                         | Input Size | PCK@0.2<sup><br>(COCO-Wholebody-Hand) | PCK@0.2<sup><br>(Hand5) | AUC<sup><br>(Hand5) | FLOPS<sup><br>(G) | ORT-Latency<sup><br>(ms)<sup><br>(i7-11700) | TRT-FP16-Latency<sup><br>(ms)<sup><br>(GTX 1660Ti) |                                                                                                                                          Download                                                                                                                                          |\n| :-------------------------------------------------------------------------------------------------------------------: | :--------: | :-----------------------------------: | :---------------------: | :-----------------: | :---------------: | :-----------------------------------------: | :------------------------------------------------: | :----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n| [RTMPose-m\\*<sup><br>(alpha version)](./rtmpose/hand_2d_keypoint/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py) |  256x256   |                 81.5                  |          96.4           |        83.9         |       2.581       |                      -                      |                         -                          | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.pth)<br>[onnx](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/onnx_sdk/rtmpose-m_simcc-hand5_pt-aic-coco_210e-256x256-74fb594_20230320.zip) |\n\n</details>\n\n### 预训练模型\n\n我们提供了 UDP 预训练的 CSPNeXt 模型参数，训练配置请参考 [pretrain_cspnext_udp folder](./rtmpose/pretrain_cspnext_udp/)。\n\n<details close>\n<summary><b>AIC+COCO</b></summary>\n\n|    Model     | Input Size | Params<sup><br>(M) | Flops<sup><br>(G) | AP<sup><br>(GT) | AR<sup><br>(GT) |                                                     Download                                                      |\n| :----------: | :--------: | :----------------: | :---------------: | :-------------: | :-------------: | :---------------------------------------------------------------------------------------------------------------: |\n| CSPNeXt-tiny |  256x192   |        6.03        |       1.43        |      65.5       |      68.9       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth) |\n|  CSPNeXt-s   |  256x192   |        8.58        |       1.78        |      70.0       |      73.3       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth) |\n|  CSPNeXt-m   |  256x192   |       17.53        |       3.05        |      74.8       |      77.7       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth) |\n|  CSPNeXt-l   |  256x192   |       32.44        |       5.32        |      77.2       |      79.9       | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmpose/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth) |\n\n</details>\n\n<details open>\n<summary><b>Body8</b></summary>\n\n- `*` 代表模型在 7 个开源数据集上训练得到：\n  - [AI Challenger](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#aic)\n  - [MS COCO](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco)\n  - [CrowdPose](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#crowdpose)\n  - [MPII](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#mpii)\n  - [sub-JHMDB](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#sub-jhmdb-dataset)\n  - [Halpe](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_wholebody_keypoint.html#halpe)\n  - [PoseTrack18](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#posetrack18)\n- `Body8` 代表除了以上提到的 7 个数据集，再加上 [OCHuman](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#ochuman) 合并后一起进行评测得到的指标。\n\n|     Model      | Input Size | Params<sup><br>(M) | Flops<sup><br>(G) | AP<sup><br>(COCO) | PCK@0.2<sup><br>(Body8) | AUC<sup><br>(Body8) |                                      Download                                      |\n| :------------: | :--------: | :----------------: | :---------------: | :---------------: | :---------------------: | :-----------------: | :--------------------------------------------------------------------------------: |\n| CSPNeXt-tiny\\* |  256x192   |        6.03        |       1.43        |       65.9        |          96.34          |        63.80        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-tiny_udp-body7_210e-256x192-a3775292_20230504.pth) |\n|  CSPNeXt-s\\*   |  256x192   |        8.58        |       1.78        |       68.7        |          96.59          |        64.92        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-s_udp-body7_210e-256x192-8c9ccbdb_20230504.pth) |\n|  CSPNeXt-m\\*   |  256x192   |       17.53        |       3.05        |       73.7        |          97.42          |        68.19        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-body7_210e-256x192-e0c9327b_20230504.pth) |\n|  CSPNeXt-l\\*   |  256x192   |       32.44        |       5.32        |       75.7        |          97.76          |        69.57        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-body7_210e-256x192-5e9558ef_20230504.pth) |\n|  CSPNeXt-m\\*   |  384x288   |       17.53        |       6.86        |       75.8        |          97.60          |        70.18        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-m_udp-body7_210e-384x288-b9bc2b57_20230504.pth) |\n|  CSPNeXt-l\\*   |  384x288   |       32.44        |       11.96       |       77.2        |          97.89          |        71.23        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-l_udp-body7_210e-384x288-b15bc30d_20230504.pth) |\n|  CSPNeXt-x\\*   |  384x288   |       54.92        |       19.96       |       78.1        |          98.00          |        71.79        | [pth](https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth) |\n\n</details>\n\n#### ImageNet\n\n我们提供了 ImageNet 分类训练的 CSPNeXt 模型参数，更多细节请参考 [RTMDet](https://github.com/open-mmlab/mmdetection/blob/latest/configs/rtmdet/README.md#classification)。\n\n|    Model     | Input Size | Params<sup><br>(M) | Flops<sup><br>(G) | Top-1 (%) | Top-5 (%) |                                                           Download                                                            |\n| :----------: | :--------: | :----------------: | :---------------: | :-------: | :-------: | :---------------------------------------------------------------------------------------------------------------------------: |\n| CSPNeXt-tiny |  224x224   |        2.73        |       0.34        |   69.44   |   89.45   |  [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-tiny_imagenet_600e-3a2dd350.pth)   |\n|  CSPNeXt-s   |  224x224   |        4.89        |       0.66        |   74.41   |   92.23   |    [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-s_imagenet_600e-ea671761.pth)    |\n|  CSPNeXt-m   |  224x224   |       13.05        |       1.93        |   79.27   |   94.79   | [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth) |\n|  CSPNeXt-l   |  224x224   |       27.16        |       4.19        |   81.30   |   95.62   | [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth) |\n|  CSPNeXt-x   |  224x224   |       48.85        |       7.76        |   82.10   |   95.69   | [pth](https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-x_8xb256-rsb-a1-600e_in1k-b3f78edd.pth) |\n\n## 👀 可视化 [🔝](#-table-of-contents)\n\n<div align=center>\n<img src='https://user-images.githubusercontent.com/13503330/221795678-2c4ae2ec-ac23-4368-8083-0ebeb29f0d3c.gif' width=900/>\n<img src=\"https://user-images.githubusercontent.com/13503330/219270443-421d9b02-fcec-46de-90f2-ce769c67575a.png\" width=900 />\n</div>\n\n## 😎 快速尝试 [🔝](#-table-of-contents)\n\n我们提供了多种途径来让用户尝试 RTMPose 模型：\n\n- [在线 RTMPose Demo](https://openxlab.org.cn/apps/detail/mmpose/RTMPose)\n- [Examples](https://github.com/open-mmlab/mmpose/tree/dev-1.x/projects/rtmpose/examples/onnxruntime) 基于 Python 和 ONNXRuntime （无 MMCV 依赖）\n- [rtmlib 推理库](https://github.com/Tau-J/rtmlib/tree/main) （无 MMCV、Pytorch 依赖）\n- MMPose demo 脚本 （基于 Pytorch）\n- MMDeploy SDK 预编译包 （推荐，速度提升6-10倍）\n\n### rtmlib 推理库\n\n[rtmlib](https://github.com/Tau-J/rtmlib/tree/main) 提供了开箱即用的 RTMPose 全系列官方及衍生模型的推理：\n\n- 无需安装 mmcv，mmengine，mmpose 等一系列训练库，无需 pytorch 环境，有 opencv 就能推理\n- 超级友好简洁的推理和可视化接口\n- 支持 CPU 和 GPU 推理\n- 自动下载和缓存 onnx 模型\n- 支持 RTMPose 全系列官方及衍生模型：RTMPose，DWPose，RTMO，RTMW etc.\n\n### MMPose demo 脚本\n\n通过 MMPose 提供的 demo 脚本可以基于 Pytorch 快速进行[模型推理](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html)和效果验证。\n\n**提示：**\n\n- 基于 Pytorch 推理并不能达到 RTMPose 模型的最大推理速度，只用于模型效果验证。\n- 输入模型路径可以是本地路径，也可以是下载链接。\n\n```shell\n# 前往 mmpose 目录\ncd ${PATH_TO_MMPOSE}\n\n# RTMDet 与 RTMPose 联合推理\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input {YOUR_TEST_IMG_or_VIDEO} \\\n    --show\n\n# 摄像头推理\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input webcam \\\n    --show\n```\n\n效果展示：\n\n![topdown_inference_with_rtmdet](https://user-images.githubusercontent.com/13503330/220005020-06bdf37f-6817-4681-a2c8-9dd55e4fbf1e.png)\n\n### MMDeploy SDK 预编译包 （推荐）\n\nMMDeploy 提供了预编译的 SDK，用于对 RTMPose 项目进行 Pipeline 推理，其中推理所用的模型为 SDK 版本。\n\n- 所有的模型必须经过 `tools/deploy.py` 导出后才能使用 PoseTracker 进行推理。\n- 导出 SDK 版模型的教程见 [SDK 推理](#%EF%B8%8F-sdk-推理)，推理的详细参数设置见 [Pipeline 推理](#-pipeline-推理)。\n- 你可以从 [硬件模型库](https://platform.openmmlab.com/deploee) 直接下载 SDK 版模型（ONNX、 TRT、ncnn 等）。\n- 同时我们也支持 [在线模型转换](https://platform.openmmlab.com/deploee/task-convert-list)。\n\n#### Linux\\\\\n\n说明：\n\n- GCC 版本需大于 7.5\n- cmake 版本需大于 3.20\n\n##### Python 推理\n\n1. 安装 mmdeploy_runtime 或者 mmdeploy_runtime_gpu\n\n```shell\n# for onnxruntime\npip install mmdeploy-runtime\n\n# for onnxruntime-gpu / tensorrt\npip install mmdeploy-runtime-gpu\n```\n\n2. 下载预编译包：\n\n```shell\n# onnxruntime\n# for ubuntu\nwget -c  https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n# 解压并将 third_party 中第三方推理库的动态库添加到 PATH\n\n# for centos7 and lower\nwget -c https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64.tar.gz\n# 解压并将 third_party 中第三方推理库的动态库添加到 PATH\n\n# onnxruntime-gpu / tensorrt\n# for ubuntu\nwget -c  https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3.tar.gz\n# 解压并将 third_party 中第三方推理库的动态库添加到 PATH\n\n# for centos7 and lower\nwget -c https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cuda11.3.tar.gz\n# 解压并将 third_party 中第三方推理库的动态库添加到 PATH\n```\n\n3. 下载 sdk 模型并解压到 `./example/python` 下。（该模型只用于演示，如需其他模型，请参考 [SDK 推理](#%EF%B8%8F-sdk-推理)）\n\n```shell\n# rtmdet-nano + rtmpose-m for cpu sdk\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-cpu.zip\n\nunzip rtmpose-cpu.zip\n```\n\n4. 使用 `pose_tracker.py` 进行推理：\n\n```shell\n# 进入 ./example/python\n\n# 请传入模型目录，而不是模型文件\n# 格式：\n# python pose_tracker.py cpu {det work-dir} {pose work-dir} {your_video.mp4}\n\n# 示例：\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4\n\n# 摄像头\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0\n```\n\n##### ONNX\n\n```shell\n# 下载预编译包\nwget https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n\n# 解压文件\ntar -xzvf mmdeploy-1.0.0-linux-x86_64-cxx11abi.tar.gz\n\n# 切换到 sdk 目录\ncd mmdeploy-1.0.0-linux-x86_64-cxx11abi\n\n# 设置环境变量\nsource set_env.sh\n\n# 如果系统中没有安装 opencv 3+，请执行以下命令。如果已安装，可略过\nbash install_opencv.sh\n\n# 编译可执行程序\nbash build_sdk.sh\n\n# 图片推理\n# 请传入模型目录，而不是模型文件\n./bin/det_pose rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_img.jpg --device cpu\n\n# 视频推理\n# 请传入模型目录，而不是模型文件\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4 --device cpu\n\n# 摄像头推理\n# 请传入模型目录，而不是模型文件\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0 --device cpu\n```\n\n##### TensorRT\n\n```shell\n# 下载预编译包\nwget https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3.tar.gz\n\n# 解压文件\ntar -xzvf mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3.tar.gz\n\n# 切换到 sdk 目录\ncd mmdeploy-1.0.0-linux-x86_64-cxx11abi-cuda11.3\n\n# 设置环境变量\nsource set_env.sh\n\n# 如果系统中没有安装 opencv 3+，请执行以下命令。如果已安装，可略过\nbash install_opencv.sh\n\n# 编译可执行程序\nbash build_sdk.sh\n\n# 图片推理\n# 请传入模型目录，而不是模型文件\n./bin/det_pose rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_img.jpg --device cuda\n\n# 视频推理\n# 请传入模型目录，而不是模型文件\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4 --device cuda\n\n# 摄像头推理\n# 请传入模型目录，而不是模型文件\n./bin/pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0 --device cuda\n```\n\n详细参数设置见 [Pipeline 推理](#-pipeline-推理)。\n\n#### Windows\n\n##### Python 推理\n\n1. 安装 mmdeploy_runtime 或者 mmdeploy_runtime_gpu\n\n```shell\n# for onnxruntime\npip install mmdeploy-runtime\n# 下载 [sdk](https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-windows-amd64.zip) 并将 third_party 中第三方推理库的动态库添加到 PATH\n\n# for onnxruntime-gpu / tensorrt\npip install mmdeploy-runtime-gpu\n# 下载 [sdk](https://github.com/open-mmlab/mmdeploy/releases/download/v1.0.0/mmdeploy-1.0.0-windows-amd64-cuda11.3.zip) 并将 third_party 中第三方推理库的动态库添加到 PATH\n```\n\n2. 下载 sdk 模型并解压到 `./example/python` 下。（该模型只用于演示，如需其他模型，请参考 [SDK 推理](#%EF%B8%8F-sdk-推理)）\n\n```shell\n# rtmdet-nano + rtmpose-m for cpu sdk\nwget https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-cpu.zip\n\nunzip rtmpose-cpu.zip\n```\n\n3. 使用 `pose_tracker.py` 进行推理：\n\n```shell\n# 进入 ./example/python\n# 请传入模型目录，而不是模型文件\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4\n\n# 摄像头\n# 请传入模型目录，而不是模型文件\npython pose_tracker.py cpu rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ 0\n```\n\n##### 可执行文件推理\n\n1. 安装 [cmake](https://cmake.org/download/)。\n2. 前往 [mmdeploy](https://github.com/open-mmlab/mmdeploy/releases) 下载 win 预编译包。\n3. 解压文件，进入 sdk 目录。\n4. 使用管理员权限打开 PowerShell，执行以下命令：\n\n```shell\nset-ExecutionPolicy RemoteSigned\n```\n\n5. 安装 OpenCV：\n\n```shell\n# in sdk folder:\n.\\install_opencv.ps1\n```\n\n6. 配置环境变量：\n\n```shell\n# in sdk folder:\n. .\\set_env.ps1\n```\n\n7. 编译 sdk：\n\n```shell\n# in sdk folder:\n# 如果你通过 .\\install_opencv.ps1 安装 opencv，直接运行如下指令：\n.\\build_sdk.ps1\n# 如果你自行安装了 opencv，需要指定 OpenCVConfig.cmake 的路径：\n.\\build_sdk.ps1 \"path/to/folder/of/OpenCVConfig.cmake\"\n```\n\n8. 可执行文件会在如下路径生成：\n\n```shell\nexample\\cpp\\build\\Release\n```\n\n### MMPose demo 脚本\n\n通过 MMPose 提供的 demo 脚本可以基于 Pytorch 快速进行[模型推理](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html)和效果验证。\n\n**提示：**\n\n- 基于 Pytorch 推理并不能达到 RTMPose 模型的真实推理速度，只用于模型效果验证。\n\n```shell\n# 前往 mmpose 目录\ncd ${PATH_TO_MMPOSE}\n\n# RTMDet 与 RTMPose 联合推理\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    {PATH_TO_CHECKPOINT}/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    {PATH_TO_CHECKPOINT}/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input {YOUR_TEST_IMG_or_VIDEO} \\\n    --show\n\n# 摄像头推理\npython demo/topdown_demo_with_mmdet.py \\\n    projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    {PATH_TO_CHECKPOINT}/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    {PATH_TO_CHECKPOINT}/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    --input webcam \\\n    --show\n```\n\n效果展示：\n\n![topdown_inference_with_rtmdet](https://user-images.githubusercontent.com/13503330/220005020-06bdf37f-6817-4681-a2c8-9dd55e4fbf1e.png)\n\n## 👨‍🏫 模型训练 [🔝](#-table-of-contents)\n\n请参考 [训练与测试](https://mmpose.readthedocs.io/en/latest/user_guides/train_and_test.html) 进行 RTMPose 的训练。\n\n**提示**：\n\n- 当用户的数据集较小时请根据情况缩小 `batch_size` 和 `base_lr`。\n- 模型选择\n  - m：推荐首选使用\n  - t/s：适用于极端低算力的移动设备，或对推理速度要求严格的场景\n  - l：适用于算力较强、对速度不敏感的场景\n\n## 🏗️ 部署教程 [🔝](#-table-of-contents)\n\n本教程将展示如何通过 [MMDeploy](https://github.com/open-mmlab/mmdeploy/tree/main) 部署 RTMPose 项目。\n\n- 你可以从 [硬件模型库](https://platform.openmmlab.com/deploee) 直接下载 SDK 版模型（ONNX、 TRT、ncnn 等）。\n- 同时我们也支持 [在线模型转换](https://platform.openmmlab.com/deploee/task-convert-list)。\n\n### 🧩 安装\n\n在开始部署之前，首先你需要确保正确安装了 MMPose, MMDetection, MMDeploy，相关安装教程如下：\n\n- [安装 MMPose 与 MMDetection](https://mmpose.readthedocs.io/zh_CN/latest/installation.html)\n- [安装 MMDeploy](https://mmdeploy.readthedocs.io/zh_CN/latest/04-supported-codebases/mmpose.html)\n\n根据部署后端的不同，有的后端需要对自定义算子进行编译，请根据需求前往对应的文档确保环境搭建正确：\n\n- [ONNX](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/onnxruntime.html)\n- [TensorRT](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/tensorrt.html)\n- [OpenVINO](https://mmdeploy.readthedocs.io/zh_CN/latest/05-supported-backends/openvino.html)\n- [TorchScript](https://mmdeploy.readthedocs.io/en/latest/05-supported-backends/torchscript.html)\n- [更多](https://github.com/open-mmlab/mmdeploy/tree/main/docs/en/05-supported-backends)\n\n### 🛠️ 模型转换\n\n在完成安装之后，你就可以开始模型部署了。通过 MMDeploy 提供的 `tools/deploy.py` 可以方便地将 Pytorch 模型转换到不同的部署后端。\n\n我们本节演示将 RTMDet 和 RTMPose 模型导出为 ONNX 和 TensorRT 格式，如果你希望了解更多内容请前往 [MMDeploy 文档](https://mmdeploy.readthedocs.io/zh_CN/latest/02-how-to-run/convert_model.html)。\n\n- ONNX 配置\n\n  \\- RTMDet：[`detection_onnxruntime_static.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmdet/detection/detection_onnxruntime_static.py)\n\n  \\- RTMPose：[`pose-detection_simcc_onnxruntime_dynamic.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py)\n\n- TensorRT 配置\n\n  \\- RTMDet：[`detection_tensorrt_static-320x320.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmdet/detection/detection_tensorrt_static-320x320.py)\n\n  \\- RTMPose：[`pose-detection_simcc_tensorrt_dynamic-256x192.py`](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py)\n\n- 更多\n\n  |   Backend   |                                                                                Config                                                                                |\n  | :---------: | :------------------------------------------------------------------------------------------------------------------------------------------------------------------: |\n  |  ncnn-fp16  | [pose-detection_simcc_ncnn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_ncnn-fp16_static-256x192.py) |\n  |   CoreML    |    [pose-detection_simcc_coreml_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_coreml_static-256x192.py)    |\n  |  OpenVINO   |  [pose-detection_simcc_openvino_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_openvino_static-256x192.py)  |\n  |    RKNN     | [pose-detection_simcc_rknn-fp16_static-256x192.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_simcc_rknn-fp16_static-256x192.py) |\n  | TorchScript |                    [pose-detection_torchscript.py](https://github.com/open-mmlab/mmdeploy/blob/main/configs/mmpose/pose-detection_torchscript.py)                    |\n\n如果你需要对部署配置进行修改，请参考 [MMDeploy config tutorial](https://mmdeploy.readthedocs.io/zh_CN/latest/02-how-to-run/write_config.html).\n\n本教程中使用的文件结构如下：\n\n```shell\n|----mmdeploy\n|----mmdetection\n|----mmpose\n```\n\n#### ONNX\n\n运行如下命令：\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}\n\n# 转换 RTMDet\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmdet/detection/detection_onnxruntime_static.py \\\n    ../mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmdet-nano \\\n    --device cpu \\\n    --show \\\n    --dump-info   # 导出 sdk info\n\n# 转换 RTMPose\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmpose-m \\\n    --device cpu \\\n    --show \\\n    --dump-info   # 导出 sdk info\n```\n\n默认导出模型文件为 `{work-dir}/end2end.onnx`\n\n#### TensorRT\n\n运行如下命令：\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}\n\n# 转换 RTMDet\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmdet/detection/detection_tensorrt_static-320x320.py \\\n    ../mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-trt/rtmdet-nano \\\n    --device cuda:0 \\\n    --show \\\n    --dump-info   # 导出 sdk info\n\n# 转换 RTMPose\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_tensorrt_dynamic-256x192.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-trt/rtmpose-m \\\n    --device cuda:0 \\\n    --show \\\n    --dump-info   # 导出 sdk info\n```\n\n默认导出模型文件为 `{work-dir}/end2end.engine`\n\n🎊 如果模型顺利导出，你将会看到样例图片上的检测结果：\n\n![convert_models](https://user-images.githubusercontent.com/13503330/217726963-7815dd01-561a-4605-b0c6-07b6fe1956c3.png)\n\n#### 高级设置\n\n如果需要使用 TensorRT-FP16，你可以通过修改以下配置开启：\n\n```Python\n# in MMDeploy config\nbackend_config = dict(\n    type='tensorrt',\n    common_config=dict(\n        fp16_mode=True  # 打开 fp16\n    ))\n```\n\n### 🕹️ SDK 推理\n\n要进行 Pipeline 推理，需要先用 MMDeploy 导出 SDK 版本的 det 和 pose 模型，只需要在参数中加上`--dump-info`。\n\n此处以 onnxruntime 的 cpu 模型为例，运行如下命令：\n\n```shell\n# RTMDet\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmdet/detection/detection_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_nano_8xb32-100e_coco-obj365-person-05d8511e.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmdet-nano \\\n    --device cpu \\\n    --show \\\n    --dump-info   # 导出 sdk info\n\n# RTMPose\n# 输入模型路径可以是本地路径，也可以是下载链接。\npython tools/deploy.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    ../mmpose/projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-m_simcc-aic-coco_pt-aic-coco_420e-256x192-63eb25f7_20230126.pth \\\n    demo/resources/human-pose.jpg \\\n    --work-dir rtmpose-ort/rtmpose-m \\\n    --device cpu \\\n    --show \\\n    --dump-info  # 导出 sdk info\n```\n\n默认会导出三个 json 文件：\n\n```shell\n|----sdk\n     |----end2end.onnx    # ONNX model\n     |----end2end.engine  # TensorRT engine file\n\n     |----pipeline.json   #\n     |----deploy.json     # json files for the SDK\n     |----detail.json     #\n```\n\n#### Python API\n\n```Python\n# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\n\nimport cv2\nimport numpy as np\nfrom mmdeploy_runtime import PoseDetector\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='show how to use sdk python api')\n    parser.add_argument('device_name', help='name of device, cuda or cpu')\n    parser.add_argument(\n        'model_path',\n        help='path of mmdeploy SDK model dumped by model converter')\n    parser.add_argument('image_path', help='path of an image')\n    parser.add_argument(\n        '--bbox',\n        default=None,\n        nargs='+',\n        type=int,\n        help='bounding box of an object in format (x, y, w, h)')\n    args = parser.parse_args()\n    return args\n\ndef main():\n    args = parse_args()\n\n    img = cv2.imread(args.image_path)\n\n    detector = PoseDetector(\n        model_path=args.model_path, device_name=args.device_name, device_id=0)\n\n    if args.bbox is None:\n        result = detector(img)\n    else:\n        # converter (x, y, w, h) -> (left, top, right, bottom)\n        print(args.bbox)\n        bbox = np.array(args.bbox, dtype=int)\n        bbox[2:] += bbox[:2]\n        result = detector(img, bbox)\n    print(result)\n\n    _, point_num, _ = result.shape\n    points = result[:, :, :2].reshape(point_num, 2)\n    for [x, y] in points.astype(int):\n        cv2.circle(img, (x, y), 1, (0, 255, 0), 2)\n\n    cv2.imwrite('output_pose.png', img)\n\nif __name__ == '__main__':\n    main()\n```\n\n#### C++ API\n\n```C++\n#include \"mmdeploy/pose_detector.hpp\"\n#include \"opencv2/imgcodecs.hpp\"\n#include \"opencv2/imgproc.hpp\"\n#include \"utils/argparse.h\" // See: https://github.com/open-mmlab/mmdeploy/blob/main/demo/csrc/cpp/utils/argparse.h\n\nDEFINE_ARG_string(model_path, \"Model path\");\nDEFINE_ARG_string(image_path, \"Input image path\");\nDEFINE_string(device_name, \"cpu\", R\"(Device name, e.g. \"cpu\", \"cuda\")\");\nDEFINE_int32(bbox_x, -1, R\"(x position of the bounding box)\");\nDEFINE_int32(bbox_y, -1, R\"(y position of the bounding box)\");\nDEFINE_int32(bbox_w, -1, R\"(width of the bounding box)\");\nDEFINE_int32(bbox_h, -1, R\"(height of the bounding box)\");\n\nint main(int argc, char* argv[]) {\n  if (!utils::ParseArguments(argc, argv)) {\n    return -1;\n  }\n\n  cv::Mat img = cv::imread(ARGS_image_path);\n\n  mmdeploy::PoseDetector detector(mmdeploy::Model{ARGS_model_path}, mmdeploy::Device{FLAGS_device_name, 0});\n\n  mmdeploy::PoseDetector::Result result{0, 0, nullptr};\n\n  if (FLAGS_bbox_x == -1 || FLAGS_bbox_y == -1 || FLAGS_bbox_w == -1 || FLAGS_bbox_h == -1) {\n    result = detector.Apply(img);\n  } else {\n    // convert (x, y, w, h) -> (left, top, right, bottom)\n    mmdeploy::cxx::Rect rect;\n    rect.left = FLAGS_bbox_x;\n    rect.top = FLAGS_bbox_y;\n    rect.right = FLAGS_bbox_x + FLAGS_bbox_w;\n    rect.bottom = FLAGS_bbox_y + FLAGS_bbox_h;\n    result = detector.Apply(img, {rect});\n  }\n\n  // Draw circles at detected keypoints\n  for (size_t i = 0; i < result[0].length; ++i) {\n    cv::Point keypoint(result[0].point[i].x, result[0].point[i].y);\n    cv::circle(img, keypoint, 1, cv::Scalar(0, 255, 0), 2);  // Draw filled circle\n  }\n\n  // Save the output image\n  cv::imwrite(\"output_pose.png\", img);\n\n  return 0;\n}\n```\n\n对于 C++ API 示例，请将 MMDeploy 加入到 CMake 项目中：\n\n```CMake\nfind_package(MMDeploy REQUIRED)\ntarget_link_libraries(${name} PRIVATE mmdeploy ${OpenCV_LIBS})\n```\n\n#### 其他语言\n\n- [C# API 示例](https://github.com/open-mmlab/mmdeploy/tree/main/demo/csharp)\n- [JAVA API 示例](https://github.com/open-mmlab/mmdeploy/tree/main/demo/java)\n\n### 🚀 Pipeline 推理\n\n#### 图片推理\n\n如果用户有跟随 MMDeploy 安装教程进行正确编译，在 `mmdeploy/build/bin/` 路径下会看到 `det_pose` 的可执行文件。\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}/build/bin/\n\n# 单张图片推理\n./det_pose rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_img.jpg --device cpu\n\nrequired arguments:\n  det_model           Detection 模型路径 [string]\n  pose_model          Pose 模型路径 [string]\n  image               输入图片路径 [string]\n\noptional arguments:\n  --device            推理设备 \"cpu\", \"cuda\" [string = \"cpu\"]\n  --output            导出图片路径 [string = \"det_pose_output.jpg\"]\n  --skeleton          骨架定义文件路径，或使用预定义骨架:\n                      \"coco\" [string = \"coco\", \"coco-wholoebody\"]\n  --det_label         用于姿势估计的检测标签 [int32 = 0]\n                      (0 在 coco 中对应 person)\n  --det_thr           检测分数阈值 [double = 0.5]\n  --det_min_bbox_size 最小检测框大小 [double = -1]\n  --pose_thr          关键点置信度阈值 [double = 0]\n```\n\n**API** **示例**\n\n\\- [`det_pose.py`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/python/det_pose.py)\n\n\\- [`det_pose.cxx`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/csrc/cpp/det_pose.cxx)\n\n#### 视频推理\n\n如果用户有跟随 MMDeploy 安装教程进行正确编译，在 `mmdeploy/build/bin/` 路径下会看到 `pose_tracker` 的可执行文件。\n\n- 将 `input` 输入 `0` 可以使用摄像头推理\n\n```shell\n# 前往 mmdeploy 目录\ncd ${PATH_TO_MMDEPLOY}/build/bin/\n\n# 视频推理\n./pose_tracker rtmpose-ort/rtmdet-nano/ rtmpose-ort/rtmpose-m/ your_video.mp4 --device cpu\n\nrequired arguments:\n  det_model             Detection 模型路径 [string]\n  pose_model            Pose 模型路径 [string]\n  input                 输入图片路径或摄像头序号 [string]\n\noptional arguments:\n  --device              推理设备 \"cpu\", \"cuda\" [string = \"cpu\"]\n  --output              导出视频路径 [string = \"\"]\n  --output_size         输出视频帧的长边 [int32 = 0]\n  --flip                设置为1，用于水平翻转输入 [int32 = 0]\n  --show                使用`cv::imshow`时，传递给`cv::waitKey`的延迟;\n                        -1: 关闭 [int32 = 1]\n  --skeleton            骨架数据的路径或预定义骨架的名称:\n                        \"coco\", \"coco-wholebody\" [string = \"coco\"]\n  --background          导出视频背景颜色, \"default\": 原图, \"black\":\n                        纯黑背景 [string = \"default\"]\n  --det_interval        检测间隔 [int32 = 1]\n  --det_label           用于姿势估计的检测标签 [int32 = 0]\n                        (0 在 coco 中对应 person)\n  --det_thr             检测分数阈值 [double = 0.5]\n  --det_min_bbox_size   最小检测框大小 [double = -1]\n  --det_nms_thr         NMS IOU阈值，用于合并检测到的bboxes和\n                        追踪到的目标的 bboxes [double = 0.7]\n  --pose_max_num_bboxes 每一帧用于姿势估计的 bboxes 的最大数量\n                        [int32 = -1]\n  --pose_kpt_thr        可见关键点的阈值 [double = 0.5]\n  --pose_min_keypoints  有效姿势的最小关键点数量，-1表示上限(n_kpts/2) [int32 = -1]\n  --pose_bbox_scale     将关键点扩展到 bbox 的比例 [double = 1.25]\n  --pose_min_bbox_size  最小追踪尺寸，尺寸小于阈值的 bbox 将被剔除 [double = -1]\n  --pose_nms_thr        用于抑制重叠姿势的 NMS OKS/IOU阈值。\n                        当多个姿态估计重叠到同一目标时非常有用 [double = 0.5]\n  --track_iou_thr       追踪 IOU 阈值 [double = 0.4]\n  --track_max_missing   最大追踪容错 [int32 = 10]\n```\n\n**API** **示例**\n\n\\- [`pose_tracker.py`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/python/pose_tracker.py)\n\n\\- [`pose_tracker.cxx`](https://github.com/open-mmlab/mmdeploy/blob/main/demo/csrc/cpp/pose_tracker.cxx)\n\n## 📚 常用功能 [🔝](#-table-of-contents)\n\n### 🚀 模型测速 [🔝](#-table-of-contents)\n\n如果需要测试模型在部署框架下的推理速度，MMDeploy 提供了方便的 `tools/profiler.py` 脚本。\n\n用户需要准备一个存放测试图片的文件夹`./test_images`，profiler 将随机从该目录下抽取图片用于模型测速。\n\n```shell\npython tools/profiler.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    {RTMPOSE_PROJECT}/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    ../test_images \\\n    --model {WORK_DIR}/end2end.onnx \\\n    --shape 256x192 \\\n    --device cpu \\\n    --warmup 50 \\\n    --num-iter 200\n```\n\n测试结果如下：\n\n```shell\n01/30 15:06:35 - mmengine - INFO - [onnxruntime]-70 times per count: 8.73 ms, 114.50 FPS\n01/30 15:06:36 - mmengine - INFO - [onnxruntime]-90 times per count: 9.05 ms, 110.48 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-110 times per count: 9.87 ms, 101.32 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-130 times per count: 9.99 ms, 100.10 FPS\n01/30 15:06:38 - mmengine - INFO - [onnxruntime]-150 times per count: 10.39 ms, 96.29 FPS\n01/30 15:06:39 - mmengine - INFO - [onnxruntime]-170 times per count: 10.77 ms, 92.86 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-190 times per count: 10.98 ms, 91.05 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-210 times per count: 11.19 ms, 89.33 FPS\n01/30 15:06:41 - mmengine - INFO - [onnxruntime]-230 times per count: 11.16 ms, 89.58 FPS\n01/30 15:06:42 - mmengine - INFO - [onnxruntime]-250 times per count: 11.06 ms, 90.41 FPS\n----- Settings:\n+------------+---------+\n| batch size |    1    |\n|   shape    | 256x192 |\n| iterations |   200   |\n|   warmup   |    50   |\n+------------+---------+\n----- Results:\n+--------+------------+---------+\n| Stats  | Latency/ms |   FPS   |\n+--------+------------+---------+\n|  Mean  |   11.060   |  90.412 |\n| Median |   11.852   |  84.375 |\n|  Min   |   7.812    | 128.007 |\n|  Max   |   13.690   |  73.044 |\n+--------+------------+---------+\n```\n\n如果你希望详细了解 profiler 的更多参数设置与功能，可以前往 [Profiler Docs](https://mmdeploy.readthedocs.io/en/main/02-how-to-run/useful_tools.html#profiler)\n\n### 📊 精度验证 [🔝](#-table-of-contents)\n\n如果需要测试模型在部署框架下的推理精度，MMDeploy 提供了方便的 `tools/test.py` 脚本。\n\n```shell\npython tools/test.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    {RTMPOSE_PROJECT}/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    --model {PATH_TO_MODEL}/rtmpose_m.pth \\\n    --device cpu\n```\n\n详细内容请参考 [MMDeploys Docs](https://github.com/open-mmlab/mmdeploy/blob/main/docs/zh_cn/02-how-to-run/profile_model.md)\n\n## 📜 引用 [🔝](#-table-of-contents)\n\n如果您觉得 RTMPose 对您的研究工作有所帮助，请考虑引用它：\n\n```bibtex\n@misc{https://doi.org/10.48550/arxiv.2303.07399,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n"
  },
  {
    "path": "projects/rtmpose/app.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nimport os\nfrom functools import partial\n\n# prepare environment\nproject_path = os.path.join(os.path.dirname(os.path.abspath(__file__)))\nmmpose_path = project_path.split('/projects', 1)[0]\n\nos.system('python -m pip install Openmim')\nos.system('python -m pip install openxlab')\nos.system('python -m pip install gradio==3.38.0')\n\nos.system('python -m mim install \"mmcv>=2.0.0\"')\nos.system('python -m mim install \"mmengine>=0.9.0\"')\nos.system('python -m mim install \"mmdet>=3.0.0\"')\nos.system(f'python -m mim install -e {mmpose_path}')\n\nimport gradio as gr  # noqa\nfrom openxlab.model import download  # noqa\n\nfrom mmpose.apis import MMPoseInferencer  # noqa\n\n# download checkpoints\ndownload(model_repo='mmpose/RTMPose', model_name='dwpose-l')\ndownload(model_repo='mmpose/RTMPose', model_name='RTMW-x')\ndownload(model_repo='mmpose/RTMPose', model_name='RTMO-l')\ndownload(model_repo='mmpose/RTMPose', model_name='RTMPose-l-body8')\ndownload(model_repo='mmpose/RTMPose', model_name='RTMPose-m-face6')\n\nmodels = [\n    'rtmpose | body', 'rtmo | body', 'rtmpose | face', 'dwpose | wholebody',\n    'rtmw | wholebody'\n]\ncached_model = {model: None for model in models}\n\n\ndef predict(input,\n            draw_heatmap=False,\n            model_type='body',\n            skeleton_style='mmpose',\n            input_type='image'):\n    \"\"\"Visualize the demo images.\n\n    Using mmdet to detect the human.\n    \"\"\"\n\n    if model_type == 'rtmpose | face':\n        if cached_model[model_type] is None:\n            cached_model[model_type] = MMPoseInferencer(pose2d='face')\n        model = cached_model[model_type]\n\n    elif model_type == 'dwpose | wholebody':\n        if cached_model[model_type] is None:\n            cached_model[model_type] = MMPoseInferencer(\n                pose2d=os.path.join(\n                    project_path, 'rtmpose/wholebody_2d_keypoint/'\n                    'rtmpose-l_8xb32-270e_coco-wholebody-384x288.py'),\n                pose2d_weights='https://download.openmmlab.com/mmpose/v1/'\n                'projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-'\n                '384x288-2438fd99_20230728.pth')\n        model = cached_model[model_type]\n\n    elif model_type == 'rtmw | wholebody':\n        if cached_model[model_type] is None:\n            cached_model[model_type] = MMPoseInferencer(\n                pose2d=os.path.join(\n                    project_path, 'rtmpose/wholebody_2d_keypoint/'\n                    'rtmw-l_8xb320-270e_cocktail14-384x288.py'),\n                pose2d_weights='https://download.openmmlab.com/mmpose/v1/'\n                'projects/rtmw/rtmw-dw-x-l_simcc-cocktail14_270e-'\n                '384x288-20231122.pth')\n        model = cached_model[model_type]\n\n    elif model_type == 'rtmpose | body':\n        if cached_model[model_type] is None:\n            cached_model[model_type] = MMPoseInferencer(pose2d='rtmpose-l')\n        model = cached_model[model_type]\n\n    elif model_type == 'rtmo | body':\n        if cached_model[model_type] is None:\n            cached_model[model_type] = MMPoseInferencer(pose2d='rtmo')\n        model = cached_model[model_type]\n        draw_heatmap = False\n\n    else:\n        raise ValueError\n\n    if input_type == 'image':\n\n        result = next(\n            model(\n                input,\n                return_vis=True,\n                draw_heatmap=draw_heatmap,\n                skeleton_style=skeleton_style))\n        img = result['visualization'][0][..., ::-1]\n        return img\n\n    elif input_type == 'video':\n\n        for _ in model(\n                input,\n                vis_out_dir='test.mp4',\n                draw_heatmap=draw_heatmap,\n                skeleton_style=skeleton_style):\n            pass\n\n        return 'test.mp4'\n\n    return None\n\n\nnews_list = [\n    '2023-8-1: We support [DWPose](https://arxiv.org/pdf/2307.15880.pdf).',\n    '2023-9-25: We release an alpha version of RTMW model, the technical '\n    'report will be released soon.',\n    '2023-12-11: Update RTMW models, the online version is the RTMW-l with '\n    '70.1 mAP on COCO-Wholebody.',\n    '2023-12-13: We release an alpha version of RTMO (One-stage RTMPose) '\n    'models.',\n]\n\nwith gr.Blocks() as demo:\n\n    with gr.Tab('Upload-Image'):\n        input_img = gr.Image(type='numpy')\n        button = gr.Button('Inference', variant='primary')\n        hm = gr.Checkbox(label='draw-heatmap', info='Whether to draw heatmap')\n        model_type = gr.Dropdown(models, label='Model | Keypoint Type')\n\n        gr.Markdown('## News')\n        for news in news_list[::-1]:\n            gr.Markdown(news)\n\n        gr.Markdown('## Output')\n        out_image = gr.Image(type='numpy')\n        gr.Examples(['./tests/data/coco/000000000785.jpg'], input_img)\n        input_type = 'image'\n        button.click(\n            partial(predict, input_type=input_type),\n            [input_img, hm, model_type], out_image)\n\n    with gr.Tab('Webcam-Image'):\n        input_img = gr.Image(source='webcam', type='numpy')\n        button = gr.Button('Inference', variant='primary')\n        hm = gr.Checkbox(label='draw-heatmap', info='Whether to draw heatmap')\n        model_type = gr.Dropdown(models, label='Model | Keypoint Type')\n\n        gr.Markdown('## News')\n        for news in news_list[::-1]:\n            gr.Markdown(news)\n\n        gr.Markdown('## Output')\n        out_image = gr.Image(type='numpy')\n\n        input_type = 'image'\n        button.click(\n            partial(predict, input_type=input_type),\n            [input_img, hm, model_type], out_image)\n\n    with gr.Tab('Upload-Video'):\n        input_video = gr.Video(type='mp4')\n        button = gr.Button('Inference', variant='primary')\n        hm = gr.Checkbox(label='draw-heatmap', info='Whether to draw heatmap')\n        model_type = gr.Dropdown(models, label='Model | Keypoint type')\n\n        gr.Markdown('## News')\n        for news in news_list[::-1]:\n            gr.Markdown(news)\n\n        gr.Markdown('## Output')\n        out_video = gr.Video()\n\n        input_type = 'video'\n        button.click(\n            partial(predict, input_type=input_type),\n            [input_video, hm, model_type], out_video)\n\n    with gr.Tab('Webcam-Video'):\n        input_video = gr.Video(source='webcam', format='mp4')\n        button = gr.Button('Inference', variant='primary')\n        hm = gr.Checkbox(label='draw-heatmap', info='Whether to draw heatmap')\n        model_type = gr.Dropdown(models, label='Model | Keypoint Type')\n\n        gr.Markdown('## News')\n        for news in news_list[::-1]:\n            gr.Markdown(news)\n\n        gr.Markdown('## Output')\n        out_video = gr.Video()\n\n        input_type = 'video'\n        button.click(\n            partial(predict, input_type=input_type),\n            [input_video, hm, model_type], out_video)\n\ngr.close_all()\ndemo.queue()\ndemo.launch()\n"
  },
  {
    "path": "projects/rtmpose/benchmark/README.md",
    "content": "# RTMPose Benchmarks\n\nEnglish | [简体中文](./README_CN.md)\n\nCommunity users are welcome to contribute to this project directory by performing inference speed tests on different hardware devices.\n\nCurrently tested:\n\n- CPU\n  - Intel i7-11700\n- GPU\n  - NVIDIA GeForce 1660 Ti\n  - NVIDIA GeForce RTX 3090\n- Nvidia Jetson\n  - AGX Orin\n  - Orin NX\n- ARM\n  - Snapdragon 865\n\n## Body 2d (17 Keypoints)\n\n### Model Info\n\n|                                      Config                                       | Input Size | AP<sup><br>(COCO) | Params(M) | FLOPS(G) |\n| :-------------------------------------------------------------------------------: | :--------: | :---------------: | :-------: | :------: |\n| [RTMPose-t](../rtmpose/body_2d_keypoint/rtmpose-tiny_8xb256-420e_coco-256x192.py) |  256x192   |       68.5        |   3.34    |   0.36   |\n|  [RTMPose-s](../rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py)   |  256x192   |       72.2        |   5.47    |   0.68   |\n|  [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py)   |  256x192   |       75.8        |   13.59   |   1.93   |\n|  [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py)   |  256x192   |       76.5        |   27.66   |   4.16   |\n|  [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py)   |  384x288   |       77.0        |   13.72   |   4.33   |\n|  [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py)   |  384x288   |       77.3        |   27.79   |   9.35   |\n\n### Speed Benchmark\n\n- Numbers displayed in the table are inference latencies in millisecond(ms).\n\n|   Config    | Input Size | ORT<sup><br>(i7-11700) | TRT-FP16<sup><br>(GTX 1660Ti) | TRT-FP16<sup><br>(RTX 3090) | ncnn-FP16<sup><br>(Snapdragon 865) | TRT-FP16<sup><br>(Jetson AGX Orin) | TRT-FP16<sup><br>(Jetson Orin NX) |\n| :---------: | :--------: | :--------------------: | :---------------------------: | :-------------------------: | :--------------------------------: | :--------------------------------: | :-------------------------------: |\n| [RTMPose-t](../rtmpose/body_2d_keypoint/rtmpose-tiny_8xb256-420e_coco-256x192.py) |  256x192   |          3.20          |             1.06              |            0.98             |                9.02                |                1.63                |               1.97                |\n| [RTMPose-s](../rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |          4.48          |             1.39              |            1.12             |               13.89                |                1.85                |               2.18                |\n| [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |         11.06          |             2.29              |            1.18             |               26.44                |                2.72                |               3.35                |\n| [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |         18.85          |             3.46              |            1.37             |               45.37                |                3.67                |               4.78                |\n| [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py) |  384x288   |         24.78          |             3.66              |            1.20             |               26.44                |                3.45                |               5.08                |\n| [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py) |  384x288   |           -            |             6.05              |            1.74             |                 -                  |                4.93                |               7.23                |\n\n## WholeBody 2d (133 Keypoints)\n\n### Model Info\n\n| Config                                                                                       | Input Size | Whole AP | Whole AR | FLOPS(G) |\n| :------------------------------------------------------------------------------------------- | :--------: | :------: | :------: | :------: |\n| [RTMPose-m](../rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   60.4   |   66.7   |   2.22   |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   63.2   |   69.4   |   4.52   |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   67.0   |   72.3   |  10.07   |\n\n### Speed Benchmark\n\n- Numbers displayed in the table are inference latencies in millisecond(ms).\n- Data from different community users are separated by `|`.\n\n| Config                                        | Input Size | ORT<sup><br>(i7-11700) | TRT-FP16<sup><br>(GTX 1660Ti) | TRT-FP16<sup><br>(RTX 3090) | TRT-FP16<sup><br>(Jetson AGX Orin) | TRT-FP16<sup><br>(Jetson Orin NX) |\n| :-------------------------------------------- | :--------: | :--------------------: | :---------------------------: | :-------------------------: | :--------------------------------: | :-------------------------------: |\n| [RTMPose-m](../rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |         13.50          |             4.00              |        1.17 \\| 1.84         |                2.79                |               3.51                |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |         23.41          |             5.67              |        1.44 \\| 2.61         |                3.80                |               4.95                |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |         44.58          |             7.68              |        1.75 \\| 4.24         |                5.08                |               7.20                |\n\n## How To Test Speed\n\nIf you need to test the inference speed of the model under the deployment framework, MMDeploy provides a convenient `tools/profiler.py` script.\n\nThe user needs to prepare a folder for the test images `./test_images`, the profiler will randomly read images from this directory for the model speed test.\n\n```shell\npython tools/profiler.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    {RTMPOSE_PROJECT}/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    ../test_images \\\n    --model {WORK_DIR}/end2end.onnx \\\n    --shape 256x192 \\\n    --device cpu \\\n    --warmup 50 \\\n    --num-iter 200\n```\n\nThe result is as follows:\n\n```shell\n01/30 15:06:35 - mmengine - INFO - [onnxruntime]-70 times per count: 8.73 ms, 114.50 FPS\n01/30 15:06:36 - mmengine - INFO - [onnxruntime]-90 times per count: 9.05 ms, 110.48 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-110 times per count: 9.87 ms, 101.32 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-130 times per count: 9.99 ms, 100.10 FPS\n01/30 15:06:38 - mmengine - INFO - [onnxruntime]-150 times per count: 10.39 ms, 96.29 FPS\n01/30 15:06:39 - mmengine - INFO - [onnxruntime]-170 times per count: 10.77 ms, 92.86 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-190 times per count: 10.98 ms, 91.05 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-210 times per count: 11.19 ms, 89.33 FPS\n01/30 15:06:41 - mmengine - INFO - [onnxruntime]-230 times per count: 11.16 ms, 89.58 FPS\n01/30 15:06:42 - mmengine - INFO - [onnxruntime]-250 times per count: 11.06 ms, 90.41 FPS\n----- Settings:\n+------------+---------+\n| batch size |    1    |\n|   shape    | 256x192 |\n| iterations |   200   |\n|   warmup   |    50   |\n+------------+---------+\n----- Results:\n+--------+------------+---------+\n| Stats  | Latency/ms |   FPS   |\n+--------+------------+---------+\n|  Mean  |   11.060   |  90.412 |\n| Median |   11.852   |  84.375 |\n|  Min   |   7.812    | 128.007 |\n|  Max   |   13.690   |  73.044 |\n+--------+------------+---------+\n```\n\nIf you want to learn more details of profiler, you can refer to the [Profiler Docs](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/useful_tools.html#profiler).\n"
  },
  {
    "path": "projects/rtmpose/benchmark/README_CN.md",
    "content": "# RTMPose Benchmarks\n\n简体中文 | [English](./README.md)\n\n欢迎社区用户在不同硬件设备上进行推理速度测试，贡献到本项目目录下。\n\n当前已测试：\n\n- CPU\n  - Intel i7-11700\n- GPU\n  - NVIDIA GeForce 1660 Ti\n  - NVIDIA GeForce RTX 3090\n- Nvidia Jetson\n  - AGX Orin\n  - Orin NX\n- ARM\n  - Snapdragon 865\n\n### 人体 2d 关键点 (17 Keypoints)\n\n### Model Info\n\n|                                      Config                                       | Input Size | AP<sup><br>(COCO) | Params(M) | FLOPS(G) |\n| :-------------------------------------------------------------------------------: | :--------: | :---------------: | :-------: | :------: |\n| [RTMPose-t](../rtmpose/body_2d_keypoint/rtmpose-tiny_8xb256-420e_coco-256x192.py) |  256x192   |       68.5        |   3.34    |   0.36   |\n|  [RTMPose-s](../rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py)   |  256x192   |       72.2        |   5.47    |   0.68   |\n|  [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py)   |  256x192   |       75.8        |   13.59   |   1.93   |\n|  [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py)   |  256x192   |       76.5        |   27.66   |   4.16   |\n|  [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py)   |  384x288   |       77.0        |   13.72   |   4.33   |\n|  [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py)   |  384x288   |       77.3        |   27.79   |   9.35   |\n\n### Speed Benchmark\n\n图中所示为模型推理时间，单位毫秒。\n\n|   Config    | Input Size | ORT<sup><br>(i7-11700) | TRT-FP16<sup><br>(GTX 1660Ti) | TRT-FP16<sup><br>(RTX 3090) | ncnn-FP16<sup><br>(Snapdragon 865) | TRT-FP16<sup><br>(Jetson AGX Orin) | TRT-FP16<sup><br>(Jetson Orin NX) |\n| :---------: | :--------: | :--------------------: | :---------------------------: | :-------------------------: | :--------------------------------: | :--------------------------------: | :-------------------------------: |\n| [RTMPose-t](../rtmpose/body_2d_keypoint/rtmpose-tiny_8xb256-420e_coco-256x192.py) |  256x192   |          3.20          |             1.06              |            0.98             |                9.02                |                1.63                |               1.97                |\n| [RTMPose-s](../rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   |          4.48          |             1.39              |            1.12             |               13.89                |                1.85                |               2.18                |\n| [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py) |  256x192   |         11.06          |             2.29              |            1.18             |               26.44                |                2.72                |               3.35                |\n| [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py) |  256x192   |         18.85          |             3.46              |            1.37             |               45.37                |                3.67                |               4.78                |\n| [RTMPose-m](../rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py) |  384x288   |         24.78          |             3.66              |            1.20             |               26.44                |                3.45                |               5.08                |\n| [RTMPose-l](../rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py) |  384x288   |           -            |             6.05              |            1.74             |                 -                  |                4.93                |               7.23                |\n\n### 人体全身 2d 关键点 (133 Keypoints)\n\n### Model Info\n\n| Config                                                                                       | Input Size | Whole AP | Whole AR | FLOPS(G) |\n| :------------------------------------------------------------------------------------------- | :--------: | :------: | :------: | :------: |\n| [RTMPose-m](../rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   60.4   |   66.7   |   2.22   |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |   63.2   |   69.4   |   4.52   |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |   67.0   |   72.3   |  10.07   |\n\n### Speed Benchmark\n\n- 图中所示为模型推理时间，单位毫秒。\n- 来自不同社区用户的测试数据用 `|` 分隔开。\n\n| Config                                        | Input Size | ORT<sup><br>(i7-11700) | TRT-FP16<sup><br>(GTX 1660Ti) | TRT-FP16<sup><br>(RTX 3090) | TRT-FP16<sup><br>(Jetson AGX Orin) | TRT-FP16<sup><br>(Jetson Orin NX) |\n| :-------------------------------------------- | :--------: | :--------------------: | :---------------------------: | :-------------------------: | :--------------------------------: | :-------------------------------: |\n| [RTMPose-m](../rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |         13.50          |             4.00              |        1.17 \\| 1.84         |                2.79                |               3.51                |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py) |  256x192   |         23.41          |             5.67              |        1.44 \\| 2.61         |                3.80                |               4.95                |\n| [RTMPose-l](../rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py) |  384x288   |         44.58          |             7.68              |        1.75 \\| 4.24         |                5.08                |               7.20                |\n\n## 如何测试推理速度\n\n我们使用 MMDeploy 提供的 `tools/profiler.py` 脚本进行模型测速。\n\n用户需要准备一个存放测试图片的文件夹`./test_images`，profiler 将随机从该目录下抽取图片用于模型测速。\n\n```shell\npython tools/profiler.py \\\n    configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    {RTMPOSE_PROJECT}/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py \\\n    ../test_images \\\n    --model {WORK_DIR}/end2end.onnx \\\n    --shape 256x192 \\\n    --device cpu \\\n    --warmup 50 \\\n    --num-iter 200\n```\n\nThe result is as follows:\n\n```shell\n01/30 15:06:35 - mmengine - INFO - [onnxruntime]-70 times per count: 8.73 ms, 114.50 FPS\n01/30 15:06:36 - mmengine - INFO - [onnxruntime]-90 times per count: 9.05 ms, 110.48 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-110 times per count: 9.87 ms, 101.32 FPS\n01/30 15:06:37 - mmengine - INFO - [onnxruntime]-130 times per count: 9.99 ms, 100.10 FPS\n01/30 15:06:38 - mmengine - INFO - [onnxruntime]-150 times per count: 10.39 ms, 96.29 FPS\n01/30 15:06:39 - mmengine - INFO - [onnxruntime]-170 times per count: 10.77 ms, 92.86 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-190 times per count: 10.98 ms, 91.05 FPS\n01/30 15:06:40 - mmengine - INFO - [onnxruntime]-210 times per count: 11.19 ms, 89.33 FPS\n01/30 15:06:41 - mmengine - INFO - [onnxruntime]-230 times per count: 11.16 ms, 89.58 FPS\n01/30 15:06:42 - mmengine - INFO - [onnxruntime]-250 times per count: 11.06 ms, 90.41 FPS\n----- Settings:\n+------------+---------+\n| batch size |    1    |\n|   shape    | 256x192 |\n| iterations |   200   |\n|   warmup   |    50   |\n+------------+---------+\n----- Results:\n+--------+------------+---------+\n| Stats  | Latency/ms |   FPS   |\n+--------+------------+---------+\n|  Mean  |   11.060   |  90.412 |\n| Median |   11.852   |  84.375 |\n|  Min   |   7.812    | 128.007 |\n|  Max   |   13.690   |  73.044 |\n+--------+------------+---------+\n```\n\nIf you want to learn more details of profiler, you can refer to the [Profiler Docs](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/useful_tools.html#profiler).\n"
  },
  {
    "path": "projects/rtmpose/examples/PoseTracker-Android-Prototype/README.md",
    "content": "# PoseTracker-Android-Prototype\n\nPoseTracker Android Demo Prototype, which is based on [mmdeploy](https://github.com/open-mmlab/mmdeploy/tree/dev-1.x)\n\nPlease refer to [Original Repository](https://github.com/hanrui1sensetime/PoseTracker-Android-Prototype).\n"
  },
  {
    "path": "projects/rtmpose/examples/README.md",
    "content": "## List of examples\n\n### 1. RTMPose-Deploy\n\nRTMPose-Deploy is a C++ code example for RTMPose localized deployment.\n\n- [ONNXRuntime-CPU](https://github.com/HW140701/RTMPose-Deploy)\n- [TensorRT](https://github.com/Dominic23331/rtmpose_tensorrt)\n\n### 2. RTMPose inference with ONNXRuntime (Python)\n\nThis example shows how to run RTMPose inference with ONNXRuntime in Python.\n\n### 3. PoseTracker Android Demo\n\nPoseTracker Android Demo Prototype based on mmdeploy.\n\n- [Original Repository](https://github.com/hanrui1sensetime/PoseTracker-Android-Prototype)\n\n### 4. rtmlib\n\nrtmlib is a super lightweight library to conduct pose estimation based on RTMPose models WITHOUT any dependencies like mmcv, mmpose, mmdet, etc.\n\n- [Original Repository](https://github.com/Tau-J/rtmlib/tree/main)\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/README.md",
    "content": "# RTMPose-Deploy\n\n[中文说明](./README_CN.md)\n\nRTMPose-Deploy is a C ++ code example for RTMPose localized deployment.\n\nAt present, RTMPose-Deploy has completed to use ONNXRuntime-CPU and TensorRT to deploy the RTMDet and RTMPose on the Windows system.\n\n| Deployment Framework | Repo                                                                 |\n| -------------------- | -------------------------------------------------------------------- |\n| ONNXRuntime-CPU      | [RTMPose-Deploy](https://github.com/HW140701/RTMPose-Deploy)         |\n| TensorRT             | [rtmpose_tensorrt](https://github.com/Dominic23331/rtmpose_tensorrt) |\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/README_CN.md",
    "content": "# RTMPose-Deploy\n\nRTMPose-Deploy 是一个进行 RTMPose 本地化部署的 C++ 代码示例。\n\n目前，RTMPose-Deploy 已完成在 Windows 系统上使用 OnnxRuntime CPU 和TensorRT 对 RTMDet 和 RTMPose 完成了部署。\n\n| 部署框架        | 仓库                                                                 |\n| --------------- | -------------------------------------------------------------------- |\n| ONNXRuntime-CPU | [RTMPose-Deploy](https://github.com/HW140701/RTMPose-Deploy)         |\n| TensorRT        | [rtmpose_tensorrt](https://github.com/Dominic23331/rtmpose_tensorrt) |\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/characterset_convert.h",
    "content": "#ifndef _CHARACTERSET_CONVERT_H_\n#define _CHARACTERSET_CONVERT_H_\n\n#include <string>\n\n#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)\n\n#include <Windows.h>\n\n#elif defined(linux) || defined(__linux)\n\n#include <iconv.h>\n#include <malloc.h>\n\n#endif\n\nnamespace stubbornhuang\n{\n\tclass CharactersetConvert\n\t{\n\tpublic:\n#if defined(WIN32) || defined(_WIN32) || defined(__WIN32__) || defined(__NT__)\n\t\tstatic std::wstring string_to_wstring(const std::string& str)\n\t\t{\n\t\t\tstd::wstring result;\n\t\t\tint len = MultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, NULL, 0);\n\t\t\twchar_t* wstr = new wchar_t[len + 1];\n\t\t\tmemset(wstr, 0, len + 1);\n\t\t\tMultiByteToWideChar(CP_ACP, 0, str.c_str(), -1, wstr, len);\n\t\t\twstr[len] = '\\0';\n\t\t\tresult.append(wstr);\n\t\t\tdelete[] wstr;\n\t\t\treturn result;\n\t\t}\n\n\t\tstatic std::string gbk_to_utf8(const std::string& gbk_str)\n\t\t{\n\t\t\tint len = MultiByteToWideChar(CP_ACP, 0, gbk_str.c_str(), -1, NULL, 0);\n\t\t\twchar_t* wstr = new wchar_t[len + 1];\n\t\t\tmemset(wstr, 0, len + 1);\n\t\t\tMultiByteToWideChar(CP_ACP, 0, gbk_str.c_str(), -1, wstr, len);\n\t\t\tlen = WideCharToMultiByte(CP_UTF8, 0, wstr, -1, NULL, 0, NULL, NULL);\n\t\t\tchar* str = new char[len + 1];\n\t\t\tmemset(str, 0, len + 1);\n\t\t\tWideCharToMultiByte(CP_UTF8, 0, wstr, -1, str, len, NULL, NULL);\n\t\t\tstd::string strTemp = str;\n\t\t\tif (wstr) delete[] wstr;\n\t\t\tif (str) delete[] str;\n\t\t\treturn strTemp;\n\t\t}\n\n\t\tstatic std::string utf8_to_gbk(const std::string& utf8_str)\n\t\t{\n\t\t\tint len = MultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, NULL, 0);\n\t\t\twchar_t* wszGBK = new wchar_t[len + 1];\n\t\t\tmemset(wszGBK, 0, len * 2 + 2);\n\t\t\tMultiByteToWideChar(CP_UTF8, 0, utf8_str.c_str(), -1, wszGBK, len);\n\t\t\tlen = WideCharToMultiByte(CP_ACP, 0, wszGBK, -1, NULL, 0, NULL, NULL);\n\t\t\tchar* szGBK = new char[len + 1];\n\t\t\tmemset(szGBK, 0, len + 1);\n\t\t\tWideCharToMultiByte(CP_ACP, 0, wszGBK, -1, szGBK, len, NULL, NULL);\n\t\t\tstd::string strTemp(szGBK);\n\t\t\tif (wszGBK) delete[] wszGBK;\n\t\t\tif (szGBK) delete[] szGBK;\n\t\t\treturn strTemp;\n\t\t}\n\n#elif defined(linux) || defined(__linux)\n\t\tstatic int code_convert(\n\t\t\tconst char* from_charset,\n\t\t\tconst char* to_charset,\n\t\t\tchar* inbuf, size_t inlen,\n\t\t\tchar* outbuf, size_t outlen\n\t\t) {\n\t\t\ticonv_t cd;\n\t\t\tchar** pin = &inbuf;\n\t\t\tchar** pout = &outbuf;\n\n\t\t\tcd = iconv_open(to_charset, from_charset);\n\t\t\tif (cd == 0)\n\t\t\t\treturn -1;\n\n\t\t\tmemset(outbuf, 0, outlen);\n\n\t\t\tif ((int)iconv(cd, pin, &inlen, pout, &outlen) == -1)\n\t\t\t{\n\t\t\t\ticonv_close(cd);\n\t\t\t\treturn -1;\n\t\t\t}\n\t\t\ticonv_close(cd);\n\t\t\t*pout = '\\0';\n\n\t\t\treturn 0;\n\t\t}\n\n\t\tstatic int u2g(char* inbuf, size_t inlen, char* outbuf, size_t outlen) {\n\t\t\treturn code_convert(\"utf-8\", \"gb2312\", inbuf, inlen, outbuf, outlen);\n\t\t}\n\n\t\tstatic int g2u(char* inbuf, size_t inlen, char* outbuf, size_t outlen) {\n\t\t\treturn code_convert(\"gb2312\", \"utf-8\", inbuf, inlen, outbuf, outlen);\n\t\t}\n\n\n\t\tstatic std::string gbk_to_utf8(const std::string& gbk_str)\n\t\t{\n\t\t\tint length = gbk_str.size() * 2 + 1;\n\n\t\t\tchar* temp = (char*)malloc(sizeof(char) * length);\n\n\t\t\tif (g2u((char*)gbk_str.c_str(), gbk_str.size(), temp, length) >= 0)\n\t\t\t{\n\t\t\t\tstd::string str_result;\n\t\t\t\tstr_result.append(temp);\n\t\t\t\tfree(temp);\n\t\t\t\treturn str_result;\n\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfree(temp);\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t}\n\n\t\tstatic std::string utf8_to_gbk(const std::string& utf8_str)\n\t\t{\n\t\t\tint length = strlen(utf8_str);\n\n\t\t\tchar* temp = (char*)malloc(sizeof(char) * length);\n\n\t\t\tif (u2g((char*)utf8_str, length, temp, length) >= 0)\n\t\t\t{\n\t\t\t\tstd::string str_result;\n\t\t\t\tstr_result.append(temp);\n\t\t\t\tfree(temp);\n\n\t\t\t\treturn str_result;\n\t\t\t}\n\t\t\telse\n\t\t\t{\n\t\t\t\tfree(temp);\n\t\t\t\treturn \"\";\n\t\t\t}\n\t\t}\n\n#endif\n\n\t};\n}\n\n#endif // !_CHARACTERSET_CONVERT_H_\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/main.cpp",
    "content": "#include <iostream>\n\n#include \"opencv2/opencv.hpp\"\n\n#include \"rtmpose_utils.h\"\n#include \"rtmpose_onnxruntime.h\"\n#include \"rtmdet_onnxruntime.h\"\n#include \"rtmpose_tracker_onnxruntime.h\"\n\nstd::vector<std::pair<int, int>> coco_17_joint_links = {\n\t{0,1},{0,2},{1,3},{2,4},{5,7},{7,9},{6,8},{8,10},{5,6},{5,11},{6,12},{11,12},{11,13},{13,15},{12,14},{14,16}\n};\n\nint main()\n{\n\tstd::string rtm_detnano_onnx_path = \"\";\n\tstd::string rtm_pose_onnx_path = \"\";\n#ifdef _DEBUG\n\trtm_detnano_onnx_path = \"../../resource/model/rtmpose-cpu/rtmpose-ort/rtmdet-nano/end2end.onnx\";\n\trtm_pose_onnx_path = \"../../resource/model/rtmpose-cpu/rtmpose-ort/rtmpose-m/end2end.onnx\";\n#else\n\trtm_detnano_onnx_path = \"./resource/model/rtmpose-cpu/rtmpose-ort/rtmdet-nano/end2end.onnx\";\n\trtm_pose_onnx_path = \"./resource/model/rtmpose-cpu/rtmpose-ort/rtmpose-m/end2end.onnx\";\n#endif\n\n\tRTMPoseTrackerOnnxruntime rtmpose_tracker_onnxruntime(rtm_detnano_onnx_path, rtm_pose_onnx_path);\n\n\tcv::VideoCapture video_reader(0);\n\tint frame_num = 0;\n\tDetectBox detect_box;\n\twhile (video_reader.isOpened())\n\t{\n\t\tcv::Mat frame;\n\t\tvideo_reader >> frame;\n\n\t\tif (frame.empty())\n\t\t\tbreak;\n\n\t\tstd::pair<DetectBox, std::vector<PosePoint>> inference_box= rtmpose_tracker_onnxruntime.Inference(frame);\n\t\tDetectBox detect_box = inference_box.first;\n\t\tstd::vector<PosePoint> pose_result = inference_box.second;\n\n\t\tcv::rectangle(\n\t\t\tframe,\n\t\t\tcv::Point(detect_box.left, detect_box.top),\n\t\t\tcv::Point(detect_box.right, detect_box.bottom),\n\t\t\tcv::Scalar{ 255, 0, 0 },\n\t\t\t2);\n\n\t\tfor (int i = 0; i < pose_result.size(); ++i)\n\t\t{\n\t\t\tcv::circle(frame, cv::Point(pose_result[i].x, pose_result[i].y), 1, cv::Scalar{ 0, 0, 255 }, 5, cv::LINE_AA);\n\t\t}\n\n\t\tfor (int i = 0; i < coco_17_joint_links.size(); ++i)\n\t\t{\n\t\t\tstd::pair<int, int> joint_links = coco_17_joint_links[i];\n\t\t\tcv::line(\n\t\t\t\tframe,\n\t\t\t\tcv::Point(pose_result[joint_links.first].x, pose_result[joint_links.first].y),\n\t\t\t\tcv::Point(pose_result[joint_links.second].x, pose_result[joint_links.second].y),\n\t\t\t\tcv::Scalar{ 0, 255, 0 },\n\t\t\t\t2,\n\t\t\t\tcv::LINE_AA);\n\t\t}\n\n\t\timshow(\"RTMPose\", frame);\n\t\tcv::waitKey(1);\n\t}\n\n\tvideo_reader.release();\n\tcv::destroyAllWindows();\n\n\treturn 0;\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmdet_onnxruntime.cpp",
    "content": "#include \"rtmdet_onnxruntime.h\"\n\n#include <iostream>\n#include <thread>\n\n#include \"characterset_convert.h\"\n\n\nRTMDetOnnxruntime::RTMDetOnnxruntime(const std::string& onnx_model_path)\n\t:m_session(nullptr),\n\tm_env(nullptr)\n{\n\tstd::wstring onnx_model_path_wstr = stubbornhuang::CharactersetConvert::string_to_wstring(onnx_model_path);\n\n\tm_env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, \"rtmdet_onnxruntime_cpu\");\n\n\tint cpu_processor_num = std::thread::hardware_concurrency();\n\tcpu_processor_num /= 2;\n\n\tOrt::SessionOptions session_options;\n\tsession_options.SetIntraOpNumThreads(cpu_processor_num);\n\tsession_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);\n\tsession_options.SetLogSeverityLevel(4);\n\n\tOrtSessionOptionsAppendExecutionProvider_CPU(session_options, 0);\n\tm_session = Ort::Session(m_env, onnx_model_path_wstr.c_str(), session_options);\n\n\tPrintModelInfo(m_session);\n}\n\nRTMDetOnnxruntime::~RTMDetOnnxruntime()\n{\n}\n\nDetectBox RTMDetOnnxruntime::Inference(const cv::Mat& input_mat)\n{\n\t// Deep copy\n\tcv::Mat input_mat_copy;\n\tinput_mat.copyTo(input_mat_copy);\n\n\t// BGR to RGB\n\tcv::Mat input_mat_copy_rgb;\n\tcv::cvtColor(input_mat_copy, input_mat_copy_rgb, CV_BGR2RGB);\n\n\t// image data, HWC->CHW, image_data - mean / std normalize\n\tint image_height = input_mat_copy_rgb.rows;\n\tint image_width = input_mat_copy_rgb.cols;\n\tint image_channels = input_mat_copy_rgb.channels();\n\n\tstd::vector<float> input_image_array;\n\tinput_image_array.resize(1 * image_channels * image_height * image_width);\n\n\tfloat* input_image = input_image_array.data();\n\tfor (int h = 0; h < image_height; ++h)\n\t{\n\t\tfor (int w = 0; w < image_width; ++w)\n\t\t{\n\t\t\tfor (int c = 0; c < image_channels; ++c)\n\t\t\t{\n\t\t\t\tint chw_index = c * image_height * image_width + h * image_width + w;\n\n\t\t\t\tfloat tmp = input_mat_copy_rgb.ptr<uchar>(h)[w * 3 + c];\n\n\t\t\t\tinput_image[chw_index] = (tmp - IMAGE_MEAN[c]) / IMAGE_STD[c];\n\t\t\t}\n\t\t}\n\t}\n\n\t// inference\n\tstd::vector<const char*> m_onnx_input_names{ \"input\" };\n\tstd::vector<const char*> m_onnx_output_names{ \"dets\",\"labels\"};\n\tstd::array<int64_t, 4> input_shape{ 1, image_channels, image_height, image_width };\n\n\tauto memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);\n\tOrt::Value input_tensor = Ort::Value::CreateTensor<float>(\n\t\tmemory_info,\n\t\tinput_image_array.data(),\n\t\tinput_image_array.size(),\n\t\tinput_shape.data(),\n\t\tinput_shape.size()\n\t);\n\n\tassert(input_tensor.IsTensor());\n\n\tauto output_tensors = m_session.Run(\n\t\tOrt::RunOptions{ nullptr },\n\t\tm_onnx_input_names.data(),\n\t\t&input_tensor,\n\t\t1,\n\t\tm_onnx_output_names.data(),\n\t\tm_onnx_output_names.size()\n\t);\n\n\t// pose process\n\tstd::vector<int64_t> det_result_dims = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();\n\tstd::vector<int64_t> label_result_dims = output_tensors[1].GetTensorTypeAndShapeInfo().GetShape();\n\n\tassert(det_result_dims.size() == 3 && label_result_dims.size() == 2);\n\n\tint batch_size = det_result_dims[0] == label_result_dims[0] ? det_result_dims[0] : 0;\n\tint num_dets = det_result_dims[1] == label_result_dims[1] ? det_result_dims[1] : 0;\n\tint reshap_dims = det_result_dims[2];\n\n\tfloat* det_result = output_tensors[0].GetTensorMutableData<float>();\n\tint* label_result = output_tensors[1].GetTensorMutableData<int>();\n\n\tstd::vector<DetectBox> all_box;\n\tfor (int i = 0; i < num_dets; ++i)\n\t{\n\t\tint classes = label_result[i];\n\t\tif (classes != 0)\n\t\t\tcontinue;\n\n\t\tDetectBox temp_box;\n\t\ttemp_box.left = int(det_result[i * reshap_dims]);\n\t\ttemp_box.top = int(det_result[i * reshap_dims + 1]);\n\t\ttemp_box.right = int(det_result[i * reshap_dims + 2]);\n\t\ttemp_box.bottom = int(det_result[i * reshap_dims + 3]);\n\t\ttemp_box.score = det_result[i * reshap_dims + 4];\n\t\ttemp_box.label = label_result[i];\n\n\t\tall_box.emplace_back(temp_box);\n\t}\n\n\t// descending sort\n\tstd::sort(all_box.begin(), all_box.end(), BoxCompare);\n\n\t//cv::rectangle(input_mat_copy, cv::Point{ all_box[0].left, all_box[0].top }, cv::Point{ all_box[0].right, all_box[0].bottom }, cv::Scalar{ 0, 255, 0 });\n\n\t//cv::imwrite(\"detect.jpg\", input_mat_copy);\n\n\tDetectBox result_box;\n\n\tif (!all_box.empty())\n\t{\n\t\tresult_box = all_box[0];\n\t}\n\n\treturn result_box;\n}\n\nvoid RTMDetOnnxruntime::PrintModelInfo(Ort::Session& session)\n{\n\t// print the number of model input nodes\n\tsize_t num_input_nodes = session.GetInputCount();\n\tsize_t num_output_nodes = session.GetOutputCount();\n\tstd::cout << \"Number of input node is:\" << num_input_nodes << std::endl;\n\tstd::cout << \"Number of output node is:\" << num_output_nodes << std::endl;\n\n\t// print node name\n\tOrt::AllocatorWithDefaultOptions allocator;\n\tstd::cout << std::endl;\n\tfor (auto i = 0; i < num_input_nodes; i++)\n\t\tstd::cout << \"The input op-name \" << i << \" is:\" << session.GetInputNameAllocated(i, allocator) << std::endl;\n\tfor (auto i = 0; i < num_output_nodes; i++)\n\t\tstd::cout << \"The output op-name \" << i << \" is:\" << session.GetOutputNameAllocated(i, allocator) << std::endl;\n\n\n\t// print input and output dims\n\tfor (auto i = 0; i < num_input_nodes; i++)\n\t{\n\t\tstd::vector<int64_t> input_dims = session.GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape();\n\t\tstd::cout << std::endl << \"input \" << i << \" dim is: \";\n\t\tfor (auto j = 0; j < input_dims.size(); j++)\n\t\t\tstd::cout << input_dims[j] << \" \";\n\t}\n\tfor (auto i = 0; i < num_output_nodes; i++)\n\t{\n\t\tstd::vector<int64_t> output_dims = session.GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape();\n\t\tstd::cout << std::endl << \"output \" << i << \" dim is: \";\n\t\tfor (auto j = 0; j < output_dims.size(); j++)\n\t\t\tstd::cout << output_dims[j] << \" \";\n\t}\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmdet_onnxruntime.h",
    "content": "#ifndef _RTM_DET_ONNX_RUNTIME_H_\n#define _RTM_DET_ONNX_RUNTIME_H_\n\n#include <string>\n\n#include \"opencv2/opencv.hpp\"\n\n#include \"onnxruntime_cxx_api.h\"\n#include \"cpu_provider_factory.h\"\n#include \"rtmpose_utils.h\"\n\n\nclass RTMDetOnnxruntime\n{\npublic:\n\tRTMDetOnnxruntime() = delete;\n\tRTMDetOnnxruntime(const std::string& onnx_model_path);\n\tvirtual~RTMDetOnnxruntime();\n\npublic:\n\tDetectBox Inference(const cv::Mat& input_mat);\n\nprivate:\n\tvoid PrintModelInfo(Ort::Session& session);\n\nprivate:\n\tOrt::Env m_env;\n\tOrt::Session m_session;\n\n};\n\n#endif // !_RTM_DET_ONNX_RUNTIME_H_\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmpose_onnxruntime.cpp",
    "content": "#include \"rtmpose_onnxruntime.h\"\n\n#include <iostream>\n#include <thread>\n\n#include \"characterset_convert.h\"\n#include \"rtmpose_utils.h\"\n\n#undef max\n\n\nRTMPoseOnnxruntime::RTMPoseOnnxruntime(const std::string& onnx_model_path)\n\t:m_session(nullptr)\n{\n\tstd::wstring onnx_model_path_wstr = stubbornhuang::CharactersetConvert::string_to_wstring(onnx_model_path);\n\n\tm_env = Ort::Env(ORT_LOGGING_LEVEL_ERROR, \"rtmpose_onnxruntime_cpu\");\n\n\tint cpu_processor_num = std::thread::hardware_concurrency();\n\tcpu_processor_num /= 2;\n\n\tOrt::SessionOptions session_options;\n\tsession_options.SetIntraOpNumThreads(cpu_processor_num);\n\tsession_options.SetGraphOptimizationLevel(GraphOptimizationLevel::ORT_ENABLE_ALL);\n\tsession_options.SetLogSeverityLevel(4);\n\n\tOrtSessionOptionsAppendExecutionProvider_CPU(session_options, 0);\n\tm_session = Ort::Session(m_env, onnx_model_path_wstr.c_str(), session_options);\n\n\tPrintModelInfo(m_session);\n}\n\nRTMPoseOnnxruntime::~RTMPoseOnnxruntime()\n{\n}\n\nstd::vector<PosePoint> RTMPoseOnnxruntime::Inference(const cv::Mat& input_mat, const DetectBox& box)\n{\n\tstd::vector<PosePoint> pose_result;\n\n\tif (!box.IsValid())\n\t\treturn pose_result;\n\n\tstd::pair<cv::Mat, cv::Mat> crop_result_pair = CropImageByDetectBox(input_mat, box);\n\n\tcv::Mat crop_mat = crop_result_pair.first;\n\tcv::Mat affine_transform_reverse = crop_result_pair.second;\n\n\t// deep copy\n\tcv::Mat crop_mat_copy;\n\tcrop_mat.copyTo(crop_mat_copy);\n\n\t// BGR to RGB\n\tcv::Mat input_mat_copy_rgb;\n\tcv::cvtColor(crop_mat, input_mat_copy_rgb, CV_BGR2RGB);\n\n\t// image data, HWC->CHW, image_data - mean / std normalize\n\tint image_height = input_mat_copy_rgb.rows;\n\tint image_width = input_mat_copy_rgb.cols;\n\tint image_channels = input_mat_copy_rgb.channels();\n\n\tstd::vector<float> input_image_array;\n\tinput_image_array.resize(1 * image_channels * image_height * image_width);\n\n\tfloat* input_image = input_image_array.data();\n\tfor (int h = 0; h < image_height; ++h)\n\t{\n\t\tfor (int w = 0; w < image_width; ++w)\n\t\t{\n\t\t\tfor (int c = 0; c < image_channels; ++c)\n\t\t\t{\n\t\t\t\tint chw_index = c * image_height * image_width + h * image_width + w;\n\n\t\t\t\tfloat tmp = input_mat_copy_rgb.ptr<uchar>(h)[w * 3 + c];\n\n\t\t\t\tinput_image[chw_index] = (tmp - IMAGE_MEAN[c]) / IMAGE_STD[c];\n\t\t\t}\n\t\t}\n\t}\n\n\t// inference\n\tstd::vector<const char*> m_onnx_input_names{ \"input\" };\n\tstd::vector<const char*> m_onnx_output_names{ \"simcc_x\",\"simcc_y\" };\n\tstd::array<int64_t, 4> input_shape{ 1, image_channels, image_height, image_width };\n\n\tauto memory_info = Ort::MemoryInfo::CreateCpu(OrtDeviceAllocator, OrtMemTypeCPU);\n\tOrt::Value input_tensor = Ort::Value::CreateTensor<float>(\n\t\tmemory_info,\n\t\tinput_image_array.data(),\n\t\tinput_image_array.size(),\n\t\tinput_shape.data(),\n\t\tinput_shape.size()\n\t);\n\n\tassert(input_tensor.IsTensor());\n\n\tauto output_tensors = m_session.Run(\n\t\tOrt::RunOptions{ nullptr },\n\t\tm_onnx_input_names.data(),\n\t\t&input_tensor,\n\t\t1,\n\t\tm_onnx_output_names.data(),\n\t\tm_onnx_output_names.size()\n\t);\n\n\t// pose process\n\tstd::vector<int64_t> simcc_x_dims = output_tensors[0].GetTensorTypeAndShapeInfo().GetShape();\n\tstd::vector<int64_t> simcc_y_dims = output_tensors[1].GetTensorTypeAndShapeInfo().GetShape();\n\n\tassert(simcc_x_dims.size() == 3 && simcc_y_dims.size() == 3);\n\n\tint batch_size = simcc_x_dims[0] == simcc_y_dims[0] ? simcc_x_dims[0] : 0;\n\tint joint_num = simcc_x_dims[1] == simcc_y_dims[1] ? simcc_x_dims[1] : 0;\n\tint extend_width = simcc_x_dims[2];\n\tint extend_height = simcc_y_dims[2];\n\n\tfloat* simcc_x_result = output_tensors[0].GetTensorMutableData<float>();\n\tfloat* simcc_y_result = output_tensors[1].GetTensorMutableData<float>();\n\n\n\tfor (int i = 0; i < joint_num; ++i)\n\t{\n\t\t// find the maximum and maximum indexes in the value of each Extend_width length\n\t\tauto x_biggest_iter = std::max_element(simcc_x_result + i * extend_width, simcc_x_result + i * extend_width + extend_width);\n\t\tint max_x_pos = std::distance(simcc_x_result + i * extend_width, x_biggest_iter);\n\t\tint pose_x = max_x_pos / 2;\n\t\tfloat score_x = *x_biggest_iter;\n\n\t\t// find the maximum and maximum indexes in the value of each exten_height length\n\t\tauto y_biggest_iter = std::max_element(simcc_y_result + i * extend_height, simcc_y_result + i * extend_height + extend_height);\n\t\tint max_y_pos = std::distance(simcc_y_result + i * extend_height, y_biggest_iter);\n\t\tint pose_y = max_y_pos / 2;\n\t\tfloat score_y = *y_biggest_iter;\n\n\t\t//float score = (score_x + score_y) / 2;\n\t\tfloat score = std::max(score_x, score_y);\n\n\t\tPosePoint temp_point;\n\t\ttemp_point.x = int(pose_x);\n\t\ttemp_point.y = int(pose_y);\n\t\ttemp_point.score = score;\n\t\tpose_result.emplace_back(temp_point);\n\t}\n\n\t// anti affine transformation to obtain the coordinates on the original picture\n\tfor (int i = 0; i < pose_result.size(); ++i)\n\t{\n\t\tcv::Mat origin_point_Mat = cv::Mat::ones(3, 1, CV_64FC1);\n\t\torigin_point_Mat.at<double>(0, 0) = pose_result[i].x;\n\t\torigin_point_Mat.at<double>(1, 0) = pose_result[i].y;\n\n\t\tcv::Mat temp_result_mat = affine_transform_reverse * origin_point_Mat;\n\n\t\tpose_result[i].x = temp_result_mat.at<double>(0, 0);\n\t\tpose_result[i].y = temp_result_mat.at<double>(1, 0);\n\t}\n\n\treturn pose_result;\n}\n\nstd::pair<cv::Mat, cv::Mat> RTMPoseOnnxruntime::CropImageByDetectBox(const cv::Mat& input_image, const DetectBox& box)\n{\n\tstd::pair<cv::Mat, cv::Mat> result_pair;\n\n\tif (!input_image.data)\n\t{\n\t\treturn result_pair;\n\t}\n\n\tif (!box.IsValid())\n\t{\n\t\treturn result_pair;\n\t}\n\n\t// deep copy\n\tcv::Mat input_mat_copy;\n\tinput_image.copyTo(input_mat_copy);\n\n\t// calculate the width, height and center points of the human detection box\n\tint box_width = box.right - box.left;\n\tint box_height = box.bottom - box.top;\n\tint box_center_x = box.left + box_width / 2;\n\tint box_center_y = box.top + box_height / 2;\n\n\tfloat aspect_ratio = 192.0 / 256.0;\n\n\t// adjust the width and height ratio of the size of the picture in the RTMPOSE input\n\tif (box_width > (aspect_ratio * box_height))\n\t{\n\t\tbox_height = box_width / aspect_ratio;\n\t}\n\telse if (box_width < (aspect_ratio * box_height))\n\t{\n\t\tbox_width = box_height * aspect_ratio;\n\t}\n\n\tfloat scale_image_width = box_width * 1.2;\n\tfloat scale_image_height = box_height * 1.2;\n\n\t// get the affine matrix\n\tcv::Mat affine_transform = GetAffineTransform(\n\t\tbox_center_x,\n\t\tbox_center_y,\n\t\tscale_image_width,\n\t\tscale_image_height,\n\t\t192,\n\t\t256\n\t);\n\n\tcv::Mat affine_transform_reverse = GetAffineTransform(\n\t\tbox_center_x,\n\t\tbox_center_y,\n\t\tscale_image_width,\n\t\tscale_image_height,\n\t\t192,\n\t\t256,\n\t\ttrue\n\t);\n\n\t// affine transform\n\tcv::Mat affine_image;\n\tcv::warpAffine(input_mat_copy, affine_image, affine_transform, cv::Size(192, 256), cv::INTER_LINEAR);\n\t//cv::imwrite(\"affine_img.jpg\", affine_image);\n\n\tresult_pair = std::make_pair(affine_image, affine_transform_reverse);\n\n\treturn result_pair;\n}\n\nvoid RTMPoseOnnxruntime::PrintModelInfo(Ort::Session& session)\n{\n\t// print the number of model input nodes\n\tsize_t num_input_nodes = session.GetInputCount();\n\tsize_t num_output_nodes = session.GetOutputCount();\n\tstd::cout << \"Number of input node is:\" << num_input_nodes << std::endl;\n\tstd::cout << \"Number of output node is:\" << num_output_nodes << std::endl;\n\n\t// print node name\n\tOrt::AllocatorWithDefaultOptions allocator;\n\tstd::cout << std::endl;\n\tfor (auto i = 0; i < num_input_nodes; i++)\n\t\tstd::cout << \"The input op-name \" << i << \" is:\" << session.GetInputNameAllocated(i, allocator) << std::endl;\n\tfor (auto i = 0; i < num_output_nodes; i++)\n\t\tstd::cout << \"The output op-name \" << i << \" is:\" << session.GetOutputNameAllocated(i, allocator) << std::endl;\n\n\t// print input and output dims\n\tfor (auto i = 0; i < num_input_nodes; i++)\n\t{\n\t\tstd::vector<int64_t> input_dims = session.GetInputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape();\n\t\tstd::cout << std::endl << \"input \" << i << \" dim is: \";\n\t\tfor (auto j = 0; j < input_dims.size(); j++)\n\t\t\tstd::cout << input_dims[j] << \" \";\n\t}\n\tfor (auto i = 0; i < num_output_nodes; i++)\n\t{\n\t\tstd::vector<int64_t> output_dims = session.GetOutputTypeInfo(i).GetTensorTypeAndShapeInfo().GetShape();\n\t\tstd::cout << std::endl << \"output \" << i << \" dim is: \";\n\t\tfor (auto j = 0; j < output_dims.size(); j++)\n\t\t\tstd::cout << output_dims[j] << \" \";\n\t}\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmpose_onnxruntime.h",
    "content": "#ifndef _RTM_POSE_ONNXRUNTIME_H_\n#define _RTM_POSE_ONNXRUNTIME_H_\n\n#include <string>\n\n#include \"onnxruntime_cxx_api.h\"\n#include \"cpu_provider_factory.h\"\n#include \"opencv2/opencv.hpp\"\n\n#include \"rtmdet_onnxruntime.h\"\n#include \"rtmpose_utils.h\"\n\nclass RTMPoseOnnxruntime\n{\npublic:\n\tRTMPoseOnnxruntime() = delete;\n\tRTMPoseOnnxruntime(const std::string& onnx_model_path);\n\tvirtual~RTMPoseOnnxruntime();\n\npublic:\n\tstd::vector<PosePoint> Inference(const cv::Mat& input_mat, const DetectBox& box);\n\nprivate:\n\tstd::pair<cv::Mat, cv::Mat> CropImageByDetectBox(const cv::Mat& input_image, const DetectBox& box);\n\nprivate:\n\tvoid PrintModelInfo(Ort::Session& session);\n\nprivate:\n\tOrt::Env m_env;\n\tOrt::Session m_session;\n};\n\n#endif // !_RTM_POSE_ONNXRUNTIME_H_\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmpose_tracker_onnxruntime.cpp",
    "content": "#include \"rtmpose_tracker_onnxruntime.h\"\n\nRTMPoseTrackerOnnxruntime::RTMPoseTrackerOnnxruntime(const std::string& det_model_path, const std::string& pose_model_path, int dectect_interval)\n\t:m_rtm_det_ptr(nullptr),\n\tm_rtm_pose_ptr(nullptr),\n\tm_frame_num(0),\n\tm_dectect_interval(dectect_interval)\n{\n\tm_rtm_det_ptr = std::make_unique<RTMDetOnnxruntime>(det_model_path);\n\tm_rtm_pose_ptr = std::make_unique<RTMPoseOnnxruntime>(pose_model_path);\n}\n\nRTMPoseTrackerOnnxruntime::~RTMPoseTrackerOnnxruntime()\n{\n}\n\nstd::pair<DetectBox, std::vector<PosePoint>> RTMPoseTrackerOnnxruntime::Inference(const cv::Mat& input_mat)\n{\n\tstd::pair<DetectBox, std::vector<PosePoint>> result;\n\n\tif (m_rtm_det_ptr == nullptr || m_rtm_pose_ptr == nullptr)\n\t\treturn result;\n\n\tif (m_frame_num % m_dectect_interval == 0)\n\t{\n\t\tm_detect_box = m_rtm_det_ptr->Inference(input_mat);\n\t}\n\n\tstd::vector<PosePoint> pose_result = m_rtm_pose_ptr->Inference(input_mat, m_detect_box);\n\n\tm_frame_num += 1;\n\n\treturn std::make_pair(m_detect_box, pose_result);\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmpose_tracker_onnxruntime.h",
    "content": "#ifndef _RTM_POSE_TRACKER_ONNXRUNTIME_H_\n#define _RTM_POSE_TRACKER_ONNXRUNTIME_H_\n\n#include \"rtmdet_onnxruntime.h\"\n#include \"rtmpose_onnxruntime.h\"\n\n#include <vector>\n#include <memory>\n\nclass RTMPoseTrackerOnnxruntime\n{\npublic:\n\tRTMPoseTrackerOnnxruntime() = delete;\n\tRTMPoseTrackerOnnxruntime(\n\t\tconst std::string& det_model_path,\n\t\tconst std::string& pose_model_path,\n\t\tint dectect_interval = 10\n\t);\n\tvirtual~RTMPoseTrackerOnnxruntime();\n\npublic:\n\tstd::pair<DetectBox, std::vector<PosePoint>> Inference(const cv::Mat& input_mat);\n\nprivate:\n\tstd::unique_ptr<RTMDetOnnxruntime> m_rtm_det_ptr;\n\tstd::unique_ptr<RTMPoseOnnxruntime> m_rtm_pose_ptr;\n\tunsigned int m_frame_num;\n\tDetectBox m_detect_box;\n\tint m_dectect_interval;\n};\n\n#endif // !_RTM_POSE_TRACKER_ONNXRUNTIME_H_\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/OnnxRumtime-CPU/src/RTMPoseOnnxRuntime/rtmpose_utils.h",
    "content": "#ifndef _RTM_POSE_UTILS_H_\n#define _RTM_POSE_UTILS_H_\n\n#include \"opencv2/opencv.hpp\"\n\nconst std::vector<float> IMAGE_MEAN{ 123.675, 116.28, 103.53 };\nconst std::vector<float> IMAGE_STD{ 58.395, 57.12, 57.375 };\n\nstruct DetectBox\n{\n\tint left;\n\tint top;\n\tint right;\n\tint bottom;\n\tfloat score;\n\tint label;\n\n\tDetectBox()\n\t{\n\t\tleft = -1;\n\t\ttop = -1;\n\t\tright = -1;\n\t\tbottom = -1;\n\t\tscore = -1.0;\n\t\tlabel = -1;\n\t}\n\n\tbool IsValid() const\n\t{\n\t\treturn left != -1 && top != -1 && right != -1 && bottom != -1 && score != -1.0 && label != -1;\n\t}\n};\n\nstatic bool BoxCompare(\n\tconst DetectBox& a,\n\tconst DetectBox& b) {\n\treturn a.score > b.score;\n}\n\nstruct PosePoint\n{\n\tint x;\n\tint y;\n\tfloat score;\n\n\tPosePoint()\n\t{\n\t\tx = 0;\n\t\ty = 0;\n\t\tscore = 0.0;\n\t}\n};\n\ntypedef PosePoint Vector2D;\n\n\nstatic cv::Mat GetAffineTransform(float center_x, float center_y, float scale_width, float scale_height, int output_image_width, int output_image_height, bool inverse = false)\n{\n\t// solve the affine transformation matrix\n\n\t// get the three points corresponding to the source picture and the target picture\n\tcv::Point2f src_point_1;\n\tsrc_point_1.x = center_x;\n\tsrc_point_1.y = center_y;\n\n\tcv::Point2f src_point_2;\n\tsrc_point_2.x = center_x;\n\tsrc_point_2.y = center_y - scale_width * 0.5;\n\n\tcv::Point2f src_point_3;\n\tsrc_point_3.x = src_point_2.x - (src_point_1.y - src_point_2.y);\n\tsrc_point_3.y = src_point_2.y + (src_point_1.x - src_point_2.x);\n\n\n\tfloat alphapose_image_center_x = output_image_width / 2;\n\tfloat alphapose_image_center_y = output_image_height / 2;\n\n\tcv::Point2f dst_point_1;\n\tdst_point_1.x = alphapose_image_center_x;\n\tdst_point_1.y = alphapose_image_center_y;\n\n\tcv::Point2f dst_point_2;\n\tdst_point_2.x = alphapose_image_center_x;\n\tdst_point_2.y = alphapose_image_center_y - output_image_width * 0.5;\n\n\tcv::Point2f dst_point_3;\n\tdst_point_3.x = dst_point_2.x - (dst_point_1.y - dst_point_2.y);\n\tdst_point_3.y = dst_point_2.y + (dst_point_1.x - dst_point_2.x);\n\n\n\tcv::Point2f srcPoints[3];\n\tsrcPoints[0] = src_point_1;\n\tsrcPoints[1] = src_point_2;\n\tsrcPoints[2] = src_point_3;\n\n\tcv::Point2f dstPoints[3];\n\tdstPoints[0] = dst_point_1;\n\tdstPoints[1] = dst_point_2;\n\tdstPoints[2] = dst_point_3;\n\n\t// get affine matrix\n\tcv::Mat affineTransform;\n\tif (inverse)\n\t{\n\t\taffineTransform = cv::getAffineTransform(dstPoints, srcPoints);\n\t}\n\telse\n\t{\n\t\taffineTransform = cv::getAffineTransform(srcPoints, dstPoints);\n\t}\n\n\treturn affineTransform;\n}\n\n#endif // !_RTM_POSE_UTILS_H_\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/README.md",
    "content": "# rtmpose_tensorrt\n\n## Description\n\nThis repository is use the TensorRT to deploy RTMDet and RTMPose. Your computer should have these components:\n\n- NVIDIA GPU\n- CUDA\n- cudnn\n- TensorRT 8.x\n- OPENCV\n- VS2019\n\nThe effect of the code is as follows:\n\n![mabaoguo](https://github.com/Dominic23331/rtmpose_tensorrt/assets/53283758/568563be-a31d-4d03-9629-842dad3745e2)\n\n## Get Started\n\n### I. Convert Model\n\n#### 1. RTMDet\n\nWhen you start to convert a RTMDet model, you can use **convert_rtmdet.py** to convert pth file to onnx.\n\n```shell\npython convert_rtmdet.py --config <model cfg> --checkpoint <checkpoint> --output <output path>\n```\n\nNote that RTMDet should be the mmdetection version, and the conversion of mmyolo is not supported.\n\n#### 2. RTMPose\n\nYou can use mmdeploy to convert RTMPose. The mmdeploy config file should use **configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py**.  The convert command as follow:\n\n```shell\npython tools/deploy.py <deploy cfg> <model cfg> <checkpoint> <image path>\n```\n\n#### 3. Convert to TensorRT engine file\n\nYou can use trtexec to convert an ONNX file to engine file. The command as follow:\n\n```\ntrtexec --onnx=<ONNX file> --saveEngine=<output file>\n```\n\n**Note that the engine files included in the project are only for storing examples. As the engine files generated by TensorRT are related to hardware, it is necessary to regenerate the engine files on the computer where the code needs to be run.**\n\n### II. Run\n\nAt first, you should fill in the model locations for RTMDet and RTMPose as follows:\n\n```c++\n// set engine file path\nstring detEngineFile = \"./model/rtmdet.engine\";\nstring poseEngineFile = \"./model/rtmpose_m.engine\";\n```\n\nThen, you can set the cap to video file or camera.\n\n```\n// open cap\ncv::VideoCapture cap(0);\n```\n\nIf you want to change iou threshold or confidence threshold, you can change them when you initialize RTMDet model.\n\n```\nRTMDet det_model(detEngineFile, logger, 0.5, 0.65);\n```\n\nFinally, you can run the **main.cpp** file to get result.\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/python/convert_rtmdet.py",
    "content": "import argparse\n\nimport torch\nimport torch.nn.functional as F\nfrom mmdet.apis import init_detector\nfrom torch import nn\n\n\ndef build_model_from_cfg(config_path: str, checkpoint_path: str, device):\n    model = init_detector(config_path, checkpoint_path, device=device)\n    model.eval()\n    return model\n\n\nclass RTMDet(nn.Module):\n    \"\"\"Load RTMDet model and add postprocess.\n\n    Args:\n        model (nn.Module): The RTMDet model.\n    \"\"\"\n\n    def __init__(self, model: nn.Module) -> None:\n        super().__init__()\n        self.model = model\n        self.stage = [80, 40, 20]\n        self.input_shape = 640\n\n    def forward(self, inputs):\n        \"\"\"model forward function.\"\"\"\n        boxes = []\n        neck_outputs = self.model(inputs)\n        for i, (cls, box) in enumerate(zip(*neck_outputs)):\n            cls = cls.permute(0, 2, 3, 1)\n            box = box.permute(0, 2, 3, 1)\n            box = self.decode(box, cls, i)\n            boxes.append(box)\n        result_box = torch.cat(boxes, dim=1)\n        return result_box\n\n    def decode(self, box: torch.Tensor, cls: torch.Tensor, stage: int):\n        \"\"\"RTMDet postprocess function.\n\n        Args:\n            box (torch.Tensor): output boxes.\n            cls (torch.Tensor): output cls.\n            stage (int): RTMDet output stage.\n\n        Returns:\n            torch.Tensor: The decode boxes.\n                Format is [x1, y1, x2, y2, class, confidence]\n        \"\"\"\n        cls = F.sigmoid(cls)\n        conf = torch.max(cls, dim=3, keepdim=True)[0]\n        cls = torch.argmax(cls, dim=3, keepdim=True).to(torch.float32)\n\n        box = torch.cat([box, cls, conf], dim=-1)\n\n        step = self.input_shape // self.stage[stage]\n\n        block_step = torch.linspace(\n            0, self.stage[stage] - 1, steps=self.stage[stage],\n            device='cuda') * step\n        block_x = torch.broadcast_to(block_step,\n                                     [self.stage[stage], self.stage[stage]])\n        block_y = torch.transpose(block_x, 1, 0)\n        block_x = torch.unsqueeze(block_x, 0)\n        block_y = torch.unsqueeze(block_y, 0)\n        block = torch.stack([block_x, block_y], -1)\n\n        box[..., :2] = block - box[..., :2]\n        box[..., 2:4] = block + box[..., 2:4]\n        box = box.reshape(1, -1, 6)\n        return box\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='convert rtmdet model to ONNX.')\n    parser.add_argument(\n        '--config', type=str, help='rtmdet config file path from mmdetection.')\n    parser.add_argument(\n        '--checkpoint',\n        type=str,\n        help='rtmdet checkpoint path from mmdetection.')\n    parser.add_argument('--output', type=str, help='output filename.')\n    parser.add_argument(\n        '--device',\n        type=str,\n        default='cuda:0',\n        help='Device used for inference')\n    parser.add_argument(\n        '--input-name', type=str, default='image', help='ONNX input name.')\n    parser.add_argument(\n        '--output-name', type=str, default='output', help='ONNX output name.')\n    parser.add_argument(\n        '--opset', type=int, default=11, help='ONNX opset version.')\n    args = parser.parse_args()\n    return args\n\n\nif __name__ == '__main__':\n    args = parse_args()\n\n    model = build_model_from_cfg(args.config, args.checkpoint, args.device)\n    rtmdet = RTMDet(model)\n    rtmdet.eval()\n    x = torch.randn((1, 3, 640, 640), device=args.device)\n\n    torch.onnx.export(\n        rtmdet,\n        x,\n        args.output,\n        input_names=[args.input_name],\n        output_names=[args.output_name],\n        opset_version=args.opset)\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/inference.cpp",
    "content": "#include \"inference.h\"\n\n\n/**\n * @brief Inference network\n * @param image Input image\n * @param detect_model RTMDet model\n * @param pose_model RTMPose model\n * @return Inference result\n*/\nstd::vector<std::vector<PosePoint>> inference(cv::Mat& image, RTMDet& detect_model, RTMPose& pose_model)\n{\n\tcv::Mat im0;\n\timage.copyTo(im0);\n\n\t// inference detection model\n\tstd::vector<Box> det_result = detect_model.predict(image);\n\tstd::vector<std::vector<PosePoint>> result;\n\tfor (int i = 0; i < det_result.size(); i++)\n\t{\n\t\t// Select the detection box labeled as human\n\t\tif (!isEqual(det_result[i].cls, 0.0))\n\t\t\tcontinue;\n\n\t\t// cut image to input the pose model\n\t\tcv::Mat person_image = img_cut(im0, det_result[i].x1, det_result[i].y1, det_result[i].x2, det_result[i].y2);\n\t\tstd::vector<PosePoint> pose_result = pose_model.predict(person_image);\n\n\t\t// Restore points to original image\n\t\tfor (int j = 0; j < pose_result.size(); j++)\n\t\t{\n\t\t\tpose_result[j].x += det_result[i].x1;\n\t\t\tpose_result[j].y += det_result[i].y1;\n\t\t}\n\t\tresult.push_back(pose_result);\n\t}\n\treturn result;\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/inference.h",
    "content": "#pragma once\n#include <iostream>\n#include <string>\n\n#include <NvInfer.h>\n#include <opencv2/opencv.hpp>\n\n#include \"rtmdet.h\"\n#include \"rtmpose.h\"\n#include \"utils.h\"\n\n\n\nstd::vector<std::vector<PosePoint>> inference(cv::Mat& image, RTMDet& detect_model, RTMPose& pose_model);\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/main.cpp",
    "content": "#include <iostream>\n#include <string>\n#include <tuple>\n#include <NvInfer.h>\n#include <opencv2/opencv.hpp>\n\n#include \"rtmdet.h\"\n#include \"rtmpose.h\"\n#include \"utils.h\"\n#include \"inference.h\"\n\n\nusing namespace std;\n\n/**\n * @brief Setting up Tensorrt logger\n*/\nclass Logger : public nvinfer1::ILogger\n{\n    void log(Severity severity, const char* msg) noexcept override\n    {\n        // Only output logs with severity greater than warning\n        if (severity <= Severity::kWARNING)\n            std::cout << msg << std::endl;\n    }\n}logger;\n\n\nint main()\n{\n    // set engine file path\n    string detEngineFile = \"./model/rtmdet.engine\";\n    string poseEngineFile = \"./model/rtmpose_m.engine\";\n\n    // init model\n    RTMDet det_model(detEngineFile, logger);\n    RTMPose pose_model(poseEngineFile, logger);\n\n    // open cap\n    cv::VideoCapture cap(0);\n\n    while (cap.isOpened())\n    {\n        cv::Mat frame;\n        cv::Mat show_frame;\n        cap >> frame;\n\n        if (frame.empty())\n            break;\n\n        frame.copyTo(show_frame);\n        auto result = inference(frame, det_model, pose_model);\n        draw_pose(show_frame, result);\n\n        cv::imshow(\"result\", show_frame);\n        if (cv::waitKey(1) == 'q')\n            break;\n    }\n    cv::destroyAllWindows();\n    cap.release();\n\n    return 0;\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/rtmdet.cpp",
    "content": "#include \"rtmdet.h\"\n\n\n// set network params\nfloat RTMDet::input_h = 640;\nfloat RTMDet::input_w = 640;\nfloat RTMDet::mean[3] = { 123.675, 116.28, 103.53 };\nfloat RTMDet::std[3] = { 58.395, 57.12, 57.375 };\n\n/**\n * @brief RTMDet`s constructor\n * @param model_path RTMDet engine file path\n * @param logger Nvinfer ILogger\n * @param conf_thre The confidence threshold\n * @param iou_thre The iou threshold of nms\n*/\nRTMDet::RTMDet(std::string model_path, nvinfer1::ILogger& logger, float conf_thre, float iou_thre) : conf_thre(conf_thre), iou_thre(iou_thre)\n{\n    // read the engine file\n    std::ifstream engineStream(model_path, std::ios::binary);\n    engineStream.seekg(0, std::ios::end);\n    const size_t modelSize = engineStream.tellg();\n    engineStream.seekg(0, std::ios::beg);\n    std::unique_ptr<char[]> engineData(new char[modelSize]);\n    engineStream.read(engineData.get(), modelSize);\n    engineStream.close();\n\n    // create tensorrt model\n    runtime = nvinfer1::createInferRuntime(logger);\n    engine = runtime->deserializeCudaEngine(engineData.get(), modelSize);\n    context = engine->createExecutionContext();\n\n    // Define input dimensions\n    context->setBindingDimensions(0, nvinfer1::Dims4(1, 3, input_h, input_w));\n\n    // create CUDA stream\n    cudaStreamCreate(&stream);\n\n    // Initialize offset\n    offset.push_back(0);\n    offset.push_back(0);\n}\n\n\n/**\n * @brief RTMDet`s destructor\n*/\nRTMDet::~RTMDet()\n{\n    cudaFree(stream);\n    cudaFree(buffer[0]);\n    cudaFree(buffer[1]);\n}\n\n\n/**\n * @brief Display network input and output parameters\n*/\nvoid RTMDet::show()\n{\n    for (int i = 0; i < engine->getNbBindings(); i++)\n    {\n        std::cout << \"node: \" << engine->getBindingName(i) << \", \";\n        if (engine->bindingIsInput(i))\n        {\n            std::cout << \"type: input\" << \", \";\n        }\n        else\n        {\n            std::cout << \"type: output\" << \", \";\n        }\n        nvinfer1::Dims dim = engine->getBindingDimensions(i);\n        std::cout << \"dimensions: \";\n        for (int d = 0; d < dim.nbDims; d++)\n        {\n            std::cout << dim.d[d] << \" \";\n        }\n        std::cout << \"\\n\";\n    }\n}\n\n\n/**\n * @brief Network preprocessing function\n * @param image Input image\n * @return Processed Tensor\n*/\nstd::vector<float> RTMDet::preprocess(cv::Mat& image)\n{\n    // resize image\n    std::tuple<cv::Mat, int, int> resized = resize(image, input_w, input_h);\n    cv::Mat resized_image = std::get<0>(resized);\n    offset[0] = std::get<1>(resized);\n    offset[1] = std::get<2>(resized);\n\n    // BGR2RGB\n    cv::cvtColor(resized_image, resized_image, cv::COLOR_BGR2RGB);\n\n    // subtract mean and divide variance\n    std::vector<float> input_tensor;\n    for (int k = 0; k < 3; k++)\n    {\n        for (int i = 0; i < resized_image.rows; i++)\n        {\n            for (int j = 0; j < resized_image.cols; j++)\n            {\n                input_tensor.emplace_back(((float)resized_image.at<cv::Vec3b>(i, j)[k] - mean[k]) / std[k]);\n            }\n        }\n    }\n\n    return input_tensor;\n}\n\n\n/**\n * @brief Network post-processing function\n * @param boxes_result The result of rtmdet\n * @param img_w The width of input image\n * @param img_h The height of input image\n * @return Detect boxes\n*/\nstd::vector<Box> RTMDet::postprocess(std::vector<float> boxes_result, int img_w, int img_h)\n{\n    std::vector<Box> result;\n    std::vector<float> buff;\n    for (int i = 0; i < 8400; i++)\n    {\n        // x1, y1, x2, y2, class, confidence\n        buff.insert(buff.end(), boxes_result.begin() + i * 6, boxes_result.begin() + i * 6 + 6);\n        // drop the box which confidence less than threshold\n        if (buff[5] < conf_thre)\n        {\n            buff.clear();\n            continue;\n        }\n\n        Box box;\n        box.x1 = buff[0];\n        box.y1 = buff[1];\n        box.x2 = buff[2];\n        box.y2 = buff[3];\n        box.cls = buff[4];\n        box.conf = buff[5];\n        result.emplace_back(box);\n        buff.clear();\n    }\n\n    // nms\n    result = non_maximum_suppression(result, iou_thre);\n\n    // return the box to real image\n    for (int i = 0; i < result.size(); i++)\n    {\n        result[i].x1 = MAX((result[i].x1 - offset[0]) * img_w / (input_w - 2 * offset[0]), 0);\n        result[i].y1 = MAX((result[i].y1 - offset[1]) * img_h / (input_h - 2 * offset[1]), 0);\n        result[i].x2 = MIN((result[i].x2 - offset[0]) * img_w / (input_w - 2 * offset[0]), img_w);\n        result[i].y2 = MIN((result[i].y2 - offset[1]) * img_h / (input_h - 2 * offset[1]), img_h);\n    }\n\n    return result;\n}\n\n\n/**\n * @brief Predict function\n * @param image Input image\n * @return Predict results\n*/\nstd::vector<Box> RTMDet::predict(cv::Mat& image)\n{\n    // get input image size\n    int img_w = image.cols;\n    int img_h = image.rows;\n    std::vector<float> input = preprocess(image);\n\n    // apply for GPU space\n    cudaMalloc(&buffer[0], 3 * input_h * input_w * sizeof(float));\n    cudaMalloc(&buffer[1], 8400 * 6 * sizeof(float));\n\n    // copy data to GPU\n    cudaMemcpyAsync(buffer[0], input.data(), 3 * input_h * input_w * sizeof(float), cudaMemcpyHostToDevice, stream);\n\n    // network inference\n    context->enqueueV2(buffer, stream, nullptr);\n    cudaStreamSynchronize(stream);\n\n    // get result from GPU\n    std::vector<float> boxes_result(8400 * 6);\n    cudaMemcpyAsync(boxes_result.data(), buffer[1], 8400 * 6 * sizeof(float), cudaMemcpyDeviceToHost);\n\n    std::vector<Box> result = postprocess(boxes_result, img_w, img_h);\n\n    cudaFree(buffer[0]);\n    cudaFree(buffer[1]);\n\n    return result;\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/rtmdet.h",
    "content": "#pragma once\n#include <iostream>\n#include <fstream>\n#include <vector>\n#include <tuple>\n#include <opencv2/opencv.hpp>\n#include <NvInfer.h>\n\n#include \"utils.h\"\n\n\n\nclass RTMDet\n{\npublic:\n\tRTMDet(std::string model_path, nvinfer1::ILogger& logger, float conf_thre=0.5, float iou_thre=0.65);\n\tvoid show();\n\tstd::vector<Box> predict(cv::Mat& image);\n\t~RTMDet();\n\nprivate:\n\tstatic float input_w;\n\tstatic float input_h;\n\tstatic float mean[3];\n\tstatic float std[3];\n\n\tfloat conf_thre;\n\tfloat iou_thre;\n\tstd::vector<int> offset;\n\n\tnvinfer1::IRuntime* runtime;\n\tnvinfer1::ICudaEngine* engine;\n\tnvinfer1::IExecutionContext* context;\n\n\tvoid* buffer[2];\n\tcudaStream_t stream;\n\n\tstd::vector<float> preprocess(cv::Mat& image);\n\tstd::vector<Box> postprocess(std::vector<float> boxes_result, int img_w, int img_h);\n};\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/rtmpose.cpp",
    "content": "#include \"rtmpose.h\"\n\n\n// set network params\nfloat RTMPose::input_h = 256;\nfloat RTMPose::input_w = 192;\nint RTMPose::extend_width = 384;\nint RTMPose::extend_height = 512;\nint RTMPose::num_points = 17;\nfloat RTMPose::mean[3] = { 123.675, 116.28, 103.53 };\nfloat RTMPose::std[3] = { 58.395, 57.12, 57.375 };\n\n/**\n * @brief RTMPose`s constructor\n * @param model_path RTMPose engine file path\n * @param logger Nvinfer ILogger\n*/\nRTMPose::RTMPose(std::string model_path, nvinfer1::ILogger& logger)\n{\n    // read the engine file\n    std::ifstream engineStream(model_path, std::ios::binary);\n    engineStream.seekg(0, std::ios::end);\n    const size_t modelSize = engineStream.tellg();\n    engineStream.seekg(0, std::ios::beg);\n    std::unique_ptr<char[]> engineData(new char[modelSize]);\n    engineStream.read(engineData.get(), modelSize);\n    engineStream.close();\n\n    // create tensorrt model\n    runtime = nvinfer1::createInferRuntime(logger);\n    engine = runtime->deserializeCudaEngine(engineData.get(), modelSize);\n    context = engine->createExecutionContext();\n\n    // Define input dimensions\n    context->setBindingDimensions(0, nvinfer1::Dims4(1, 3, input_h, input_w));\n\n    // create CUDA stream\n    cudaStreamCreate(&stream);\n\n    // Initialize offset\n    offset.push_back(0);\n    offset.push_back(0);\n}\n\n/**\n * @brief RTMPose`s destructor\n*/\nRTMPose::~RTMPose()\n{\n    cudaFree(stream);\n    cudaFree(buffer[0]);\n    cudaFree(buffer[1]);\n    cudaFree(buffer[2]);\n}\n\n\n/**\n * @brief Display network input and output parameters\n*/\nvoid RTMPose::show()\n{\n    for (int i = 0; i < engine->getNbBindings(); i++)\n    {\n        std::cout << \"node: \" << engine->getBindingName(i) << \", \";\n        if (engine->bindingIsInput(i))\n        {\n            std::cout << \"type: input\" << \", \";\n        }\n        else\n        {\n            std::cout << \"type: output\" << \", \";\n        }\n        nvinfer1::Dims dim = engine->getBindingDimensions(i);\n        std::cout << \"dimensions: \";\n        for (int d = 0; d < dim.nbDims; d++)\n        {\n            std::cout << dim.d[d] << \" \";\n        }\n        std::cout << \"\\n\";\n    }\n}\n\n\n/**\n * @brief Network preprocessing function\n * @param image Input image\n * @return Processed Tensor\n*/\nstd::vector<float> RTMPose::preprocess(cv::Mat& image)\n{\n    // resize image\n    std::tuple<cv::Mat, int, int> resized = resize(image, input_w, input_h);\n    cv::Mat resized_image = std::get<0>(resized);\n    offset[0] = std::get<1>(resized);\n    offset[1] = std::get<2>(resized);\n\n    // BGR2RGB\n    cv::cvtColor(resized_image, resized_image, cv::COLOR_BGR2RGB);\n\n    // subtract mean and divide variance\n    std::vector<float> input_tensor;\n    for (int k = 0; k < 3; k++)\n    {\n        for (int i = 0; i < resized_image.rows; i++)\n        {\n            for (int j = 0; j < resized_image.cols; j++)\n            {\n                input_tensor.emplace_back(((float)resized_image.at<cv::Vec3b>(i, j)[k] - mean[k]) / std[k]);\n            }\n        }\n    }\n\n    return input_tensor;\n}\n\n\n/**\n * @brief Network post-processing function\n * @param simcc_x_result SimCC x dimension output\n * @param simcc_y_result SimCC y dimension output\n * @param img_w The width of input image\n * @param img_h The height of input image\n * @return\n*/\nstd::vector<PosePoint> RTMPose::postprocess(std::vector<float> simcc_x_result, std::vector<float> simcc_y_result, int img_w, int img_h)\n{\n    std::vector<PosePoint> pose_result;\n    for (int i = 0; i < num_points; ++i)\n    {\n        // find the maximum and maximum indexes in the value of each Extend_width length\n        auto x_biggest_iter = std::max_element(simcc_x_result.begin() + i * extend_width, simcc_x_result.begin() + i * extend_width + extend_width);\n        int max_x_pos = std::distance(simcc_x_result.begin() + i * extend_width, x_biggest_iter);\n        int pose_x = max_x_pos / 2;\n        float score_x = *x_biggest_iter;\n\n        // find the maximum and maximum indexes in the value of each exten_height length\n        auto y_biggest_iter = std::max_element(simcc_y_result.begin() + i * extend_height, simcc_y_result.begin() + i * extend_height + extend_height);\n        int max_y_pos = std::distance(simcc_y_result.begin() + i * extend_height, y_biggest_iter);\n        int pose_y = max_y_pos / 2;\n        float score_y = *y_biggest_iter;\n\n        // get point confidence\n        float score = MAX(score_x, score_y);\n\n        PosePoint temp_point;\n        temp_point.x = (pose_x - offset[0]) * img_w / (input_w - 2 * offset[0]);\n        temp_point.y = (pose_y - offset[1]) * img_h / (input_h - 2 * offset[1]);\n        temp_point.score = score;\n        pose_result.emplace_back(temp_point);\n    }\n\n    return pose_result;\n}\n\n\n/**\n * @brief Predict function\n * @param image Input image\n * @return Predict results\n*/\nstd::vector<PosePoint> RTMPose::predict(cv::Mat& image)\n{\n    // get input image size\n    int img_w = image.cols;\n    int img_h = image.rows;\n    std::vector<float> input = preprocess(image);\n\n    // apply for GPU space\n    cudaMalloc(&buffer[0], 3 * input_h * input_w * sizeof(float));\n    cudaMalloc(&buffer[1], num_points * extend_width * sizeof(float));\n    cudaMalloc(&buffer[2], num_points * extend_height * sizeof(float));\n\n    // copy data to GPU\n    cudaMemcpyAsync(buffer[0], input.data(), 3 * input_h * input_w * sizeof(float), cudaMemcpyHostToDevice, stream);\n\n    // network inference\n    context->enqueueV2(buffer, stream, nullptr);\n    cudaStreamSynchronize(stream);\n\n    // get result from GPU\n    std::vector<float> simcc_x_result(num_points * extend_width);\n    std::vector<float> simcc_y_result(num_points * extend_height);\n    cudaMemcpyAsync(simcc_x_result.data(), buffer[1], num_points * extend_width * sizeof(float), cudaMemcpyDeviceToHost);\n    cudaMemcpyAsync(simcc_y_result.data(), buffer[2], num_points * extend_height * sizeof(float), cudaMemcpyDeviceToHost);\n\n    std::vector<PosePoint> pose_result = postprocess(simcc_x_result, simcc_y_result, img_w, img_h);\n\n    cudaFree(buffer[0]);\n    cudaFree(buffer[1]);\n    cudaFree(buffer[2]);\n\n    return pose_result;\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/rtmpose.h",
    "content": "#pragma once\n#include <iostream>\n#include <fstream>\n#include <string>\n#include <vector>\n#include <tuple>\n#include <algorithm>\n#include <opencv2/opencv.hpp>\n#include <NvInfer.h>\n\n#include \"utils.h\"\n\n\n\nclass RTMPose\n{\npublic:\n\tRTMPose(std::string model_path, nvinfer1::ILogger &logger);\n\tvoid show();\n\tstd::vector<PosePoint> predict(cv::Mat& image);\n\t~RTMPose();\n\nprivate:\n\tstatic float input_w;\n\tstatic float input_h;\n\tstatic int extend_width;\n\tstatic int extend_height;\n\tstatic float mean[3];\n\tstatic float std[3];\n\tstatic int num_points;\n\n\tstd::vector<int> offset;\n\n\tnvinfer1::IRuntime* runtime;\n\tnvinfer1::ICudaEngine* engine;\n\tnvinfer1::IExecutionContext* context;\n\n\tvoid* buffer[3];\n\tcudaStream_t stream;\n\n\tstd::vector<float> preprocess(cv::Mat& image);\n\tstd::vector<PosePoint> postprocess(std::vector<float> simcc_x_result, std::vector<float> simcc_y_result, int img_w, int img_h);\n};\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/utils.cpp",
    "content": "#include \"utils.h\"\n\n\n// set points links\nstd::vector<std::pair<int, int>> coco_17_joint_links = {\n\t{0,1},{0,2},{1,3},{2,4},{5,7},{7,9},{6,8},{8,10},{5,6},\n\t{5,11},{6,12},{11,12},{11,13},{13,15},{12,14},{14,16}\n};\n\n\n/**\n * @brief Mix two images\n * @param srcImage Original image\n * @param mixImage Past image\n * @param startPoint Start point\n * @return Success or not\n*/\nbool MixImage(cv::Mat& srcImage, cv::Mat mixImage, cv::Point startPoint)\n{\n\n\tif (!srcImage.data || !mixImage.data)\n\t{\n\t\treturn false;\n\t}\n\n\tint addCols = startPoint.x + mixImage.cols > srcImage.cols ? 0 : mixImage.cols;\n\tint addRows = startPoint.y + mixImage.rows > srcImage.rows ? 0 : mixImage.rows;\n\tif (addCols == 0 || addRows == 0)\n\t{\n\t\treturn false;\n\t}\n\n\tcv::Mat roiImage = srcImage(cv::Rect(startPoint.x, startPoint.y, addCols, addRows));\n\n\tmixImage.copyTo(roiImage, mixImage);\n\treturn true;\n}\n\n\n/**\n * @brief Resize image\n * @param img Input image\n * @param w Resized width\n * @param h Resized height\n * @return Resized image and offset\n*/\nstd::tuple<cv::Mat, int, int> resize(cv::Mat& img, int w, int h)\n{\n\tcv::Mat result;\n\n\tint ih = img.rows;\n\tint iw = img.cols;\n\n\tfloat scale = MIN(float(w) / float(iw), float(h) / float(ih));\n\tint nw = iw * scale;\n\tint nh = ih * scale;\n\n\tcv::resize(img, img, cv::Size(nw, nh));\n\tresult = cv::Mat::ones(cv::Size(w, h), CV_8UC1) * 128;\n\tcv::cvtColor(result, result, cv::COLOR_GRAY2RGB);\n\tcv::cvtColor(img, img, cv::COLOR_BGR2RGB);\n\n\tbool ifg = MixImage(result, img, cv::Point((w - nw) / 2, (h - nh) / 2));\n\tif (!ifg)\n\t{\n\t\tstd::cerr << \"MixImage failed\" << std::endl;\n\t\tabort();\n\t}\n\n\tstd::tuple<cv::Mat, int, int> res_tuple = std::make_tuple(result, (w - nw) / 2, (h - nh) / 2);\n\n\treturn res_tuple;\n}\n\n\n/**\n * @brief Compare two boxes\n * @param b1 Box1\n * @param b2 Box2\n * @return Compare result\n*/\nbool compare_boxes(const Box& b1, const Box& b2)\n{\n\treturn b1.conf < b2.conf;\n}\n\n\n/**\n * @brief Iou function\n * @param b1 Box1\n * @param b2 Box2\n * @return Iou\n*/\nfloat intersection_over_union(const Box& b1, const Box& b2)\n{\n\tfloat x1 = std::max(b1.x1, b2.x1);\n\tfloat y1 = std::max(b1.y1, b2.y1);\n\tfloat x2 = std::min(b1.x2, b2.x2);\n\tfloat y2 = std::min(b1.y2, b2.y2);\n\n\t// get intersection\n\tfloat box_intersection = std::max((float)0, x2 - x1) * std::max((float)0, y2 - y1);\n\n\t// get union\n\tfloat area1 = (b1.x2 - b1.x1) * (b1.y2 - b1.y1);\n\tfloat area2 = (b2.x2 - b2.x1) * (b2.y2 - b2.y1);\n\tfloat box_union = area1 + area2 - box_intersection;\n\n\t// To prevent the denominator from being zero, add a very small numerical value to the denominator\n\tfloat iou = box_intersection / (box_union + 0.0001);\n\n\treturn iou;\n}\n\n\n/**\n * @brief Non-Maximum Suppression function\n * @param boxes Input boxes\n * @param iou_thre Iou threshold\n * @return Boxes after nms\n*/\nstd::vector<Box> non_maximum_suppression(std::vector<Box> boxes, float iou_thre)\n{\n\t// Sort boxes based on confidence\n\tstd::sort(boxes.begin(), boxes.end(), compare_boxes);\n\n\tstd::vector<Box> result;\n\tstd::vector<Box> temp;\n\twhile (!boxes.empty())\n\t{\n\t\ttemp.clear();\n\n\t\tBox chosen_box = boxes.back();\n\t\tboxes.pop_back();\n\t\tfor (int i = 0; i < boxes.size(); i++)\n\t\t{\n\t\t\tif (boxes[i].cls != chosen_box.cls || intersection_over_union(boxes[i], chosen_box) < iou_thre)\n\t\t\t\ttemp.push_back(boxes[i]);\n\t\t}\n\n\t\tboxes = temp;\n\t\tresult.push_back(chosen_box);\n\t}\n\treturn result;\n}\n\n\n/**\n * @brief Cut image\n * @param image Input image\n * @param x1 The left coordinate of cut box\n * @param y1 The top coordinate of cut box\n * @param x2 The right coordinate of cut box\n * @param y2 The bottom coordinate of cut box\n * @return Cut image\n*/\ncv::Mat img_cut(cv::Mat& image, int x1, int y1, int x2, int y2)\n{\n\tcv::Rect roi(x1, y1, x2 - x1, y2 - y1);\n\tcv::Mat croppedImage = image(roi);\n\treturn croppedImage;\n}\n\n\n/**\n * @brief Judge whether two floating point numbers are equal\n * @param a Number a\n * @param b Number b\n * @return Result\n*/\nbool isEqual(float a, float b)\n{\n\treturn std::fabs(a - b) < 1e-5;\n}\n\n\n/**\n * @brief Draw detection result to image\n * @param image Input image\n * @param points Detection result\n*/\nvoid draw_pose(cv::Mat& image, std::vector<std::vector<PosePoint>> points)\n{\n\tfor (int p = 0; p < points.size(); p++)\n\t{\n\t\t// draw points links\n\t\tfor (int i = 0; i < coco_17_joint_links.size(); i++)\n\t\t{\n\t\t\tstd::pair<int, int> joint_link = coco_17_joint_links[i];\n\t\t\tcv::line(\n\t\t\t\timage,\n\t\t\t\tcv::Point(points[p][joint_link.first].x, points[p][joint_link.first].y),\n\t\t\t\tcv::Point(points[p][joint_link.second].x, points[p][joint_link.second].y),\n\t\t\t\tcv::Scalar{ 0, 255, 0 },\n\t\t\t\t2,\n\t\t\t\tcv::LINE_AA\n\t\t\t);\n\t\t}\n\t\t//draw points\n\t\tfor (int i = 0; i < points[p].size(); i++)\n\t\t{\n\t\t\tcv::circle(\n\t\t\t\timage,\n\t\t\t\tcv::Point(points[p][i].x, points[p][i].y),\n\t\t\t\t1,\n\t\t\t\tcv::Scalar{ 0, 0, 255 },\n\t\t\t\t5,\n\t\t\t\tcv::LINE_AA\n\t\t\t);\n\t\t}\n\t}\n}\n"
  },
  {
    "path": "projects/rtmpose/examples/RTMPose-Deploy/Windows/TensorRT/src/RTMPoseTensorRT/utils.h",
    "content": "#pragma once\n#include <iostream>\n#include <tuple>\n#include <algorithm>\n#include <cmath>\n#include <opencv2/opencv.hpp>\n\n\n/**\n * @brief Key point structure\n*/\nstruct PosePoint\n{\n\tint x;\n\tint y;\n\tfloat score;\n\n\tPosePoint()\n\t{\n\t\tx = 0;\n\t\ty = 0;\n\t\tscore = 0.0;\n\t}\n};\n\n/**\n * @brief Detection box structure\n*/\nstruct Box\n{\n\tfloat x1;\n\tfloat y1;\n\tfloat x2;\n\tfloat y2;\n\tint cls;\n\tfloat conf;\n\n\tBox()\n\t{\n\t\tx1 = 0;\n\t\ty1 = 0;\n\t\tx2 = 0;\n\t\ty2 = 0;\n\t\tcls = 0;\n\t\tconf = 0;\n\t}\n};\n\nbool MixImage(cv::Mat& srcImage, cv::Mat mixImage, cv::Point startPoint);\nstd::tuple<cv::Mat, int, int> resize(cv::Mat& img, int w, int h);\nbool compare_boxes(const Box& b1, const Box& b2);\nfloat intersection_over_union(const Box& b1, const Box& b2);\nstd::vector<Box> non_maximum_suppression(std::vector<Box> boxes, float iou_thre);\ncv::Mat img_cut(cv::Mat& image, int x1, int y1, int x2, int y2);\nbool isEqual(float a, float b);\nvoid draw_pose(cv::Mat& image, std::vector<std::vector<PosePoint>> points);\n"
  },
  {
    "path": "projects/rtmpose/examples/onnxruntime/README.md",
    "content": "# RTMPose inference with ONNXRuntime\n\nThis example shows how to run RTMPose inference with ONNXRuntime in Python.\n\n## Prerequisites\n\n### 1. Install onnxruntime inference engine.\n\nChoose one of the following ways to install onnxruntime.\n\n- CPU version\n\n```bash\nwget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-1.8.1.tgz\ntar -zxvf onnxruntime-linux-x64-1.8.1.tgz\nexport ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-1.8.1\nexport LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH\n```\n\n- GPU version\n\n```bash\npip install onnxruntime-gpu==1.8.1\nwget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-gpu-1.8.1.tgz\ntar -zxvf onnxruntime-linux-x64-gpu-1.8.1.tgz\nexport ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-gpu-1.8.1\nexport LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH\n```\n\n### 2. Convert model to onnx files\n\n- Install `mim` tool.\n\n```bash\npip install -U openmim\n```\n\n- Download `mmpose` model.\n\n```bash\n# choose one rtmpose model\nmim download mmpose --config rtmpose-m_8xb64-270e_coco-wholebody-256x192 --dest .\n```\n\n- Clone `mmdeploy` repo.\n\n```bash\ngit clone https://github.com/open-mmlab/mmdeploy.git\n```\n\n- Convert model to onnx files.\n\n```bash\npython mmdeploy/tools/deploy.py \\\n    mmdeploy/configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    mmpose/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py \\\n    mmpose/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.pth \\\n    mmdeploy/demo/resources/human-pose.jpg \\\n    --work-dir mmdeploy_model/mmpose/ort \\\n    --device cuda \\\n    --dump-info\n```\n\n## Run demo\n\n### Install dependencies\n\n```bash\npip install -r requirements.txt\n```\n\n### Usage:\n\n```bash\npython main.py \\\n    {ONNX_FILE} \\\n    {IMAGE_FILE} \\\n    --device {DEVICE} \\\n    --save-path {SAVE_PATH}\n```\n\n### Description of all arguments\n\n- `ONNX_FILE`: The path of onnx file\n- `IMAGE_FILE`: The path of image file\n- `DEVICE`: The device to run the model, default is `cpu`\n- `SAVE_PATH`: The path to save the output image, default is `output.jpg`\n"
  },
  {
    "path": "projects/rtmpose/examples/onnxruntime/README_CN.md",
    "content": "# 使用ONNXRuntime进行RTMPose推理\n\n本示例展示了如何在Python中用ONNXRuntime推理RTMPose模型。\n\n## 准备\n\n### 1. 安装onnxruntime推理引擎.\n\n选择以下方式之一来安装onnxruntime。\n\n- CPU版本\n\n```bash\nwget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-1.8.1.tgz\ntar -zxvf onnxruntime-linux-x64-1.8.1.tgz\nexport ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-1.8.1\nexport LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH\n```\n\n- GPU版本\n\n```bash\npip install onnxruntime-gpu==1.8.1\nwget https://github.com/microsoft/onnxruntime/releases/download/v1.8.1/onnxruntime-linux-x64-gpu-1.8.1.tgz\ntar -zxvf onnxruntime-linux-x64-gpu-1.8.1.tgz\nexport ONNXRUNTIME_DIR=$(pwd)/onnxruntime-linux-x64-gpu-1.8.1\nexport LD_LIBRARY_PATH=$ONNXRUNTIME_DIR/lib:$LD_LIBRARY_PATH\n```\n\n### 2. 将模型转换为onnx文件\n\n- 安装`mim`工具\n\n```bash\npip install -U openmim\n```\n\n- 下载`mmpose`模型\n\n```bash\n# choose one rtmpose model\nmim download mmpose --config rtmpose-m_8xb64-270e_coco-wholebody-256x192 --dest .\n```\n\n- 克隆`mmdeploy`仓库\n\n```bash\ngit clone https://github.com/open-mmlab/mmdeploy.git\n```\n\n- 将模型转换为onnx文件\n\n```bash\npython mmdeploy/tools/deploy.py \\\n    mmdeploy/configs/mmpose/pose-detection_simcc_onnxruntime_dynamic.py \\\n    mmpose/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py \\\n    mmpose/rtmpose-m_simcc-coco-wholebody_pt-aic-coco_270e-256x192-cd5e845c_20230123.pth \\\n    mmdeploy/demo/resources/human-pose.jpg \\\n    --work-dir mmdeploy_model/mmpose/ort \\\n    --device cuda \\\n    --dump-info\n```\n\n## 运行\n\n### 安装依赖\n\n```bash\npip install -r requirements.txt\n```\n\n### 用法：\n\n```bash\npython main.py \\\n    {ONNX_FILE} \\\n    {IMAGE_FILE} \\\n    --device {DEVICE} \\\n    --save-path {SAVE_PATH}\n```\n\n### 参数解释\n\n- `ONNX_FILE`: onnx文件的路径\n- `IMAGE_FILE`: 图像文件的路径\n- `DEVICE`: 运行模型的设备，默认为\\`cpu'\n- `SAVE_PATH`: 保存输出图像的路径，默认为 \"output.jpg\"\n"
  },
  {
    "path": "projects/rtmpose/examples/onnxruntime/main.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport time\nfrom typing import List, Tuple\n\nimport cv2\nimport loguru\nimport numpy as np\nimport onnxruntime as ort\n\nlogger = loguru.logger\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='RTMPose ONNX inference demo.')\n    parser.add_argument('onnx_file', help='ONNX file path')\n    parser.add_argument('image_file', help='Input image file path')\n    parser.add_argument(\n        '--device', help='device type for inference', default='cpu')\n    parser.add_argument(\n        '--save-path',\n        help='path to save the output image',\n        default='output.jpg')\n    args = parser.parse_args()\n    return args\n\n\ndef preprocess(\n    img: np.ndarray, input_size: Tuple[int, int] = (192, 256)\n) -> Tuple[np.ndarray, np.ndarray, np.ndarray]:\n    \"\"\"Do preprocessing for RTMPose model inference.\n\n    Args:\n        img (np.ndarray): Input image in shape.\n        input_size (tuple): Input image size in shape (w, h).\n\n    Returns:\n        tuple:\n        - resized_img (np.ndarray): Preprocessed image.\n        - center (np.ndarray): Center of image.\n        - scale (np.ndarray): Scale of image.\n    \"\"\"\n    # get shape of image\n    img_shape = img.shape[:2]\n    bbox = np.array([0, 0, img_shape[1], img_shape[0]])\n\n    # get center and scale\n    center, scale = bbox_xyxy2cs(bbox, padding=1.25)\n\n    # do affine transformation\n    resized_img, scale = top_down_affine(input_size, scale, center, img)\n\n    # normalize image\n    mean = np.array([123.675, 116.28, 103.53])\n    std = np.array([58.395, 57.12, 57.375])\n    resized_img = (resized_img - mean) / std\n\n    return resized_img, center, scale\n\n\ndef build_session(onnx_file: str, device: str = 'cpu') -> ort.InferenceSession:\n    \"\"\"Build onnxruntime session.\n\n    Args:\n        onnx_file (str): ONNX file path.\n        device (str): Device type for inference.\n\n    Returns:\n        sess (ort.InferenceSession): ONNXRuntime session.\n    \"\"\"\n    providers = ['CPUExecutionProvider'\n                 ] if device == 'cpu' else ['CUDAExecutionProvider']\n    sess = ort.InferenceSession(path_or_bytes=onnx_file, providers=providers)\n\n    return sess\n\n\ndef inference(sess: ort.InferenceSession, img: np.ndarray) -> np.ndarray:\n    \"\"\"Inference RTMPose model.\n\n    Args:\n        sess (ort.InferenceSession): ONNXRuntime session.\n        img (np.ndarray): Input image in shape.\n\n    Returns:\n        outputs (np.ndarray): Output of RTMPose model.\n    \"\"\"\n    # build input\n    input = [img.transpose(2, 0, 1)]\n\n    # build output\n    sess_input = {sess.get_inputs()[0].name: input}\n    sess_output = []\n    for out in sess.get_outputs():\n        sess_output.append(out.name)\n\n    # run model\n    outputs = sess.run(sess_output, sess_input)\n\n    return outputs\n\n\ndef postprocess(outputs: List[np.ndarray],\n                model_input_size: Tuple[int, int],\n                center: Tuple[int, int],\n                scale: Tuple[int, int],\n                simcc_split_ratio: float = 2.0\n                ) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Postprocess for RTMPose model output.\n\n    Args:\n        outputs (np.ndarray): Output of RTMPose model.\n        model_input_size (tuple): RTMPose model Input image size.\n        center (tuple): Center of bbox in shape (x, y).\n        scale (tuple): Scale of bbox in shape (w, h).\n        simcc_split_ratio (float): Split ratio of simcc.\n\n    Returns:\n        tuple:\n        - keypoints (np.ndarray): Rescaled keypoints.\n        - scores (np.ndarray): Model predict scores.\n    \"\"\"\n    # use simcc to decode\n    simcc_x, simcc_y = outputs\n    keypoints, scores = decode(simcc_x, simcc_y, simcc_split_ratio)\n\n    # rescale keypoints\n    keypoints = keypoints / model_input_size * scale + center - scale / 2\n\n    return keypoints, scores\n\n\ndef visualize(img: np.ndarray,\n              keypoints: np.ndarray,\n              scores: np.ndarray,\n              filename: str = 'output.jpg',\n              thr=0.3) -> np.ndarray:\n    \"\"\"Visualize the keypoints and skeleton on image.\n\n    Args:\n        img (np.ndarray): Input image in shape.\n        keypoints (np.ndarray): Keypoints in image.\n        scores (np.ndarray): Model predict scores.\n        thr (float): Threshold for visualize.\n\n    Returns:\n        img (np.ndarray): Visualized image.\n    \"\"\"\n    # default color\n    skeleton = [(15, 13), (13, 11), (16, 14), (14, 12), (11, 12), (5, 11),\n                (6, 12), (5, 6), (5, 7), (6, 8), (7, 9), (8, 10), (1, 2),\n                (0, 1), (0, 2), (1, 3), (2, 4), (3, 5), (4, 6), (15, 17),\n                (15, 18), (15, 19), (16, 20), (16, 21), (16, 22), (91, 92),\n                (92, 93), (93, 94), (94, 95), (91, 96), (96, 97), (97, 98),\n                (98, 99), (91, 100), (100, 101), (101, 102), (102, 103),\n                (91, 104), (104, 105), (105, 106), (106, 107), (91, 108),\n                (108, 109), (109, 110), (110, 111), (112, 113), (113, 114),\n                (114, 115), (115, 116), (112, 117), (117, 118), (118, 119),\n                (119, 120), (112, 121), (121, 122), (122, 123), (123, 124),\n                (112, 125), (125, 126), (126, 127), (127, 128), (112, 129),\n                (129, 130), (130, 131), (131, 132)]\n    palette = [[51, 153, 255], [0, 255, 0], [255, 128, 0], [255, 255, 255],\n               [255, 153, 255], [102, 178, 255], [255, 51, 51]]\n    link_color = [\n        1, 1, 2, 2, 0, 0, 0, 0, 1, 2, 1, 2, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 2, 2,\n        2, 2, 2, 2, 2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 1, 1, 1, 1, 2, 2, 2,\n        2, 4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 1, 1, 1, 1\n    ]\n    point_color = [\n        0, 0, 0, 0, 0, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 1, 2, 2, 2, 2, 2, 2, 2, 3,\n        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3,\n        3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 2, 2,\n        4, 4, 4, 4, 5, 5, 5, 5, 6, 6, 6, 6, 1, 1, 1, 1, 3, 2, 2, 2, 2, 4, 4, 4,\n        4, 5, 5, 5, 5, 6, 6, 6, 6, 1, 1, 1, 1\n    ]\n\n    # draw keypoints and skeleton\n    for kpts, score in zip(keypoints, scores):\n        keypoints_num = len(score)\n        for kpt, color in zip(kpts, point_color):\n            cv2.circle(img, tuple(kpt.astype(np.int32)), 1, palette[color], 1,\n                       cv2.LINE_AA)\n        for (u, v), color in zip(skeleton, link_color):\n            if u < keypoints_num and v < keypoints_num \\\n                        and score[u] > thr and score[v] > thr:\n                cv2.line(img, tuple(kpts[u].astype(np.int32)),\n                         tuple(kpts[v].astype(np.int32)), palette[color], 2,\n                         cv2.LINE_AA)\n\n    # save to local\n    cv2.imwrite(filename, img)\n\n    return img\n\n\ndef bbox_xyxy2cs(bbox: np.ndarray,\n                 padding: float = 1.) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Transform the bbox format from (x,y,w,h) into (center, scale)\n\n    Args:\n        bbox (ndarray): Bounding box(es) in shape (4,) or (n, 4), formatted\n            as (left, top, right, bottom)\n        padding (float): BBox padding factor that will be multilied to scale.\n            Default: 1.0\n\n    Returns:\n        tuple: A tuple containing center and scale.\n        - np.ndarray[float32]: Center (x, y) of the bbox in shape (2,) or\n            (n, 2)\n        - np.ndarray[float32]: Scale (w, h) of the bbox in shape (2,) or\n            (n, 2)\n    \"\"\"\n    # convert single bbox from (4, ) to (1, 4)\n    dim = bbox.ndim\n    if dim == 1:\n        bbox = bbox[None, :]\n\n    # get bbox center and scale\n    x1, y1, x2, y2 = np.hsplit(bbox, [1, 2, 3])\n    center = np.hstack([x1 + x2, y1 + y2]) * 0.5\n    scale = np.hstack([x2 - x1, y2 - y1]) * padding\n\n    if dim == 1:\n        center = center[0]\n        scale = scale[0]\n\n    return center, scale\n\n\ndef _fix_aspect_ratio(bbox_scale: np.ndarray,\n                      aspect_ratio: float) -> np.ndarray:\n    \"\"\"Extend the scale to match the given aspect ratio.\n\n    Args:\n        scale (np.ndarray): The image scale (w, h) in shape (2, )\n        aspect_ratio (float): The ratio of ``w/h``\n\n    Returns:\n        np.ndarray: The reshaped image scale in (2, )\n    \"\"\"\n    w, h = np.hsplit(bbox_scale, [1])\n    bbox_scale = np.where(w > h * aspect_ratio,\n                          np.hstack([w, w / aspect_ratio]),\n                          np.hstack([h * aspect_ratio, h]))\n    return bbox_scale\n\n\ndef _rotate_point(pt: np.ndarray, angle_rad: float) -> np.ndarray:\n    \"\"\"Rotate a point by an angle.\n\n    Args:\n        pt (np.ndarray): 2D point coordinates (x, y) in shape (2, )\n        angle_rad (float): rotation angle in radian\n\n    Returns:\n        np.ndarray: Rotated point in shape (2, )\n    \"\"\"\n    sn, cs = np.sin(angle_rad), np.cos(angle_rad)\n    rot_mat = np.array([[cs, -sn], [sn, cs]])\n    return rot_mat @ pt\n\n\ndef _get_3rd_point(a: np.ndarray, b: np.ndarray) -> np.ndarray:\n    \"\"\"To calculate the affine matrix, three pairs of points are required. This\n    function is used to get the 3rd point, given 2D points a & b.\n\n    The 3rd point is defined by rotating vector `a - b` by 90 degrees\n    anticlockwise, using b as the rotation center.\n\n    Args:\n        a (np.ndarray): The 1st point (x,y) in shape (2, )\n        b (np.ndarray): The 2nd point (x,y) in shape (2, )\n\n    Returns:\n        np.ndarray: The 3rd point.\n    \"\"\"\n    direction = a - b\n    c = b + np.r_[-direction[1], direction[0]]\n    return c\n\n\ndef get_warp_matrix(center: np.ndarray,\n                    scale: np.ndarray,\n                    rot: float,\n                    output_size: Tuple[int, int],\n                    shift: Tuple[float, float] = (0., 0.),\n                    inv: bool = False) -> np.ndarray:\n    \"\"\"Calculate the affine transformation matrix that can warp the bbox area\n    in the input image to the output size.\n\n    Args:\n        center (np.ndarray[2, ]): Center of the bounding box (x, y).\n        scale (np.ndarray[2, ]): Scale of the bounding box\n            wrt [width, height].\n        rot (float): Rotation angle (degree).\n        output_size (np.ndarray[2, ] | list(2,)): Size of the\n            destination heatmaps.\n        shift (0-100%): Shift translation ratio wrt the width/height.\n            Default (0., 0.).\n        inv (bool): Option to inverse the affine transform direction.\n            (inv=False: src->dst or inv=True: dst->src)\n\n    Returns:\n        np.ndarray: A 2x3 transformation matrix\n    \"\"\"\n    shift = np.array(shift)\n    src_w = scale[0]\n    dst_w = output_size[0]\n    dst_h = output_size[1]\n\n    # compute transformation matrix\n    rot_rad = np.deg2rad(rot)\n    src_dir = _rotate_point(np.array([0., src_w * -0.5]), rot_rad)\n    dst_dir = np.array([0., dst_w * -0.5])\n\n    # get four corners of the src rectangle in the original image\n    src = np.zeros((3, 2), dtype=np.float32)\n    src[0, :] = center + scale * shift\n    src[1, :] = center + src_dir + scale * shift\n    src[2, :] = _get_3rd_point(src[0, :], src[1, :])\n\n    # get four corners of the dst rectangle in the input image\n    dst = np.zeros((3, 2), dtype=np.float32)\n    dst[0, :] = [dst_w * 0.5, dst_h * 0.5]\n    dst[1, :] = np.array([dst_w * 0.5, dst_h * 0.5]) + dst_dir\n    dst[2, :] = _get_3rd_point(dst[0, :], dst[1, :])\n\n    if inv:\n        warp_mat = cv2.getAffineTransform(np.float32(dst), np.float32(src))\n    else:\n        warp_mat = cv2.getAffineTransform(np.float32(src), np.float32(dst))\n\n    return warp_mat\n\n\ndef top_down_affine(input_size: dict, bbox_scale: dict, bbox_center: dict,\n                    img: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Get the bbox image as the model input by affine transform.\n\n    Args:\n        input_size (dict): The input size of the model.\n        bbox_scale (dict): The bbox scale of the img.\n        bbox_center (dict): The bbox center of the img.\n        img (np.ndarray): The original image.\n\n    Returns:\n        tuple: A tuple containing center and scale.\n        - np.ndarray[float32]: img after affine transform.\n        - np.ndarray[float32]: bbox scale after affine transform.\n    \"\"\"\n    w, h = input_size\n    warp_size = (int(w), int(h))\n\n    # reshape bbox to fixed aspect ratio\n    bbox_scale = _fix_aspect_ratio(bbox_scale, aspect_ratio=w / h)\n\n    # get the affine matrix\n    center = bbox_center\n    scale = bbox_scale\n    rot = 0\n    warp_mat = get_warp_matrix(center, scale, rot, output_size=(w, h))\n\n    # do affine transform\n    img = cv2.warpAffine(img, warp_mat, warp_size, flags=cv2.INTER_LINEAR)\n\n    return img, bbox_scale\n\n\ndef get_simcc_maximum(simcc_x: np.ndarray,\n                      simcc_y: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Get maximum response location and value from simcc representations.\n\n    Note:\n        instance number: N\n        num_keypoints: K\n        heatmap height: H\n        heatmap width: W\n\n    Args:\n        simcc_x (np.ndarray): x-axis SimCC in shape (K, Wx) or (N, K, Wx)\n        simcc_y (np.ndarray): y-axis SimCC in shape (K, Wy) or (N, K, Wy)\n\n    Returns:\n        tuple:\n        - locs (np.ndarray): locations of maximum heatmap responses in shape\n            (K, 2) or (N, K, 2)\n        - vals (np.ndarray): values of maximum heatmap responses in shape\n            (K,) or (N, K)\n    \"\"\"\n    N, K, Wx = simcc_x.shape\n    simcc_x = simcc_x.reshape(N * K, -1)\n    simcc_y = simcc_y.reshape(N * K, -1)\n\n    # get maximum value locations\n    x_locs = np.argmax(simcc_x, axis=1)\n    y_locs = np.argmax(simcc_y, axis=1)\n    locs = np.stack((x_locs, y_locs), axis=-1).astype(np.float32)\n    max_val_x = np.amax(simcc_x, axis=1)\n    max_val_y = np.amax(simcc_y, axis=1)\n\n    # get maximum value across x and y axis\n    mask = max_val_x > max_val_y\n    max_val_x[mask] = max_val_y[mask]\n    vals = max_val_x\n    locs[vals <= 0.] = -1\n\n    # reshape\n    locs = locs.reshape(N, K, 2)\n    vals = vals.reshape(N, K)\n\n    return locs, vals\n\n\ndef decode(simcc_x: np.ndarray, simcc_y: np.ndarray,\n           simcc_split_ratio) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Modulate simcc distribution with Gaussian.\n\n    Args:\n        simcc_x (np.ndarray[K, Wx]): model predicted simcc in x.\n        simcc_y (np.ndarray[K, Wy]): model predicted simcc in y.\n        simcc_split_ratio (int): The split ratio of simcc.\n\n    Returns:\n        tuple: A tuple containing center and scale.\n        - np.ndarray[float32]: keypoints in shape (K, 2) or (n, K, 2)\n        - np.ndarray[float32]: scores in shape (K,) or (n, K)\n    \"\"\"\n    keypoints, scores = get_simcc_maximum(simcc_x, simcc_y)\n    keypoints /= simcc_split_ratio\n\n    return keypoints, scores\n\n\ndef main():\n    args = parse_args()\n    logger.info('Start running model on RTMPose...')\n\n    # read image from file\n    logger.info('1. Read image from {}...'.format(args.image_file))\n    img = cv2.imread(args.image_file)\n\n    # build onnx model\n    logger.info('2. Build onnx model from {}...'.format(args.onnx_file))\n    sess = build_session(args.onnx_file, args.device)\n    h, w = sess.get_inputs()[0].shape[2:]\n    model_input_size = (w, h)\n\n    # preprocessing\n    logger.info('3. Preprocess image...')\n    resized_img, center, scale = preprocess(img, model_input_size)\n\n    # inference\n    logger.info('4. Inference...')\n    start_time = time.time()\n    outputs = inference(sess, resized_img)\n    end_time = time.time()\n    logger.info('4. Inference done, time cost: {:.4f}s'.format(end_time -\n                                                               start_time))\n\n    # postprocessing\n    logger.info('5. Postprocess...')\n    keypoints, scores = postprocess(outputs, model_input_size, center, scale)\n\n    # visualize inference result\n    logger.info('6. Visualize inference result...')\n    visualize(img, keypoints, scores, args.save_path)\n\n    logger.info('Done...')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "projects/rtmpose/examples/onnxruntime/requirements.txt",
    "content": "loguru==0.6.0\nnumpy==1.21.6\nonnxruntime==1.14.1\nonnxruntime-gpu==1.8.1\n"
  },
  {
    "path": "projects/rtmpose/examples/rtmlib/README.md",
    "content": "# rtmlib\n\n![demo](https://github.com/Tau-J/rtmlib/assets/13503330/b7e8ce8b-3134-43cf-bba6-d81656897289)\n\nrtmlib is a super lightweight library to conduct pose estimation based on [RTMPose](https://github.com/open-mmlab/mmpose/tree/dev-1.x/projects/rtmpose) models **WITHOUT** any dependencies like mmcv, mmpose, mmdet, etc.\n\nBasically, rtmlib only requires these dependencies:\n\n- numpy\n- opencv-python\n- opencv-contrib-python\n- onnxruntime\n\nOptionally, you can use other common backends like opencv, onnxruntime, openvino, tensorrt to accelerate the inference process.\n\n- For openvino users, please add the path `<your python path>\\envs\\<your env name>\\Lib\\site-packages\\openvino\\libs` into your environment path.\n\n## Installation\n\n- install from pypi:\n\n```shell\npip install rtmlib -i https://pypi.org/simple\n```\n\n- install from source code:\n\n```shell\ngit clone https://github.com/Tau-J/rtmlib.git\ncd rtmlib\n\npip install -r requirements.txt\n\npip install -e .\n\n# [optional]\n# pip install onnxruntime-gpu\n# pip install openvino\n\n```\n\n## Quick Start\n\nRun `webui.py`:\n\n```shell\n# Please make sure you have installed gradio\n# pip install gradio\n\npython webui.py\n```\n\n![image](https://github.com/Tau-J/rtmlib/assets/13503330/49ef11a1-a1b5-4a20-a2e1-d49f8be6a25d)\n\nHere is also a simple demo to show how to use rtmlib to conduct pose estimation on a single image.\n\n```python\nimport cv2\n\nfrom rtmlib import Wholebody, draw_skeleton\n\ndevice = 'cpu'  # cpu, cuda\nbackend = 'onnxruntime'  # opencv, onnxruntime, openvino\nimg = cv2.imread('./demo.jpg')\n\nopenpose_skeleton = False  # True for openpose-style, False for mmpose-style\n\nwholebody = Wholebody(to_openpose=openpose_skeleton,\n                      mode='balanced',  # 'performance', 'lightweight', 'balanced'. Default: 'balanced'\n                      backend=backend, device=device)\n\nkeypoints, scores = wholebody(img)\n\n# visualize\n\n# if you want to use black background instead of original image,\n# img_show = np.zeros(img_show.shape, dtype=np.uint8)\n\nimg_show = draw_skeleton(img_show, keypoints, scores, kpt_thr=0.5)\n\n\ncv2.imshow('img', img_show)\ncv2.waitKey()\n```\n\n### Visualization\n\n|                                            MMPose-style                                             |                                            OpenPose-style                                             |\n| :-------------------------------------------------------------------------------------------------: | :---------------------------------------------------------------------------------------------------: |\n| <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/c9e6fbaa-00f0-4961-ac87-d881edca778b\"> | <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/9afc996a-59e6-4200-a655-59dae10b46c4\"> |\n| <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/b12e5f60-fec0-42a1-b7b6-365e93894fb1\"> | <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/5acf7431-6ef0-44a8-ae52-9d8c8cb988c9\"> |\n| <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/091b8ce3-32d5-463b-9f41-5c683afa7a11\"> | <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/4ffc7be1-50d6-44ff-8c6b-22ea8975aad4\"> |\n| <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/6fddfc14-7519-42eb-a7a4-98bf5441f324\"> | <img width=\"357\" alt=\"result\" src=\"https://github.com/Tau-J/rtmlib/assets/13503330/2523e568-e0c3-4c2e-8e54-d1a67100c537\"> |\n\n### Citation\n\n```\n@misc{rtmlib,\n  title={rtmlib},\n  author={Jiang, Tao},\n  year={2023},\n  howpublished = {\\url{https://github.com/Tau-J/rtmlib}},\n}\n\n@misc{jiang2023,\n  doi = {10.48550/ARXIV.2303.07399},\n  url = {https://arxiv.org/abs/2303.07399},\n  author = {Jiang, Tao and Lu, Peng and Zhang, Li and Ma, Ningsheng and Han, Rui and Lyu, Chengqi and Li, Yining and Chen, Kai},\n  keywords = {Computer Vision and Pattern Recognition (cs.CV), FOS: Computer and information sciences, FOS: Computer and information sciences},\n  title = {RTMPose: Real-Time Multi-Person Pose Estimation based on MMPose},\n  publisher = {arXiv},\n  year = {2023},\n  copyright = {Creative Commons Attribution 4.0 International}\n}\n\n@misc{lu2023rtmo,\n      title={{RTMO}: Towards High-Performance One-Stage Real-Time Multi-Person Pose Estimation},\n      author={Peng Lu and Tao Jiang and Yining Li and Xiangtai Li and Kai Chen and Wenming Yang},\n      year={2023},\n      eprint={2312.07526},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/README.md",
    "content": "# Welcome to RTMDet Project of MMPose\n\n**Highlight:** If you are deploy `projects/rtmpose/rtmdet` with [deploee](https://platform.openmmlab.com/deploee), please input [full http download link of train_config](https://raw.githubusercontent.com/open-mmlab/mmpose/main/projects/rtmpose/rtmdet/hand/rtmdet_nano_320-8xb32_hand.py) instead of relative path, deploee cannot parse mmdet config within mmpose repo.\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/hand/rtmdet_nano_320-8xb32_hand.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_l_8xb32-300e_coco.py'\n\ninput_shape = 320\n\nmodel = dict(\n    backbone=dict(\n        deepen_factor=0.33,\n        widen_factor=0.25,\n        use_depthwise=True,\n    ),\n    neck=dict(\n        in_channels=[64, 128, 256],\n        out_channels=64,\n        num_csp_blocks=1,\n        use_depthwise=True,\n    ),\n    bbox_head=dict(\n        in_channels=64,\n        feat_channels=64,\n        share_conv=False,\n        exp_on_reg=False,\n        use_depthwise=True,\n        num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\n# file_client_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({'data/': 's3://openmmlab/datasets/'}))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='CachedMosaic',\n        img_scale=(input_shape, input_shape),\n        pad_val=114.0,\n        max_cached_images=20,\n        random_pop=False),\n    dict(\n        type='RandomResize',\n        scale=(input_shape * 2, input_shape * 2),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='RandomResize',\n        scale=(input_shape, input_shape),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(input_shape, input_shape), keep_ratio=True),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ndata_mode = 'topdown'\ndata_root = 'data/'\n\ntrain_dataset = dict(\n    _delete_=True,\n    type='ConcatDataset',\n    datasets=[\n        dict(\n            type='mmpose.OneHand10KDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='onehand10k/annotations/onehand10k_train.json',\n            data_prefix=dict(img='pose/OneHand10K/')),\n        dict(\n            type='mmpose.FreiHandDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='freihand/annotations/freihand_train.json',\n            data_prefix=dict(img='pose/FreiHand/')),\n        dict(\n            type='mmpose.Rhd2DDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='rhd/annotations/rhd_train.json',\n            data_prefix=dict(img='pose/RHD/')),\n        dict(\n            type='mmpose.HalpeHandDataset',\n            data_root=data_root,\n            data_mode=data_mode,\n            pipeline=train_pipeline,\n            ann_file='halpe/annotations/halpe_train_v1.json',\n            data_prefix=dict(\n                img='pose/Halpe/hico_20160224_det/images/train2015/')  # noqa\n        )\n    ],\n    ignore_keys=[\n        'CLASSES', 'dataset_keypoint_weights', 'dataset_name', 'flip_indices',\n        'flip_pairs', 'keypoint_colors', 'keypoint_id2name',\n        'keypoint_name2id', 'lower_body_ids', 'num_keypoints',\n        'num_skeleton_links', 'sigmas', 'skeleton_link_colors',\n        'skeleton_links', 'upper_body_ids'\n    ],\n)\n\ntest_dataset = dict(\n    _delete_=True,\n    type='mmpose.OneHand10KDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    pipeline=test_pipeline,\n    ann_file='onehand10k/annotations/onehand10k_test.json',\n    data_prefix=dict(img='pose/OneHand10K/'),\n)\n\ntrain_dataloader = dict(dataset=train_dataset)\nval_dataloader = dict(dataset=test_dataset)\ntest_dataloader = val_dataloader\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='PipelineSwitchHook',\n        switch_epoch=280,\n        switch_pipeline=train_pipeline_stage2)\n]\n\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'onehand10k/annotations/onehand10k_test.json',\n    metric='bbox',\n    format_only=False)\ntest_evaluator = val_evaluator\n\ntrain_cfg = dict(val_interval=1)\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/humanart_detection.py",
    "content": "# dataset settings\ndataset_type = 'CocoDataset'\ndata_root = 'data/'\n\n# Example to use different file client\n# Method 1: simply set the data root and let the file I/O module\n# automatically infer from prefix (not support LMDB and Memcache yet)\n\n# data_root = 's3://openmmlab/datasets/detection/coco/'\n\n# Method 2: Use `backend_args`, `file_client_args` in versions before 3.0.0rc6\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         './data/': 's3://openmmlab/datasets/detection/',\n#         'data/': 's3://openmmlab/datasets/detection/'\n#     }))\nbackend_args = None\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile', backend_args=backend_args),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='Resize', scale=(1333, 800), keep_ratio=True),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='PackDetInputs')\n]\ntest_pipeline = [\n    dict(type='LoadImageFromFile', backend_args=backend_args),\n    dict(type='Resize', scale=(1333, 800), keep_ratio=True),\n    # If you don't have a gt annotation, delete the pipeline\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\ntrain_dataloader = dict(\n    batch_size=2,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    batch_sampler=dict(type='AspectRatioBatchSampler'),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        filter_cfg=dict(filter_empty_gt=True, min_size=32),\n        pipeline=train_pipeline,\n        backend_args=backend_args))\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='HumanArt/annotations/validation_humanart_coco.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=test_pipeline,\n        backend_args=backend_args))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart_coco.json',\n    metric='bbox',\n    format_only=False,\n    backend_args=backend_args)\ntest_evaluator = val_evaluator\n\n# inference on test dataset and\n# format the output results for submission.\n# test_dataloader = dict(\n#     batch_size=1,\n#     num_workers=2,\n#     persistent_workers=True,\n#     drop_last=False,\n#     sampler=dict(type='DefaultSampler', shuffle=False),\n#     dataset=dict(\n#         type=dataset_type,\n#         data_root=data_root,\n#         ann_file=data_root + 'annotations/image_info_test-dev2017.json',\n#         data_prefix=dict(img='test2017/'),\n#         test_mode=True,\n#         pipeline=test_pipeline))\n# test_evaluator = dict(\n#     type='CocoMetric',\n#     metric='bbox',\n#     format_only=True,\n#     ann_file=data_root + 'annotations/image_info_test-dev2017.json',\n#     outfile_prefix='./work_dirs/coco_detection/test')\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_l_8xb32-300e_humanart.py",
    "content": "_base_ = [\n    'mmdet::_base_/default_runtime.py',\n    'mmdet::_base_/schedules/schedule_1x.py', './humanart_detection.py',\n    'mmdet::rtmdet_tta.py'\n]\nmodel = dict(\n    type='RTMDet',\n    data_preprocessor=dict(\n        type='DetDataPreprocessor',\n        mean=[103.53, 116.28, 123.675],\n        std=[57.375, 57.12, 58.395],\n        bgr_to_rgb=False,\n        batch_augments=None),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1,\n        widen_factor=1,\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[256, 512, 1024],\n        out_channels=256,\n        num_csp_blocks=3,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    bbox_head=dict(\n        type='RTMDetSepBNHead',\n        num_classes=80,\n        in_channels=256,\n        stacked_convs=2,\n        feat_channels=256,\n        anchor_generator=dict(\n            type='MlvlPointGenerator', offset=0, strides=[8, 16, 32]),\n        bbox_coder=dict(type='DistancePointBBoxCoder'),\n        loss_cls=dict(\n            type='QualityFocalLoss',\n            use_sigmoid=True,\n            beta=2.0,\n            loss_weight=1.0),\n        loss_bbox=dict(type='GIoULoss', loss_weight=2.0),\n        with_objectness=False,\n        exp_on_reg=True,\n        share_conv=True,\n        pred_kernel_size=1,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    train_cfg=dict(\n        assigner=dict(type='DynamicSoftLabelAssigner', topk=13),\n        allowed_border=-1,\n        pos_weight=-1,\n        debug=False),\n    test_cfg=dict(\n        nms_pre=30000,\n        min_bbox_size=0,\n        score_thr=0.001,\n        nms=dict(type='nms', iou_threshold=0.65),\n        max_per_img=300),\n)\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='CachedMosaic', img_scale=(640, 640), pad_val=114.0),\n    dict(\n        type='RandomResize',\n        scale=(1280, 1280),\n        ratio_range=(0.1, 2.0),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(640, 640)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='Pad', size=(640, 640), pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='CachedMixUp',\n        img_scale=(640, 640),\n        ratio_range=(1.0, 1.0),\n        max_cached_images=20,\n        pad_val=(114, 114, 114)),\n    dict(type='PackDetInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='RandomResize',\n        scale=(640, 640),\n        ratio_range=(0.1, 2.0),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(640, 640)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='Pad', size=(640, 640), pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='Resize', scale=(640, 640), keep_ratio=True),\n    dict(type='Pad', size=(640, 640), pad_val=dict(img=(114, 114, 114))),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    batch_sampler=None,\n    pin_memory=True,\n    dataset=dict(pipeline=train_pipeline))\nval_dataloader = dict(\n    batch_size=5, num_workers=10, dataset=dict(pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n\nmax_epochs = 300\nstage2_num_epochs = 20\nbase_lr = 0.0005\ninterval = 10\n\ntrain_cfg = dict(\n    max_epochs=max_epochs,\n    val_interval=interval,\n    dynamic_intervals=[(max_epochs - stage2_num_epochs, 1)])\n\nval_evaluator = dict(proposal_nums=(100, 1, 10))\ntest_evaluator = val_evaluator\n\n# optimizer\noptim_wrapper = dict(\n    _delete_=True,\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        interval=interval,\n        max_keep_ckpts=3  # only keep latest 3 checkpoints\n    ))\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_m_640-8xb32_coco-person.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_m_8xb32-300e_coco.py'\n\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth'  # noqa\n\nmodel = dict(\n    backbone=dict(\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=checkpoint)),\n    bbox_head=dict(num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\ntrain_dataloader = dict(dataset=dict(metainfo=dict(classes=('person', ))))\n\nval_dataloader = dict(dataset=dict(metainfo=dict(classes=('person', ))))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_m_8xb32-300e_humanart.py",
    "content": "_base_ = './rtmdet_l_8xb32-300e_humanart.py'\n\nmodel = dict(\n    backbone=dict(deepen_factor=0.67, widen_factor=0.75),\n    neck=dict(in_channels=[192, 384, 768], out_channels=192, num_csp_blocks=2),\n    bbox_head=dict(in_channels=192, feat_channels=192))\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_nano_320-8xb32_coco-person.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_l_8xb32-300e_coco.py'\n\ninput_shape = 320\n\nmodel = dict(\n    backbone=dict(\n        deepen_factor=0.33,\n        widen_factor=0.25,\n        use_depthwise=True,\n    ),\n    neck=dict(\n        in_channels=[64, 128, 256],\n        out_channels=64,\n        num_csp_blocks=1,\n        use_depthwise=True,\n    ),\n    bbox_head=dict(\n        in_channels=64,\n        feat_channels=64,\n        share_conv=False,\n        exp_on_reg=False,\n        use_depthwise=True,\n        num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='CachedMosaic',\n        img_scale=(input_shape, input_shape),\n        pad_val=114.0,\n        max_cached_images=20,\n        random_pop=False),\n    dict(\n        type='RandomResize',\n        scale=(input_shape * 2, input_shape * 2),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImageFromFile'),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='RandomResize',\n        scale=(input_shape, input_shape),\n        ratio_range=(0.5, 1.5),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(input_shape, input_shape)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile'),\n    dict(type='Resize', scale=(input_shape, input_shape), keep_ratio=True),\n    dict(\n        type='Pad',\n        size=(input_shape, input_shape),\n        pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ntrain_dataloader = dict(\n    dataset=dict(pipeline=train_pipeline, metainfo=dict(classes=('person', ))))\n\nval_dataloader = dict(\n    dataset=dict(pipeline=test_pipeline, metainfo=dict(classes=('person', ))))\ntest_dataloader = val_dataloader\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='PipelineSwitchHook',\n        switch_epoch=280,\n        switch_pipeline=train_pipeline_stage2)\n]\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_s_8xb32-300e_humanart.py",
    "content": "_base_ = './rtmdet_l_8xb32-300e_humanart.py'\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-s_imagenet_600e.pth'  # noqa\nmodel = dict(\n    backbone=dict(\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=checkpoint)),\n    neck=dict(in_channels=[128, 256, 512], out_channels=128, num_csp_blocks=1),\n    bbox_head=dict(in_channels=128, feat_channels=128, exp_on_reg=False))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(type='CachedMosaic', img_scale=(640, 640), pad_val=114.0),\n    dict(\n        type='RandomResize',\n        scale=(1280, 1280),\n        ratio_range=(0.5, 2.0),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(640, 640)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='Pad', size=(640, 640), pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='CachedMixUp',\n        img_scale=(640, 640),\n        ratio_range=(1.0, 1.0),\n        max_cached_images=20,\n        pad_val=(114, 114, 114)),\n    dict(type='PackDetInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='RandomResize',\n        scale=(640, 640),\n        ratio_range=(0.5, 2.0),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(640, 640)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='Pad', size=(640, 640), pad_val=dict(img=(114, 114, 114))),\n    dict(type='PackDetInputs')\n]\n\ntrain_dataloader = dict(dataset=dict(pipeline=train_pipeline))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='PipelineSwitchHook',\n        switch_epoch=280,\n        switch_pipeline=train_pipeline_stage2)\n]\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_tiny_8xb32-300e_humanart.py",
    "content": "_base_ = './rtmdet_s_8xb32-300e_humanart.py'\n\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-tiny_imagenet_600e.pth'  # noqa\n\nmodel = dict(\n    backbone=dict(\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=checkpoint)),\n    neck=dict(in_channels=[96, 192, 384], out_channels=96, num_csp_blocks=1),\n    bbox_head=dict(in_channels=96, feat_channels=96, exp_on_reg=False))\n\ntrain_pipeline = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='CachedMosaic',\n        img_scale=(640, 640),\n        pad_val=114.0,\n        max_cached_images=20,\n        random_pop=False),\n    dict(\n        type='RandomResize',\n        scale=(1280, 1280),\n        ratio_range=(0.5, 2.0),\n        keep_ratio=True),\n    dict(type='RandomCrop', crop_size=(640, 640)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    dict(type='Pad', size=(640, 640), pad_val=dict(img=(114, 114, 114))),\n    dict(\n        type='CachedMixUp',\n        img_scale=(640, 640),\n        ratio_range=(1.0, 1.0),\n        max_cached_images=10,\n        random_pop=False,\n        pad_val=(114, 114, 114),\n        prob=0.5),\n    dict(type='PackDetInputs')\n]\n\ntrain_dataloader = dict(dataset=dict(pipeline=train_pipeline))\n"
  },
  {
    "path": "projects/rtmpose/rtmdet/person/rtmdet_x_8xb32-300e_humanart.py",
    "content": "_base_ = './rtmdet_l_8xb32-300e_humanart.py'\n\nmodel = dict(\n    backbone=dict(deepen_factor=1.33, widen_factor=1.25),\n    neck=dict(\n        in_channels=[320, 640, 1280], out_channels=320, num_csp_blocks=4),\n    bbox_head=dict(in_channels=320, feat_channels=320))\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/animal_2d_keypoint/rtmpose-m_8xb64-210e_ap10k-256x256.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (256, 256)\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'AP10KDataset'\ndata_mode = 'topdown'\ndata_root = 'data/ap10k/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-train-split1.json',\n        data_prefix=dict(img='data/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-val-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/ap10k-test-split1.json',\n        data_prefix=dict(img='data/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-val-split1.json')\ntest_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/ap10k-test-split1.json')\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-l_8xb256-420e_coco-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-l_8xb512-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-256x192-4dba18fc_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=5,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=5,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-l_8xb512-700e_body8-halpe26-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-body7_pt-body7_420e-384x288-3f5a1437_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb256-420e_coco-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb512-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-256x192-e48f03d0_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-m_8xb512-700e_body8-halpe26-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 512\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-body7_pt-body7_420e-384x288-65e718c4_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\n# backend_args = dict(backend='local')\nbackend_args = dict(\n    backend='petrel',\n    path_mapping=dict({\n        f'{data_root}': 's3://openmmlab/datasets/',\n        f'{data_root}': 's3://openmmlab/datasets/'\n    }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\n# default_hooks = dict(\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-s_8xb1024-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 1024\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.0),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-s_simcc-body7_pt-body7_420e-256x192-acd4a1ef_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.6, 1.4],\n        rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-s_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-t_8xb1024-700e_body8-halpe26-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 1024\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-body7_210e-256x192-a3775292_20230504.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.6, 1.4],\n        rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-t_8xb256-420e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 420\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file=f'{data_root}person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # Turn off EMA while training the tiny model\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-x_8xb256-700e_body8-halpe26-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 26\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 20\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\ncoco_halpe26 = [(i, i) for i in range(17)] + [(17, 20), (18, 22), (19, 24),\n                                              (20, 21), (21, 23), (22, 25)]\n\naic_halpe26 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7),\n               (5, 9), (6, 12), (7, 14), (8, 16), (9, 11), (10, 13), (11, 15),\n               (12, 17), (13, 18)]\n\ncrowdpose_halpe26 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16), (12, 17),\n                     (13, 18)]\n\nmpii_halpe26 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (8, 18),\n    (9, 17),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_halpe26 = [\n    (0, 18),\n    (2, 17),\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_halpe26 = [(i, i) for i in range(26)]\n\nochuman_halpe26 = [(i, i) for i in range(17)]\n\nposetrack_halpe26 = [\n    (0, 0),\n    (2, 17),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    pin_memory=True,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            dataset_coco,\n            dataset_aic,\n            dataset_crowdpose,\n            dataset_mpii,\n            dataset_jhmdb,\n            dataset_halpe,\n            dataset_posetrack,\n        ],\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\n# val datasets\nval_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_val_v1.0.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=coco_halpe26)\n    ],\n)\n\nval_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_val.json',\n    data_prefix=dict(\n        img='pose/ai_challenge/ai_challenger_keypoint'\n        '_validation_20170911/keypoint_validation_images_20170911/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_halpe26)\n    ],\n)\n\nval_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_test.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_halpe26)\n    ],\n)\n\nval_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_val.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_halpe26)\n    ],\n)\n\nval_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_test.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_halpe26)\n    ],\n)\n\nval_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_val_v1.json',\n    data_prefix=dict(img='detection/coco/val2017/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_halpe26)\n    ],\n)\n\nval_ochuman = dict(\n    type='OCHumanDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='ochuman/annotations/'\n    'ochuman_coco_format_val_range_0.00_1.00.json',\n    data_prefix=dict(img='pose/OCHuman/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=ochuman_halpe26)\n    ],\n)\n\nval_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_val.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_halpe26)\n    ],\n)\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/halpe26.py'),\n        datasets=[\n            val_coco,\n            val_aic,\n            val_crowdpose,\n            val_mpii,\n            val_jhmdb,\n            val_halpe,\n            val_ochuman,\n            val_posetrack,\n        ],\n        pipeline=val_pipeline,\n        test_mode=True,\n    ))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\ntest_evaluator = [dict(type='PCKAccuracy', thr=0.1), dict(type='AUC')]\nval_evaluator = test_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/body_2d_keypoint/rtmpose-x_8xb256-700e_coco-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 17\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 700\nstage2_num_epochs = 20\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 64\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file=f'{data_root}person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/face_2d_keypoint/rtmpose-m_8xb256-120e_lapa-256x256.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 106\ninput_size = (256, 256)\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.005,\n        begin=30,\n        end=max_epochs,\n        T_max=max_epochs - 30,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_trainval.json',\n        data_prefix=dict(img='LaPa/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img='LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img='LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=3, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/face_2d_keypoint/rtmpose-s_8xb256-120e_lapa-256x256.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 106\ninput_size = (256, 256)\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.005,\n        begin=30,\n        end=max_epochs,\n        T_max=max_epochs - 30,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/cspnext-s_imagenet_600e-ea671761.pth')\n    ),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_trainval.json',\n        data_prefix=dict(img='LaPa/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img='LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img='LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=3, interval=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/face_2d_keypoint/rtmpose-t_8xb256-120e_lapa-256x256.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 106\ninput_size = (256, 256)\n\n# runtime\nmax_epochs = 120\nstage2_num_epochs = 10\nbase_lr = 4e-3\ntrain_batch_size = 256\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=1)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.005,\n        begin=30,\n        end=max_epochs,\n        T_max=max_epochs - 30,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/cspnext-tiny_imagenet_600e-3a2dd350.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'LapaDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.2),\n            dict(type='MedianBlur', p=0.2),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_trainval.json',\n        data_prefix=dict(img='LaPa/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img='LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/lapa_test.json',\n        data_prefix=dict(img='LaPa/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='NME', rule='less', max_keep_ckpts=3, interval=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/hand_2d_keypoint/rtmpose-m_8xb32-210e_coco-wholebody-hand-256x256.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 21\ninput_size = (256, 256)\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 32\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(5.66, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyHandDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5],\n        rotate_factor=180),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    # dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=180),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='AUC', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = [\n    dict(type='PCKAccuracy', thr=0.2),\n    dict(type='AUC'),\n    dict(type='EPE')\n]\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pretrain_cspnext_udp/cspnext-l_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-l_8xb256-rsb-a1-600e_in1k-6a760974.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=1024,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pretrain_cspnext_udp/cspnext-m_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=768,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pretrain_cspnext_udp/cspnext-s_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-s_imagenet_600e-ea671761.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pretrain_cspnext_udp/cspnext-tiny_udp_8xb256-210e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# runtime\nmax_epochs = 210\nstage2_num_epochs = 30\nbase_lr = 4e-3\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 105 to 210 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# codec settings\ncodec = dict(\n    type='UDPHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmdetection/v3.0/'\n            'rtmdet/cspnext_rsb_pretrain/'\n            'cspnext-tiny_imagenet_600e-3a2dd350.pth')),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=384,\n        out_channels=17,\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=False,\n        flip_mode='heatmap',\n        shift_heatmap=False,\n    ))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/',\n#         f'{data_root}': 's3://openmmlab/datasets/detection/coco/'\n#     }))\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size'], use_udp=True),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=256,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        # bbox_file='data/coco/person_detection_results/'\n        # 'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    # dict(\n    #     type='EMAHook',\n    #     ema_type='ExpMomentumEMA',\n    #     momentum=0.0002,\n    #     update_buffers=True,\n    #     priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/README.md",
    "content": "# GroupFisher Pruning for RTMPose\n\n# Description\n\nWe try to apply a pruning algorithm to RTMPose models. In detail, we prune a RTMPose model to a smaller size as the same as a smaller RTMPose model, like pruning RTMPose-S to the size of RTMPose-T.\nThe expriments show that the pruned model have better performance(AP) than the RTMPose model with the similar size and inference speed.\n\nConcretly, we select the RTMPose-S as the base model and prune it to the size of RTMPose-T, and use GroupFisher pruning algorithm which is able to determine the pruning structure automatically.\nFurthermore, we provide two version of the pruned models including only using coco and using both of coco and ai-challenge datasets.\n\n# Results and Models\n\n| Arch                                                                  | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> | Flops | Params |                   ckpt                    |      log       |\n| :-------------------------------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :---: | :----: | :---------------------------------------: | :------------: |\n| [rtmpose-s-pruned](./group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   | 0.691 |      0.885      |      0.765      | 0.745 |      0.925      | 0.34  |  3.42  | [pruned][rp_sc_p] \\| [finetuned][rp_sc_f] | [log][rp_sc_l] |\n| [rtmpose-s-aic-coco-pruned](./group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.py) |  256x192   | 0.694 |      0.884      |      0.771      | 0.747 |      0.922      | 0.35  |  3.43  | [pruned][rp_sa_p] \\| [finetuned][rp_sa_f] | [log][rp_sa_l] |\n\n## Get Started\n\nWe have three steps to apply GroupFisher to your model, including Prune, Finetune, Deploy.\n\nNote: please use torch>=1.12, as we need fxtracer to parse the models automatically.\n\n### Prune\n\n```bash\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 PORT=29500 ./tools/dist_train.sh \\\n  {config_folder}/group_fisher_{normalization_type}_prune_{model_name}.py 8 \\\n  --work-dir $WORK_DIR\n```\n\nIn the pruning config file. You have to fill some args as below.\n\n```python\n\"\"\"\n_base_ (str): The path to your pretrained model checkpoint.\npretrained_path (str): The path to your pretrained model checkpoint.\n\ninterval (int): Interval between pruning two channels. You should ensure you\n    can reach your target pruning ratio when the training ends.\nnormalization_type (str): GroupFisher uses two methods to normlized the channel\n    importance, including ['flops','act']. The former uses flops, while the\n    latter uses the memory occupation of activation feature maps.\nlr_ratio (float): Ratio to decrease lr rate. As pruning progress is unstable,\n    you need to decrease the original lr rate until the pruning training work\n    steadly without getting nan.\n\ntarget_flop_ratio (float): The target flop ratio to prune your model.\ninput_shape (Tuple): input shape to measure the flops.\n\"\"\"\n```\n\nAfter the pruning process, you will get a checkpoint of the pruned model named flops\\_{target_flop_ratio}.pth in your workdir.\n\n### Finetune\n\n```bash\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 PORT=29500 ./tools/dist_train.sh \\\n   {config_folder}/group_fisher_{normalization_type}_finetune_{model_name}.py 8 \\\n  --work-dir $WORK_DIR\n```\n\nThere are also some args for you to fill in the config file as below.\n\n```python\n\"\"\"\n_base_(str): The path to your pruning config file.\npruned_path (str): The path to the checkpoint of the pruned model.\nfinetune_lr (float): The lr rate to finetune. Usually, we directly use the lr\n    rate of the pretrain.\n\"\"\"\n```\n\nAfter finetuning, except a checkpoint of the best model, there is also a fix_subnet.json, which records the pruned model structure. It will be used when deploying.\n\n### Test\n\n```bash\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 PORT=29500 ./tools/dist_test.sh \\\n   {config_folder}/group_fisher_{normalization_type}_finetune_{model_name}.py {checkpoint_path} 8\n```\n\n### Deploy\n\nFor a pruned model, you only need to use the pruning deploy config to instead the pretrain config to deploy the pruned version of your model. If you are not familiar with mmdeploy, it's recommended to refer to [MMDeploy document](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/convert_model.html).\n\n```bash\npython {mmdeploy}/tools/deploy.py \\\n    {mmdeploy}/{mmdeploy_config}.py \\\n    {config_folder}/group_fisher_{normalization_type}_deploy_{model_name}.py \\\n    {path_to_finetuned_checkpoint}.pth \\\n    {mmdeploy}/tests/data/tiger.jpeg\n```\n\nThe deploy config has some args as below:\n\n```python\n\"\"\"\n_base_ (str): The path to your pretrain config file.\nfix_subnet (Union[dict,str]): The dict store the pruning structure or the\n    json file including it.\ndivisor (int): The divisor the make the channel number divisible.\n\"\"\"\n```\n\nThe divisor is important for the actual inference speed, and we suggest you to test it in \\[1,2,4,8,16,32\\] to find the fastest divisor.\n\n## Reference\n\n[GroupFisher in MMRazor](https://github.com/open-mmlab/mmrazor/tree/main/configs/pruning/base/group_fisher)\n\n[rp_sa_f]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth\n[rp_sa_l]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.json\n[rp_sa_p]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_prune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth\n[rp_sc_f]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.pth\n[rp_sc_l]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.json\n[rp_sc_p]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_prune_rtmpose-s_8xb256-420e_coco-256x192.pth\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/README_CN.md",
    "content": "# 使用GroupFisher剪枝RTMPose\n\n# 概述\n\n我们尝试使用 GroupFisher 算法对 RTMPose 模型进行剪枝。具体来说，我们将一个 RTMPose 模型剪枝到与较小的 RTMPose 模型相同的大小，例如将 RTMPose-S 剪枝到 RTMPose-T 的大小。\n实验表明，剪枝后的模型比具有相似大小和推理速度的 RTMPose 模型具有更好的性能（AP）。\n\n我们使用能自动确定剪枝结构的 GroupFisher 剪枝算法，将 RTMPose-S 剪枝到 RTMPose-T 的大小。\n此外，我们提供了两个版本的剪枝模型，其中一个只使用 coco 数据集，另一个同时使用 coco 和 ai-challenge 数据集。\n\n# 实验结果\n\n| Arch                                                                  | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> | Flops | Params |                   ckpt                    |      log       |\n| :-------------------------------------------------------------------- | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :---: | :----: | :---------------------------------------: | :------------: |\n| [rtmpose-s-pruned](./group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.py) |  256x192   | 0.691 |      0.885      |      0.765      | 0.745 |      0.925      | 0.34  |  3.42  | [pruned][rp_sc_p] \\| [finetuned][rp_sc_f] | [log][rp_sc_l] |\n| [rtmpose-s-aic-coco-pruned](./group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.py) |  256x192   | 0.694 |      0.884      |      0.771      | 0.747 |      0.922      | 0.35  |  3.43  | [pruned][rp_sa_p] \\| [finetuned][rp_sa_f] | [log][rp_sa_l] |\n\n## Get Started\n\n我们需要三个步骤来将 GroupFisher 应用于你的模型，包括剪枝（Prune），微调（Finetune），部署（Deploy）。\n注意：请使用torch>=1.12，因为我们需要fxtracer来自动解析模型。\n\n### Prune\n\n```bash\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 PORT=29500 ./tools/dist_train.sh \\\n  {config_folder}/group_fisher_{normalization_type}_prune_{model_name}.py 8 \\\n  --work-dir $WORK_DIR\n```\n\n在剪枝配置文件中，你需要填写以下参数。\n\n```python\n\"\"\"\n_base_ (str): The path to your pretrained model checkpoint.\npretrained_path (str): The path to your pretrained model checkpoint.\n\ninterval (int): Interval between pruning two channels. You should ensure you\n    can reach your target pruning ratio when the training ends.\nnormalization_type (str): GroupFisher uses two methods to normlized the channel\n    importance, including ['flops','act']. The former uses flops, while the\n    latter uses the memory occupation of activation feature maps.\nlr_ratio (float): Ratio to decrease lr rate. As pruning progress is unstable,\n    you need to decrease the original lr rate until the pruning training work\n    steadly without getting nan.\n\ntarget_flop_ratio (float): The target flop ratio to prune your model.\ninput_shape (Tuple): input shape to measure the flops.\n\"\"\"\n```\n\n在剪枝结束后，你将获得一个剪枝模型的 checkpoint，该 checkpoint 的名称为 flops\\_{target_flop_ratio}.pth，位于你的 workdir 中。\n\n### Finetune\n\n```bash\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 PORT=29500 ./tools/dist_train.sh \\\n   {config_folder}/group_fisher_{normalization_type}_finetune_{model_name}.py 8 \\\n  --work-dir $WORK_DIR\n```\n\n微调时也有一些参数需要你填写。\n\n```python\n\"\"\"\n_base_(str): The path to your pruning config file.\npruned_path (str): The path to the checkpoint of the pruned model.\nfinetune_lr (float): The lr rate to finetune. Usually, we directly use the lr\n    rate of the pretrain.\n\"\"\"\n```\n\n在微调结束后，除了最佳模型的 checkpoint 外，还有一个 fix_subnet.json，它记录了剪枝模型的结构。它将在部署时使用。\n\n### Test\n\n```bash\nCUDA_VISIBLE_DEVICES=0,1,2,3,4,5,6,7 PORT=29500 ./tools/dist_test.sh \\\n   {config_folder}/group_fisher_{normalization_type}_finetune_{model_name}.py {checkpoint_path} 8\n```\n\n### Deploy\n\n对于剪枝模型，你只需要使用剪枝部署 config 来代替预训练 config 来部署模型的剪枝版本。如果你不熟悉 MMDeploy，请参看[MMDeploy document](https://mmdeploy.readthedocs.io/en/latest/02-how-to-run/convert_model.html)。\n\n```bash\npython {mmdeploy}/tools/deploy.py \\\n    {mmdeploy}/{mmdeploy_config}.py \\\n    {config_folder}/group_fisher_{normalization_type}_deploy_{model_name}.py \\\n    {path_to_finetuned_checkpoint}.pth \\\n    {mmdeploy}/tests/data/tiger.jpeg\n```\n\n部署配置文件有如下参数：\n\n```python\n\"\"\"\n_base_ (str): The path to your pretrain config file.\nfix_subnet (Union[dict,str]): The dict store the pruning structure or the\n    json file including it.\ndivisor (int): The divisor the make the channel number divisible.\n\"\"\"\n```\n\ndivisor 设置十分重要，我们建议你在尝试 \\[1,2,4,8,16,32\\]，以找到最佳设置。\n\n## Reference\n\n[GroupFisher in MMRazor](https://github.com/open-mmlab/mmrazor/tree/main/configs/pruning/base/group_fisher)\n\n[rp_sa_f]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth\n[rp_sa_l]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.json\n[rp_sa_p]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_prune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth\n[rp_sc_f]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.pth\n[rp_sc_l]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.json\n[rp_sc_p]: https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_prune_rtmpose-s_8xb256-420e_coco-256x192.pth\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/group_fisher_deploy_rtmpose-s_8xb256-420e_aic-coco-256x192.py",
    "content": "#############################################################################\n\"\"\"You have to fill these args.\n\n_base_(str): The path to your pretrain config file.\nfix_subnet (Union[dict,str]): The dict store the pruning structure or the\n    json file including it.\ndivisor (int): The divisor the make the channel number divisible.\n\"\"\"\n\n_base_ = 'mmpose::body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_aic-coco-256x192.py'  # noqa\nfix_subnet = {\n    'backbone.stem.0.conv_(0, 16)_16': 8,\n    'backbone.stem.1.conv_(0, 16)_16': 9,\n    'backbone.stem.2.conv_(0, 32)_32': 9,\n    'backbone.stage1.0.conv_(0, 64)_64': 32,\n    'backbone.stage1.1.short_conv.conv_(0, 32)_32': 30,\n    'backbone.stage1.1.main_conv.conv_(0, 32)_32': 29,\n    'backbone.stage1.1.blocks.0.conv1.conv_(0, 32)_32': 24,\n    'backbone.stage1.1.final_conv.conv_(0, 64)_64': 27,\n    'backbone.stage2.0.conv_(0, 128)_128': 62,\n    'backbone.stage2.1.short_conv.conv_(0, 64)_64': 63,\n    'backbone.stage2.1.main_conv.conv_(0, 64)_64': 64,\n    'backbone.stage2.1.blocks.0.conv1.conv_(0, 64)_64': 56,\n    'backbone.stage2.1.blocks.1.conv1.conv_(0, 64)_64': 62,\n    'backbone.stage2.1.final_conv.conv_(0, 128)_128': 65,\n    'backbone.stage3.0.conv_(0, 256)_256': 167,\n    'backbone.stage3.1.short_conv.conv_(0, 128)_128': 127,\n    'backbone.stage3.1.main_conv.conv_(0, 128)_128': 128,\n    'backbone.stage3.1.blocks.0.conv1.conv_(0, 128)_128': 124,\n    'backbone.stage3.1.blocks.1.conv1.conv_(0, 128)_128': 123,\n    'backbone.stage3.1.final_conv.conv_(0, 256)_256': 172,\n    'backbone.stage4.0.conv_(0, 512)_512': 337,\n    'backbone.stage4.1.conv1.conv_(0, 256)_256': 256,\n    'backbone.stage4.1.conv2.conv_(0, 512)_512': 379,\n    'backbone.stage4.2.short_conv.conv_(0, 256)_256': 188,\n    'backbone.stage4.2.main_conv.conv_(0, 256)_256': 227,\n    'backbone.stage4.2.blocks.0.conv1.conv_(0, 256)_256': 238,\n    'backbone.stage4.2.blocks.0.conv2.pointwise_conv.conv_(0, 256)_256': 195,\n    'backbone.stage4.2.final_conv.conv_(0, 512)_512': 163\n}\ndivisor = 8\n##############################################################################\n\narchitecture = _base_.model\n\nmodel = dict(\n    _delete_=True,\n    _scope_='mmrazor',\n    type='GroupFisherDeploySubModel',\n    architecture=architecture,\n    fix_subnet=fix_subnet,\n    divisor=divisor,\n)\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/group_fisher_deploy_rtmpose-s_8xb256-420e_coco-256x192.py",
    "content": "#############################################################################\n\"\"\"You have to fill these args.\n\n_base_(str): The path to your pretrain config file.\nfix_subnet (Union[dict,str]): The dict store the pruning structure or the\n    json file including it.\ndivisor (int): The divisor the make the channel number divisible.\n\"\"\"\n\n_base_ = 'mmpose::body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py'  # noqa\nfix_subnet = {\n    'backbone.stem.0.conv_(0, 16)_16': 8,\n    'backbone.stem.1.conv_(0, 16)_16': 10,\n    'backbone.stem.2.conv_(0, 32)_32': 11,\n    'backbone.stage1.0.conv_(0, 64)_64': 32,\n    'backbone.stage1.1.short_conv.conv_(0, 32)_32': 32,\n    'backbone.stage1.1.main_conv.conv_(0, 32)_32': 23,\n    'backbone.stage1.1.blocks.0.conv1.conv_(0, 32)_32': 25,\n    'backbone.stage1.1.final_conv.conv_(0, 64)_64': 25,\n    'backbone.stage2.0.conv_(0, 128)_128': 71,\n    'backbone.stage2.1.short_conv.conv_(0, 64)_64': 61,\n    'backbone.stage2.1.main_conv.conv_(0, 64)_64': 62,\n    'backbone.stage2.1.blocks.0.conv1.conv_(0, 64)_64': 57,\n    'backbone.stage2.1.blocks.1.conv1.conv_(0, 64)_64': 59,\n    'backbone.stage2.1.final_conv.conv_(0, 128)_128': 69,\n    'backbone.stage3.0.conv_(0, 256)_256': 177,\n    'backbone.stage3.1.short_conv.conv_(0, 128)_128': 122,\n    'backbone.stage3.1.main_conv.conv_(0, 128)_128': 123,\n    'backbone.stage3.1.blocks.0.conv1.conv_(0, 128)_128': 125,\n    'backbone.stage3.1.blocks.1.conv1.conv_(0, 128)_128': 123,\n    'backbone.stage3.1.final_conv.conv_(0, 256)_256': 171,\n    'backbone.stage4.0.conv_(0, 512)_512': 351,\n    'backbone.stage4.1.conv1.conv_(0, 256)_256': 256,\n    'backbone.stage4.1.conv2.conv_(0, 512)_512': 367,\n    'backbone.stage4.2.short_conv.conv_(0, 256)_256': 183,\n    'backbone.stage4.2.main_conv.conv_(0, 256)_256': 216,\n    'backbone.stage4.2.blocks.0.conv1.conv_(0, 256)_256': 238,\n    'backbone.stage4.2.blocks.0.conv2.pointwise_conv.conv_(0, 256)_256': 195,\n    'backbone.stage4.2.final_conv.conv_(0, 512)_512': 187\n}\ndivisor = 16\n##############################################################################\n\narchitecture = _base_.model\n\nmodel = dict(\n    _delete_=True,\n    _scope_='mmrazor',\n    type='GroupFisherDeploySubModel',\n    architecture=architecture,\n    fix_subnet=fix_subnet,\n    divisor=divisor,\n)\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/group_fisher_finetune_rtmpose-s_8xb256-420e_aic-coco-256x192.py",
    "content": "#############################################################################\n\"\"\"# You have to fill these args.\n\n_base_(str): The path to your pruning config file.\npruned_path (str): The path to the checkpoint of the pruned model.\nfinetune_lr (float): The lr rate to finetune. Usually, we directly use the lr\n    rate of the pretrain.\n\"\"\"\n\n_base_ = './group_fisher_prune_rtmpose-s_8xb256-420e_aic-coco-256x192.py'  # noqa\npruned_path = 'https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_prune_rtmpose-s_8xb256-420e_aic-coco-256x192.pth'  # noqa\nfinetune_lr = 4e-3\n##############################################################################\n\nalgorithm = _base_.model\nalgorithm.init_cfg = dict(type='Pretrained', checkpoint=pruned_path)\n\nmodel = dict(\n    _delete_=True,\n    _scope_='mmrazor',\n    type='GroupFisherSubModel',\n    algorithm=algorithm,\n)\n\n# restore lr\noptim_wrapper = dict(optimizer=dict(lr=finetune_lr))\n\n# remove pruning related hooks\ncustom_hooks = _base_.custom_hooks[:-2]\n\n# delete ddp\nmodel_wrapper_cfg = None\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/group_fisher_finetune_rtmpose-s_8xb256-420e_coco-256x192.py",
    "content": "#############################################################################\n\"\"\"# You have to fill these args.\n\n_base_(str): The path to your pruning config file.\npruned_path (str): The path to the checkpoint of the pruned model.\nfinetune_lr (float): The lr rate to finetune. Usually, we directly use the lr\n    rate of the pretrain.\n\"\"\"\n\n_base_ = './group_fisher_prune_rtmpose-s_8xb256-420e_coco-256x192.py'\npruned_path = 'https://download.openmmlab.com/mmrazor/v1/pruning/group_fisher/rtmpose-s/group_fisher_prune_rtmpose-s_8xb256-420e_coco-256x192.pth'  # noqa\nfinetune_lr = 4e-3\n##############################################################################\n\nalgorithm = _base_.model\nalgorithm.init_cfg = dict(type='Pretrained', checkpoint=pruned_path)\n# algorithm.update(dict(architecture=dict(test_cfg=dict(flip_test=False), ))) # disable flip test # noqa\n\nmodel = dict(\n    _delete_=True,\n    _scope_='mmrazor',\n    type='GroupFisherSubModel',\n    algorithm=algorithm,\n)\n\n# restore lr\noptim_wrapper = dict(optimizer=dict(lr=finetune_lr))\n\n# remove pruning related hooks\ncustom_hooks = _base_.custom_hooks[:-2]\n\n# delete ddp\nmodel_wrapper_cfg = None\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/group_fisher_prune_rtmpose-s_8xb256-420e_aic-coco-256x192.py",
    "content": "#############################################################################\n\"\"\"You have to fill these args.\n\n_base_ (str): The path to your pretrained model checkpoint.\npretrained_path (str): The path to your pretrained model checkpoint.\n\ninterval (int): Interval between pruning two channels. You should ensure you\n    can reach your target pruning ratio when the training ends.\nnormalization_type (str): GroupFisher uses two methods to normlized the channel\n    importance, including ['flops','act']. The former uses flops, while the\n    latter uses the memory occupation of activation feature maps.\nlr_ratio (float): Ratio to decrease lr rate. As pruning progress is unstable,\n    you need to decrease the original lr rate until the pruning training work\n    steadly without getting nan.\n\ntarget_flop_ratio (float): The target flop ratio to prune your model.\ninput_shape (Tuple): input shape to measure the flops.\n\"\"\"\n\n_base_ = 'mmpose::body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_aic-coco-256x192.py'  # noqa\npretrained_path = 'https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-s_simcc-aic-coco_pt-aic-coco_420e-256x192-fcb2599b_20230126.pth'  # noqa\n\ninterval = 10\nnormalization_type = 'act'\nlr_ratio = 0.1\n\ntarget_flop_ratio = 0.51\ninput_shape = (1, 3, 256, 192)\n##############################################################################\n\narchitecture = _base_.model\n\nif hasattr(_base_, 'data_preprocessor'):\n    architecture.update({'data_preprocessor': _base_.data_preprocessor})\n    data_preprocessor = None\n\narchitecture.init_cfg = dict(type='Pretrained', checkpoint=pretrained_path)\narchitecture['_scope_'] = _base_.default_scope\n\nmodel = dict(\n    _delete_=True,\n    _scope_='mmrazor',\n    type='GroupFisherAlgorithm',\n    architecture=architecture,\n    interval=interval,\n    mutator=dict(\n        type='GroupFisherChannelMutator',\n        parse_cfg=dict(type='ChannelAnalyzer', tracer_type='FxTracer'),\n        channel_unit_cfg=dict(\n            type='GroupFisherChannelUnit',\n            default_args=dict(normalization_type=normalization_type, ),\n        ),\n    ),\n)\n\nmodel_wrapper_cfg = dict(\n    type='mmrazor.GroupFisherDDP',\n    broadcast_buffers=False,\n)\n\noptim_wrapper = dict(\n    optimizer=dict(lr=_base_.optim_wrapper.optimizer.lr * lr_ratio))\n\ncustom_hooks = getattr(_base_, 'custom_hooks', []) + [\n    dict(type='mmrazor.PruningStructureHook'),\n    dict(\n        type='mmrazor.ResourceInfoHook',\n        interval=interval,\n        demo_input=dict(\n            type='mmrazor.DefaultDemoInput',\n            input_shape=input_shape,\n        ),\n        save_ckpt_thr=[target_flop_ratio],\n    ),\n]\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/pruning/group_fisher_prune_rtmpose-s_8xb256-420e_coco-256x192.py",
    "content": "#############################################################################\n\"\"\"You have to fill these args.\n\n_base_ (str): The path to your pretrained model checkpoint.\npretrained_path (str): The path to your pretrained model checkpoint.\n\ninterval (int): Interval between pruning two channels. You should ensure you\n    can reach your target pruning ratio when the training ends.\nnormalization_type (str): GroupFisher uses two methods to normlized the channel\n    importance, including ['flops','act']. The former uses flops, while the\n    latter uses the memory occupation of activation feature maps.\nlr_ratio (float): Ratio to decrease lr rate. As pruning progress is unstable,\n    you need to decrease the original lr rate until the pruning training work\n    steadly without getting nan.\n\ntarget_flop_ratio (float): The target flop ratio to prune your model.\ninput_shape (Tuple): input shape to measure the flops.\n\"\"\"\n\n_base_ = 'mmpose::body_2d_keypoint/rtmpose/coco/rtmpose-s_8xb256-420e_coco-256x192.py'  # noqa\npretrained_path = 'https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmpose-s_simcc-coco_pt-aic-coco_420e-256x192-8edcf0d7_20230127.pth'  # noqa\n\ninterval = 10\nnormalization_type = 'act'\nlr_ratio = 0.1\n\ntarget_flop_ratio = 0.51\ninput_shape = (1, 3, 256, 192)\n##############################################################################\n\narchitecture = _base_.model\n\nif hasattr(_base_, 'data_preprocessor'):\n    architecture.update({'data_preprocessor': _base_.data_preprocessor})\n    data_preprocessor = None\n\narchitecture.init_cfg = dict(type='Pretrained', checkpoint=pretrained_path)\narchitecture['_scope_'] = _base_.default_scope\n\nmodel = dict(\n    _delete_=True,\n    _scope_='mmrazor',\n    type='GroupFisherAlgorithm',\n    architecture=architecture,\n    interval=interval,\n    mutator=dict(\n        type='GroupFisherChannelMutator',\n        parse_cfg=dict(type='ChannelAnalyzer', tracer_type='FxTracer'),\n        channel_unit_cfg=dict(\n            type='GroupFisherChannelUnit',\n            default_args=dict(normalization_type=normalization_type, ),\n        ),\n    ),\n)\n\nmodel_wrapper_cfg = dict(\n    type='mmrazor.GroupFisherDDP',\n    broadcast_buffers=False,\n)\n\noptim_wrapper = dict(\n    optimizer=dict(lr=_base_.optim_wrapper.optimizer.lr * lr_ratio))\n\ncustom_hooks = getattr(_base_, 'custom_hooks', []) + [\n    dict(type='mmrazor.PruningStructureHook'),\n    dict(\n        type='mmrazor.ResourceInfoHook',\n        interval=interval,\n        demo_input=dict(\n            type='mmrazor.DefaultDemoInput',\n            input_shape=input_shape,\n        ),\n        save_ckpt_thr=[target_flop_ratio],\n    ),\n]\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb32-270e_coco-wholebody-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 32\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-l_8xb64-270e_coco-wholebody-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-l_udp-aic-coco_210e-256x192-273b7631_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-m_8xb64-270e_coco-wholebody-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-m_udp-aic-coco_210e-256x192-f2f7d6f6_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-s_8xb64-270e_coco-wholebody-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-s_udp-aic-coco_210e-256x192-92f5a029_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=512,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-t_8xb64-270e_coco-wholebody-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 64\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.167,\n        widen_factor=0.375,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-tiny_udp-aic-coco_210e-256x192-cbed682d_20230130.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=384,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.75, 1.25],\n        rotate_factor=60),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmpose-x_8xb32-270e_coco-wholebody-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 30\nbase_lr = 4e-3\ntrain_batch_size = 32\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        _scope_='mmdet',\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        out_indices=(4, ),\n        channel_attention=True,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/cspnext-x_udp-body7_210e-384x288-d28b58e6_20230529.pth'  # noqa\n        )),\n    head=dict(\n        type='RTMCCHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=10.,\n            label_softmax=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, ))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_train_v1.0.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file=data_root + 'annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmw-l_8xb1024-270e_cocktail14-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 1024\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=8192)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmw-l_8xb320-270e_cocktail14-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 320\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=2560)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1024,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmw-m_8xb1024-270e_cocktail14-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 1024\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=8192)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=0.67,\n        widen_factor=0.75,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'rtmposev1/rtmpose-m_simcc-ucoco_dw-ucoco_270e-256x192-c8b76419_20230728.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[192, 384, 768],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=768,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmw-x_8xb320-270e_cocktail14-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (288, 384)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 320\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        # use cosine lr from 150 to 300 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=2560)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(6., 6.93),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-384x288-f5b50679_20230822.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/rtmpose/wholebody_2d_keypoint/rtmw-x_8xb704-270e_cocktail14-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\n# common setting\nnum_keypoints = 133\ninput_size = (192, 256)\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\ntrain_batch_size = 704\nval_batch_size = 32\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=21)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.1),\n    clip_grad=dict(max_norm=35, norm_type=2),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=5632)\n\n# codec settings\ncodec = dict(\n    type='SimCCLabel',\n    input_size=input_size,\n    sigma=(4.9, 5.66),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained',\n            prefix='backbone.',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/'\n            'wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-256x192-05f5bcb7_20230822.pth'  # noqa\n        )),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMWHead',\n        in_channels=1280,\n        out_channels=num_keypoints,\n        input_size=input_size,\n        in_featuremap_size=tuple([s // 32 for s in input_size]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=dict(\n            type='KLDiscretLoss',\n            use_target_weight=True,\n            beta=1.,\n            label_softmax=True,\n            label_beta=10.,\n            mask=list(range(23, 91)),\n            mask_weight=0.5,\n        ),\n        decoder=codec),\n    test_cfg=dict(flip_test=True))\n\n# base dataset settings\ndataset_type = 'CocoWholeBodyDataset'\ndata_mode = 'topdown'\ndata_root = 'data/'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.5, 1.5], rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PhotometricDistortion'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=0.5),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(\n        type='GenerateTarget',\n        encoder=codec,\n        use_dataset_keypoint_weights=True),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\n# train datasets\ndataset_coco = dict(\n    type=dataset_type,\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='coco/annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='detection/coco/train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nubody_scenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\n\nubody_datasets = []\nfor scene in ubody_scenes:\n    each = dict(\n        type='UBody2dDataset',\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file=f'Ubody/annotations/{scene}/train_annotations.json',\n        data_prefix=dict(img='pose/UBody/images/'),\n        pipeline=[],\n        sample_interval=10)\n    ubody_datasets.append(each)\n\ndataset_ubody = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/ubody2d.py'),\n    datasets=ubody_datasets,\n    pipeline=[],\n    test_mode=False,\n)\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe, dataset_ubody],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='interhand26m/annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_camera.json',\n    joint_file='interhand26m/annotations/all/'\n    'InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='interhand2.6m/images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand2d],\n    pipeline=[],\n    test_mode=False,\n)\n\ntrain_datasets = [dataset_wb, dataset_body, dataset_face, dataset_hand]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=train_batch_size,\n    num_workers=4,\n    pin_memory=False,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        metainfo=dict(from_file='configs/_base_/datasets/coco_wholebody.py'),\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        test_mode=False,\n    ))\n\nval_dataloader = dict(\n    batch_size=val_batch_size,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='CocoWholeBodyDataset',\n        ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json',\n        data_prefix=dict(img='data/detection/coco/val2017/'),\n        pipeline=val_pipeline,\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        test_mode=True))\n\ntest_dataloader = val_dataloader\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(\n        save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\n# evaluators\nval_evaluator = dict(\n    type='CocoWholeBodyMetric',\n    ann_file='data/coco/annotations/coco_wholebody_val_v1.0.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/rtmpose/yolox/humanart/yolox_l_8xb8-300e_humanart.py",
    "content": "_base_ = './yolox_s_8xb8-300e_humanart.py'\n\n# model settings\nmodel = dict(\n    backbone=dict(deepen_factor=1.0, widen_factor=1.0),\n    neck=dict(\n        in_channels=[256, 512, 1024], out_channels=256, num_csp_blocks=3),\n    bbox_head=dict(in_channels=256, feat_channels=256))\n"
  },
  {
    "path": "projects/rtmpose/yolox/humanart/yolox_m_8xb8-300e_humanart.py",
    "content": "_base_ = './yolox_s_8xb8-300e_humanart.py'\n\n# model settings\nmodel = dict(\n    backbone=dict(deepen_factor=0.67, widen_factor=0.75),\n    neck=dict(in_channels=[192, 384, 768], out_channels=192, num_csp_blocks=2),\n    bbox_head=dict(in_channels=192, feat_channels=192),\n)\n"
  },
  {
    "path": "projects/rtmpose/yolox/humanart/yolox_nano_8xb8-300e_humanart.py",
    "content": "_base_ = './yolox_tiny_8xb8-300e_humanart.py'\n\n# model settings\nmodel = dict(\n    backbone=dict(deepen_factor=0.33, widen_factor=0.25, use_depthwise=True),\n    neck=dict(\n        in_channels=[64, 128, 256],\n        out_channels=64,\n        num_csp_blocks=1,\n        use_depthwise=True),\n    bbox_head=dict(in_channels=64, feat_channels=64, use_depthwise=True))\n"
  },
  {
    "path": "projects/rtmpose/yolox/humanart/yolox_s_8xb8-300e_humanart.py",
    "content": "_base_ = [\n    'mmdet::_base_/schedules/schedule_1x.py',\n    'mmdet::_base_/default_runtime.py', 'mmdet::yolox/yolox_tta.py'\n]\n\nimg_scale = (640, 640)  # width, height\n\n# model settings\nmodel = dict(\n    type='YOLOX',\n    data_preprocessor=dict(\n        type='DetDataPreprocessor',\n        pad_size_divisor=32,\n        batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=10)\n        ]),\n    backbone=dict(\n        type='CSPDarknet',\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(2, 3, 4),\n        use_depthwise=False,\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n    ),\n    neck=dict(\n        type='YOLOXPAFPN',\n        in_channels=[128, 256, 512],\n        out_channels=128,\n        num_csp_blocks=1,\n        use_depthwise=False,\n        upsample_cfg=dict(scale_factor=2, mode='nearest'),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish')),\n    bbox_head=dict(\n        type='YOLOXHead',\n        num_classes=80,\n        in_channels=128,\n        feat_channels=128,\n        stacked_convs=2,\n        strides=(8, 16, 32),\n        use_depthwise=False,\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='Swish'),\n        loss_cls=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_obj=dict(\n            type='CrossEntropyLoss',\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_l1=dict(type='L1Loss', reduction='sum', loss_weight=1.0)),\n    train_cfg=dict(assigner=dict(type='SimOTAAssigner', center_radius=2.5)),\n    # In order to align the source code, the threshold of the val phase is\n    # 0.01, and the threshold of the test phase is 0.001.\n    test_cfg=dict(score_thr=0.01, nms=dict(type='nms', iou_threshold=0.65)))\n\n# dataset settings\ndata_root = 'data/'\ndataset_type = 'CocoDataset'\n\n# Example to use different file client\n# Method 1: simply set the data root and let the file I/O module\n# automatically infer from prefix (not support LMDB and Memcache yet)\n\n# data_root = 's3://openmmlab/datasets/detection/coco/'\n\n# Method 2: Use `backend_args`, `file_client_args` in versions before 3.0.0rc6\n# backend_args = dict(\n#     backend='petrel',\n#     path_mapping=dict({\n#         './data/': 's3://openmmlab/datasets/detection/',\n#         'data/': 's3://openmmlab/datasets/detection/'\n#     }))\nbackend_args = None\n\ntrain_pipeline = [\n    dict(type='Mosaic', img_scale=img_scale, pad_val=114.0),\n    dict(\n        type='RandomAffine',\n        scaling_ratio_range=(0.1, 2),\n        # img_scale is (width, height)\n        border=(-img_scale[0] // 2, -img_scale[1] // 2)),\n    dict(\n        type='MixUp',\n        img_scale=img_scale,\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    # According to the official implementation, multi-scale\n    # training is not considered here but in the\n    # 'mmdet/models/detectors/yolox.py'.\n    # Resize and Pad are for the last 15 epochs when Mosaic,\n    # RandomAffine, and MixUp are closed by YOLOXModeSwitchHook.\n    dict(type='Resize', scale=img_scale, keep_ratio=True),\n    dict(\n        type='Pad',\n        pad_to_square=True,\n        # If the image is three-channel, the pad value needs\n        # to be set separately for each channel.\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='FilterAnnotations', min_gt_bbox_wh=(1, 1), keep_empty=False),\n    dict(type='PackDetInputs')\n]\n\ntrain_dataset = dict(\n    # use MultiImageMixDataset wrapper to support mosaic and mixup\n    type='MultiImageMixDataset',\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='HumanArt/annotations/training_humanart_coco.json',\n        data_prefix=dict(img=''),\n        pipeline=[\n            dict(type='LoadImageFromFile', backend_args=backend_args),\n            dict(type='LoadAnnotations', with_bbox=True)\n        ],\n        filter_cfg=dict(filter_empty_gt=False, min_size=32),\n        backend_args=backend_args),\n    pipeline=train_pipeline)\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile', backend_args=backend_args),\n    dict(type='Resize', scale=img_scale, keep_ratio=True),\n    dict(\n        type='Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ntrain_dataloader = dict(\n    batch_size=8,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=train_dataset)\nval_dataloader = dict(\n    batch_size=8,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        ann_file='HumanArt/annotations/validation_humanart_coco.json',\n        data_prefix=dict(img=''),\n        test_mode=True,\n        pipeline=test_pipeline,\n        backend_args=backend_args))\ntest_dataloader = val_dataloader\n\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'HumanArt/annotations/validation_humanart_coco.json',\n    metric='bbox',\n    backend_args=backend_args)\ntest_evaluator = val_evaluator\n\n# training settings\nmax_epochs = 300\nnum_last_epochs = 15\ninterval = 10\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=interval)\n\n# optimizer\n# default 8 gpu\nbase_lr = 0.01\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(\n        type='SGD', lr=base_lr, momentum=0.9, weight_decay=5e-4,\n        nesterov=True),\n    paramwise_cfg=dict(norm_decay_mult=0., bias_decay_mult=0.))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        # use quadratic formula to warm up 5 epochs\n        # and lr is updated by iteration\n        # TODO: fix default scope in get function\n        type='mmdet.QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        # use cosine lr from 5 to 285 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=5,\n        T_max=max_epochs - num_last_epochs,\n        end=max_epochs - num_last_epochs,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(\n        # use fixed lr during last 15 epochs\n        type='ConstantLR',\n        by_epoch=True,\n        factor=1,\n        begin=max_epochs - num_last_epochs,\n        end=max_epochs,\n    )\n]\n\ndefault_hooks = dict(\n    checkpoint=dict(\n        interval=interval,\n        max_keep_ckpts=3  # only keep latest 3 checkpoints\n    ))\n\ncustom_hooks = [\n    dict(\n        type='YOLOXModeSwitchHook',\n        num_last_epochs=num_last_epochs,\n        priority=48),\n    dict(type='SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0001,\n        update_buffers=True,\n        priority=49)\n]\n\n# NOTE: `auto_scale_lr` is for automatically scaling LR,\n# USER SHOULD NOT CHANGE ITS VALUES.\n# base_batch_size = (8 GPUs) x (8 samples per GPU)\nauto_scale_lr = dict(base_batch_size=64)\n"
  },
  {
    "path": "projects/rtmpose/yolox/humanart/yolox_tiny_8xb8-300e_humanart.py",
    "content": "_base_ = './yolox_s_8xb8-300e_humanart.py'\n\n# model settings\nmodel = dict(\n    data_preprocessor=dict(batch_augments=[\n        dict(\n            type='BatchSyncRandomResize',\n            random_size_range=(320, 640),\n            size_divisor=32,\n            interval=10)\n    ]),\n    backbone=dict(deepen_factor=0.33, widen_factor=0.375),\n    neck=dict(in_channels=[96, 192, 384], out_channels=96),\n    bbox_head=dict(in_channels=96, feat_channels=96))\n\nimg_scale = (640, 640)  # width, height\n\ntrain_pipeline = [\n    dict(type='Mosaic', img_scale=img_scale, pad_val=114.0),\n    dict(\n        type='RandomAffine',\n        scaling_ratio_range=(0.5, 1.5),\n        # img_scale is (width, height)\n        border=(-img_scale[0] // 2, -img_scale[1] // 2)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(type='RandomFlip', prob=0.5),\n    # Resize and Pad are for the last 15 epochs when Mosaic and\n    # RandomAffine are closed by YOLOXModeSwitchHook.\n    dict(type='Resize', scale=img_scale, keep_ratio=True),\n    dict(\n        type='Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='FilterAnnotations', min_gt_bbox_wh=(1, 1), keep_empty=False),\n    dict(type='PackDetInputs')\n]\n\ntest_pipeline = [\n    dict(type='LoadImageFromFile', backend_args={{_base_.backend_args}}),\n    dict(type='Resize', scale=(416, 416), keep_ratio=True),\n    dict(\n        type='Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='LoadAnnotations', with_bbox=True),\n    dict(\n        type='PackDetInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor'))\n]\n\ntrain_dataloader = dict(dataset=dict(pipeline=train_pipeline))\nval_dataloader = dict(dataset=dict(pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "projects/rtmpose/yolox/humanart/yolox_x_8xb8-300e_humanart.py",
    "content": "_base_ = './yolox_s_8xb8-300e_humanart.py'\n\n# model settings\nmodel = dict(\n    backbone=dict(deepen_factor=1.33, widen_factor=1.25),\n    neck=dict(\n        in_channels=[320, 640, 1280], out_channels=320, num_csp_blocks=4),\n    bbox_head=dict(in_channels=320, feat_channels=320))\n"
  },
  {
    "path": "projects/rtmpose3d/README.md",
    "content": "# RTMPose3D: Real-Time 3D Pose Estimation toolkit based on RTMPose\n\n> ***Technical Report***:\n> [RTMW: Real-Time Multi-Person 2D and 3D Whole-body Pose Estimation](https://arxiv.org/abs/2407.08634)\n\n## Abstract\n\nRTMPose3D is a toolkit for real-time 3D pose estimation. It is based on the RTMPose model, which is a 2D pose estimation model that is capable of predicting 2D keypoints and body part associations in real-time. RTMPose3D extends RTMPose by adding a 3D pose estimation branch that can predict 3D keypoints from images directly.\n\nPlease refer to our [technical report](https://arxiv.org/pdf/2407.08634) for more details.\n\n## 🗂️ Model Zoo\n\n| Model                                                      | AP on COCO-Wholebody | MPJPE on H3WB |                                                   Download                                                    |\n| :--------------------------------------------------------- | :------------------: | :-----------: | :-----------------------------------------------------------------------------------------------------------: |\n| [RTMW3D-L](./configs/rtmw3d-l_8xb64_cocktail14-384x288.py) |        0.678         |     0.056     | [ckpt](https://download.openmmlab.com/mmpose/v1/wholebody_3d_keypoint/rtmw3d/rtmw3d-l_8xb64_cocktail14-384x288-794dbc78_20240626.pth) |\n| [RTMW3D-X](./configs/rtmw3d-x_8xb32_cocktail14-384x288.py) |        0.680         |     0.057     | [ckpt](https://download.openmmlab.com/mmpose/v1/wholebody_3d_keypoint/rtmw3d/rtmw3d-x_8xb64_cocktail14-384x288-b0a0eab7_20240626.pth) |\n\n## 📚 Usage\n\n👉🏼 TRY RTMPose3D NOW\n\n```bash\ncd /path/to/mmpose/projects/rtmpose3d\nexport PYTHONPATH=$(pwd):$PYTHONPATH\npython body3d_img2pose_demo.py configs/rtmdet_m_640-8xb32_coco-person.py https://download.openmmlab.com/mmpose/v1/projects/rtmpose/rtmdet_m_8xb32-100e_coco-obj365-person-235e8209.pth configs\\rtmw3d-l_8xb64_cocktail14-384x288.py rtmw3d-l_cock14-0d4ad840_20240422.pth --input /path/to/image --output-root /path/to/output\n```\n\n## 📜 Citation [🔝](#-table-of-contents)\n\nIf you find RTMPose3D toolkit or RTMW3D models useful in your research, please consider cite:\n\n```bibtex\n@article{jiang2024rtmw,\n  title={RTMW: Real-Time Multi-Person 2D and 3D Whole-body Pose Estimation},\n  author={Jiang, Tao and Xie, Xinchen and Li, Yining},\n  journal={arXiv preprint arXiv:2407.08634},\n  year={2024}\n}\n\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n"
  },
  {
    "path": "projects/rtmpose3d/configs/rtmw3d-l_8xb64_cocktail14-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\ncustom_imports = dict(imports=['rtmpose3d'], allow_failed_imports=False)\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\nnum_keypoints = 133\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=2024)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=4096)\n\n# codec settings\ncodec = dict(\n    type='SimCC3DLabel',\n    input_size=(288, 384, 288),\n    sigma=(6., 6.93, 6.),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False,\n    root_index=(11, 12))\n\nbackbone_path = 'https://download.openmmlab.com/mmpose/v1/projects/rtmposev1/rtmpose-l_simcc-ucoco_dw-ucoco_270e-256x192-4d6dfc62_20230728.pth'  # noqa\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator3D',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.,\n        widen_factor=1.,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=backbone_path)),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[256, 512, 1024],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMW3DHead',\n        in_channels=1024,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.1,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=[\n            dict(\n                type='KLDiscretLossWithWeight',\n                use_target_weight=True,\n                beta=10.,\n                label_softmax=True),\n            dict(\n                type='BoneLoss',\n                joint_parents=[\n                    0, 1, 2, 3, 4, 5, 6, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16,\n                    17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30,\n                    31, 32, 33, 34, 35, 36, 37, 38, 2, 2, 2, 2, 2, 3, 3, 3, 3,\n                    3, 50, 50, 51, 52, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 3, 3,\n                    3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 7, 91, 92, 93, 94, 91, 96, 97, 98, 91, 100,\n                    101, 102, 91, 104, 105, 106, 91, 108, 109, 110, 8, 112,\n                    113, 114, 113, 112, 117, 118, 117, 112, 121, 122, 123, 112,\n                    125, 126, 127, 112, 129, 130, 131\n                ],\n                use_target_weight=True,\n                loss_weight=2.0)\n        ],\n        decoder=codec),\n    # test_cfg=dict(flip_test=False, mode='2d')\n    test_cfg=dict(flip_test=False))\n\n# base dataset settings\ndata_mode = 'topdown'\ndataset_type = 'H36MWholeBodyDataset'\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=(288, 384)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=(288, 384)),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=(288, 384)),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\ndata_mode = 'topdown'\ndata_root = 'data/'\n\n# train datasets\ndataset_coco = dict(\n    type='CocoWholeBodyDataset',\n    data_root='data/coco/',\n    data_mode='topdown',\n    ann_file='annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        # dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root='data/interhand2.6m/',\n    data_mode='topdown',\n    ann_file='annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='annotations/all/InterHand2.6M_train_camera.json',\n    joint_file='annotations/all/InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_interhand3d = dict(\n    type='InterHand3DDataset',\n    data_root='data/interhand2.6m/',\n    data_mode='topdown',\n    ann_file='annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='annotations/all/InterHand2.6M_train_camera.json',\n    joint_file='annotations/all/InterHand2.6M_train_joint_3d.json',\n    use_gt_root_depth=True,\n    rootnet_result_file=None,\n    data_prefix=dict(img='images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand3d],\n    pipeline=[],\n    test_mode=False,\n)\n\n# ubody dataset\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\nubody_datasets = []\nfor scene in scenes:\n    train_ann = f'annotations/{scene}/train_3dkeypoint_annotation.json'\n    ubody = dict(\n        type='UBody3dDataset',\n        data_root='data/UBody/',\n        ann_file=train_ann,\n        data_mode='topdown',\n        causal=True,\n        seq_len=1,\n        data_prefix=dict(img='images/'),\n        subset_frac=0.1,\n        pipeline=[])\n    ubody_datasets.append(ubody)\n\n# h3wb dataset\nh3wb_dataset = dict(\n    type='H36MWholeBodyDataset',\n    ann_file='annotation_body3d/h3wb_train_bbox.npz',\n    seq_len=1,\n    causal=True,\n    data_root='data/h36m/',\n    data_prefix=dict(img='images/'),\n    test_mode=False,\n    pipeline=[])\n\ntrain_datasets = [\n    dataset_wb,\n    dataset_body,\n    dataset_face,\n    *ubody_datasets,\n    h3wb_dataset,\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        metainfo=dict(from_file='mmpose::_base_/datasets/h3wb.py'),\n        test_mode=False))\n# hooks\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1))\n\n# eval h3wb\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='H36MWholeBodyDataset',\n        ann_file='annotation_body3d/h3wb_train_bbox.npz',\n        seq_len=1,\n        causal=True,\n        data_root='data/h36m/',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='SimpleMPJPE', mode='mpjpe'),\n    dict(type='SimpleMPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n\n# eval coco\n# val_dataloader = dict(\n#     batch_size=64,\n#     num_workers=10,\n#     persistent_workers=True,\n#     drop_last=False,\n#     sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n#     dataset=dict(\n#         type='CocoWholeBodyDataset',\n#         data_root='data/coco/',\n#         data_mode='topdown',\n#         ann_file='annotations/coco_wholebody_val_v1.0.json',\n#         data_prefix=dict(img='val2017/'),\n#         test_mode=True,\n#         bbox_file='data/coco/person_detection_results/'\n#         'COCO_val2017_detections_AP_H_56_person.json',\n#         pipeline=val_pipeline,\n#     ))\n# test_dataloader = val_dataloader\n\n# # evaluators\n# val_evaluator = dict(\n#     type='CocoWholeBodyMetric',\n#     ann_file='data/coco/' + 'annotations/coco_wholebody_val_v1.0.json')\n# test_evaluator = val_evaluator\n\n# hooks\n# default_hooks = dict(\n#     checkpoint=dict(\n#         save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n"
  },
  {
    "path": "projects/rtmpose3d/configs/rtmw3d-x_8xb32_cocktail14-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\ncustom_imports = dict(imports=['rtmpose3d'], allow_failed_imports=False)\n\nvis_backends = [\n    dict(type='LocalVisBackend'),\n]\nvisualizer = dict(\n    type='Pose3dLocalVisualizer', vis_backends=vis_backends, name='visualizer')\n\n# runtime\nmax_epochs = 270\nstage2_num_epochs = 10\nbase_lr = 5e-4\nnum_keypoints = 133\n\ntrain_cfg = dict(max_epochs=max_epochs, val_interval=10)\nrandomness = dict(seed=2024)\n\n# optimizer\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\n# learning rate\nparam_scheduler = [\n    dict(\n        type='LinearLR',\n        start_factor=1.0e-5,\n        by_epoch=False,\n        begin=0,\n        end=1000),\n    dict(\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=max_epochs // 2,\n        end=max_epochs,\n        T_max=max_epochs // 2,\n        by_epoch=True,\n        convert_to_iter_based=True),\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=4096)\n\n# codec settings\ncodec = dict(\n    type='SimCC3DLabel',\n    input_size=(288, 384, 288),\n    sigma=(6., 6.93, 6.),\n    simcc_split_ratio=2.0,\n    normalize=False,\n    use_dark=False,\n    root_index=(11, 12))\n\nbackbone_path = 'https://download.openmmlab.com/mmpose/v1/wholebody_2d_keypoint/rtmpose/ubody/rtmpose-x_simcc-ucoco_pt-aic-coco_270e-384x288-f5b50679_20230822.pth'  # noqa\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator3D',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='CSPNeXt',\n        arch='P5',\n        expand_ratio=0.5,\n        deepen_factor=1.33,\n        widen_factor=1.25,\n        channel_attention=True,\n        norm_cfg=dict(type='BN'),\n        act_cfg=dict(type='SiLU'),\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=backbone_path)),\n    neck=dict(\n        type='CSPNeXtPAFPN',\n        in_channels=[320, 640, 1280],\n        out_channels=None,\n        out_indices=(\n            1,\n            2,\n        ),\n        num_csp_blocks=2,\n        expand_ratio=0.5,\n        norm_cfg=dict(type='SyncBN'),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    head=dict(\n        type='RTMW3DHead',\n        in_channels=1280,\n        out_channels=133,\n        input_size=codec['input_size'],\n        in_featuremap_size=tuple([s // 32 for s in codec['input_size']]),\n        simcc_split_ratio=codec['simcc_split_ratio'],\n        final_layer_kernel_size=7,\n        gau_cfg=dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='SiLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss=[\n            dict(\n                type='KLDiscretLossWithWeight',\n                use_target_weight=True,\n                beta=10.,\n                label_softmax=True),\n            dict(\n                type='BoneLoss',\n                joint_parents=[\n                    0, 1, 2, 3, 4, 5, 6, 5, 6, 7, 8, 11, 12, 13, 14, 15, 16,\n                    17, 18, 19, 20, 21, 22, 23, 23, 24, 25, 26, 27, 28, 29, 30,\n                    31, 32, 33, 34, 35, 36, 37, 38, 2, 2, 2, 2, 2, 3, 3, 3, 3,\n                    3, 50, 50, 51, 52, 0, 0, 0, 0, 0, 2, 2, 2, 2, 2, 2, 3, 3,\n                    3, 3, 3, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,\n                    0, 0, 0, 0, 7, 91, 92, 93, 94, 91, 96, 97, 98, 91, 100,\n                    101, 102, 91, 104, 105, 106, 91, 108, 109, 110, 8, 112,\n                    113, 114, 113, 112, 117, 118, 117, 112, 121, 122, 123, 112,\n                    125, 126, 127, 112, 129, 130, 131\n                ],\n                use_target_weight=True,\n                loss_weight=2.0)\n        ],\n        decoder=codec),\n    # test_cfg=dict(flip_test=False, mode='2d')\n    test_cfg=dict(flip_test=False))\n\n# base dataset settings\ndata_mode = 'topdown'\n\nbackend_args = dict(backend='local')\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform', scale_factor=[0.6, 1.4], rotate_factor=80),\n    dict(type='TopdownAffine', input_size=(288, 384)),\n    dict(type='YOLOXHSVRandomAug'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=1,\n                max_height=0.4,\n                max_width=0.4,\n                min_holes=1,\n                min_height=0.2,\n                min_width=0.2,\n                p=1.0),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=(288, 384)),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\ntrain_pipeline_stage2 = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[0.5, 1.5],\n        rotate_factor=90),\n    dict(type='TopdownAffine', input_size=(288, 384)),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='Blur', p=0.1),\n            dict(type='MedianBlur', p=0.1),\n        ]),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\n\n# mapping\n\naic_coco133 = [(0, 6), (1, 8), (2, 10), (3, 5), (4, 7), (5, 9), (6, 12),\n               (7, 14), (8, 16), (9, 11), (10, 13), (11, 15)]\n\ncrowdpose_coco133 = [(0, 5), (1, 6), (2, 7), (3, 8), (4, 9), (5, 10), (6, 11),\n                     (7, 12), (8, 13), (9, 14), (10, 15), (11, 16)]\n\nmpii_coco133 = [\n    (0, 16),\n    (1, 14),\n    (2, 12),\n    (3, 11),\n    (4, 13),\n    (5, 15),\n    (10, 10),\n    (11, 8),\n    (12, 6),\n    (13, 5),\n    (14, 7),\n    (15, 9),\n]\n\njhmdb_coco133 = [\n    (3, 6),\n    (4, 5),\n    (5, 12),\n    (6, 11),\n    (7, 8),\n    (8, 7),\n    (9, 14),\n    (10, 13),\n    (11, 10),\n    (12, 9),\n    (13, 16),\n    (14, 15),\n]\n\nhalpe_coco133 = [(i, i)\n                 for i in range(17)] + [(20, 17), (21, 20), (22, 18), (23, 21),\n                                        (24, 19),\n                                        (25, 22)] + [(i, i - 3)\n                                                     for i in range(26, 136)]\n\nposetrack_coco133 = [\n    (0, 0),\n    (3, 3),\n    (4, 4),\n    (5, 5),\n    (6, 6),\n    (7, 7),\n    (8, 8),\n    (9, 9),\n    (10, 10),\n    (11, 11),\n    (12, 12),\n    (13, 13),\n    (14, 14),\n    (15, 15),\n    (16, 16),\n]\n\nhumanart_coco133 = [(i, i) for i in range(17)] + [(17, 99), (18, 120),\n                                                  (19, 17), (20, 20)]\n\ndata_mode = 'topdown'\ndata_root = 'data/'\n\n# train datasets\ndataset_coco = dict(\n    type='CocoWholeBodyDataset',\n    data_root='data/coco/',\n    data_mode='topdown',\n    ann_file='annotations/coco_wholebody_train_v1.0.json',\n    data_prefix=dict(img='train2017/'),\n    pipeline=[],\n)\n\ndataset_aic = dict(\n    type='AicDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='aic/annotations/aic_train.json',\n    data_prefix=dict(img='pose/ai_challenge/ai_challenger_keypoint'\n                     '_train_20170902/keypoint_train_images_20170902/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=aic_coco133)\n    ],\n)\n\ndataset_crowdpose = dict(\n    type='CrowdPoseDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='crowdpose/annotations/mmpose_crowdpose_trainval.json',\n    data_prefix=dict(img='pose/CrowdPose/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=crowdpose_coco133)\n    ],\n)\n\ndataset_mpii = dict(\n    type='MpiiDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='mpii/annotations/mpii_train.json',\n    data_prefix=dict(img='pose/MPI/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mpii_coco133)\n    ],\n)\n\ndataset_jhmdb = dict(\n    type='JhmdbDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='jhmdb/annotations/Sub1_train.json',\n    data_prefix=dict(img='pose/JHMDB/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=jhmdb_coco133)\n    ],\n)\n\ndataset_halpe = dict(\n    type='HalpeDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='halpe/annotations/halpe_train_v1.json',\n    data_prefix=dict(img='pose/Halpe/hico_20160224_det/images/train2015'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=halpe_coco133)\n    ],\n)\n\ndataset_posetrack = dict(\n    type='PoseTrack18Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='posetrack18/annotations/posetrack18_train.json',\n    data_prefix=dict(img='pose/PoseChallenge2018/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=posetrack_coco133)\n    ],\n)\n\ndataset_humanart = dict(\n    type='HumanArt21Dataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='HumanArt/annotations/training_humanart.json',\n    filter_cfg=dict(scenes=['real_human']),\n    data_prefix=dict(img='pose/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=humanart_coco133)\n    ])\n\nface_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale', padding=1.25),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\nwflw_coco133 = [(i * 2, 23 + i)\n                for i in range(17)] + [(33 + i, 40 + i) for i in range(5)] + [\n                    (42 + i, 45 + i) for i in range(5)\n                ] + [(51 + i, 50 + i)\n                     for i in range(9)] + [(60, 59), (61, 60), (63, 61),\n                                           (64, 62), (65, 63), (67, 64),\n                                           (68, 65), (69, 66), (71, 67),\n                                           (72, 68), (73, 69),\n                                           (75, 70)] + [(76 + i, 71 + i)\n                                                        for i in range(20)]\ndataset_wflw = dict(\n    type='WFLWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='wflw/annotations/face_landmarks_wflw_train.json',\n    data_prefix=dict(img='pose/WFLW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=wflw_coco133), *face_pipeline\n    ],\n)\n\nmapping_300w_coco133 = [(i, 23 + i) for i in range(68)]\ndataset_300w = dict(\n    type='Face300WDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='300w/annotations/face_landmarks_300w_train.json',\n    data_prefix=dict(img='pose/300w/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=mapping_300w_coco133), *face_pipeline\n    ],\n)\n\ncofw_coco133 = [(0, 40), (2, 44), (4, 42), (1, 49), (3, 45), (6, 47), (8, 59),\n                (10, 62), (9, 68), (11, 65), (18, 54), (19, 58), (20, 53),\n                (21, 56), (22, 71), (23, 77), (24, 74), (25, 85), (26, 89),\n                (27, 80), (28, 31)]\ndataset_cofw = dict(\n    type='COFWDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='cofw/annotations/cofw_train.json',\n    data_prefix=dict(img='pose/COFW/images/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=cofw_coco133), *face_pipeline\n    ],\n)\n\nlapa_coco133 = [(i * 2, 23 + i) for i in range(17)] + [\n    (33 + i, 40 + i) for i in range(5)\n] + [(42 + i, 45 + i) for i in range(5)] + [\n    (51 + i, 50 + i) for i in range(4)\n] + [(58 + i, 54 + i) for i in range(5)] + [(66, 59), (67, 60), (69, 61),\n                                            (70, 62), (71, 63), (73, 64),\n                                            (75, 65), (76, 66), (78, 67),\n                                            (79, 68), (80, 69),\n                                            (82, 70)] + [(84 + i, 71 + i)\n                                                         for i in range(20)]\ndataset_lapa = dict(\n    type='LapaDataset',\n    data_root=data_root,\n    data_mode=data_mode,\n    ann_file='LaPa/annotations/lapa_trainval.json',\n    data_prefix=dict(img='pose/LaPa/'),\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=lapa_coco133), *face_pipeline\n    ],\n)\n\ndataset_wb = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_coco, dataset_halpe],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_body = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_aic,\n        dataset_crowdpose,\n        dataset_mpii,\n        dataset_jhmdb,\n        dataset_posetrack,\n        # dataset_humanart,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\ndataset_face = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[\n        dataset_wflw,\n        dataset_300w,\n        dataset_cofw,\n        dataset_lapa,\n    ],\n    pipeline=[],\n    test_mode=False,\n)\n\nhand_pipeline = [\n    dict(type='LoadImage', backend_args=backend_args),\n    dict(type='GetBBoxCenterScale'),\n    dict(\n        type='RandomBBoxTransform',\n        shift_factor=0.,\n        scale_factor=[1.5, 2.0],\n        rotate_factor=0),\n]\n\ninterhand_left = [(21, 95), (22, 94), (23, 93), (24, 92), (25, 99), (26, 98),\n                  (27, 97), (28, 96), (29, 103), (30, 102), (31, 101),\n                  (32, 100), (33, 107), (34, 106), (35, 105), (36, 104),\n                  (37, 111), (38, 110), (39, 109), (40, 108), (41, 91)]\ninterhand_right = [(i - 21, j + 21) for i, j in interhand_left]\ninterhand_coco133 = interhand_right + interhand_left\n\ndataset_interhand2d = dict(\n    type='InterHand2DDoubleDataset',\n    data_root='data/interhand2.6m/',\n    data_mode='topdown',\n    ann_file='annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='annotations/all/InterHand2.6M_train_camera.json',\n    joint_file='annotations/all/InterHand2.6M_train_joint_3d.json',\n    data_prefix=dict(img='images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_interhand3d = dict(\n    type='InterHand3DDataset',\n    data_root='data/interhand2.6m/',\n    data_mode='topdown',\n    ann_file='annotations/all/InterHand2.6M_train_data.json',\n    camera_param_file='annotations/all/InterHand2.6M_train_camera.json',\n    joint_file='annotations/all/InterHand2.6M_train_joint_3d.json',\n    use_gt_root_depth=True,\n    rootnet_result_file=None,\n    data_prefix=dict(img='images/train/'),\n    sample_interval=10,\n    pipeline=[\n        dict(\n            type='KeypointConverter',\n            num_keypoints=num_keypoints,\n            mapping=interhand_coco133,\n        ), *hand_pipeline\n    ],\n)\n\ndataset_hand = dict(\n    type='CombinedDataset',\n    metainfo=dict(from_file='mmpose::_base_/datasets/coco_wholebody.py'),\n    datasets=[dataset_interhand3d],\n    pipeline=[],\n    test_mode=False,\n)\n\n# ubody dataset\nscenes = [\n    'Magic_show', 'Entertainment', 'ConductMusic', 'Online_class', 'TalkShow',\n    'Speech', 'Fitness', 'Interview', 'Olympic', 'TVShow', 'Singing',\n    'SignLanguage', 'Movie', 'LiveVlog', 'VideoConference'\n]\nubody_datasets = []\nfor scene in scenes:\n    train_ann = f'annotations/{scene}/train_3dkeypoint_annotation.json'\n    ubody = dict(\n        type='UBody3dDataset',\n        data_root='data/UBody/',\n        ann_file=train_ann,\n        data_mode='topdown',\n        causal=True,\n        seq_len=1,\n        data_prefix=dict(img='images/'),\n        subset_frac=0.1,\n        pipeline=[])\n    ubody_datasets.append(ubody)\n\n# h3wb dataset\nh3wb_dataset = dict(\n    type='H36MWholeBodyDataset',\n    ann_file='annotation_body3d/h3wb_train_bbox.npz',\n    seq_len=1,\n    causal=True,\n    data_root='data/h36m/',\n    data_prefix=dict(img='images/'),\n    test_mode=False,\n    pipeline=[])\n\ntrain_datasets = [\n    dataset_wb,\n    dataset_body,\n    dataset_face,\n    *ubody_datasets,\n    h3wb_dataset,\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=10,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type='CombinedDataset',\n        datasets=train_datasets,\n        pipeline=train_pipeline,\n        metainfo=dict(from_file='mmpose::_base_/datasets/h3wb.py'),\n        test_mode=False))\n\n# hooks\ncustom_hooks = [\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        priority=49),\n    dict(\n        type='mmdet.PipelineSwitchHook',\n        switch_epoch=max_epochs - stage2_num_epochs,\n        switch_pipeline=train_pipeline_stage2)\n]\n\ndefault_hooks = dict(\n    checkpoint=dict(\n        type='CheckpointHook',\n        save_best='MPJPE',\n        rule='less',\n        max_keep_ckpts=1))\n\n# eval h3wb\nval_dataloader = dict(\n    batch_size=64,\n    num_workers=10,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type='H36MWholeBodyDataset',\n        ann_file='annotation_body3d/h3wb_train_bbox.npz',\n        seq_len=1,\n        causal=True,\n        data_root='data/h36m/',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = [\n    dict(type='SimpleMPJPE', mode='mpjpe'),\n    dict(type='SimpleMPJPE', mode='p-mpjpe')\n]\ntest_evaluator = val_evaluator\n\n# eval coco\n# val_dataloader = dict(\n#     batch_size=64,\n#     num_workers=10,\n#     persistent_workers=True,\n#     drop_last=False,\n#     sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n#     dataset=dict(\n#         type='CocoWholeBodyDataset',\n#         data_root='data/coco/',\n#         data_mode='topdown',\n#         ann_file='annotations/coco_wholebody_val_v1.0.json',\n#         data_prefix=dict(img='val2017/'),\n#         test_mode=True,\n#         bbox_file='data/coco/person_detection_results/'\n#         'COCO_val2017_detections_AP_H_56_person.json',\n#         pipeline=val_pipeline,\n#     ))\n# test_dataloader = val_dataloader\n\n# # evaluators\n# val_evaluator = dict(\n#     type='CocoWholeBodyMetric',\n#     ann_file='data/coco/' + 'annotations/coco_wholebody_val_v1.0.json')\n# test_evaluator = val_evaluator\n\n# hooks\n# default_hooks = dict(\n#     checkpoint=dict(\n#         save_best='coco-wholebody/AP', rule='greater', max_keep_ckpts=1))\n"
  },
  {
    "path": "projects/rtmpose3d/demo/body3d_img2pose_demo.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport logging\nimport mimetypes\nimport os\nimport time\nfrom argparse import ArgumentParser\nfrom typing import List\n\nimport cv2\nimport json_tricks as json\nimport mmcv\nimport mmengine\nimport numpy as np\nfrom mmengine.logging import print_log\n\nfrom mmpose.apis import inference_topdown, init_model\nfrom mmpose.registry import VISUALIZERS\nfrom mmpose.structures import (PoseDataSample, merge_data_samples,\n                               split_instances)\nfrom mmpose.utils import adapt_mmdet_pipeline\nfrom mmpose.visualization import Pose3dLocalVisualizer\n\ntry:\n    from mmdet.apis import inference_detector, init_detector\n    has_mmdet = True\nexcept (ImportError, ModuleNotFoundError):\n    has_mmdet = False\n\nfrom rtmpose3d import *  # noqa: F401, F403\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument('det_config', help='Config file for detection')\n    parser.add_argument('det_checkpoint', help='Checkpoint file for detection')\n    parser.add_argument(\n        'pose3d_estimator_config',\n        type=str,\n        default=None,\n        help='Config file for the 3D pose estimator')\n    parser.add_argument(\n        'pose3d_estimator_checkpoint',\n        type=str,\n        default=None,\n        help='Checkpoint file for the 3D pose estimator')\n    parser.add_argument('--input', type=str, default='', help='Video path')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='Whether to show visualizations')\n    parser.add_argument(\n        '--disable-rebase-keypoint',\n        action='store_true',\n        default=False,\n        help='Whether to disable rebasing the predicted 3D pose so its '\n        'lowest keypoint has a height of 0 (landing on the ground). Rebase '\n        'is useful for visualization when the model do not predict the '\n        'global position of the 3D pose.')\n    parser.add_argument(\n        '--disable-norm-pose-2d',\n        action='store_true',\n        default=False,\n        help='Whether to scale the bbox (along with the 2D pose) to the '\n        'average bbox scale of the dataset, and move the bbox (along with the '\n        '2D pose) to the average bbox center of the dataset. This is useful '\n        'when bbox is small, especially in multi-person scenarios.')\n    parser.add_argument(\n        '--num-instances',\n        type=int,\n        default=1,\n        help='The number of 3D poses to be visualized in every frame. If '\n        'less than 0, it will be set to the number of pose results in the '\n        'first frame.')\n    parser.add_argument(\n        '--output-root',\n        type=str,\n        default='',\n        help='Root of the output video file. '\n        'Default not saving the visualization video.')\n    parser.add_argument(\n        '--save-predictions',\n        action='store_true',\n        default=False,\n        help='Whether to save predicted results')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--det-cat-id',\n        type=int,\n        default=0,\n        help='Category id for bounding box detection model')\n    parser.add_argument(\n        '--bbox-thr',\n        type=float,\n        default=0.5,\n        help='Bounding box score threshold')\n    parser.add_argument('--kpt-thr', type=float, default=0.3)\n    parser.add_argument(\n        '--use-oks-tracking', action='store_true', help='Using OKS tracking')\n    parser.add_argument(\n        '--tracking-thr', type=float, default=0.3, help='Tracking threshold')\n    parser.add_argument(\n        '--show-interval', type=int, default=0, help='Sleep seconds per frame')\n    parser.add_argument(\n        '--thickness',\n        type=int,\n        default=1,\n        help='Link thickness for visualization')\n    parser.add_argument(\n        '--radius',\n        type=int,\n        default=3,\n        help='Keypoint radius for visualization')\n    parser.add_argument(\n        '--online',\n        action='store_true',\n        default=False,\n        help='Inference mode. If set to True, can not use future frame'\n        'information when using multi frames for inference in the 2D pose'\n        'detection stage. Default: False.')\n\n    args = parser.parse_args()\n    return args\n\n\ndef process_one_image(args, detector, frame: np.ndarray, frame_idx: int,\n                      pose_estimator,\n                      pose_est_results_last: List[PoseDataSample],\n                      pose_est_results_list: List[List[PoseDataSample]],\n                      next_id: int, visualize_frame: np.ndarray,\n                      visualizer: Pose3dLocalVisualizer):\n    \"\"\"Visualize detected and predicted keypoints of one image.\n\n    Pipeline of this function:\n\n                              frame\n                                |\n                                V\n                        +-----------------+\n                        |     detector    |\n                        +-----------------+\n                                |  det_result\n                                V\n                        +-----------------+\n                        |  pose_estimator |\n                        +-----------------+\n                                |  pose_est_results\n                                V\n                       +-----------------+\n                       | post-processing |\n                       +-----------------+\n                                |  pred_3d_data_samples\n                                V\n                         +------------+\n                         | visualizer |\n                         +------------+\n\n    Args:\n        args (Argument): Custom command-line arguments.\n        detector (mmdet.BaseDetector): The mmdet detector.\n        frame (np.ndarray): The image frame read from input image or video.\n        frame_idx (int): The index of current frame.\n        pose_estimator (TopdownPoseEstimator): The pose estimator for 2d pose.\n        pose_est_results_last (list(PoseDataSample)): The results of pose\n            estimation from the last frame for tracking instances.\n        pose_est_results_list (list(list(PoseDataSample))): The list of all\n            pose estimation results converted by\n            ``convert_keypoint_definition`` from previous frames. In\n            pose-lifting stage it is used to obtain the 2d estimation sequence.\n        next_id (int): The next track id to be used.\n        pose_lifter (PoseLifter): The pose-lifter for estimating 3d pose.\n        visualize_frame (np.ndarray): The image for drawing the results on.\n        visualizer (Visualizer): The visualizer for visualizing the 2d and 3d\n            pose estimation results.\n\n    Returns:\n        pose_est_results (list(PoseDataSample)): The pose estimation result of\n            the current frame.\n        pose_est_results_list (list(list(PoseDataSample))): The list of all\n            converted pose estimation results until the current frame.\n        pred_3d_instances (InstanceData): The result of pose-lifting.\n            Specifically, the predicted keypoints and scores are saved at\n            ``pred_3d_instances.keypoints`` and\n            ``pred_3d_instances.keypoint_scores``.\n        next_id (int): The next track id to be used.\n    \"\"\"\n    # pose_dataset = pose_estimator.cfg.test_dataloader.dataset\n    pose_det_dataset_name = pose_estimator.dataset_meta['dataset_name']\n\n    # First stage: conduct 2D pose detection in a Topdown manner\n    # use detector to obtain person bounding boxes\n    det_result = inference_detector(detector, frame)\n    pred_instance = det_result.pred_instances.cpu().numpy()\n\n    # filter out the person instances with category and bbox threshold\n    # e.g. 0 for person in COCO\n    bboxes = pred_instance.bboxes\n    bboxes = bboxes[np.logical_and(pred_instance.labels == args.det_cat_id,\n                                   pred_instance.scores > args.bbox_thr)]\n\n    # estimate pose results for current image\n    pose_est_results = inference_topdown(pose_estimator, frame, bboxes)\n\n    # post-processing\n    for idx, pose_est_result in enumerate(pose_est_results):\n        pose_est_result.track_id = pose_est_results[idx].get('track_id', 1e4)\n\n        pred_instances = pose_est_result.pred_instances\n        keypoints = pred_instances.keypoints\n        keypoint_scores = pred_instances.keypoint_scores\n        if keypoint_scores.ndim == 3:\n            keypoint_scores = np.squeeze(keypoint_scores, axis=1)\n            pose_est_results[\n                idx].pred_instances.keypoint_scores = keypoint_scores\n        if keypoints.ndim == 4:\n            keypoints = np.squeeze(keypoints, axis=1)\n\n        keypoints = -keypoints[..., [0, 2, 1]]\n\n        # rebase height (z-axis)\n        if not args.disable_rebase_keypoint:\n            keypoints[..., 2] -= np.min(\n                keypoints[..., 2], axis=-1, keepdims=True)\n\n        pose_est_results[idx].pred_instances.keypoints = keypoints\n\n    pose_est_results = sorted(\n        pose_est_results, key=lambda x: x.get('track_id', 1e4))\n\n    pred_3d_data_samples = merge_data_samples(pose_est_results)\n    pred_3d_instances = pred_3d_data_samples.get('pred_instances', None)\n\n    if args.num_instances < 0:\n        args.num_instances = len(pose_est_results)\n\n    # Visualization\n    if visualizer is not None:\n        visualizer.add_datasample(\n            'result',\n            visualize_frame,\n            data_sample=pred_3d_data_samples,\n            det_data_sample=pred_3d_data_samples,\n            draw_gt=False,\n            draw_2d=True,\n            dataset_2d=pose_det_dataset_name,\n            dataset_3d=pose_det_dataset_name,\n            show=args.show,\n            draw_bbox=True,\n            kpt_thr=args.kpt_thr,\n            convert_keypoint=False,\n            axis_limit=400,\n            axis_azimuth=70,\n            axis_elev=15,\n            num_instances=args.num_instances,\n            wait_time=args.show_interval)\n\n    return pose_est_results, pose_est_results_list, pred_3d_instances, next_id\n\n\ndef main():\n    assert has_mmdet, 'Please install mmdet to run the demo.'\n\n    args = parse_args()\n\n    assert args.show or (args.output_root != '')\n    assert args.input != ''\n    assert args.det_config is not None\n    assert args.det_checkpoint is not None\n\n    detector = init_detector(\n        args.det_config, args.det_checkpoint, device=args.device.lower())\n    detector.cfg = adapt_mmdet_pipeline(detector.cfg)\n\n    pose_estimator = init_model(\n        args.pose3d_estimator_config,\n        args.pose3d_estimator_checkpoint,\n        device=args.device.lower())\n\n    det_kpt_color = pose_estimator.dataset_meta.get('keypoint_colors', None)\n    det_dataset_skeleton = pose_estimator.dataset_meta.get(\n        'skeleton_links', None)\n    det_dataset_link_color = pose_estimator.dataset_meta.get(\n        'skeleton_link_colors', None)\n\n    pose_estimator.cfg.model.test_cfg.mode = 'vis'\n    pose_estimator.cfg.visualizer.radius = args.radius\n    pose_estimator.cfg.visualizer.line_width = args.thickness\n    pose_estimator.cfg.visualizer.det_kpt_color = det_kpt_color\n    pose_estimator.cfg.visualizer.det_dataset_skeleton = det_dataset_skeleton\n    pose_estimator.cfg.visualizer.det_dataset_link_color = det_dataset_link_color  # noqa: E501\n    pose_estimator.cfg.visualizer.skeleton = det_dataset_skeleton\n    pose_estimator.cfg.visualizer.link_color = det_dataset_link_color\n    pose_estimator.cfg.visualizer.kpt_color = det_kpt_color\n    visualizer = VISUALIZERS.build(pose_estimator.cfg.visualizer)\n\n    if args.input == 'webcam':\n        input_type = 'webcam'\n    else:\n        input_type = mimetypes.guess_type(args.input)[0].split('/')[0]\n\n    if args.output_root == '':\n        save_output = False\n    else:\n        mmengine.mkdir_or_exist(args.output_root)\n        output_file = os.path.join(args.output_root,\n                                   os.path.basename(args.input))\n        if args.input == 'webcam':\n            output_file += '.mp4'\n        save_output = True\n\n    if args.save_predictions:\n        assert args.output_root != ''\n        args.pred_save_path = f'{args.output_root}/results_' \\\n            f'{os.path.splitext(os.path.basename(args.input))[0]}.json'\n\n    if save_output:\n        fourcc = cv2.VideoWriter_fourcc(*'mp4v')\n\n    pose_est_results_list = []\n    pred_instances_list = []\n    if input_type == 'image':\n        frame = mmcv.imread(args.input, channel_order='rgb')\n        _, _, pred_3d_instances, _ = process_one_image(\n            args=args,\n            detector=detector,\n            frame=args.input,\n            frame_idx=0,\n            pose_estimator=pose_estimator,\n            pose_est_results_last=[],\n            pose_est_results_list=pose_est_results_list,\n            next_id=0,\n            visualize_frame=frame,\n            visualizer=visualizer)\n\n        if args.save_predictions:\n            # save prediction results\n            pred_instances_list = split_instances(pred_3d_instances)\n\n        if save_output:\n            frame_vis = visualizer.get_image()\n            mmcv.imwrite(mmcv.rgb2bgr(frame_vis), output_file)\n\n    elif input_type in ['webcam', 'video']:\n        next_id = 0\n        pose_est_results = []\n\n        if args.input == 'webcam':\n            video = cv2.VideoCapture(0)\n        else:\n            video = cv2.VideoCapture(args.input)\n\n        (major_ver, minor_ver, subminor_ver) = (cv2.__version__).split('.')\n        if int(major_ver) < 3:\n            fps = video.get(cv2.cv.CV_CAP_PROP_FPS)\n        else:\n            fps = video.get(cv2.CAP_PROP_FPS)\n\n        video_writer = None\n        frame_idx = 0\n\n        while video.isOpened():\n            success, frame = video.read()\n            frame_idx += 1\n\n            if not success:\n                break\n\n            pose_est_results_last = pose_est_results\n\n            # First stage: 2D pose detection\n            # make person results for current image\n            (pose_est_results, pose_est_results_list, pred_3d_instances,\n             next_id) = process_one_image(\n                 args=args,\n                 detector=detector,\n                 frame=frame,\n                 frame_idx=frame_idx,\n                 pose_estimator=pose_estimator,\n                 pose_est_results_last=pose_est_results_last,\n                 pose_est_results_list=pose_est_results_list,\n                 next_id=next_id,\n                 visualize_frame=mmcv.bgr2rgb(frame),\n                 visualizer=visualizer)\n\n            if args.save_predictions:\n                # save prediction results\n                pred_instances_list.append(\n                    dict(\n                        frame_id=frame_idx,\n                        instances=split_instances(pred_3d_instances)))\n\n            if save_output:\n                frame_vis = visualizer.get_image()\n                if video_writer is None:\n                    # the size of the image with visualization may vary\n                    # depending on the presence of heatmaps\n                    video_writer = cv2.VideoWriter(output_file, fourcc, fps,\n                                                   (frame_vis.shape[1],\n                                                    frame_vis.shape[0]))\n                video_writer.write(mmcv.rgb2bgr(frame_vis))\n\n            if args.show:\n                # press ESC to exit\n                if cv2.waitKey(5) & 0xFF == 27:\n                    break\n                time.sleep(args.show_interval)\n\n        video.release()\n\n        if video_writer:\n            video_writer.release()\n    else:\n        args.save_predictions = False\n        raise ValueError(\n            f'file {os.path.basename(args.input)} has invalid format.')\n\n    if args.save_predictions:\n        with open(args.pred_save_path, 'w') as f:\n            json.dump(\n                dict(\n                    meta_info=pose_estimator.dataset_meta,\n                    instance_info=pred_instances_list),\n                f,\n                indent='\\t')\n        print(f'predictions have been saved at {args.pred_save_path}')\n\n    if save_output:\n        input_type = input_type.replace('webcam', 'video')\n        print_log(\n            f'the output {input_type} has been saved at {output_file}',\n            logger='current',\n            level=logging.INFO)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "projects/rtmpose3d/demo/rtmdet_m_640-8xb32_coco-person.py",
    "content": "_base_ = 'mmdet::rtmdet/rtmdet_m_8xb32-300e_coco.py'\n\ncheckpoint = 'https://download.openmmlab.com/mmdetection/v3.0/rtmdet/cspnext_rsb_pretrain/cspnext-m_8xb256-rsb-a1-600e_in1k-ecb3bbd9.pth'  # noqa\n\nmodel = dict(\n    backbone=dict(\n        init_cfg=dict(\n            type='Pretrained', prefix='backbone.', checkpoint=checkpoint)),\n    bbox_head=dict(num_classes=1),\n    test_cfg=dict(\n        nms_pre=1000,\n        min_bbox_size=0,\n        score_thr=0.05,\n        nms=dict(type='nms', iou_threshold=0.6),\n        max_per_img=100))\n\ntrain_dataloader = dict(dataset=dict(metainfo=dict(classes=('person', ))))\n\nval_dataloader = dict(dataset=dict(metainfo=dict(classes=('person', ))))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "projects/rtmpose3d/rtmpose3d/__init__.py",
    "content": "from .loss import KLDiscretLossWithWeight\nfrom .pose_estimator import TopdownPoseEstimator3D\nfrom .rtmw3d_head import RTMW3DHead\nfrom .simcc_3d_label import SimCC3DLabel\n\n__all__ = [\n    'TopdownPoseEstimator3D', 'RTMW3DHead', 'SimCC3DLabel',\n    'KLDiscretLossWithWeight'\n]\n"
  },
  {
    "path": "projects/rtmpose3d/rtmpose3d/loss.py",
    "content": "from mmpose.models.losses import KLDiscretLoss\nfrom mmpose.registry import MODELS\n\n\n@MODELS.register_module()\nclass KLDiscretLossWithWeight(KLDiscretLoss):\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n        self._loss_name = 'loss_kld'\n\n    def forward(self, pred_simcc, gt_simcc, target_weight):\n        N, K, _ = pred_simcc[0].shape\n        loss = 0\n\n        for pred, target, weight in zip(pred_simcc, gt_simcc, target_weight):\n            pred = pred.reshape(-1, pred.size(-1))\n            target = target.reshape(-1, target.size(-1))\n            weight = weight.reshape(-1)\n\n            t_loss = self.criterion(pred, target).mul(weight)\n\n            if self.mask is not None:\n                t_loss = t_loss.reshape(N, K)\n                t_loss[:, self.mask] = t_loss[:, self.mask] * self.mask_weight\n\n            loss = loss + t_loss.sum()\n\n        return loss / K\n\n    @property\n    def loss_name(self):\n        \"\"\"Loss Name.\n\n        Returns:\n            str: The name of this loss item.\n        \"\"\"\n        return self._loss_name\n"
  },
  {
    "path": "projects/rtmpose3d/rtmpose3d/pose_estimator.py",
    "content": "from itertools import zip_longest\nfrom typing import Optional\n\nimport numpy as np\n\nfrom mmpose.models.pose_estimators import TopdownPoseEstimator\nfrom mmpose.registry import MODELS\nfrom mmpose.utils.typing import InstanceList, PixelDataList, SampleList\n\n\n@MODELS.register_module()\nclass TopdownPoseEstimator3D(TopdownPoseEstimator):\n\n    def __init__(self, **kwargs):\n        super().__init__(**kwargs)\n\n        # a default camera parameter for 3D pose estimation\n        self.camera_param = {\n            'c': [512.54150496, 515.45148698],\n            'f': [1145.04940459, 1143.78109572],\n        }\n\n    def add_pred_to_datasample(self, batch_pred_instances: InstanceList,\n                               batch_pred_fields: Optional[PixelDataList],\n                               batch_data_samples: SampleList) -> SampleList:\n        \"\"\"Add predictions into data samples.\n\n        Args:\n            batch_pred_instances (List[InstanceData]): The predicted instances\n                of the input data batch\n            batch_pred_fields (List[PixelData], optional): The predicted\n                fields (e.g. heatmaps) of the input batch\n            batch_data_samples (List[PoseDataSample]): The input data batch\n\n        Returns:\n            List[PoseDataSample]: A list of data samples where the predictions\n            are stored in the ``pred_instances`` field of each data sample.\n        \"\"\"\n        assert len(batch_pred_instances) == len(batch_data_samples)\n        if batch_pred_fields is None:\n            batch_pred_fields = []\n        output_keypoint_indices = self.test_cfg.get('output_keypoint_indices',\n                                                    None)\n        mode = self.test_cfg.get('mode', '3d')\n        assert mode in ['2d', '3d', 'vis']\n        for pred_instances, pred_fields, data_sample in zip_longest(\n                batch_pred_instances, batch_pred_fields, batch_data_samples):\n\n            gt_instances = data_sample.gt_instances\n\n            # convert keypoint coordinates from input space to image space\n            input_center = data_sample.metainfo['input_center']\n            input_scale = data_sample.metainfo['input_scale']\n            input_size = data_sample.metainfo['input_size']\n            keypoints_3d = pred_instances.keypoints\n            keypoints_simcc = pred_instances.keypoints_simcc\n\n            # convert keypoints from input space to image space\n            keypoints_2d = keypoints_3d[..., :2].copy()\n            keypoints_2d = keypoints_2d / input_size * input_scale \\\n                + input_center - 0.5 * input_scale\n\n            # convert keypoints from image space to camera space\n            if gt_instances.get('camera_params', None) is not None:\n                camera_params = gt_instances.camera_params[0]\n                f = np.array(camera_params['f'])\n                c = np.array(camera_params['c'])\n            else:\n                f = np.array([1145.04940459, 1143.78109572])\n                c = np.array(data_sample.ori_shape) / 2\n            kpts_pixel = np.concatenate([\n                keypoints_2d,\n                (keypoints_3d[..., 2] + gt_instances.root_z)[..., None]\n            ],\n                                        axis=-1)\n            kpts_cam = kpts_pixel.copy()\n            kpts_cam[..., :2] = (kpts_pixel[..., :2] - c) / f * kpts_pixel[...,\n                                                                           2:]\n\n            if mode == '3d':\n                # Evaluation with 3D keypoint coordinates\n                pred_instances.keypoints = kpts_cam\n                pred_instances.transformed_keypoints = keypoints_2d\n            elif mode == 'vis':\n                # Visualization with SimCC keypoints\n                pred_instances.keypoints = keypoints_simcc\n                pred_instances.transformed_keypoints = keypoints_2d\n            else:\n                # Evaluation with 2D keypoint coordinates\n                pred_instances.keypoints = keypoints_2d\n                pred_instances.transformed_keypoints = keypoints_2d\n\n            if 'keypoints_visible' not in pred_instances:\n                pred_instances.keypoints_visible = \\\n                    pred_instances.keypoint_scores\n\n            if output_keypoint_indices is not None:\n                # select output keypoints with given indices\n                num_keypoints = pred_instances.keypoints.shape[1]\n                for key, value in pred_instances.all_items():\n                    if key.startswith('keypoint'):\n                        pred_instances.set_field(\n                            value[:, output_keypoint_indices], key)\n\n            # add bbox information into pred_instances\n            pred_instances.bboxes = gt_instances.bboxes\n            pred_instances.bbox_scores = gt_instances.bbox_scores\n\n            data_sample.pred_instances = pred_instances\n\n            if pred_fields is not None:\n                if output_keypoint_indices is not None:\n                    # select output heatmap channels with keypoint indices\n                    # when the number of heatmap channel matches num_keypoints\n                    for key, value in pred_fields.all_items():\n                        if value.shape[0] != num_keypoints:\n                            continue\n                        pred_fields.set_field(value[output_keypoint_indices],\n                                              key)\n                data_sample.pred_fields = pred_fields\n\n        return batch_data_samples\n"
  },
  {
    "path": "projects/rtmpose3d/rtmpose3d/rtmw3d_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport numpy as np\nimport torch\nfrom mmcv.cnn import ConvModule\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor, nn\n\nfrom mmpose.codecs.utils import get_simcc_maximum as get_2d_simcc_maximum\nfrom mmpose.evaluation.functional import keypoint_mpjpe\nfrom mmpose.models.heads import BaseHead\nfrom mmpose.models.utils.rtmcc_block import RTMCCBlock, ScaleNorm\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, InstanceList, OptConfigType,\n                                 OptSampleList)\nfrom .utils import get_simcc_maximum\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass RTMW3DHead(BaseHead):\n    \"\"\"Top-down head introduced in RTMPose-Wholebody (2023).\n\n    Args:\n        in_channels (int | sequence[int]): Number of channels in the input\n            feature map.\n        out_channels (int): Number of channels in the output heatmap.\n        input_size (tuple): Size of input image in shape [w, h].\n        in_featuremap_size (int | sequence[int]): Size of input feature map.\n        simcc_split_ratio (float): Split ratio of pixels.\n            Default: 2.0.\n        final_layer_kernel_size (int): Kernel size of the convolutional layer.\n            Default: 1.\n        gau_cfg (Config): Config dict for the Gated Attention Unit.\n            Default: dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='ReLU',\n                use_rel_bias=False,\n                pos_enc=False).\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KLDiscretLoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n    \"\"\"\n\n    def __init__(\n        self,\n        in_channels: Union[int, Sequence[int]],\n        out_channels: int,\n        input_size: Tuple[int, int],\n        in_featuremap_size: Tuple[int, int],\n        simcc_split_ratio: float = 2.0,\n        final_layer_kernel_size: int = 1,\n        gau_cfg: ConfigType = dict(\n            hidden_dims=256,\n            s=128,\n            expansion_factor=2,\n            dropout_rate=0.,\n            drop_path=0.,\n            act_fn='ReLU',\n            use_rel_bias=False,\n            pos_enc=False),\n        loss: ConfigType = dict(type='KLDiscretLoss', use_target_weight=True),\n        decoder: OptConfigType = None,\n        init_cfg: OptConfigType = None,\n    ):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n        self.input_size = input_size\n        self.in_featuremap_size = in_featuremap_size\n        self.simcc_split_ratio = simcc_split_ratio\n\n        self.loss_module = nn.ModuleList()\n        if isinstance(loss, dict):\n            self.loss_module.append(MODELS.build(loss))\n        elif isinstance(loss, (list, tuple)):\n            for cfg in loss:\n                self.loss_module.append(MODELS.build(cfg))\n        else:\n            raise TypeError(f'loss_decode must be a dict or sequence of dict,\\\n                but got {type(loss)}')\n\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        if isinstance(in_channels, (tuple, list)):\n            raise ValueError(\n                f'{self.__class__.__name__} does not support selecting '\n                'multiple input features.')\n\n        # Define SimCC layers\n        flatten_dims = self.in_featuremap_size[0] * self.in_featuremap_size[1]\n\n        ps = 2\n        self.ps = nn.PixelShuffle(ps)\n        self.conv_dec = ConvModule(\n            in_channels // ps**2,\n            in_channels // 4,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            act_cfg=dict(type='ReLU'))\n\n        self.final_layer = ConvModule(\n            in_channels,\n            out_channels,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            act_cfg=dict(type='ReLU'))\n        self.final_layer2 = ConvModule(\n            in_channels // ps + in_channels // 4,\n            out_channels,\n            kernel_size=final_layer_kernel_size,\n            stride=1,\n            padding=final_layer_kernel_size // 2,\n            norm_cfg=dict(type='BN', requires_grad=True),\n            act_cfg=dict(type='ReLU'))\n\n        self.mlp = nn.Sequential(\n            ScaleNorm(flatten_dims),\n            nn.Linear(flatten_dims, gau_cfg['hidden_dims'] // 2, bias=False))\n\n        self.mlp2 = nn.Sequential(\n            ScaleNorm(flatten_dims * ps**2),\n            nn.Linear(\n                flatten_dims * ps**2, gau_cfg['hidden_dims'] // 2, bias=False))\n\n        W = int(self.input_size[0] * self.simcc_split_ratio)\n        H = int(self.input_size[1] * self.simcc_split_ratio)\n        D = int(self.input_size[2] * self.simcc_split_ratio)\n\n        self.gau = RTMCCBlock(\n            self.out_channels,\n            gau_cfg['hidden_dims'],\n            gau_cfg['hidden_dims'],\n            s=gau_cfg['s'],\n            expansion_factor=gau_cfg['expansion_factor'],\n            dropout_rate=gau_cfg['dropout_rate'],\n            drop_path=gau_cfg['drop_path'],\n            attn_type='self-attn',\n            act_fn=gau_cfg['act_fn'],\n            use_rel_bias=gau_cfg['use_rel_bias'],\n            pos_enc=gau_cfg['pos_enc'])\n\n        self.cls_x = nn.Linear(gau_cfg['hidden_dims'], W, bias=False)\n        self.cls_y = nn.Linear(gau_cfg['hidden_dims'], H, bias=False)\n        self.cls_z = nn.Linear(gau_cfg['hidden_dims'], D, bias=False)\n\n    def forward(self, feats: Tuple[Tensor,\n                                   Tensor]) -> Tuple[Tensor, Tensor, Tensor]:\n        \"\"\"Forward the network.\n\n        The input is the feature map extracted by backbone and the\n        output is the simcc representation.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            pred_x (Tensor): 1d representation of x.\n            pred_y (Tensor): 1d representation of y.\n        \"\"\"\n        # enc_b  n / 2, h, w\n        # enc_t  n,     h, w\n        enc_b, enc_t = feats\n\n        feats_t = self.final_layer(enc_t)\n        feats_t = torch.flatten(feats_t, 2)\n        feats_t = self.mlp(feats_t)\n\n        dec_t = self.ps(enc_t)\n        dec_t = self.conv_dec(dec_t)\n        enc_b = torch.cat([dec_t, enc_b], dim=1)\n\n        feats_b = self.final_layer2(enc_b)\n        feats_b = torch.flatten(feats_b, 2)\n        feats_b = self.mlp2(feats_b)\n\n        feats = torch.cat([feats_t, feats_b], dim=2)\n\n        feats = self.gau(feats)\n\n        pred_x = self.cls_x(feats)\n        pred_y = self.cls_y(feats)\n        pred_z = self.cls_z(feats)\n\n        return pred_x, pred_y, pred_z\n\n    def decode(self, batch_outputs: Union[Tensor,\n                                          Tuple[Tensor]]) -> InstanceList:\n        \"\"\"Decode keypoints from outputs.\n\n        Args:\n            batch_outputs (Tensor | Tuple[Tensor]): The network outputs of\n                a data batch\n\n        Returns:\n            List[InstanceData]: A list of InstanceData, each contains the\n            decoded pose information of the instances of one data sample.\n        \"\"\"\n\n        def _pack_and_call(args, func):\n            if not isinstance(args, tuple):\n                args = (args, )\n            return func(*args)\n\n        if self.decoder is None:\n            raise RuntimeError(\n                f'The decoder has not been set in {self.__class__.__name__}. '\n                'Please set the decoder configs in the init parameters to '\n                'enable head methods `head.predict()` and `head.decode()`')\n\n        batch_output_np = to_numpy(batch_outputs, unzip=True)\n        batch_keypoints = []\n        batch_keypoints_simcc = []\n        batch_scores = []\n        for outputs in batch_output_np:\n            keypoints, keypoints_simcc, scores = _pack_and_call(\n                outputs, self.decoder.decode)\n            batch_keypoints.append(keypoints)\n            batch_keypoints_simcc.append(keypoints_simcc)\n            batch_scores.append(scores)\n\n        preds = []\n        for keypoints, keypoints_simcc, scores in zip(batch_keypoints,\n                                                      batch_keypoints_simcc,\n                                                      batch_scores):\n            pred = InstanceData(\n                keypoints=keypoints,\n                keypoints_simcc=keypoints_simcc,\n                keypoint_scores=scores)\n            preds.append(pred)\n\n        return preds\n\n    def predict(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        test_cfg: OptConfigType = {},\n    ) -> InstanceList:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-stage features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            List[InstanceData]: The pose predictions, each contains\n            the following fields:\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n                - keypoint_x_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the x direction\n                - keypoint_y_labels (np.ndarray, optional): The predicted 1-D\n                    intensity distribution in the y direction\n        \"\"\"\n        x, y, z = self.forward(feats)\n\n        preds = self.decode((x, y, z))\n\n        if test_cfg.get('output_heatmaps', False):\n            raise NotImplementedError\n        else:\n            return preds\n\n    def loss(\n        self,\n        feats: Tuple[Tensor],\n        batch_data_samples: OptSampleList,\n        train_cfg: OptConfigType = {},\n    ) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\"\"\"\n\n        pred_x, pred_y, pred_z = self.forward(feats)\n\n        gt_x = torch.cat([\n            d.gt_instance_labels.keypoint_x_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        gt_y = torch.cat([\n            d.gt_instance_labels.keypoint_y_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        gt_z = torch.cat([\n            d.gt_instance_labels.keypoint_z_labels for d in batch_data_samples\n        ],\n                         dim=0)\n        keypoint_weights = torch.cat(\n            [\n                d.gt_instance_labels.keypoint_weights\n                for d in batch_data_samples\n            ],\n            dim=0,\n        )\n\n        weight_z = torch.cat(\n            [d.gt_instance_labels.weight_z for d in batch_data_samples],\n            dim=0,\n        )\n\n        with_z_labels = [\n            d.gt_instance_labels.with_z_label[0] for d in batch_data_samples\n        ]\n\n        N, K, _ = pred_x.shape\n        keypoint_weights_ = keypoint_weights.clone()\n        pred_simcc = (pred_x, pred_y, pred_z)\n        gt_simcc = (gt_x, gt_y, gt_z)\n\n        keypoint_weights = torch.cat([\n            keypoint_weights[None, ...], keypoint_weights[None, ...],\n            weight_z[None, ...]\n        ])\n\n        # calculate losses\n        losses = dict()\n        for i, loss_ in enumerate(self.loss_module):\n            if loss_.loss_name in ['loss_bone', 'loss_mpjpe']:\n                pred_coords = get_3d_coord(pred_x, pred_y, pred_z,\n                                           with_z_labels)\n                gt_coords = get_3d_coord(gt_x, gt_y, gt_z, with_z_labels)\n                loss = loss_(pred_coords, gt_coords, keypoint_weights_)\n            else:\n                loss = loss_(pred_simcc, gt_simcc, keypoint_weights)\n            losses[loss_.loss_name] = loss\n\n        # calculate accuracy\n        error = simcc_mpjpe(\n            output=to_numpy(pred_simcc),\n            target=to_numpy(gt_simcc),\n            simcc_split_ratio=self.simcc_split_ratio,\n            mask=to_numpy(keypoint_weights_) > 0,\n        )\n\n        mpjpe = torch.tensor(error, device=gt_x.device)\n        losses.update(mpjpe=mpjpe)\n\n        return losses\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(type='Normal', layer=['Conv2d'], std=0.001),\n            dict(type='Constant', layer='BatchNorm2d', val=1),\n            dict(type='Normal', layer=['Linear'], std=0.01, bias=0),\n        ]\n        return init_cfg\n\n\ndef simcc_mpjpe(output: Tuple[np.ndarray, np.ndarray, np.ndarray],\n                target: Tuple[np.ndarray, np.ndarray, np.ndarray],\n                simcc_split_ratio: float,\n                mask: np.ndarray,\n                thr: float = 0.05) -> float:\n    \"\"\"Calculate the pose accuracy of PCK for each individual keypoint and the\n    averaged accuracy across all keypoints from 3D SimCC.\n\n    Note:\n        - PCK metric measures accuracy of the localization of the body joints.\n        - The distances between predicted positions and the ground-truth ones\n          are typically normalized by the bounding box size.\n\n    Args:\n        output (Tuple[np.ndarray, np.ndarray, np.ndarray]): Model predicted\n            3D SimCC (x, y, z).\n        target (Tuple[np.ndarray, np.ndarray, np.ndarray]): Groundtruth\n            3D SimCC (x, y, z).\n        simcc_split_ratio (float): SimCC split ratio for recovering actual\n            coordinates.\n        mask (np.ndarray[N, K]): Visibility mask for the target. False for\n            invisible joints, and True for visible.\n        thr (float): Threshold for PCK calculation. Default 0.05.\n        normalize (Optional[np.ndarray[N, 3]]): Normalization factor for\n            H, W, and Depth.\n\n    Returns:\n        Tuple[np.ndarray, float, int]:\n        - np.ndarray[K]: Accuracy of each keypoint.\n        - float: Averaged accuracy across all keypoints.\n        - int: Number of valid keypoints.\n    \"\"\"\n    if len(output) == 3:\n        pred_x, pred_y, pred_z = output\n        gt_x, gt_y, gt_z = target\n        pred_coords, _ = get_simcc_maximum(pred_x, pred_y, pred_z)\n        gt_coords, _ = get_simcc_maximum(gt_x, gt_y, gt_z)\n\n    else:\n        pred_x, pred_y = output\n        gt_x, gt_y = target\n        pred_coords, _ = get_2d_simcc_maximum(pred_x, pred_y)\n        gt_coords, _ = get_2d_simcc_maximum(gt_x, gt_y)\n\n    pred_coords /= simcc_split_ratio\n    gt_coords /= simcc_split_ratio\n\n    return keypoint_mpjpe(pred_coords, gt_coords, mask)\n\n\ndef get_3d_coord(simcc_x, simcc_y, simcc_z, with_z_labels):\n    N, K, W = simcc_x.shape\n    # 过滤 z 轴\n    for i, with_z in enumerate(with_z_labels):\n        if not with_z:\n            simcc_z[i] = torch.zeros_like(simcc_z[i])\n    x_locs = simcc_x.reshape(N * K, -1).argmax(dim=1)\n    y_locs = simcc_y.reshape(N * K, -1).argmax(dim=1)\n    z_locs = simcc_z.reshape(N * K, -1).argmax(dim=1)\n\n    locs = torch.stack((x_locs, y_locs, z_locs),\n                       dim=-1).to(simcc_x).reshape(N, K, 3)\n    return locs\n"
  },
  {
    "path": "projects/rtmpose3d/rtmpose3d/simcc_3d_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Optional, Tuple, Union\n\nimport numpy as np\nfrom numpy import ndarray\n\nfrom mmpose.codecs.base import BaseKeypointCodec\nfrom mmpose.codecs.utils.refinement import refine_simcc_dark\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom .utils import get_simcc_maximum\n\n\n@KEYPOINT_CODECS.register_module()\nclass SimCC3DLabel(BaseKeypointCodec):\n    r\"\"\"Generate keypoint representation via \"SimCC\" approach.\n    See the paper: `SimCC: a Simple Coordinate Classification Perspective for\n    Human Pose Estimation`_ by Li et al (2022) for more details.\n    Old name: SimDR\n\n    We generate the SimCC label for 3D keypoint estimation.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n\n    Encoded:\n\n        - keypoint_x_labels (np.ndarray): The generated SimCC label for x-axis.\n        - keypoint_y_labels (np.ndarray): The generated SimCC label for y-axis.\n        - keypoint_z_labels (np.ndarray): The generated SimCC label for z-axis.\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Input image size in [w, h]\n        sigma (float | int | tuple): The sigma value in the Gaussian SimCC\n            label. Defaults to 6.0\n        simcc_split_ratio (float): The ratio of the label size to the input\n            size. For example, if the input width is ``w``, the x label size\n            will be :math:`w*simcc_split_ratio`. Defaults to 2.0\n        normalize (bool): Whether to normalize the heatmaps. Defaults to True.\n        use_dark (bool): Whether to use the DARK post processing. Defaults to\n            False.\n        root_index (int | tuple): The index of the root keypoint. Defaults to\n            0.\n        z_range (float): The range of the z-axis. Defaults to None.\n\n    .. _`SimCC: a Simple Coordinate Classification Perspective for Human Pose\n    Estimation`: https://arxiv.org/abs/2107.03332\n    \"\"\"\n\n    auxiliary_encode_keys = {'keypoints_3d'}\n\n    label_mapping_table = dict(\n        keypoint_x_labels='keypoint_x_labels',\n        keypoint_y_labels='keypoint_y_labels',\n        keypoint_z_labels='keypoint_z_labels',\n        keypoint_weights='keypoint_weights',\n        weight_z='weight_z',\n        with_z_label='with_z_label')\n\n    instance_mapping_table = dict(\n        bbox='bboxes',\n        bbox_score='bbox_scores',\n        bbox_scale='bbox_scales',\n        lifting_target='lifting_target',\n        lifting_target_visible='lifting_target_visible',\n        camera_param='camera_params',\n        root_z='root_z')\n\n    def __init__(self,\n                 input_size: Tuple[int, int, int],\n                 sigma: Union[float, int, Tuple[float]] = 6.0,\n                 simcc_split_ratio: float = 2.0,\n                 normalize: bool = True,\n                 use_dark: bool = False,\n                 root_index: Union[int, Tuple[int]] = 0,\n                 z_range: Optional[int] = None) -> None:\n        super().__init__()\n\n        self.input_size = input_size\n        self.simcc_split_ratio = simcc_split_ratio\n        self.normalize = normalize\n        self.use_dark = use_dark\n\n        if isinstance(sigma, (float, int)):\n            self.sigma = np.array([sigma, sigma, sigma])\n        else:\n            self.sigma = np.array(sigma)\n\n        self.root_index = list(root_index) if isinstance(\n            root_index, tuple) else [root_index]\n\n        # Mean value of the root z-axis of datasets\n        # These values are statistics from the training set\n        self.root_z = [5.14388]\n        self.z_range = z_range if z_range is not None else 2.1744869\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_3d: Optional[np.ndarray] = None,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n        lifting_target = [None]\n        root_z = self.root_z\n        with_z_label = False\n        if keypoints_3d is not None:\n            lifting_target = keypoints_3d.copy()\n            root_z = keypoints_3d[..., self.root_index, 2].mean(1)\n            keypoints_3d[..., 2] -= root_z\n            keypoints_z = (keypoints_3d[..., 2] / self.z_range + 1) * (\n                self.input_size[2] / 2)\n\n            keypoints_3d = np.concatenate([keypoints, keypoints_z[..., None]],\n                                          axis=-1)\n            x, y, z, keypoint_weights = self._generate_gaussian(\n                keypoints_3d, keypoints_visible)\n            weight_z = keypoint_weights\n            with_z_label = True\n        else:\n            if keypoints.shape != np.zeros([]).shape:\n                keypoints_z = np.ones(\n                    (keypoints.shape[0], keypoints.shape[1], 1),\n                    dtype=np.float32)\n                keypoints = np.concatenate([keypoints, keypoints_z], axis=-1)\n                x, y, z, keypoint_weights = self._generate_gaussian(\n                    keypoints, keypoints_visible)\n            else:\n                # placeholder for empty keypoints\n                x, y, z = np.zeros((3, 1), dtype=np.float32)\n                keypoint_weights = np.ones((1, ))\n            weight_z = np.zeros_like(keypoint_weights)\n            with_z_label = False\n\n        encoded = dict(\n            keypoint_x_labels=x,\n            keypoint_y_labels=y,\n            keypoint_z_labels=z,\n            lifting_target=lifting_target,\n            root_z=root_z,\n            keypoint_weights=keypoint_weights,\n            weight_z=weight_z,\n            with_z_label=[with_z_label])\n\n        return encoded\n\n    def decode(self, x: np.ndarray, y: np.ndarray, z: np.ndarray):\n        \"\"\"Decode SimCC labels into 3D keypoints.\n\n        Args:\n            encoded (Tuple[np.ndarray, np.ndarray]): SimCC labels for x-axis,\n            y-axis and z-axis in shape (N, K, Wx), (N, K, Wy) and (N, K, Wz)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded coordinates in shape (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K).\n                It usually represents the confidence of the keypoint prediction\n        \"\"\"\n\n        keypoints, scores = get_simcc_maximum(x, y, z)\n\n        # Unsqueeze the instance dimension for single-instance results\n        if keypoints.ndim == 2:\n            keypoints = keypoints[None, :]\n            scores = scores[None, :]\n\n        if self.use_dark:\n            x_blur = int((self.sigma[0] * 20 - 7) // 3)\n            y_blur = int((self.sigma[1] * 20 - 7) // 3)\n            z_blur = int((self.sigma[2] * 20 - 7) // 3)\n            x_blur -= int((x_blur % 2) == 0)\n            y_blur -= int((y_blur % 2) == 0)\n            z_blur -= int((z_blur % 2) == 0)\n            keypoints[:, :, 0] = refine_simcc_dark(keypoints[:, :, 0], x,\n                                                   x_blur)\n            keypoints[:, :, 1] = refine_simcc_dark(keypoints[:, :, 1], y,\n                                                   y_blur)\n            keypoints[:, :, 2] = refine_simcc_dark(keypoints[:, :, 2], z,\n                                                   z_blur)\n\n        keypoints /= self.simcc_split_ratio\n        keypoints_simcc = keypoints.copy()\n        keypoints_z = keypoints[..., 2:3]\n\n        keypoints[..., 2:3] = (keypoints_z /\n                               (self.input_size[-1] / 2) - 1) * self.z_range\n        return keypoints, keypoints_simcc, scores\n\n    def _map_coordinates(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None\n    ) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Mapping keypoint coordinates into SimCC space.\"\"\"\n\n        keypoints_split = keypoints.copy()\n        keypoints_split = np.around(keypoints_split * self.simcc_split_ratio)\n        keypoints_split = keypoints_split.astype(np.int64)\n        keypoint_weights = keypoints_visible.copy()\n\n        return keypoints_split, keypoint_weights\n\n    def _generate_gaussian(\n        self,\n        keypoints: np.ndarray,\n        keypoints_visible: Optional[np.ndarray] = None\n    ) -> Tuple[ndarray, ndarray, ndarray, ndarray]:\n        \"\"\"Encoding keypoints into SimCC labels with Gaussian Label Smoothing\n        strategy.\"\"\"\n\n        N, K, _ = keypoints.shape\n        w, h, d = self.input_size\n        W = np.around(w * self.simcc_split_ratio).astype(int)\n        H = np.around(h * self.simcc_split_ratio).astype(int)\n        D = np.around(d * self.simcc_split_ratio).astype(int)\n\n        keypoints_split, keypoint_weights = self._map_coordinates(\n            keypoints, keypoints_visible)\n\n        target_x = np.zeros((N, K, W), dtype=np.float32)\n        target_y = np.zeros((N, K, H), dtype=np.float32)\n        target_z = np.zeros((N, K, D), dtype=np.float32)\n\n        # 3-sigma rule\n        radius = self.sigma * 3\n\n        # xy grid\n        x = np.arange(0, W, 1, dtype=np.float32)\n        y = np.arange(0, H, 1, dtype=np.float32)\n        z = np.arange(0, D, 1, dtype=np.float32)\n\n        for n, k in product(range(N), range(K)):\n            # skip unlabled keypoints\n            if keypoints_visible[n, k] < 0.5:\n                continue\n\n            mu = keypoints_split[n, k]\n\n            # check that the gaussian has in-bounds part\n            left, top, near = mu - radius\n            right, bottom, far = mu + radius + 1\n\n            if left >= W or top >= H or near >= D or right < 0 or bottom < 0 or far < 0:  # noqa: E501\n                keypoint_weights[n, k] = 0\n                continue\n\n            mu_x, mu_y, mu_z = mu\n\n            target_x[n, k] = np.exp(-((x - mu_x)**2) / (2 * self.sigma[0]**2))\n            target_y[n, k] = np.exp(-((y - mu_y)**2) / (2 * self.sigma[1]**2))\n            target_z[n, k] = np.exp(-((z - mu_z)**2) / (2 * self.sigma[2]**2))\n\n        if self.normalize:\n            norm_value = self.sigma * np.sqrt(np.pi * 2)\n            target_x /= norm_value[0]\n            target_y /= norm_value[1]\n            target_z /= norm_value[2]\n\n        return target_x, target_y, target_z, keypoint_weights\n"
  },
  {
    "path": "projects/rtmpose3d/rtmpose3d/utils.py",
    "content": "from typing import Tuple\n\nimport numpy as np\n\n\ndef get_simcc_maximum(simcc_x: np.ndarray,\n                      simcc_y: np.ndarray,\n                      simcc_z: np.ndarray,\n                      apply_softmax: bool = False\n                      ) -> Tuple[np.ndarray, np.ndarray]:\n    \"\"\"Get maximum response location and value from simcc representations.\n\n    Note:\n        instance number: N\n        num_keypoints: K\n        heatmap height: H\n        heatmap width: W\n\n    Args:\n        encoded_keypoints (dict): encoded keypoints with simcc representations.\n        apply_softmax (bool): whether to apply softmax on the heatmap.\n            Defaults to False.\n\n    Returns:\n        tuple:\n        - locs (np.ndarray): locations of maximum heatmap responses in shape\n            (K, 2) or (N, K, 2)\n        - vals (np.ndarray): values of maximum heatmap responses in shape\n            (K,) or (N, K)\n    \"\"\"\n    assert isinstance(simcc_x, np.ndarray), 'simcc_x should be numpy.ndarray'\n    assert isinstance(simcc_y, np.ndarray), 'simcc_y should be numpy.ndarray'\n    assert isinstance(simcc_z, np.ndarray), 'simcc_z should be numpy.ndarray'\n    assert simcc_x.ndim == 2 or simcc_x.ndim == 3, (\n        f'Invalid shape {simcc_x.shape}')\n    assert simcc_y.ndim == 2 or simcc_y.ndim == 3, (\n        f'Invalid shape {simcc_y.shape}')\n    assert simcc_z.ndim == 2 or simcc_z.ndim == 3, (\n        f'Invalid shape {simcc_z.shape}')\n    assert simcc_x.ndim == simcc_y.ndim == simcc_z.ndim, (\n        f'{simcc_x.shape} != {simcc_y.shape} or {simcc_z.shape}')\n\n    if simcc_x.ndim == 3:\n        n, k, _ = simcc_x.shape\n        simcc_x = simcc_x.reshape(n * k, -1)\n        simcc_y = simcc_y.reshape(n * k, -1)\n        simcc_z = simcc_z.reshape(n * k, -1)\n    else:\n        n = None\n\n    if apply_softmax:\n        simcc_x = simcc_x - np.max(simcc_x, axis=1, keepdims=True)\n        simcc_y = simcc_y - np.max(simcc_y, axis=1, keepdims=True)\n        simcc_z = simcc_z - np.max(simcc_z, axis=1, keepdims=True)\n        ex, ey, ez = np.exp(simcc_x), np.exp(simcc_y), np.exp(simcc_z)\n        simcc_x = ex / np.sum(ex, axis=1, keepdims=True)\n        simcc_y = ey / np.sum(ey, axis=1, keepdims=True)\n        simcc_z = ez / np.sum(ez, axis=1, keepdims=True)\n\n    x_locs = np.argmax(simcc_x, axis=1)\n    y_locs = np.argmax(simcc_y, axis=1)\n    z_locs = np.argmax(simcc_z, axis=1)\n    locs = np.stack((x_locs, y_locs, z_locs), axis=-1).astype(np.float32)\n    max_val_x = np.amax(simcc_x, axis=1)\n    max_val_y = np.amax(simcc_y, axis=1)\n\n    mask = max_val_x > max_val_y\n    max_val_x[mask] = max_val_y[mask]\n    vals = max_val_x\n    locs[vals <= 0.] = -1\n\n    if n is not None:\n        locs = locs.reshape(n, k, 3)\n        vals = vals.reshape(n, k)\n\n    return locs, vals\n"
  },
  {
    "path": "projects/skps/README.md",
    "content": "# Simple Keypoints\n\n## Description\n\nAuthor： @2120140200@mail.nankai.edu.cn\n\nIt is a simple keypoints detector model. The model predict a score heatmap and an encoded location map.\nThe result in wflw achieves 3.94 NME.\n\n## Usage\n\n### Prerequisites\n\n- Python 3.7\n- PyTorch 1.6 or higher\n- [MIM](https://github.com/open-mmlab/mim) v0.33 or higher\n- [MMPose](https://github.com/open-mmlab/mmpose) v1.0.0rc0 or higher\n\nAll the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. In `example_project/` root directory, run the following line to add the current directory to `PYTHONPATH`:\n\n```shell\nexport PYTHONPATH=`pwd`:$PYTHONPATH\n```\n\n### Data Preparation\n\nPrepare the COCO dataset according to the [instruction](https://mmpose.readthedocs.io/en/dev-1.x/dataset_zoo/2d_body_keypoint.html#coco).\n\n### Training commands\n\n**To train with single GPU:**\n\n```shell\nmim train mmpose configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py\n```\n\n**To train with multiple GPUs:**\n\n```shell\nmim train mmpose configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py --launcher pytorch --gpus 8\n```\n\n**To train with multiple GPUs by slurm:**\n\n```shell\nmim train mmpose configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py --launcher slurm \\\n    --gpus 16 --gpus-per-node 8 --partition $PARTITION\n```\n\n### Testing commands\n\n**To test with single GPU:**\n\n```shell\nmim test mmpose configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py -C $CHECKPOINT\n```\n\n**To test with multiple GPUs:**\n\n```shell\nmim test mmpose configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py -C $CHECKPOINT --launcher pytorch --gpus 8\n```\n\n**To test with multiple GPUs by slurm:**\n\n```shell\nmim test mmpose configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py -C $CHECKPOINT --launcher slurm \\\n    --gpus 16 --gpus-per-node 8 --partition $PARTITION\n```\n\n## Results\n\nWFLW\n\n| Arch       | Input Size | NME<sub>*test*</sub> | NME<sub>*pose*</sub> | NME<sub>*illumination*</sub> | NME<sub>*occlusion*</sub> | NME<sub>*blur*</sub> | NME<sub>*makeup*</sub> | NME<sub>*expression*</sub> |    ckpt    |    log    |\n| :--------- | :--------: | :------------------: | :------------------: | :--------------------------: | :-----------------------: | :------------------: | :--------------------: | :------------------------: | :--------: | :-------: |\n| [skps](./configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py) |  256x256   |         3.88         |         6.60         |             3.81             |           4.57            |         4.44         |          3.75          |            4.13            | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/skps/best_NME_epoch_80.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/skps/20230522_142437.log) |\n\nCOFW\n\n| Arch                                                           | Input Size | NME  |                              ckpt                              |                              log                               |\n| :------------------------------------------------------------- | :--------: | :--: | :------------------------------------------------------------: | :------------------------------------------------------------: |\n| [skps](./configs/td-hm_hrnetv2-w18_skps-1xb16-160e_cofw-256x256.py) |  256x256   | 3.20 | [ckpt](https://download.openmmlab.com/mmpose/v1/projects/skps/best_NME_epoch_113.pth) | [log](https://download.openmmlab.com/mmpose/v1/projects/skps/20230524_074949.log) |\n"
  },
  {
    "path": "projects/skps/configs/td-hm_hrnetv2-w18_skps-1xb16-160e_cofw-256x256.py",
    "content": "custom_imports = dict(imports=['custom_codecs', 'models'])\n\n_base_ = ['mmpose::_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=160, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(type='AdamW', lr=2e-3, weight_decay=0.0005))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=160,\n        milestones=[80, 120],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='SKPSHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='SKPSHead',\n        in_channels=270,\n        out_channels=29,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        heatmap_loss=dict(type='AdaptiveWingLoss', use_target_weight=True),\n        offside_loss=dict(type='AdaptiveWingLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'COFWDataset'\ndata_mode = 'topdown'\ndata_root = 'data/cofw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=1),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='RandomBrightnessContrast', p=0.5),\n            dict(type='HueSaturationValue', p=0.5),\n            dict(type='GaussianBlur', p=0.5),\n            dict(type='GaussNoise', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=8,\n                max_height=0.2,\n                max_width=0.2,\n                min_holes=1,\n                min_height=0.1,\n                min_width=0.1,\n                p=0.5),\n        ]),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0.,\n        rotate_factor=45,\n        scale_factor=(0.75, 1.25),\n        scale_prob=0),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale', padding=1),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=16,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/cofw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/cofw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/skps/configs/td-hm_hrnetv2-w18_skps-1xb64-80e_wflw-256x256.py",
    "content": "custom_imports = dict(imports=['custom_codecs', 'models'])\n\n_base_ = ['mmpose::_base_/default_runtime.py']\n\n# runtime\ntrain_cfg = dict(max_epochs=80, val_interval=1)\n\n# optimizer\noptim_wrapper = dict(\n    optimizer=dict(type='AdamW', lr=2e-3, weight_decay=0.0005))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=80,\n        milestones=[40, 60],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='NME', rule='less', interval=1))\n\n# codec settings\ncodec = dict(\n    type='SKPSHeatmap', input_size=(256, 256), heatmap_size=(64, 64), sigma=2)\n\n# model settings\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='HRNet',\n        in_channels=3,\n        extra=dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(18, 36)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(18, 36, 72)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(18, 36, 72, 144),\n                multiscale_output=True),\n            upsample=dict(mode='bilinear', align_corners=False)),\n        init_cfg=dict(\n            type='Pretrained', checkpoint='open-mmlab://msra/hrnetv2_w18'),\n    ),\n    neck=dict(\n        type='FeatureMapProcessor',\n        concat=True,\n    ),\n    head=dict(\n        type='SKPSHead',\n        in_channels=270,\n        out_channels=98,\n        conv_out_channels=(270, ),\n        conv_kernel_sizes=(1, ),\n        heatmap_loss=dict(type='AdaptiveWingLoss', use_target_weight=True),\n        offside_loss=dict(type='AdaptiveWingLoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(\n        flip_test=True,\n        flip_mode='heatmap',\n        shift_heatmap=True,\n    ))\n\n# base dataset settings\ndataset_type = 'WFLWDataset'\ndata_mode = 'topdown'\ndata_root = './data/wflw/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(\n        type='Albumentation',\n        transforms=[\n            dict(type='RandomBrightnessContrast', p=0.5),\n            dict(type='HueSaturationValue', p=0.5),\n            dict(type='GaussianBlur', p=0.5),\n            dict(type='GaussNoise', p=0.1),\n            dict(\n                type='CoarseDropout',\n                max_holes=8,\n                max_height=0.2,\n                max_width=0.2,\n                min_holes=1,\n                min_height=0.1,\n                min_width=0.1,\n                p=0.5),\n        ]),\n    dict(\n        type='RandomBBoxTransform',\n        shift_prob=0.0,\n        rotate_factor=45,\n        scale_factor=(0.75, 1.25),\n        scale_prob=1.),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=64,\n    num_workers=4,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_train.json',\n        data_prefix=dict(img='images/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=32,\n    num_workers=4,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/face_landmarks_wflw_test.json',\n        data_prefix=dict(img='images/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='NME',\n    norm_mode='keypoint_distance',\n)\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/skps/custom_codecs/__init__.py",
    "content": "from .skps_heatmap import SKPSHeatmap\n\n__all__ = ['SKPSHeatmap']\n"
  },
  {
    "path": "projects/skps/custom_codecs/skps_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport numpy as np\n\nfrom mmpose.codecs.base import BaseKeypointCodec\nfrom mmpose.codecs.utils.gaussian_heatmap import \\\n    generate_unbiased_gaussian_heatmaps\nfrom mmpose.codecs.utils.post_processing import get_heatmap_maximum\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\n@KEYPOINT_CODECS.register_module()\nclass SKPSHeatmap(BaseKeypointCodec):\n    \"\"\"Generate heatmap the same with MSRAHeatmap, and produce offset map\n    within x and y directions.\n\n    Note:\n\n        - instance number: N\n        - keypoint number: K\n        - keypoint dimension: D\n        - image size: [w, h]\n        - heatmap size: [W, H]\n        - offset_map size: [W, H]\n\n    Encoded:\n\n        - heatmaps (np.ndarray): The generated heatmap in shape (K, H, W)\n            where [W, H] is the `heatmap_size`\n        - offset_maps (np.ndarray): The generated offset map in x and y\n            direction in shape (2K, H, W) where [W, H] is the\n            `offset_map_size`\n        - keypoint_weights (np.ndarray): The target weights in shape (N, K)\n\n    Args:\n        input_size (tuple): Image size in [w, h]\n        heatmap_size (tuple): Heatmap size in [W, H]\n        sigma (float): The sigma value of the Gaussian heatmap\n    \"\"\"\n\n    def __init__(self, input_size: Tuple[int, int],\n                 heatmap_size: Tuple[int, int], sigma: float) -> None:\n        super().__init__()\n        self.input_size = input_size\n        self.heatmap_size = heatmap_size\n        self.sigma = sigma\n        self.scale_factor = (np.array(input_size) /\n                             heatmap_size).astype(np.float32)\n\n        self.y_range, self.x_range = np.meshgrid(\n            np.arange(0, self.heatmap_size[1]),\n            np.arange(0, self.heatmap_size[0]),\n            indexing='ij')\n\n    def encode(self,\n               keypoints: np.ndarray,\n               keypoints_visible: Optional[np.ndarray] = None) -> dict:\n        \"\"\"Encode keypoints into heatmaps. Note that the original keypoint\n        coordinates should be in the input image space.\n\n        Args:\n            keypoints (np.ndarray): Keypoint coordinates in shape (N, K, D)\n            keypoints_visible (np.ndarray): Keypoint visibilities in shape\n                (N, K)\n\n        Returns:\n            dict:\n            - heatmaps (np.ndarray): The generated heatmap in shape\n                (K, H, W) where [W, H] is the `heatmap_size`\n            - offset_maps (np.ndarray): The generated offset maps in x and y\n                directions in shape (2*K, H, W) where [W, H] is the\n                `offset_map_size`\n            - keypoint_weights (np.ndarray): The target weights in shape\n                (N, K)\n        \"\"\"\n\n        assert keypoints.shape[0] == 1, (\n            f'{self.__class__.__name__} only support single-instance '\n            'keypoint encoding')\n\n        if keypoints_visible is None:\n            keypoints_visible = np.ones(keypoints.shape[:2], dtype=np.float32)\n\n        heatmaps, keypoint_weights = generate_unbiased_gaussian_heatmaps(\n            heatmap_size=self.heatmap_size,\n            keypoints=keypoints / self.scale_factor,\n            keypoints_visible=keypoints_visible,\n            sigma=self.sigma)\n\n        offset_maps = self.generate_offset_map(\n            heatmap_size=self.heatmap_size,\n            keypoints=keypoints / self.scale_factor,\n        )\n\n        encoded = dict(\n            heatmaps=heatmaps,\n            keypoint_weights=keypoint_weights[0],\n            displacements=offset_maps)\n\n        return encoded\n\n    def generate_offset_map(self, heatmap_size: Tuple[int, int],\n                            keypoints: np.ndarray):\n\n        N, K, _ = keypoints.shape\n\n        # batchsize 1\n        keypoints = keypoints[0]\n\n        # caution: there will be a broadcast which produce\n        # offside_x and offside_y with shape 64x64x98\n\n        offset_x = keypoints[:, 0] - np.expand_dims(self.x_range, axis=-1)\n        offset_y = keypoints[:, 1] - np.expand_dims(self.y_range, axis=-1)\n\n        offset_map = np.concatenate([offset_x, offset_y], axis=-1)\n\n        offset_map = np.transpose(offset_map, axes=[2, 0, 1])\n\n        return offset_map\n\n    def decode(self, encoded: np.ndarray,\n               offset_maps: np.ndarray) -> Tuple[np.ndarray, np.ndarray]:\n        \"\"\"Decode keypoint coordinates from heatmaps. The decoded keypoint\n        coordinates are in the input image space.\n\n        Args:\n            encoded (np.ndarray): Heatmaps in shape (K, H, W)\n\n        Returns:\n            tuple:\n            - keypoints (np.ndarray): Decoded keypoint coordinates in shape\n                (N, K, D)\n            - scores (np.ndarray): The keypoint scores in shape (N, K). It\n                usually represents the confidence of the keypoint prediction\n        \"\"\"\n        heatmaps = encoded.copy()\n\n        offset_maps = offset_maps.copy()\n\n        K, H, W = heatmaps.shape\n\n        keypoints, scores = get_heatmap_maximum(heatmaps)\n\n        offset_x = offset_maps[:K, ...]\n        offset_y = offset_maps[K:, ...]\n\n        keypoints_interger = keypoints.astype(np.int32)\n        keypoints_decimal = np.zeros_like(keypoints)\n\n        for i in range(K):\n            [x, y] = keypoints_interger[i]\n            if x < 0 or y < 0:\n                x = y = 0\n\n            # caution: torch tensor shape is nchw, so index should be i,y,x\n            keypoints_decimal[i][0] = x + offset_x[i, y, x]\n            keypoints_decimal[i][1] = y + offset_y[i, y, x]\n\n        # Restore the keypoint scale\n        keypoints_decimal = keypoints_decimal * self.scale_factor\n\n        return keypoints_decimal[None], scores[None]\n"
  },
  {
    "path": "projects/skps/models/__init__.py",
    "content": "from .skps_head import SKPSHead\n\n__all__ = ['SKPSHead']\n"
  },
  {
    "path": "projects/skps/models/skps_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom typing import Optional, Sequence, Tuple, Union\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import build_conv_layer\nfrom mmengine.model import ModuleDict\nfrom mmengine.structures import InstanceData\nfrom torch import Tensor\n\nfrom mmpose.evaluation.functional import pose_pck_accuracy\nfrom mmpose.models.heads.base_head import BaseHead\nfrom mmpose.models.utils.tta import flip_coordinates\nfrom mmpose.registry import KEYPOINT_CODECS, MODELS\nfrom mmpose.utils.tensor_utils import to_numpy\nfrom mmpose.utils.typing import (ConfigType, Features, InstanceList,\n                                 OptConfigType, OptSampleList, Predictions)\n\nOptIntSeq = Optional[Sequence[int]]\n\n\n@MODELS.register_module()\nclass SKPSHead(BaseHead):\n    \"\"\"DisEntangled Keypoint Regression head introduced in `Bottom-up human\n    pose estimation via disentangled keypoint regression`_ by Geng et al\n    (2021). The head is composed of a heatmap branch and a displacement branch.\n\n    Args:\n        in_channels (int | Sequence[int]): Number of channels in the input\n            feature map\n        out_channels (int): Number of channels in the output heatmap\n        conv_out_channels (Sequence[int], optional): The output channel number\n            of each intermediate conv layer. ``None`` means no intermediate\n            conv layer between deconv layers and the final conv layer.\n            Defaults to ``None``\n        conv_kernel_sizes (Sequence[int | tuple], optional): The kernel size\n            of each intermediate conv layer. Defaults to ``None``\n        final_layer (dict): Arguments of the final Conv2d layer.\n            Defaults to ``dict(kernel_size=1)``\n        loss (Config): Config of the keypoint loss. Defaults to use\n            :class:`KeypointMSELoss`\n        decoder (Config, optional): The decoder config that controls decoding\n            keypoint coordinates from the network output. Defaults to ``None``\n        init_cfg (Config, optional): Config to control the initialization. See\n            :attr:`default_init_cfg` for default settings\n\n\n    .. _`Bottom-up human pose estimation via disentangled keypoint regression`:\n        https://arxiv.org/abs/2104.02300\n    \"\"\"\n\n    _version = 2\n\n    def __init__(self,\n                 in_channels: Union[int, Sequence[int]],\n                 out_channels: int,\n                 conv_out_channels: OptIntSeq = None,\n                 conv_kernel_sizes: OptIntSeq = None,\n                 final_layer: dict = dict(kernel_size=1),\n                 heatmap_loss: ConfigType = dict(\n                     type='AdaptiveWingLoss', use_target_weight=True),\n                 offside_loss: ConfigType = dict(\n                     type='AdaptiveWingLoss', use_target_weight=True),\n                 decoder: OptConfigType = None,\n                 init_cfg: OptConfigType = None):\n\n        if init_cfg is None:\n            init_cfg = self.default_init_cfg\n\n        super().__init__(init_cfg)\n\n        self.in_channels = in_channels\n        self.out_channels = out_channels\n\n        if conv_out_channels:\n            if conv_kernel_sizes is None or len(conv_out_channels) != len(\n                    conv_kernel_sizes):\n                raise ValueError(\n                    '\"conv_out_channels\" and \"conv_kernel_sizes\" should '\n                    'be integer sequences with the same length. Got '\n                    f'mismatched lengths {conv_out_channels} and '\n                    f'{conv_kernel_sizes}')\n\n            self.conv_layers = self._make_conv_layers(\n                in_channels=in_channels,\n                layer_out_channels=conv_out_channels,\n                layer_kernel_sizes=conv_kernel_sizes)\n            in_channels = conv_out_channels[-1]\n        else:\n            self.conv_layers = nn.Identity()\n\n        if final_layer is not None:\n            cfg = dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=self.out_channels * 3,\n                kernel_size=1,\n                bias=True)\n            cfg.update(final_layer)\n            self.final_layer = build_conv_layer(cfg)\n        else:\n            self.final_layer = nn.Identity()\n\n        # build losses\n        self.loss_module = ModuleDict(\n            dict(\n                heatmap=MODELS.build(heatmap_loss),\n                offside=MODELS.build(offside_loss),\n            ))\n\n        # build decoder\n        if decoder is not None:\n            self.decoder = KEYPOINT_CODECS.build(decoder)\n        else:\n            self.decoder = None\n\n        # Register the hook to automatically convert old version state dicts\n        self._register_load_state_dict_pre_hook(self._load_state_dict_pre_hook)\n\n    @property\n    def default_init_cfg(self):\n        init_cfg = [\n            dict(type='Normal', layer=['Conv2d', 'ConvTranspose2d'], std=0.01),\n            dict(type='Constant', layer='BatchNorm2d', val=1)\n        ]\n        return init_cfg\n\n    def _make_conv_layers(self, in_channels: int,\n                          layer_out_channels: Sequence[int],\n                          layer_kernel_sizes: Sequence[int]) -> nn.Module:\n        \"\"\"Create convolutional layers by given parameters.\"\"\"\n\n        layers = []\n        for out_channels, kernel_size in zip(layer_out_channels,\n                                             layer_kernel_sizes):\n            padding = (kernel_size - 1) // 2\n            cfg = dict(\n                type='Conv2d',\n                in_channels=in_channels,\n                out_channels=out_channels,\n                kernel_size=kernel_size,\n                stride=1,\n                padding=padding)\n            layers.append(build_conv_layer(cfg))\n            layers.append(nn.BatchNorm2d(num_features=out_channels))\n            layers.append(nn.ReLU(inplace=True))\n            in_channels = out_channels\n\n        return nn.Sequential(*layers)\n\n    def forward(self, feats: Tuple[Tensor]) -> Tensor:\n        \"\"\"Forward the network. The input is multi scale feature maps and the\n        output is a tuple of heatmap and displacement.\n\n        Args:\n            feats (Tuple[Tensor]): Multi scale feature maps.\n\n        Returns:\n            Tuple[Tensor]: output heatmap and displacement.\n        \"\"\"\n        x = feats[-1]\n\n        x = self.conv_layers(x)\n        x = self.final_layer(x)\n        heatmaps = x[:, :self.out_channels, ...]\n        offside = x[:, self.out_channels:, ...]\n        return heatmaps, offside\n\n    def loss(self,\n             feats: Tuple[Tensor],\n             batch_data_samples: OptSampleList,\n             train_cfg: ConfigType = {}) -> dict:\n        \"\"\"Calculate losses from a batch of inputs and data samples.\n\n        Args:\n            feats (Tuple[Tensor]): The multi-stage features\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            train_cfg (dict): The runtime config for training process.\n                Defaults to {}\n\n        Returns:\n            dict: A dictionary of losses.\n        \"\"\"\n        pred_heatmaps, pred_offside = self.forward(feats)\n        gt_heatmaps = torch.stack(\n            [d.gt_fields.heatmaps for d in batch_data_samples])\n        keypoint_weights = torch.stack([\n            d.gt_instance_labels.keypoint_weights for d in batch_data_samples\n        ])\n        gt_offside = torch.stack(\n            [d.gt_fields.displacements for d in batch_data_samples])\n\n        # calculate losses\n        losses = dict()\n        heatmap_loss = self.loss_module['heatmap'](pred_heatmaps, gt_heatmaps,\n                                                   keypoint_weights)\n\n        n, c, h, w = pred_offside.size()\n        offside_loss_x = self.loss_module['offside'](pred_offside[:, :c // 2],\n                                                     gt_offside[:, :c // 2],\n                                                     gt_heatmaps)\n\n        offside_loss_y = self.loss_module['offside'](pred_offside[:, c // 2:],\n                                                     gt_offside[:, c // 2:],\n                                                     gt_heatmaps)\n\n        offside_loss = (offside_loss_x + offside_loss_y) / 2.\n\n        losses.update({\n            'loss/heatmap': heatmap_loss,\n            'loss/offside': offside_loss,\n        })\n        # calculate accuracy\n        if train_cfg.get('compute_acc', True):\n            _, avg_acc, _ = pose_pck_accuracy(\n                output=to_numpy(pred_heatmaps),\n                target=to_numpy(gt_heatmaps),\n                mask=to_numpy(keypoint_weights) > 0)\n\n            acc_pose = torch.tensor(avg_acc, device=gt_heatmaps.device)\n            losses.update(acc_pose=acc_pose)\n\n        return losses\n\n    def predict(self,\n                feats: Features,\n                batch_data_samples: OptSampleList,\n                test_cfg: ConfigType = {}) -> Predictions:\n        \"\"\"Predict results from features.\n\n        Args:\n            feats (Tuple[Tensor] | List[Tuple[Tensor]]): The multi-stage\n                features (or multiple multi-scale features in TTA)\n            batch_data_samples (List[:obj:`PoseDataSample`]): The batch\n                data samples\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n\n        Returns:\n            Union[InstanceList | Tuple[InstanceList | PixelDataList]]: If\n            ``test_cfg['output_heatmap']==True``, return both pose and heatmap\n            prediction; otherwise only return the pose prediction.\n\n            The pose prediction is a list of ``InstanceData``, each contains\n            the following fields:\n\n                - keypoints (np.ndarray): predicted keypoint coordinates in\n                    shape (num_instances, K, D) where K is the keypoint number\n                    and D is the keypoint dimension\n                - keypoint_scores (np.ndarray): predicted keypoint scores in\n                    shape (num_instances, K)\n        \"\"\"\n\n        flip_test = test_cfg.get('flip_test', False)\n        metainfo = batch_data_samples[0].metainfo\n\n        if flip_test:\n            assert isinstance(feats, list) and len(feats) == 2\n            flip_indices = metainfo['flip_indices']\n            _feat, _feat_flip = feats\n            _heatmaps, _displacements = self.forward(_feat)\n            _heatmaps_flip, _displacements_flip = self.forward(_feat_flip)\n\n            batch_size = _heatmaps.shape[0]\n\n            _heatmaps = to_numpy(_heatmaps)\n            _displacements = to_numpy(_displacements)\n\n            _heatmaps_flip = to_numpy(_heatmaps_flip)\n            _displacements_flip = to_numpy(_displacements_flip)\n            preds = []\n            for b in range(batch_size):\n                _keypoints, _keypoint_scores = self.decoder.decode(\n                    _heatmaps[b], _displacements[b])\n\n                _keypoints_flip, _keypoint_scores_flip = self.decoder.decode(\n                    _heatmaps_flip[b], _displacements_flip[b])\n\n                # flip the kps coords\n                real_w = self.decoder.input_size[0]\n                real_h = self.decoder.input_size[1]\n\n                # the coordinate range is 0-255  for 256x256 input size\n                _keypoints_flip /= (real_w - 1)\n                _keypoints_flip = flip_coordinates(\n                    _keypoints_flip,\n                    flip_indices=flip_indices,\n                    shift_coords=False,\n                    input_size=((real_w - 1), (real_h - 1)))\n                _keypoints_flip *= (real_w - 1)\n\n                _keypoints = (_keypoints + _keypoints_flip) / 2.\n                # pack outputs\n                preds.append(InstanceData(keypoints=_keypoints))\n            return preds\n\n        else:\n            batch_heatmaps, batch_displacements = self.forward(feats)\n\n            preds = self.decode(batch_heatmaps, batch_displacements, test_cfg,\n                                metainfo)\n\n            return preds\n\n    def decode(self,\n               heatmaps: Tuple[Tensor],\n               offside: Tuple[Tensor],\n               test_cfg: ConfigType = {},\n               metainfo: dict = {}) -> InstanceList:\n        \"\"\"Decode keypoints from outputs.\n\n        Args:\n            heatmaps (Tuple[Tensor]): The output heatmaps inferred from one\n                image or multi-scale images.\n            offside (Tuple[Tensor]): The output displacement fields\n                inferred from one image or multi-scale images.\n            test_cfg (dict): The runtime config for testing process. Defaults\n                to {}\n            metainfo (dict): The metainfo of test dataset. Defaults to {}\n\n        Returns:\n            List[InstanceData]: A list of InstanceData, each contains the\n                decoded pose information of the instances of one data sample.\n        \"\"\"\n\n        if self.decoder is None:\n            raise RuntimeError(\n                f'The decoder has not been set in {self.__class__.__name__}. '\n                'Please set the decoder configs in the init parameters to '\n                'enable head methods `head.predict()` and `head.decode()`')\n\n        preds = []\n        batch_size = heatmaps.shape[0]\n\n        heatmaps = to_numpy(heatmaps)\n        offside = to_numpy(offside)\n\n        for b in range(batch_size):\n            keypoints, keypoint_scores = self.decoder.decode(\n                heatmaps[b], offside[b])\n\n            # pack outputs\n            preds.append(\n                InstanceData(\n                    keypoints=keypoints, keypoint_scores=keypoint_scores))\n\n        return preds\n\n    def _load_state_dict_pre_hook(self, state_dict, prefix, local_meta, *args,\n                                  **kwargs):\n        \"\"\"A hook function to convert old-version state dict of\n        :class:`DeepposeRegressionHead` (before MMPose v1.0.0) to a\n        compatible format of :class:`RegressionHead`.\n\n        The hook will be automatically registered during initialization.\n        \"\"\"\n        version = local_meta.get('version', None)\n        if version and version >= self._version:\n            return\n\n        # convert old-version state dict\n        keys = list(state_dict.keys())\n        for _k in keys:\n            if not _k.startswith(prefix):\n                continue\n            v = state_dict.pop(_k)\n            k = _k[len(prefix):]\n            # In old version, \"final_layer\" includes both intermediate\n            # conv layers (new \"conv_layers\") and final conv layers (new\n            # \"final_layer\").\n            #\n            # If there is no intermediate conv layer, old \"final_layer\" will\n            # have keys like \"final_layer.xxx\", which should be still\n            # named \"final_layer.xxx\";\n            #\n            # If there are intermediate conv layers, old \"final_layer\"  will\n            # have keys like \"final_layer.n.xxx\", where the weights of the last\n            # one should be renamed \"final_layer.xxx\", and others should be\n            # renamed \"conv_layers.n.xxx\"\n            k_parts = k.split('.')\n            if k_parts[0] == 'final_layer':\n                if len(k_parts) == 3:\n                    assert isinstance(self.conv_layers, nn.Sequential)\n                    idx = int(k_parts[1])\n                    if idx < len(self.conv_layers):\n                        # final_layer.n.xxx -> conv_layers.n.xxx\n                        k_new = 'conv_layers.' + '.'.join(k_parts[1:])\n                    else:\n                        # final_layer.n.xxx -> final_layer.xxx\n                        k_new = 'final_layer.' + k_parts[2]\n                else:\n                    # final_layer.xxx remains final_layer.xxx\n                    k_new = k\n            else:\n                k_new = k\n\n            state_dict[prefix + k_new] = v\n"
  },
  {
    "path": "projects/uniformer/README.md",
    "content": "# Pose Estion with UniFormer\n\nThis project implements a topdown heatmap based human pose estimator, utilizing the approach outlined in **UniFormer: Unifying Convolution and Self-attention for Visual Recognition** (TPAMI 2023) and **UniFormer: Unified Transformer for Efficient Spatiotemporal Representation Learning** (ICLR 2022).\n\n<img src=\"https://raw.githubusercontent.com/Sense-X/UniFormer/main/figures/framework.png\" alt><br>\n\n<img src=\"https://raw.githubusercontent.com/Sense-X/UniFormer/main/figures/dense_adaption.jpg\" alt><br>\n\n## Usage\n\n### Preparation\n\n1. Setup Development Environment\n\n- Python 3.7 or higher\n- PyTorch 1.6 or higher\n- [MMEngine](https://github.com/open-mmlab/mmengine) v0.6.0 or higher\n- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 or higher\n- [MMDetection](https://github.com/open-mmlab/mmdetection) v3.0.0rc6 or higher\n- [MMPose](https://github.com/open-mmlab/mmpose) v1.0.0rc1 or higher\n\nAll the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. **In `uniformer/` root directory**, run the following line to add the current directory to `PYTHONPATH`:\n\n```shell\nexport PYTHONPATH=`pwd`:$PYTHONPATH\n```\n\n2. Download Pretrained Weights\n\nTo either run inferences or train on the `uniformer pose estimation` project, you have to download the original Uniformer pretrained weights on the ImageNet1k dataset and the weights trained for the downstream pose estimation task. The original ImageNet1k weights are hosted on SenseTime's [huggingface repository](https://huggingface.co/Sense-X/uniformer_image), and the downstream pose estimation task weights are hosted either on Google Drive or Baiduyun. We have uploaded them to the OpenMMLab download URLs, allowing users to use them without burden. For example, you can take a look at [`td-hm_uniformer-b-8xb128-210e_coco-256x192.py`](./configs/td-hm_uniformer-b-8xb128-210e_coco-256x192.py#62), the corresponding pretrained weight URL is already here and when the training or testing process starts, the weight will be automatically downloaded to your device. For the downstream task weights, you can get their URLs from the [benchmark result table](#results).\n\n### Inference\n\nWe have provided a [inferencer_demo.py](../../demo/inferencer_demo.py) with which developers can utilize to run quick inference demos. Here is a basic demonstration:\n\n```shell\npython demo/inferencer_demo.py $INPUTS \\\n    --pose2d $CONFIG --pose2d-weights $CHECKPOINT \\\n    [--show] [--vis-out-dir $VIS_OUT_DIR] [--pred-out-dir $PRED_OUT_DIR]\n```\n\nFor more information on using the inferencer, please see [this document](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html#out-of-the-box-inferencer).\n\nHere's an example code:\n\n```shell\npython demo/inferencer_demo.py tests/data/coco/000000000785.jpg \\\n    --pose2d projects/uniformer/configs/td-hm_uniformer-s-8xb128-210e_coco-256x192.py \\\n    --pose2d-weights https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_256x192_global_small-d4a7fdac_20230724.pth \\\n    --vis-out-dir vis_results\n```\n\nThen you will find the demo result in `vis_results` folder, and it may be similar to this:\n\n<img src=\"https://github.com/open-mmlab/mmpose/assets/7219519/6f939457-d714-477a-9cc7-27aa98acc4af\" height=\"360px\" alt><br>\n\n### Training and Testing\n\n1. Data Preparation\n\nPrepare the COCO dataset according to the [instruction](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco).\n\n2. To Train and Test with Single GPU:\n\n```shell\npython tools/test.py $CONFIG --auto-scale-lr\n```\n\n```shell\npython tools/test.py $CONFIG $CHECKPOINT\n```\n\n3. To Train and Test with Multiple GPUs:\n\n```shell\nbash tools/dist_train.sh $CONFIG $NUM_GPUs --amp\n```\n\n```shell\nbash tools/dist_test.sh $CONFIG $CHECKPOINT $NUM_GPUs --amp\n```\n\n## Results\n\nHere is the testing results on COCO val2017:\n\n|                                Model                                | Input Size |  AP  | AP<sup>50</sup> | AP<sup>75</sup> |  AR  | AR<sup>50</sup> |                                Download                                |\n| :-----------------------------------------------------------------: | :--------: | :--: | :-------------: | :-------------: | :--: | :-------------: | :--------------------------------------------------------------------: |\n| [UniFormer-S](./configs/td-hm_uniformer-s-8xb128-210e_coco-256x192.py) |  256x192   | 74.0 |      90.2       |      82.1       | 79.5 |      94.1       | [model](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_256x192_global_small-d4a7fdac_20230724.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_256x192_global_small-d4a7fdac_20230724.log.json) |\n| [UniFormer-S](./configs/td-hm_uniformer-s-8xb128-210e_coco-384x288.py) |  384x288   | 75.9 |      90.6       |      83.0       | 81.0 |      94.3       | [model](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_384x288_global_small-7a613f78_20230724.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_384x288_global_small-7a613f78_20230724.log.json) |\n| [UniFormer-S](./configs/td-hm_uniformer-s-8xb64-210e_coco-448x320.py) |  448x320   | 76.2 |      90.6       |      83.2       | 81.4 |      94.4       | [model](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_448x320_global_small-18b760de_20230724.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_448x320_global_small-18b760de_20230724.log.json) |\n| [UniFormer-B](./configs/td-hm_uniformer-b-8xb128-210e_coco-256x192.py) |  256x192   | 75.0 |      90.5       |      83.0       | 80.4 |      94.2       | [model](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_256x192_global_base-1713bcd4_20230724.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_256x192_global_base-1713bcd4_20230724.log.json) |\n| [UniFormer-B](./configs/td-hm_uniformer-b-8xb32-210e_coco-384x288.py) |  384x288   | 76.7 |      90.8       |      84.1       | 81.9 |      94.6       | [model](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_384x288_global_base-c650da38_20230724.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_384x288_global_base-c650da38_20230724.log.json) |\n| [UniFormer-B](./configs/td-hm_uniformer-b-8xb32-210e_coco-448x320.py) |  448x320   | 77.4 |      91.0       |      84.4       | 82.5 |      94.9       | [model](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_448x320_global_base-a05c185f_20230724.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/uniformer/top_down_448x320_global_base-a05c185f_20230724.log.json) |\n\nHere is the testing results on COCO val 2017 from the official UniFormer Pose Estimation repository for comparison:\n\n| Backbone    | Input Size | AP   | AP<sup>50</sup> | AP<sup>75</sup> | AR<sup>M</sup> | AR<sup>L</sup> | AR   | Model                                                     | Log                                                      |\n| :---------- | :--------- | :--- | :-------------- | :-------------- | :------------- | :------------- | :--- | :-------------------------------------------------------- | :------------------------------------------------------- |\n| UniFormer-S | 256x192    | 74.0 | 90.3            | 82.2            | 66.8           | 76.7           | 79.5 | [google](https://drive.google.com/file/d/162R0JuTpf3gpLe1IK6oxRoQK7JSj4ylx/view?usp=sharing) | [google](https://drive.google.com/file/d/15j40u97Db6TA2gMHdn0yFEsDFb5SMBy4/view?usp=sharing) |\n| UniFormer-S | 384x288    | 75.9 | 90.6            | 83.4            | 68.6           | 79.0           | 81.4 | [google](https://drive.google.com/file/d/163vuFkpcgVOthC05jCwjGzo78Nr0eikW/view?usp=sharing) | [google](https://drive.google.com/file/d/15X9M_5cq9RQMgs64Yn9YvV5k5f0zOBHo/view?usp=sharing) |\n| UniFormer-S | 448x320    | 76.2 | 90.6            | 83.2            | 68.6           | 79.4           | 81.4 | [google](https://drive.google.com/file/d/165nQRsT58SXJegcttksHwDn46Fme5dGX/view?usp=sharing) | [google](https://drive.google.com/file/d/15IJjSWp4R5OybMdV2CZEUx_TwXdTMOee/view?usp=sharing) |\n| UniFormer-B | 256x192    | 75.0 | 90.6            | 83.0            | 67.8           | 77.7           | 80.4 | [google](https://drive.google.com/file/d/15tzJaRyEzyWp2mQhpjDbBzuGoyCaJJ-2/view?usp=sharing) | [google](https://drive.google.com/file/d/15jJyTPcJKj_id0PNdytloqt7yjH2M8UR/view?usp=sharing) |\n| UniFormer-B | 384x288    | 76.7 | 90.8            | 84.0            | 69.3           | 79.7           | 81.4 | [google](https://drive.google.com/file/d/15qtUaOR_C7-vooheJE75mhA9oJQt3gSx/view?usp=sharing) | [google](https://drive.google.com/file/d/15L1Uxo_uRSMlGnOvWzAzkJLKX6Qh_xNw/view?usp=sharing) |\n| UniFormer-B | 448x320    | 77.4 | 91.1            | 84.4            | 70.2           | 80.6           | 82.5 | [google](https://drive.google.com/file/d/156iNxetiCk8JJz41aFDmFh9cQbCaMk3D/view?usp=sharing) | [google](https://drive.google.com/file/d/15aRpZc2Tie5gsn3_l-aXto1MrC9wyzMC/view?usp=sharing) |\n\nNote:\n\n1. All the original models are pretrained on ImageNet-1K without Token Labeling and Layer Scale, as mentioned in the [official README](https://github.com/Sense-X/UniFormer/tree/main/pose_estimation) . The official team has confirmed that **Token labeling can largely improve the performance of the downstream tasks**. Developers can utilize the implementation by themselves.\n2. The original implementation did not include the **freeze BN in the backbone**. The official team has confirmed that this can improve the performance as well.\n3. To avoid running out of memory, developers can use `torch.utils.checkpoint` in the `config.py` by setting `use_checkpoint=True` and `checkpoint_num=[0, 0, 2, 0] # index for using checkpoint in every stage`\n4. We warmly welcome any contributions if you can successfully reproduce the results from the paper!\n\n## Citation\n\nIf this project benefits your work, please kindly consider citing the original papers:\n\n```bibtex\n@misc{li2022uniformer,\n      title={UniFormer: Unifying Convolution and Self-attention for Visual Recognition},\n      author={Kunchang Li and Yali Wang and Junhao Zhang and Peng Gao and Guanglu Song and Yu Liu and Hongsheng Li and Yu Qiao},\n      year={2022},\n      eprint={2201.09450},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n\n```bibtex\n@misc{li2022uniformer,\n      title={UniFormer: Unified Transformer for Efficient Spatiotemporal Representation Learning},\n      author={Kunchang Li and Yali Wang and Peng Gao and Guanglu Song and Yu Liu and Hongsheng Li and Yu Qiao},\n      year={2022},\n      eprint={2201.04676},\n      archivePrefix={arXiv},\n      primaryClass={cs.CV}\n}\n```\n"
  },
  {
    "path": "projects/uniformer/configs/td-hm_uniformer-b-8xb128-210e_coco-256x192.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\ncustom_imports = dict(imports='projects.uniformer.models')\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# enable DDP training when pretrained model is used\nfind_unused_parameters = True\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\n# hooks\ndefault_hooks = dict(\n    checkpoint=dict(save_best='coco/AP', rule='greater', interval=5))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(192, 256), heatmap_size=(48, 64), sigma=2)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='UniFormer',\n        embed_dims=[64, 128, 320, 512],\n        depths=[5, 8, 20, 7],\n        head_dim=64,\n        drop_path_rate=0.4,\n        use_checkpoint=False,  # whether use torch.utils.checkpoint\n        use_window=False,  # whether use window MHRA\n        use_hybrid=False,  # whether use hybrid MHRA\n        init_cfg=dict(\n            # Set the path to pretrained backbone here\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'uniformer/uniformer_base_in1k.pth'  # noqa\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        final_layer=dict(kernel_size=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=256,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/uniformer/configs/td-hm_uniformer-b-8xb32-210e_coco-384x288.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\ncustom_imports = dict(imports='projects.uniformer.models')\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# enable DDP training when pretrained model is used\nfind_unused_parameters = True\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(288, 384), heatmap_size=(72, 96), sigma=3)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='UniFormer',\n        embed_dims=[64, 128, 320, 512],\n        depths=[5, 8, 20, 7],\n        head_dim=64,\n        drop_path_rate=0.4,\n        use_checkpoint=False,  # whether use torch.utils.checkpoint\n        use_window=False,  # whether use window MHRA\n        use_hybrid=False,  # whether use hybrid MHRA\n        init_cfg=dict(\n            # Set the path to pretrained backbone here\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'uniformer/uniformer_base_in1k.pth'  # noqa\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        final_layer=dict(kernel_size=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=128,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=256,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/uniformer/configs/td-hm_uniformer-b-8xb32-210e_coco-448x320.py",
    "content": "_base_ = ['mmpose::_base_/default_runtime.py']\n\ncustom_imports = dict(imports='projects.uniformer.models')\n\n# runtime\ntrain_cfg = dict(max_epochs=210, val_interval=10)\n\n# enable DDP training when pretrained model is used\nfind_unused_parameters = True\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=5e-4,\n))\n\n# learning policy\nparam_scheduler = [\n    dict(\n        type='LinearLR', begin=0, end=500, start_factor=0.001,\n        by_epoch=False),  # warm-up\n    dict(\n        type='MultiStepLR',\n        begin=0,\n        end=210,\n        milestones=[170, 200],\n        gamma=0.1,\n        by_epoch=True)\n]\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=256)\n\n# hooks\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# codec settings\ncodec = dict(\n    type='MSRAHeatmap', input_size=(320, 448), heatmap_size=(80, 112), sigma=3)\n\n# model settings\nnorm_cfg = dict(type='SyncBN', requires_grad=True)\nmodel = dict(\n    type='TopdownPoseEstimator',\n    data_preprocessor=dict(\n        type='PoseDataPreprocessor',\n        mean=[123.675, 116.28, 103.53],\n        std=[58.395, 57.12, 57.375],\n        bgr_to_rgb=True),\n    backbone=dict(\n        type='UniFormer',\n        embed_dims=[64, 128, 320, 512],\n        depths=[5, 8, 20, 7],\n        head_dim=64,\n        drop_path_rate=0.55,\n        use_checkpoint=False,  # whether use torch.utils.checkpoint\n        use_window=False,  # whether use window MHRA\n        use_hybrid=False,  # whether use hybrid MHRA\n        init_cfg=dict(\n            # Set the path to pretrained backbone here\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'uniformer/uniformer_base_in1k.pth'  # noqa\n        )),\n    head=dict(\n        type='HeatmapHead',\n        in_channels=512,\n        out_channels=17,\n        final_layer=dict(kernel_size=1),\n        loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        decoder=codec),\n    test_cfg=dict(flip_test=True, flip_mode='heatmap', shift_heatmap=True))\n\n# base dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'topdown'\ndata_root = 'data/coco/'\n\n# pipelines\ntrain_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='RandomFlip', direction='horizontal'),\n    dict(type='RandomHalfBody'),\n    dict(type='RandomBBoxTransform'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='GenerateTarget', encoder=codec),\n    dict(type='PackPoseInputs')\n]\nval_pipeline = [\n    dict(type='LoadImage'),\n    dict(type='GetBBoxCenterScale'),\n    dict(type='TopdownAffine', input_size=codec['input_size']),\n    dict(type='PackPoseInputs')\n]\n\n# data loaders\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=2,\n    persistent_workers=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        pipeline=train_pipeline,\n    ))\nval_dataloader = dict(\n    batch_size=256,\n    num_workers=2,\n    persistent_workers=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False, round_up=False),\n    dataset=dict(\n        type=dataset_type,\n        data_root=data_root,\n        data_mode=data_mode,\n        ann_file='annotations/person_keypoints_val2017.json',\n        bbox_file='data/coco/person_detection_results/'\n        'COCO_val2017_detections_AP_H_56_person.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=val_pipeline,\n    ))\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json')\ntest_evaluator = val_evaluator\n"
  },
  {
    "path": "projects/uniformer/configs/td-hm_uniformer-s-8xb128-210e_coco-256x192.py",
    "content": "_base_ = ['./td-hm_uniformer-b-8xb128-210e_coco-256x192.py']\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\nmodel = dict(\n    backbone=dict(\n        depths=[3, 4, 8, 3],\n        drop_path_rate=0.2,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'uniformer/uniformer_small_in1k.pth'  # noqa\n        )))\n\ntrain_dataloader = dict(batch_size=32)\nval_dataloader = dict(batch_size=256)\n"
  },
  {
    "path": "projects/uniformer/configs/td-hm_uniformer-s-8xb128-210e_coco-384x288.py",
    "content": "_base_ = ['./td-hm_uniformer-b-8xb32-210e_coco-384x288.py']\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=2e-3,\n))\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=1024)\n\nmodel = dict(\n    backbone=dict(\n        depths=[3, 4, 8, 3],\n        drop_path_rate=0.2,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'uniformer/uniformer_small_in1k.pth'  # noqa\n        )))\n\ntrain_dataloader = dict(batch_size=128)\nval_dataloader = dict(batch_size=256)\n"
  },
  {
    "path": "projects/uniformer/configs/td-hm_uniformer-s-8xb64-210e_coco-448x320.py",
    "content": "_base_ = ['./td-hm_uniformer-b-8xb32-210e_coco-448x320.py']\n\n# optimizer\noptim_wrapper = dict(optimizer=dict(\n    type='Adam',\n    lr=1.0e-3,\n))\n\n# automatically scaling LR based on the actual training batch size\nauto_scale_lr = dict(base_batch_size=512)\n\nmodel = dict(\n    backbone=dict(\n        depths=[3, 4, 8, 3],\n        drop_path_rate=0.2,\n        init_cfg=dict(\n            type='Pretrained',\n            checkpoint='https://download.openmmlab.com/mmpose/v1/projects/'\n            'uniformer/uniformer_small_in1k.pth')))\n\ntrain_dataloader = dict(batch_size=64)\nval_dataloader = dict(batch_size=256)\n"
  },
  {
    "path": "projects/uniformer/models/__init__.py",
    "content": "from .uniformer import *  # noqa\n"
  },
  {
    "path": "projects/uniformer/models/uniformer.py",
    "content": "from collections import OrderedDict\nfrom functools import partial\nfrom typing import Dict, List, Optional, Union\n\nimport torch\nimport torch.nn as nn\nimport torch.nn.functional as F\nfrom mmcv.cnn.bricks.transformer import build_dropout\nfrom mmengine.model import BaseModule\nfrom mmengine.model.weight_init import trunc_normal_\nfrom mmengine.runner import checkpoint, load_checkpoint\nfrom mmengine.utils import to_2tuple\n\nfrom mmpose.models.backbones.base_backbone import BaseBackbone\nfrom mmpose.registry import MODELS\nfrom mmpose.utils import get_root_logger\n\n\nclass Mlp(BaseModule):\n    \"\"\"Multilayer perceptron.\n\n    Args:\n        in_features (int): Number of input features.\n        hidden_features (int): Number of hidden features.\n            Defaults to None.\n        out_features (int): Number of output features.\n            Defaults to None.\n        drop (float): Dropout rate. Defaults to 0.0.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 in_features: int,\n                 hidden_features: int = None,\n                 out_features: int = None,\n                 drop_rate: float = 0.,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Linear(in_features, hidden_features)\n        self.act = nn.GELU()\n        self.fc2 = nn.Linear(hidden_features, out_features)\n        self.drop = nn.Dropout(drop_rate)\n\n    def forward(self, x):\n        x = self.act(self.fc1(x))\n        x = self.fc2(self.drop(x))\n        x = self.drop(x)\n        return x\n\n\nclass CMlp(BaseModule):\n    \"\"\"Multilayer perceptron via convolution.\n\n    Args:\n        in_features (int): Number of input features.\n        hidden_features (int): Number of hidden features.\n            Defaults to None.\n        out_features (int): Number of output features.\n            Defaults to None.\n        drop (float): Dropout rate. Defaults to 0.0.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 in_features: int,\n                 hidden_features: int = None,\n                 out_features: int = None,\n                 drop_rate: float = 0.,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        out_features = out_features or in_features\n        hidden_features = hidden_features or in_features\n        self.fc1 = nn.Conv2d(in_features, hidden_features, kernel_size=1)\n        self.act = nn.GELU()\n        self.fc2 = nn.Conv2d(hidden_features, out_features, kernel_size=1)\n        self.drop = nn.Dropout(drop_rate)\n\n    def forward(self, x):\n        x = self.act(self.fc1(x))\n        x = self.fc2(self.drop(x))\n        x = self.drop(x)\n        return x\n\n\nclass CBlock(BaseModule):\n    \"\"\"Convolution Block.\n\n    Args:\n        embed_dim (int): Number of input features.\n        mlp_ratio (float): Ratio of mlp hidden dimension\n            to embedding dimension. Defaults to 4.\n        drop (float): Dropout rate.\n            Defaults to 0.0.\n        drop_paths (float): Stochastic depth rates.\n            Defaults to 0.0.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dim: int,\n                 mlp_ratio: float = 4.,\n                 drop_rate: float = 0.,\n                 drop_path_rate: float = 0.,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        self.pos_embed = nn.Conv2d(\n            embed_dim, embed_dim, 3, padding=1, groups=embed_dim)\n        self.norm1 = nn.BatchNorm2d(embed_dim)\n        self.conv1 = nn.Conv2d(embed_dim, embed_dim, 1)\n        self.conv2 = nn.Conv2d(embed_dim, embed_dim, 1)\n        self.attn = nn.Conv2d(\n            embed_dim, embed_dim, 5, padding=2, groups=embed_dim)\n        # NOTE: drop path for stochastic depth, we shall see if this is\n        # better than dropout here\n        self.drop_path = build_dropout(\n            dict(type='DropPath', drop_prob=drop_path_rate)\n        ) if drop_path_rate > 0. else nn.Identity()\n        self.norm2 = nn.BatchNorm2d(embed_dim)\n        mlp_hidden_dim = int(embed_dim * mlp_ratio)\n        self.mlp = CMlp(\n            in_features=embed_dim,\n            hidden_features=mlp_hidden_dim,\n            drop_rate=drop_rate)\n\n    def forward(self, x):\n        x = x + self.pos_embed(x)\n        x = x + self.drop_path(\n            self.conv2(self.attn(self.conv1(self.norm1(x)))))\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n        return x\n\n\nclass Attention(BaseModule):\n    \"\"\"Self-Attention.\n\n    Args:\n        embed_dim (int): Number of input features.\n        num_heads (int): Number of attention heads.\n            Defaults to 8.\n        qkv_bias (bool): If True, add a learnable bias to query, key, value.\n            Defaults to True.\n        qk_scale (float, optional): Override default qk scale of\n            ``head_dim ** -0.5`` if set. Defaults to None.\n        attn_drop_rate (float): Attention dropout rate.\n            Defaults to 0.0.\n        proj_drop_rate (float): Dropout rate.\n            Defaults to 0.0.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n        init_cfg (dict, optional): The config of weight initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dim: int,\n                 num_heads: int = 8,\n                 qkv_bias: bool = True,\n                 qk_scale: float = None,\n                 attn_drop_rate: float = 0.,\n                 proj_drop_rate: float = 0.,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        self.num_heads = num_heads\n        head_dim = embed_dim // num_heads\n        # NOTE scale factor was wrong in my original version, can set manually\n        # to be compat with prev weights\n        self.scale = qk_scale or head_dim**-0.5\n\n        self.qkv = nn.Linear(embed_dim, embed_dim * 3, bias=qkv_bias)\n        self.attn_drop = nn.Dropout(attn_drop_rate)\n        self.proj = nn.Linear(embed_dim, embed_dim)\n        self.proj_drop = nn.Dropout(proj_drop_rate)\n\n    def forward(self, x):\n        B, N, C = x.shape\n        qkv = self.qkv(x).reshape(B, N, 3, self.num_heads,\n                                  C // self.num_heads).permute(2, 0, 3, 1, 4)\n        q, k, v = qkv[0], qkv[1], qkv[\n            2]  # make torchscript happy (cannot use tensor as tuple)\n\n        attn = (q @ k.transpose(-2, -1)) * self.scale\n        attn = attn.softmax(dim=-1)\n        attn = self.attn_drop(attn)\n\n        x = (attn @ v).transpose(1, 2).reshape(B, N, C)\n        x = self.proj(x)\n        x = self.proj_drop(x)\n        return x\n\n\nclass PatchEmbed(BaseModule):\n    \"\"\"Image to Patch Embedding.\n\n    Args:\n        img_size (int): Number of input size.\n            Defaults to 224.\n        patch_size (int): Number of patch size.\n            Defaults to 16.\n        in_channels (int): Number of input features.\n            Defaults to 3.\n        embed_dims (int): Number of output features.\n            Defaults to 768.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 img_size: int = 224,\n                 patch_size: int = 16,\n                 in_channels: int = 3,\n                 embed_dim: int = 768,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        img_size = to_2tuple(img_size)\n        patch_size = to_2tuple(patch_size)\n        num_patches = (img_size[1] // patch_size[1]) * (\n            img_size[0] // patch_size[0])\n        self.img_size = img_size\n        self.patch_size = patch_size\n        self.num_patches = num_patches\n        self.norm = nn.LayerNorm(embed_dim)\n        self.proj = nn.Conv2d(\n            in_channels, embed_dim, kernel_size=patch_size, stride=patch_size)\n\n    def forward(self, x):\n        B, _, H, W = x.shape\n        x = self.proj(x)\n        B, _, H, W = x.shape\n        x = x.flatten(2).transpose(1, 2)\n        x = self.norm(x)\n        x = x.reshape(B, H, W, -1).permute(0, 3, 1, 2).contiguous()\n        return x\n\n\nclass SABlock(BaseModule):\n    \"\"\"Self-Attention Block.\n\n    Args:\n        embed_dim (int): Number of input features.\n        num_heads (int): Number of attention heads.\n        mlp_ratio (float): Ratio of mlp hidden dimension\n            to embedding dimension. Defaults to 4.\n        qkv_bias (bool): If True, add a learnable bias to query, key, value.\n            Defaults to True.\n        qk_scale (float, optional): Override default qk scale of\n            ``head_dim ** -0.5`` if set. Defaults to None.\n        drop (float): Dropout rate. Defaults to 0.0.\n        attn_drop (float): Attention dropout rate. Defaults to 0.0.\n        drop_paths (float): Stochastic depth rates.\n            Defaults to 0.0.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dim: int,\n                 num_heads: int,\n                 mlp_ratio: float = 4.,\n                 qkv_bias: bool = False,\n                 qk_scale: float = None,\n                 drop_rate: float = 0.,\n                 attn_drop_rate: float = 0.,\n                 drop_path_rate: float = 0.,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n\n        self.pos_embed = nn.Conv2d(\n            embed_dim, embed_dim, 3, padding=1, groups=embed_dim)\n        self.norm1 = nn.LayerNorm(embed_dim)\n        self.attn = Attention(\n            embed_dim,\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop_rate=attn_drop_rate,\n            proj_drop_rate=drop_rate)\n        # NOTE: drop path for stochastic depth,\n        # we shall see if this is better than dropout here\n        self.drop_path = build_dropout(\n            dict(type='DropPath', drop_prob=drop_path_rate)\n        ) if drop_path_rate > 0. else nn.Identity()\n        self.norm2 = nn.LayerNorm(embed_dim)\n        mlp_hidden_dim = int(embed_dim * mlp_ratio)\n        self.mlp = Mlp(\n            in_features=embed_dim,\n            hidden_features=mlp_hidden_dim,\n            drop_rate=drop_rate)\n\n    def forward(self, x):\n        x = x + self.pos_embed(x)\n        B, N, H, W = x.shape\n        x = x.flatten(2).transpose(1, 2)\n        x = x + self.drop_path(self.attn(self.norm1(x)))\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n        x = x.transpose(1, 2).reshape(B, N, H, W)\n        return x\n\n\nclass WindowSABlock(BaseModule):\n    \"\"\"Self-Attention Block.\n\n    Args:\n        embed_dim (int): Number of input features.\n        num_heads (int): Number of attention heads.\n        window_size (int): Size of the partition window. Defaults to 14.\n        mlp_ratio (float): Ratio of mlp hidden dimension\n            to embedding dimension. Defaults to 4.\n        qkv_bias (bool): If True, add a learnable bias to query, key, value.\n            Defaults to True.\n        qk_scale (float, optional): Override default qk scale of\n            ``head_dim ** -0.5`` if set. Defaults to None.\n        drop (float): Dropout rate. Defaults to 0.0.\n        attn_drop (float): Attention dropout rate. Defaults to 0.0.\n        drop_paths (float): Stochastic depth rates.\n            Defaults to 0.0.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(self,\n                 embed_dim: int,\n                 num_heads: int,\n                 window_size: int = 14,\n                 mlp_ratio: float = 4.,\n                 qkv_bias: bool = False,\n                 qk_scale: float = None,\n                 drop_rate: float = 0.,\n                 attn_drop_rate: float = 0.,\n                 drop_path_rate: float = 0.,\n                 init_cfg: Optional[dict] = None) -> None:\n        super().__init__(init_cfg=init_cfg)\n        self.windows_size = window_size\n        self.pos_embed = nn.Conv2d(\n            embed_dim, embed_dim, 3, padding=1, groups=embed_dim)\n        self.norm1 = nn.LayerNorm(embed_dim)\n        self.attn = Attention(\n            embed_dim,\n            num_heads=num_heads,\n            qkv_bias=qkv_bias,\n            qk_scale=qk_scale,\n            attn_drop_rate=attn_drop_rate,\n            proj_drop_rate=drop_rate)\n        # NOTE: drop path for stochastic depth,\n        # we shall see if this is better than dropout here\n        self.drop_path = build_dropout(\n            dict(type='DropPath', drop_prob=drop_path_rate)\n        ) if drop_path_rate > 0. else nn.Identity()\n        # self.norm2 = build_dropout(norm_cfg, embed_dims)[1]\n        self.norm2 = nn.LayerNorm(embed_dim)\n        mlp_hidden_dim = int(embed_dim * mlp_ratio)\n        self.mlp = Mlp(\n            in_features=embed_dim,\n            hidden_features=mlp_hidden_dim,\n            drop_rate=drop_rate)\n\n    def window_reverse(self, windows, H, W):\n        \"\"\"\n        Args:\n            windows: (num_windows*B, window_size, window_size, C)\n            H (int): Height of image\n            W (int): Width of image\n        Returns:\n            x: (B, H, W, C)\n        \"\"\"\n        window_size = self.window_size\n        B = int(windows.shape[0] / (H * W / window_size / window_size))\n        x = windows.view(B, H // window_size, W // window_size, window_size,\n                         window_size, -1)\n        x = x.permute(0, 1, 3, 2, 4, 5).contiguous().view(B, H, W, -1)\n        return x\n\n    def window_partition(self, x):\n        \"\"\"\n        Args:\n            x: (B, H, W, C)\n        Returns:\n            windows: (num_windows*B, window_size, window_size, C)\n        \"\"\"\n        B, H, W, C = x.shape\n        window_size = self.window_size\n        x = x.view(B, H // window_size, window_size, W // window_size,\n                   window_size, C)\n        windows = x.permute(0, 1, 3, 2, 4,\n                            5).contiguous().view(-1, window_size, window_size,\n                                                 C)\n        return windows\n\n    def forward(self, x):\n        x = x + self.pos_embed(x)\n        x = x.permute(0, 2, 3, 1)\n        B, H, W, C = x.shape\n        shortcut = x\n        x = self.norm1(x)\n\n        pad_l = pad_t = 0\n        pad_r = (self.window_size - W % self.window_size) % self.window_size\n        pad_b = (self.window_size - H % self.window_size) % self.window_size\n        x = F.pad(x, (0, 0, pad_l, pad_r, pad_t, pad_b))\n        _, H_pad, W_pad, _ = x.shape\n\n        x_windows = self.window_partition(\n            x)  # nW*B, window_size, window_size, C\n        x_windows = x_windows.view(-1, self.window_size * self.window_size,\n                                   C)  # nW*B, window_size*window_size, C\n\n        # W-MSA/SW-MSA\n        attn_windows = self.attn(x_windows)  # nW*B, window_size*window_size, C\n\n        # merge windows\n        attn_windows = attn_windows.view(-1, self.window_size,\n                                         self.window_size, C)\n        x = self.window_reverse(attn_windows, H_pad, W_pad)  # B H' W' C\n\n        # reverse cyclic shift\n        if pad_r > 0 or pad_b > 0:\n            x = x[:, :H, :W, :].contiguous()\n\n        x = shortcut + self.drop_path(x)\n        x = x + self.drop_path(self.mlp(self.norm2(x)))\n        x = x.permute(0, 3, 1, 2).reshape(B, C, H, W)\n        return x\n\n\n@MODELS.register_module()\nclass UniFormer(BaseBackbone):\n    \"\"\"The implementation of Uniformer with downstream pose estimation task.\n\n    UniFormer: Unifying Convolution and Self-attention for Visual Recognition\n      https://arxiv.org/abs/2201.09450\n    UniFormer: Unified Transformer for Efficient Spatiotemporal Representation\n      Learning https://arxiv.org/abs/2201.04676\n\n    Args:\n        depths (List[int]): number of block in each layer.\n            Default to [3, 4, 8, 3].\n        img_size (int, tuple): input image size. Default: 224.\n        in_channels (int): number of input channels. Default: 3.\n        num_classes (int): number of classes for classification head. Default\n            to 80.\n        embed_dims (List[int]): embedding dimensions.\n            Default to [64, 128, 320, 512].\n        head_dim (int): dimension of attention heads\n        mlp_ratio (int): ratio of mlp hidden dim to embedding dim\n        qkv_bias (bool, optional): if True, add a learnable bias to query, key,\n            value. Default: True\n        qk_scale (float | None, optional): override default qk scale of\n            head_dim ** -0.5 if set. Default: None.\n        representation_size (Optional[int]): enable and set representation\n            layer (pre-logits) to this value if set\n        drop_rate (float): dropout rate. Default: 0.\n        attn_drop_rate (float): attention dropout rate. Default: 0.\n        drop_path_rate (float): stochastic depth rate. Default: 0.\n        norm_layer (nn.Module): normalization layer\n        use_checkpoint (bool): whether use torch.utils.checkpoint\n        checkpoint_num (list): index for using checkpoint in every stage\n        use_windows (bool): whether use window MHRA\n        use_hybrid (bool): whether use hybrid MHRA\n        window_size (int): size of window (>14). Default: 14.\n        init_cfg (dict, optional): Config dict for initialization.\n            Defaults to None.\n    \"\"\"\n\n    def __init__(\n        self,\n        depths: List[int] = [3, 4, 8, 3],\n        img_size: int = 224,\n        in_channels: int = 3,\n        num_classes: int = 80,\n        embed_dims: List[int] = [64, 128, 320, 512],\n        head_dim: int = 64,\n        mlp_ratio: int = 4.,\n        qkv_bias: bool = True,\n        qk_scale: float = None,\n        representation_size: Optional[int] = None,\n        drop_rate: float = 0.,\n        attn_drop_rate: float = 0.,\n        drop_path_rate: float = 0.,\n        norm_layer=partial(nn.LayerNorm, eps=1e-6),\n        use_checkpoint: bool = False,\n        checkpoint_num=(0, 0, 0, 0),\n        use_window: bool = False,\n        use_hybrid: bool = False,\n        window_size: int = 14,\n        init_cfg: Optional[Union[Dict, List[Dict]]] = [\n            dict(type='TruncNormal', layer='Linear', std=0.02, bias=0.),\n            dict(type='Constant', layer='LayerNorm', val=1., bias=0.)\n        ]\n    ) -> None:\n        super(UniFormer, self).__init__(init_cfg=init_cfg)\n\n        self.num_classes = num_classes\n        self.use_checkpoint = use_checkpoint\n        self.checkpoint_num = checkpoint_num\n        self.use_window = use_window\n        self.logger = get_root_logger()\n        self.logger.info(f'Use torch.utils.checkpoint: {self.use_checkpoint}')\n        self.logger.info(\n            f'torch.utils.checkpoint number: {self.checkpoint_num}')\n        self.num_features = self.embed_dims = embed_dims\n        norm_layer = norm_layer or partial(nn.LayerNorm, eps=1e-6)\n\n        self.patch_embed1 = PatchEmbed(\n            img_size=img_size,\n            patch_size=4,\n            in_channels=in_channels,\n            embed_dim=embed_dims[0])\n        self.patch_embed2 = PatchEmbed(\n            img_size=img_size // 4,\n            patch_size=2,\n            in_channels=embed_dims[0],\n            embed_dim=embed_dims[1])\n        self.patch_embed3 = PatchEmbed(\n            img_size=img_size // 8,\n            patch_size=2,\n            in_channels=embed_dims[1],\n            embed_dim=embed_dims[2])\n        self.patch_embed4 = PatchEmbed(\n            img_size=img_size // 16,\n            patch_size=2,\n            in_channels=embed_dims[2],\n            embed_dim=embed_dims[3])\n\n        self.drop_after_pos = nn.Dropout(drop_rate)\n        dpr = [\n            x.item() for x in torch.linspace(0, drop_path_rate, sum(depths))\n        ]  # stochastic depth decay rule\n        num_heads = [dim // head_dim for dim in embed_dims]\n        self.blocks1 = nn.ModuleList([\n            CBlock(\n                embed_dim=embed_dims[0],\n                mlp_ratio=mlp_ratio,\n                drop_rate=drop_rate,\n                drop_path_rate=dpr[i]) for i in range(depths[0])\n        ])\n        self.norm1 = norm_layer(embed_dims[0])\n        self.blocks2 = nn.ModuleList([\n            CBlock(\n                embed_dim=embed_dims[1],\n                mlp_ratio=mlp_ratio,\n                drop_rate=drop_rate,\n                drop_path_rate=dpr[i + depths[0]]) for i in range(depths[1])\n        ])\n        self.norm2 = norm_layer(embed_dims[1])\n        if self.use_window:\n            self.logger.info('Use local window for all blocks in stage3')\n            self.blocks3 = nn.ModuleList([\n                WindowSABlock(\n                    embed_dim=embed_dims[2],\n                    num_heads=num_heads[2],\n                    window_size=window_size,\n                    mlp_ratio=mlp_ratio,\n                    qkv_bias=qkv_bias,\n                    qk_scale=qk_scale,\n                    drop_rate=drop_rate,\n                    attn_drop_rate=attn_drop_rate,\n                    drop_path_rate=dpr[i + depths[0] + depths[1]])\n                for i in range(depths[2])\n            ])\n        elif use_hybrid:\n            self.logger.info('Use hybrid window for blocks in stage3')\n            block3 = []\n            for i in range(depths[2]):\n                if (i + 1) % 4 == 0:\n                    block3.append(\n                        SABlock(\n                            embed_dim=embed_dims[2],\n                            num_heads=num_heads[2],\n                            mlp_ratio=mlp_ratio,\n                            qkv_bias=qkv_bias,\n                            qk_scale=qk_scale,\n                            drop_rate=drop_rate,\n                            attn_drop_rate=attn_drop_rate,\n                            drop_path_rate=dpr[i + depths[0] + depths[1]]))\n                else:\n                    block3.append(\n                        WindowSABlock(\n                            embed_dim=embed_dims[2],\n                            num_heads=num_heads[2],\n                            window_size=window_size,\n                            mlp_ratio=mlp_ratio,\n                            qkv_bias=qkv_bias,\n                            qk_scale=qk_scale,\n                            drop_rate=drop_rate,\n                            attn_drop_rate=attn_drop_rate,\n                            drop_path_rate=dpr[i + depths[0] + depths[1]]))\n            self.blocks3 = nn.ModuleList(block3)\n        else:\n            self.logger.info('Use global window for all blocks in stage3')\n            self.blocks3 = nn.ModuleList([\n                SABlock(\n                    embed_dim=embed_dims[2],\n                    num_heads=num_heads[2],\n                    mlp_ratio=mlp_ratio,\n                    qkv_bias=qkv_bias,\n                    qk_scale=qk_scale,\n                    drop_rate=drop_rate,\n                    attn_drop_rate=attn_drop_rate,\n                    drop_path_rate=dpr[i + depths[0] + depths[1]])\n                for i in range(depths[2])\n            ])\n        self.norm3 = norm_layer(embed_dims[2])\n        self.blocks4 = nn.ModuleList([\n            SABlock(\n                embed_dim=embed_dims[3],\n                num_heads=num_heads[3],\n                mlp_ratio=mlp_ratio,\n                qkv_bias=qkv_bias,\n                qk_scale=qk_scale,\n                drop_rate=drop_rate,\n                attn_drop_rate=attn_drop_rate,\n                drop_path_rate=dpr[i + depths[0] + depths[1] + depths[2]])\n            for i in range(depths[3])\n        ])\n        self.norm4 = norm_layer(embed_dims[3])\n\n        # Representation layer\n        if representation_size:\n            self.num_features = representation_size\n            self.pre_logits = nn.Sequential(\n                OrderedDict([('fc', nn.Linear(embed_dims,\n                                              representation_size)),\n                             ('act', nn.Tanh())]))\n        else:\n            self.pre_logits = nn.Identity()\n\n        self.apply(self._init_weights)\n        self.init_weights()\n\n    def init_weights(self):\n        \"\"\"Initialize the weights in backbone.\n\n        Args:\n            pretrained (str, optional): Path to pre-trained weights.\n                Defaults to None.\n        \"\"\"\n        if (isinstance(self.init_cfg, dict)\n                and self.init_cfg['type'] == 'Pretrained'):\n            pretrained = self.init_cfg['checkpoint']\n            load_checkpoint(\n                self,\n                pretrained,\n                map_location='cpu',\n                strict=False,\n                logger=self.logger)\n            self.logger.info(f'Load pretrained model from {pretrained}')\n\n    def _init_weights(self, m):\n        if isinstance(m, nn.Linear):\n            trunc_normal_(m.weight, std=.02)\n            if isinstance(m, nn.Linear) and m.bias is not None:\n                nn.init.constant_(m.bias, 0)\n        elif isinstance(m, nn.LayerNorm):\n            nn.init.constant_(m.bias, 0)\n            nn.init.constant_(m.weight, 1.0)\n\n    @torch.jit.ignore\n    def no_weight_decay(self):\n        return {'pos_embed', 'cls_token'}\n\n    def get_classifier(self):\n        return self.head\n\n    def reset_classifier(self, num_classes, global_pool=''):\n        self.num_classes = num_classes\n        self.head = nn.Linear(\n            self.embed_dims,\n            num_classes) if num_classes > 0 else nn.Identity()\n\n    def forward(self, x):\n        out = []\n        x = self.patch_embed1(x)\n        x = self.drop_after_pos(x)\n        for i, blk in enumerate(self.blocks1):\n            if self.use_checkpoint and i < self.checkpoint_num[0]:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        x_out = self.norm1(x.permute(0, 2, 3, 1))\n        out.append(x_out.permute(0, 3, 1, 2).contiguous())\n        x = self.patch_embed2(x)\n        for i, blk in enumerate(self.blocks2):\n            if self.use_checkpoint and i < self.checkpoint_num[1]:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        x_out = self.norm2(x.permute(0, 2, 3, 1))\n        out.append(x_out.permute(0, 3, 1, 2).contiguous())\n        x = self.patch_embed3(x)\n        for i, blk in enumerate(self.blocks3):\n            if self.use_checkpoint and i < self.checkpoint_num[2]:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        x_out = self.norm3(x.permute(0, 2, 3, 1))\n        out.append(x_out.permute(0, 3, 1, 2).contiguous())\n        x = self.patch_embed4(x)\n        for i, blk in enumerate(self.blocks4):\n            if self.use_checkpoint and i < self.checkpoint_num[3]:\n                x = checkpoint.checkpoint(blk, x)\n            else:\n                x = blk(x)\n        x_out = self.norm4(x.permute(0, 2, 3, 1))\n        out.append(x_out.permute(0, 3, 1, 2).contiguous())\n        return tuple(out)\n"
  },
  {
    "path": "projects/yolox_pose/README.md",
    "content": "# YOLOX-Pose\n\nThis project implements a YOLOX-based human pose estimator, utilizing the approach outlined in **YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss** (CVPRW 2022). This pose estimator is lightweight and quick, making it well-suited for crowded scenes.\n\n<img src=\"https://user-images.githubusercontent.com/26127467/226655503-3cee746e-6e42-40be-82ae-6e7cae2a4c7e.jpg\" alt><br>\n\n📌 For improved performance and compatibility, **consider using YOLOX-Pose which is built into MMPose**, which seamlessly integrates with MMPose's tools. To learn more about adopting YOLOX-Pose in your workflow, see the documentation: [YOLOX-Pose](/configs/body_2d_keypoint/yoloxpose/README.md).\n\n## Usage\n\n### Prerequisites\n\n- Python 3.7 or higher\n\n- PyTorch 1.6 or higher\n\n- [MMEngine](https://github.com/open-mmlab/mmengine) v0.6.0 or higher\n\n- [MMCV](https://github.com/open-mmlab/mmcv) v2.0.0rc4 or higher\n\n- [MMDetection](https://github.com/open-mmlab/mmdetection) v3.0.0rc6 or higher\n\n- [MMYOLO](https://github.com/open-mmlab/mmyolo) <span style=\"color:red\"> **v0.5.0**</span>\n\n- [MMPose](https://github.com/open-mmlab/mmpose) v1.0.0rc1 or higher\n\nAll the commands below rely on the correct configuration of `PYTHONPATH`, which should point to the project's directory so that Python can locate the module files. **In `yolox-pose/` root directory**, run the following line to add the current directory to `PYTHONPATH`:\n\n```shell\nexport PYTHONPATH=`pwd`:$PYTHONPATH\n```\n\n### Inference\n\nUsers can apply YOLOX-Pose models to estimate human poses using the inferencer found in the MMPose core package. Use the command below:\n\n```shell\npython demo/inferencer_demo.py $INPUTS \\\n    --pose2d $CONFIG --pose2d-weights $CHECKPOINT --scope mmyolo \\\n    [--show] [--vis-out-dir $VIS_OUT_DIR] [--pred-out-dir $PRED_OUT_DIR]\n```\n\nFor more information on using the inferencer, please see [this document](https://mmpose.readthedocs.io/en/latest/user_guides/inference.html#out-of-the-box-inferencer).\n\nHere's an example code:\n\n```shell\npython demo/inferencer_demo.py ../../tests/data/coco/000000000785.jpg \\\n    --pose2d configs/yolox-pose_s_8xb32-300e_coco.py \\\n    --pose2d-weights https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_s_8xb32-300e_coco-9f5e3924_20230321.pth \\\n    --scope mmyolo --vis-out-dir vis_results\n```\n\nThis will create an output image `vis_results/000000000785.jpg`, which appears like:\n\n<img src=\"https://user-images.githubusercontent.com/26127467/226552585-19b91294-9751-4599-98e7-5dae071a1761.jpg\" height=\"360px\" alt><br>\n\n### Training & Testing\n\n#### Data Preparation\n\nPrepare the COCO dataset according to the [instruction](https://mmpose.readthedocs.io/en/latest/dataset_zoo/2d_body_keypoint.html#coco).\n\n#### Commands\n\n**To train with multiple GPUs:**\n\n```shell\nbash tools/dist_train.sh $CONFIG 8 --amp\n```\n\n**To train with slurm:**\n\n```shell\nbash tools/slurm_train.sh $PARTITION $JOBNAME $CONFIG $WORKDIR --amp\n```\n\n**To test with single GPU:**\n\n```shell\npython tools/test.py $CONFIG $CHECKPOINT\n```\n\n**To test with multiple GPUs:**\n\n```shell\nbash tools/dist_test.sh $CONFIG $CHECKPOINT 8\n```\n\n**To test with multiple GPUs by slurm:**\n\n```shell\nbash tools/slurm_test.sh $PARTITION $JOBNAME $CONFIG $CHECKPOINT\n```\n\n### Results\n\nResults on COCO val2017\n\n|                              Model                              | Input Size |  AP   | AP<sup>50</sup> | AP<sup>75</sup> |  AR   | AR<sup>50</sup> |                                 Download                                 |\n| :-------------------------------------------------------------: | :--------: | :---: | :-------------: | :-------------: | :---: | :-------------: | :----------------------------------------------------------------------: |\n| [YOLOX-tiny-Pose](./configs/yolox-pose_tiny_4xb64-300e_coco.py) |    416     | 0.518 |      0.799      |      0.545      | 0.566 |      0.841      | [model](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_tiny_4xb64-300e_coco-c47dd83b_20230321.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_tiny_4xb64-300e_coco_20230321.json) |\n|    [YOLOX-s-Pose](./configs/yolox-pose_s_8xb32-300e_coco.py)    |    640     | 0.632 |      0.875      |      0.692      | 0.676 |      0.907      | [model](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_s_8xb32-300e_coco-9f5e3924_20230321.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_s_8xb32-300e_coco_20230321.json) |\n|    [YOLOX-m-Pose](./configs/yolox-pose_m_4xb64-300e_coco.py)    |    640     | 0.685 |      0.897      |      0.753      | 0.727 |      0.925      | [model](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_m_4xb64-300e_coco-cbd11d30_20230321.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_m_4xb64-300e_coco_20230321.json) |\n|    [YOLOX-l-Pose](./configs/yolox-pose_l_4xb64-300e_coco.py)    |    640     | 0.706 |      0.907      |      0.775      | 0.747 |      0.934      | [model](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_l_4xb64-300e_coco-122e4cf8_20230321.pth) \\| [log](https://download.openmmlab.com/mmpose/v1/projects/yolox-pose/yolox-pose_l_4xb64-300e_coco_20230321.json) |\n\nWe have only trained models with an input size of 640, as we couldn't replicate the performance enhancement mentioned in the paper when increasing the input size from 640 to 960. We warmly welcome any contributions if you can successfully reproduce the results from the paper!\n\n**NEW!**\n\n[MMYOLO](https://github.com/open-mmlab/mmyolo/blob/dev/configs/yolox/README.md#yolox-pose) also supports YOLOX-Pose and achieves better performance. Their models are fully compatible with this project. Here are their results on COCO val2017:\n\n|  Backbone  | Size | Batch Size | AMP | RTMDet-Hyp | Mem (GB) |  AP  |                                   Config                                   |                                   Download                                    |\n| :--------: | :--: | :--------: | :-: | :--------: | :------: | :--: | :------------------------------------------------------------------------: | :---------------------------------------------------------------------------: |\n| YOLOX-tiny | 416  |   8xb32    | Yes |    Yes     |   5.3    | 52.8 | [config](https://github.com/open-mmlab/mmyolo/blob/dev/configs/yolox/pose/yolox-pose_tiny_8xb32-300e-rtmdet-hyp_coco.py) | [model](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_tiny_8xb32-300e-rtmdet-hyp_coco/yolox-pose_tiny_8xb32-300e-rtmdet-hyp_coco_20230427_080351-2117af67.pth) \\| [log](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_tiny_8xb32-300e-rtmdet-hyp_coco/yolox-pose_tiny_8xb32-300e-rtmdet-hyp_coco_20230427_080351.log.json) |\n|  YOLOX-s   | 640  |   8xb32    | Yes |    Yes     |   10.7   | 63.7 | [config](https://github.com/open-mmlab/mmyolo/blob/dev/configs/yolox/pose/yolox-pose_s_8xb32-300e-rtmdet-hyp_coco.py) | [model](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_s_8xb32-300e-rtmdet-hyp_coco/yolox-pose_s_8xb32-300e-rtmdet-hyp_coco_20230427_005150-e87d843a.pth) \\| [log](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_s_8xb32-300e-rtmdet-hyp_coco/yolox-pose_s_8xb32-300e-rtmdet-hyp_coco_20230427_005150.log.json) |\n|  YOLOX-m   | 640  |   8xb32    | Yes |    Yes     |   19.2   | 69.3 | [config](https://github.com/open-mmlab/mmyolo/blob/dev/configs/yolox/pose/yolox-pose_m_8xb32-300e-rtmdet-hyp_coco.py) | [model](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_m_8xb32-300e-rtmdet-hyp_coco/yolox-pose_m_8xb32-300e-rtmdet-hyp_coco_20230427_094024-bbeacc1c.pth) \\| [log](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_m_8xb32-300e-rtmdet-hyp_coco/yolox-pose_m_8xb32-300e-rtmdet-hyp_coco_20230427_094024.log.json) |\n|  YOLOX-l   | 640  |   8xb32    | Yes |    Yes     |   30.3   | 71.1 | [config](https://github.com/open-mmlab/mmyolo/blob/dev/configs/yolox/pose/yolox-pose_l_8xb32-300e-rtmdet-hyp_coco.py) | [model](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_l_8xb32-300e-rtmdet-hyp_coco/yolox-pose_l_8xb32-300e-rtmdet-hyp_coco_20230427_041140-82d65ac8.pth) \\| [log](https://download.openmmlab.com/mmyolo/v0/yolox/pose/yolox-pose_l_8xb32-300e-rtmdet-hyp_coco/yolox-pose_l_8xb32-300e-rtmdet-hyp_coco_20230427_041140.log.json) |\n\n## Citation\n\nIf this project benefits your work, please kindly consider citing the original papers:\n\n```bibtex\n@inproceedings{maji2022yolo,\n  title={YOLO-Pose: Enhancing YOLO for Multi Person Pose Estimation Using Object Keypoint Similarity Loss},\n  author={Maji, Debapriya and Nagori, Soyeb and Mathew, Manu and Poddar, Deepak},\n  booktitle={Proceedings of the IEEE/CVF Conference on Computer Vision and Pattern Recognition},\n  pages={2637--2646},\n  year={2022}\n}\n```\n\n```bibtex\n@article{yolox2021,\n  title={{YOLOX}: Exceeding YOLO Series in 2021},\n  author={Ge, Zheng and Liu, Songtao and Wang, Feng and Li, Zeming and Sun, Jian},\n  journal={arXiv preprint arXiv:2107.08430},\n  year={2021}\n}\n```\n\nAdditionally, please cite our work as well:\n\n```bibtex\n@misc{mmpose2020,\n    title={OpenMMLab Pose Estimation Toolbox and Benchmark},\n    author={MMPose Contributors},\n    howpublished = {\\url{https://github.com/open-mmlab/mmpose}},\n    year={2020}\n}\n```\n"
  },
  {
    "path": "projects/yolox_pose/configs/_base_/default_runtime.py",
    "content": "default_scope = 'mmyolo'\ncustom_imports = dict(imports=['models', 'datasets'])\n\n# hooks\ndefault_hooks = dict(\n    timer=dict(type='IterTimerHook'),\n    logger=dict(type='LoggerHook', interval=50),\n    param_scheduler=dict(type='ParamSchedulerHook'),\n    checkpoint=dict(type='CheckpointHook', interval=10, max_keep_ckpts=3),\n    sampler_seed=dict(type='DistSamplerSeedHook'),\n    visualization=dict(type='mmpose.PoseVisualizationHook', enable=False),\n)\n\n# multi-processing backend\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'),\n)\n\n# visualizer\nvis_backends = [dict(type='LocalVisBackend')]\nvisualizer = dict(\n    type='mmpose.PoseLocalVisualizer',\n    vis_backends=vis_backends,\n    name='visualizer')\n\n# logger\nlog_processor = dict(\n    type='LogProcessor', window_size=50, by_epoch=True, num_digits=6)\nlog_level = 'INFO'\nload_from = None\nresume = False\n\n# file I/O backend\nbackend_args = dict(backend='local')\n\n# training/validation/testing progress\ntrain_cfg = dict()\nval_cfg = dict(type='ValLoop')\ntest_cfg = dict(type='TestLoop')\n"
  },
  {
    "path": "projects/yolox_pose/configs/_base_/py_default_runtime.py",
    "content": "from mmengine.hooks import (CheckpointHook, DistSamplerSeedHook, IterTimerHook,\n                            LoggerHook, ParamSchedulerHook)\nfrom mmengine.runner import LogProcessor, TestLoop, ValLoop\nfrom mmengine.visualization import LocalVisBackend\n\nfrom mmpose.engine.hooks import PoseVisualizationHook\nfrom mmpose.visualization import PoseLocalVisualizer\n\ndefault_scope = None\n# hooks\ndefault_hooks = dict(\n    timer=dict(type=IterTimerHook),\n    logger=dict(type=LoggerHook, interval=50),\n    param_scheduler=dict(type=ParamSchedulerHook),\n    checkpoint=dict(type=CheckpointHook, interval=10, max_keep_ckpts=3),\n    sampler_seed=dict(type=DistSamplerSeedHook),\n    visualization=dict(type=PoseVisualizationHook, enable=False),\n)\n\n# multi-processing backend\nenv_cfg = dict(\n    cudnn_benchmark=False,\n    mp_cfg=dict(mp_start_method='fork', opencv_num_threads=0),\n    dist_cfg=dict(backend='nccl'),\n)\n\n# visualizer\nvis_backends = [dict(type=LocalVisBackend)]\nvisualizer = dict(\n    type=PoseLocalVisualizer, vis_backends=vis_backends, name='visualizer')\n\n# logger\nlog_processor = dict(\n    type=LogProcessor, window_size=50, by_epoch=True, num_digits=6)\nlog_level = 'INFO'\nload_from = None\nresume = False\n\n# file I/O backend\nbackend_args = dict(backend='local')\n\n# training/validation/testing progress\ntrain_cfg = dict()\nval_cfg = dict(type=ValLoop)\ntest_cfg = dict(type=TestLoop)\n"
  },
  {
    "path": "projects/yolox_pose/configs/py_yolox_pose_s_8xb32_300e_coco.py",
    "content": "from mmengine.config import read_base\n\nwith read_base():\n    from ._base_.py_default_runtime import *\n\nfrom datasets import (CocoDataset, FilterDetPoseAnnotations, PackDetPoseInputs,\n                      PoseToDetConverter)\nfrom mmcv.ops import nms\nfrom mmdet.datasets.transforms import (Pad, RandomAffine, RandomFlip, Resize,\n                                       YOLOXHSVRandomAug)\nfrom mmdet.engine.hooks import SyncNormHook\nfrom mmdet.engine.schedulers import QuadraticWarmupLR\nfrom mmdet.models import CrossEntropyLoss, DetDataPreprocessor, IoULoss, L1Loss\nfrom mmdet.models.task_modules import BboxOverlaps2D\nfrom mmengine.dataset import DefaultSampler\nfrom mmengine.hooks import EMAHook\nfrom mmengine.model import PretrainedInit\nfrom mmengine.optim import ConstantLR, CosineAnnealingLR, OptimWrapper\nfrom mmengine.runner import EpochBasedTrainLoop\nfrom mmyolo.datasets.transforms import Mosaic, YOLOXMixUp\nfrom mmyolo.engine.hooks import YOLOXModeSwitchHook\nfrom mmyolo.models import (YOLOXPAFPN, ExpMomentumEMA, YOLODetector,\n                           YOLOXCSPDarknet)\nfrom models import (OksLoss, PoseBatchSyncRandomResize, PoseSimOTAAssigner,\n                    YOLOXPoseHead, YOLOXPoseHeadModule)\nfrom torch.nn import BatchNorm2d, SiLU\nfrom torch.optim import AdamW\n\nfrom mmpose.datasets.transforms import LoadImage\nfrom mmpose.evaluation import CocoMetric\n\n# model settings\nmodel = dict(\n    type=YOLODetector,\n    use_syncbn=False,\n    init_cfg=dict(\n        type=PretrainedInit,\n        checkpoint='https://download.openmmlab.com/mmyolo/v0/yolox/'\n        'yolox_s_fast_8xb32-300e-rtmdet-hyp_coco/yolox_s_fast_'\n        '8xb32-300e-rtmdet-hyp_coco_20230210_134645-3a8dfbd7.pth'),\n    data_preprocessor=dict(\n        type=DetDataPreprocessor,\n        pad_size_divisor=32,\n        batch_augments=[\n            dict(\n                type=PoseBatchSyncRandomResize,\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1)\n        ]),\n    backbone=dict(\n        type=YOLOXCSPDarknet,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type=BatchNorm2d, momentum=0.03, eps=0.001),\n        act_cfg=dict(type=SiLU, inplace=True),\n    ),\n    neck=dict(\n        type=YOLOXPAFPN,\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        in_channels=[256, 512, 1024],\n        out_channels=256,\n        norm_cfg=dict(type=BatchNorm2d, momentum=0.03, eps=0.001),\n        act_cfg=dict(type=SiLU, inplace=True)),\n    bbox_head=dict(\n        type=YOLOXPoseHead,\n        head_module=dict(\n            type=YOLOXPoseHeadModule,\n            num_classes=1,\n            in_channels=256,\n            feat_channels=256,\n            widen_factor=0.5,\n            stacked_convs=2,\n            num_keypoints=17,\n            featmap_strides=(8, 16, 32),\n            use_depthwise=False,\n            norm_cfg=dict(type=BatchNorm2d, momentum=0.03, eps=0.001),\n            act_cfg=dict(type=SiLU, inplace=True),\n        ),\n        loss_cls=dict(\n            type=CrossEntropyLoss,\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type=IoULoss,\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_obj=dict(\n            type=CrossEntropyLoss,\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_pose=dict(\n            type=OksLoss,\n            metainfo='configs/_base_/datasets/coco.py',\n            loss_weight=30.0),\n        loss_bbox_aux=dict(type=L1Loss, reduction='sum', loss_weight=1.0)),\n    train_cfg=dict(\n        assigner=dict(\n            type=PoseSimOTAAssigner,\n            center_radius=2.5,\n            iou_calculator=dict(type=BboxOverlaps2D),\n            oks_calculator=dict(\n                type=OksLoss, metainfo='configs/_base_/datasets/coco.py'))),\n    test_cfg=dict(\n        yolox_style=True,\n        multi_label=False,\n        score_thr=0.001,\n        max_per_img=300,\n        nms=dict(type=nms, iou_threshold=0.65)))\n\n# data related\nimg_scale = (640, 640)\n\n# pipelines\npre_transform = [\n    dict(type=LoadImage, backend_args=backend_args),\n    dict(type=PoseToDetConverter)\n]\n\ntrain_pipeline_stage1 = [\n    *pre_transform,\n    dict(\n        type=Mosaic,\n        img_scale=img_scale,\n        pad_val=114.0,\n        pre_transform=pre_transform),\n    dict(\n        type=RandomAffine,\n        scaling_ratio_range=(0.75, 1.0),\n        border=(-img_scale[0] // 2, -img_scale[1] // 2)),\n    dict(\n        type=YOLOXMixUp,\n        img_scale=img_scale,\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=pre_transform),\n    dict(type=YOLOXHSVRandomAug),\n    dict(type=RandomFlip, prob=0.5),\n    dict(type=FilterDetPoseAnnotations, keep_empty=False),\n    dict(\n        type=PackDetPoseInputs,\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape'))\n]\n\ntrain_pipeline_stage2 = [\n    *pre_transform,\n    dict(type=Resize, scale=img_scale, keep_ratio=True),\n    dict(\n        type=Pad, pad_to_square=True, pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type=YOLOXHSVRandomAug),\n    dict(type=RandomFlip, prob=0.5),\n    dict(type=FilterDetPoseAnnotations, keep_empty=False),\n    dict(type=PackDetPoseInputs)\n]\n\ntest_pipeline = [\n    *pre_transform,\n    dict(type=Resize, scale=img_scale, keep_ratio=True),\n    dict(\n        type=Pad, pad_to_square=True, pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(\n        type=PackDetPoseInputs,\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor', 'flip_indices'))\n]\n\n# dataset settings\ndataset_type = CocoDataset\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type=DefaultSampler, shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_mode=data_mode,\n        data_root=data_root,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        filter_cfg=dict(filter_empty_gt=False, min_size=32),\n        pipeline=train_pipeline_stage1))\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type=DefaultSampler, shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_mode=data_mode,\n        data_root=data_root,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline))\n\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type=CocoMetric,\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    score_mode='bbox')\ntest_evaluator = val_evaluator\n\ndefault_hooks.update(\n    dict(checkpoint=dict(save_best='coco/AP', rule='greater')))\n\n# optimizer\nbase_lr = 0.004\nmax_epochs = 300\nnum_last_epochs = 20\noptim_wrapper = dict(\n    type=OptimWrapper,\n    optimizer=dict(type=AdamW, lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\nparam_scheduler = [\n    dict(\n        # use quadratic formula to warm up 5 epochs\n        # and lr is updated by iteration\n        type=QuadraticWarmupLR,\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        # use cosine lr from 5 to 285 epoch\n        type=CosineAnnealingLR,\n        eta_min=base_lr * 0.05,\n        begin=5,\n        T_max=max_epochs - num_last_epochs,\n        end=max_epochs - num_last_epochs,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(\n        # use fixed lr during last num_last_epochs epochs\n        type=ConstantLR,\n        by_epoch=True,\n        factor=1,\n        begin=max_epochs - num_last_epochs,\n        end=max_epochs,\n    )\n]\n\n# runtime\ncustom_hooks = [\n    dict(\n        type=YOLOXModeSwitchHook,\n        num_last_epochs=num_last_epochs,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(type=SyncNormHook, priority=48),\n    dict(\n        type=EMAHook,\n        ema_type=ExpMomentumEMA,\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49)\n]\n\ntrain_cfg = dict(\n    type=EpochBasedTrainLoop,\n    max_epochs=max_epochs,\n    val_interval=10,\n    dynamic_intervals=[(max_epochs - num_last_epochs, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n"
  },
  {
    "path": "projects/yolox_pose/configs/yolox-pose_l_4xb64-300e_coco.py",
    "content": "_base_ = ['./yolox-pose_s_8xb32-300e_coco.py']\n\n# model settings\nmodel = dict(\n    init_cfg=dict(checkpoint='https://download.openmmlab.com/mmyolo/v0/yolox/'\n                  'yolox_l_fast_8xb8-300e_coco/yolox_l_fast_8xb8-300e_'\n                  'coco_20230213_160715-c731eb1c.pth'),\n    backbone=dict(\n        deepen_factor=1.0,\n        widen_factor=1.0,\n    ),\n    neck=dict(\n        deepen_factor=1.0,\n        widen_factor=1.0,\n    ),\n    bbox_head=dict(head_module=dict(widen_factor=1.0)))\n\ntrain_dataloader = dict(batch_size=64)\n"
  },
  {
    "path": "projects/yolox_pose/configs/yolox-pose_m_4xb64-300e_coco.py",
    "content": "_base_ = ['./yolox-pose_s_8xb32-300e_coco.py']\n\n# model settings\nmodel = dict(\n    init_cfg=dict(checkpoint='https://download.openmmlab.com/mmyolo/v0/yolox/'\n                  'yolox_m_fast_8xb32-300e-rtmdet-hyp_coco/yolox_m_fast_8xb32'\n                  '-300e-rtmdet-hyp_coco_20230210_144328-e657e182.pth'),\n    backbone=dict(\n        deepen_factor=0.67,\n        widen_factor=0.75,\n    ),\n    neck=dict(\n        deepen_factor=0.67,\n        widen_factor=0.75,\n    ),\n    bbox_head=dict(head_module=dict(widen_factor=0.75)))\n\ntrain_dataloader = dict(batch_size=64)\n"
  },
  {
    "path": "projects/yolox_pose/configs/yolox-pose_s_8xb32-300e_coco.py",
    "content": "_base_ = ['_base_/default_runtime.py']\n\n# model settings\nmodel = dict(\n    type='YOLODetector',\n    use_syncbn=False,\n    init_cfg=dict(\n        type='Pretrained',\n        checkpoint='https://download.openmmlab.com/mmyolo/v0/yolox/'\n        'yolox_s_fast_8xb32-300e-rtmdet-hyp_coco/yolox_s_fast_'\n        '8xb32-300e-rtmdet-hyp_coco_20230210_134645-3a8dfbd7.pth'),\n    data_preprocessor=dict(\n        type='mmdet.DetDataPreprocessor',\n        pad_size_divisor=32,\n        batch_augments=[\n            dict(\n                type='PoseBatchSyncRandomResize',\n                random_size_range=(480, 800),\n                size_divisor=32,\n                interval=1)\n        ]),\n    backbone=dict(\n        type='YOLOXCSPDarknet',\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        out_indices=(2, 3, 4),\n        spp_kernal_sizes=(5, 9, 13),\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='SiLU', inplace=True),\n    ),\n    neck=dict(\n        type='YOLOXPAFPN',\n        deepen_factor=0.33,\n        widen_factor=0.5,\n        in_channels=[256, 512, 1024],\n        out_channels=256,\n        norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n        act_cfg=dict(type='SiLU', inplace=True)),\n    bbox_head=dict(\n        type='YOLOXPoseHead',\n        head_module=dict(\n            type='YOLOXPoseHeadModule',\n            num_classes=1,\n            in_channels=256,\n            feat_channels=256,\n            widen_factor=0.5,\n            stacked_convs=2,\n            num_keypoints=17,\n            featmap_strides=(8, 16, 32),\n            use_depthwise=False,\n            norm_cfg=dict(type='BN', momentum=0.03, eps=0.001),\n            act_cfg=dict(type='SiLU', inplace=True),\n        ),\n        loss_cls=dict(\n            type='mmdet.CrossEntropyLoss',\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_bbox=dict(\n            type='mmdet.IoULoss',\n            mode='square',\n            eps=1e-16,\n            reduction='sum',\n            loss_weight=5.0),\n        loss_obj=dict(\n            type='mmdet.CrossEntropyLoss',\n            use_sigmoid=True,\n            reduction='sum',\n            loss_weight=1.0),\n        loss_pose=dict(\n            type='OksLoss',\n            metainfo='configs/_base_/datasets/coco.py',\n            loss_weight=30.0),\n        loss_bbox_aux=dict(\n            type='mmdet.L1Loss', reduction='sum', loss_weight=1.0)),\n    train_cfg=dict(\n        assigner=dict(\n            type='PoseSimOTAAssigner',\n            center_radius=2.5,\n            iou_calculator=dict(type='mmdet.BboxOverlaps2D'),\n            oks_calculator=dict(\n                type='OksLoss', metainfo='configs/_base_/datasets/coco.py'))),\n    test_cfg=dict(\n        yolox_style=True,\n        multi_label=False,\n        score_thr=0.001,\n        max_per_img=300,\n        nms=dict(type='nms', iou_threshold=0.65)))\n\n# data related\nimg_scale = (640, 640)\n\n# pipelines\npre_transform = [\n    dict(type='mmpose.LoadImage', backend_args=_base_.backend_args),\n    dict(type='PoseToDetConverter')\n]\n\ntrain_pipeline_stage1 = [\n    *pre_transform,\n    dict(\n        type='Mosaic',\n        img_scale=img_scale,\n        pad_val=114.0,\n        pre_transform=pre_transform),\n    dict(\n        type='mmdet.RandomAffine',\n        scaling_ratio_range=(0.75, 1.0),\n        border=(-img_scale[0] // 2, -img_scale[1] // 2)),\n    dict(\n        type='YOLOXMixUp',\n        img_scale=img_scale,\n        ratio_range=(0.8, 1.6),\n        pad_val=114.0,\n        pre_transform=pre_transform),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='mmdet.RandomFlip', prob=0.5),\n    dict(type='FilterDetPoseAnnotations', keep_empty=False),\n    dict(\n        type='PackDetPoseInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape'))\n]\n\ntrain_pipeline_stage2 = [\n    *pre_transform,\n    dict(type='mmdet.Resize', scale=img_scale, keep_ratio=True),\n    dict(\n        type='mmdet.Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='mmdet.RandomFlip', prob=0.5),\n    dict(type='FilterDetPoseAnnotations', keep_empty=False),\n    dict(type='PackDetPoseInputs')\n]\n\ntest_pipeline = [\n    *pre_transform,\n    dict(type='mmdet.Resize', scale=img_scale, keep_ratio=True),\n    dict(\n        type='mmdet.Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(\n        type='PackDetPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor', 'flip_indices'))\n]\n\n# dataset settings\ndataset_type = 'CocoDataset'\ndata_mode = 'bottomup'\ndata_root = 'data/coco/'\n\ntrain_dataloader = dict(\n    batch_size=32,\n    num_workers=8,\n    persistent_workers=True,\n    pin_memory=True,\n    sampler=dict(type='DefaultSampler', shuffle=True),\n    dataset=dict(\n        type=dataset_type,\n        data_mode=data_mode,\n        data_root=data_root,\n        ann_file='annotations/person_keypoints_train2017.json',\n        data_prefix=dict(img='train2017/'),\n        filter_cfg=dict(filter_empty_gt=False, min_size=32),\n        pipeline=train_pipeline_stage1))\n\nval_dataloader = dict(\n    batch_size=1,\n    num_workers=2,\n    persistent_workers=True,\n    pin_memory=True,\n    drop_last=False,\n    sampler=dict(type='DefaultSampler', shuffle=False),\n    dataset=dict(\n        type=dataset_type,\n        data_mode=data_mode,\n        data_root=data_root,\n        ann_file='annotations/person_keypoints_val2017.json',\n        data_prefix=dict(img='val2017/'),\n        test_mode=True,\n        pipeline=test_pipeline))\n\ntest_dataloader = val_dataloader\n\n# evaluators\nval_evaluator = dict(\n    type='mmpose.CocoMetric',\n    ann_file=data_root + 'annotations/person_keypoints_val2017.json',\n    score_mode='bbox')\ntest_evaluator = val_evaluator\n\ndefault_hooks = dict(checkpoint=dict(save_best='coco/AP', rule='greater'))\n\n# optimizer\nbase_lr = 0.004\nmax_epochs = 300\nnum_last_epochs = 20\noptim_wrapper = dict(\n    type='OptimWrapper',\n    optimizer=dict(type='AdamW', lr=base_lr, weight_decay=0.05),\n    paramwise_cfg=dict(\n        norm_decay_mult=0, bias_decay_mult=0, bypass_duplicate=True))\n\nparam_scheduler = [\n    dict(\n        # use quadratic formula to warm up 5 epochs\n        # and lr is updated by iteration\n        type='mmdet.QuadraticWarmupLR',\n        by_epoch=True,\n        begin=0,\n        end=5,\n        convert_to_iter_based=True),\n    dict(\n        # use cosine lr from 5 to 285 epoch\n        type='CosineAnnealingLR',\n        eta_min=base_lr * 0.05,\n        begin=5,\n        T_max=max_epochs - num_last_epochs,\n        end=max_epochs - num_last_epochs,\n        by_epoch=True,\n        convert_to_iter_based=True),\n    dict(\n        # use fixed lr during last num_last_epochs epochs\n        type='ConstantLR',\n        by_epoch=True,\n        factor=1,\n        begin=max_epochs - num_last_epochs,\n        end=max_epochs,\n    )\n]\n\n# runtime\ncustom_hooks = [\n    dict(\n        type='YOLOXModeSwitchHook',\n        num_last_epochs=num_last_epochs,\n        new_train_pipeline=train_pipeline_stage2,\n        priority=48),\n    dict(type='mmdet.SyncNormHook', priority=48),\n    dict(\n        type='EMAHook',\n        ema_type='ExpMomentumEMA',\n        momentum=0.0002,\n        update_buffers=True,\n        strict_load=False,\n        priority=49)\n]\n\ntrain_cfg = dict(\n    type='EpochBasedTrainLoop',\n    max_epochs=max_epochs,\n    val_interval=10,\n    dynamic_intervals=[(max_epochs - num_last_epochs, 1)])\n\nauto_scale_lr = dict(base_batch_size=256)\n"
  },
  {
    "path": "projects/yolox_pose/configs/yolox-pose_tiny_4xb64-300e_coco.py",
    "content": "_base_ = ['./yolox-pose_s_8xb32-300e_coco.py']\n\n# model settings\nmodel = dict(\n    init_cfg=dict(checkpoint='https://download.openmmlab.com/mmyolo/v0/yolox/'\n                  'yolox_tiny_fast_8xb32-300e-rtmdet-hyp_coco/yolox_tiny_fast_'\n                  '8xb32-300e-rtmdet-hyp_coco_20230210_143637-4c338102.pth'),\n    data_preprocessor=dict(batch_augments=[\n        dict(\n            type='PoseBatchSyncRandomResize',\n            random_size_range=(320, 640),\n            size_divisor=32,\n            interval=1)\n    ]),\n    backbone=dict(\n        deepen_factor=0.33,\n        widen_factor=0.375,\n    ),\n    neck=dict(\n        deepen_factor=0.33,\n        widen_factor=0.375,\n    ),\n    bbox_head=dict(head_module=dict(widen_factor=0.375)))\n\n# data settings\nimg_scale = _base_.img_scale\npre_transform = _base_.pre_transform\n\ntrain_pipeline_stage1 = [\n    *pre_transform,\n    dict(\n        type='Mosaic',\n        img_scale=(img_scale),\n        pad_val=114.0,\n        pre_transform=pre_transform),\n    dict(\n        type='mmdet.RandomAffine',\n        scaling_ratio_range=(0.75, 1.0),\n        border=(-img_scale[0] // 2, -img_scale[1] // 2)),\n    dict(type='mmdet.YOLOXHSVRandomAug'),\n    dict(type='mmdet.RandomFlip', prob=0.5),\n    dict(\n        type='FilterDetPoseAnnotations',\n        min_gt_bbox_wh=(1, 1),\n        keep_empty=False),\n    dict(\n        type='PackDetPoseInputs',\n        meta_keys=('img_id', 'img_path', 'ori_shape', 'img_shape'))\n]\n\ntest_pipeline = [\n    *pre_transform,\n    dict(type='mmdet.Resize', scale=(416, 416), keep_ratio=True),\n    dict(\n        type='mmdet.Pad',\n        pad_to_square=True,\n        pad_val=dict(img=(114.0, 114.0, 114.0))),\n    dict(\n        type='PackDetPoseInputs',\n        meta_keys=('id', 'img_id', 'img_path', 'ori_shape', 'img_shape',\n                   'scale_factor', 'flip_indices'))\n]\n\ntrain_dataloader = dict(\n    batch_size=64, dataset=dict(pipeline=train_pipeline_stage1))\nval_dataloader = dict(dataset=dict(pipeline=test_pipeline))\ntest_dataloader = val_dataloader\n"
  },
  {
    "path": "projects/yolox_pose/datasets/__init__.py",
    "content": "import mmengine\nimport mmyolo\n\ncompatible_version = '0.5.0'\nif mmengine.digit_version(mmyolo.__version__)[1] > \\\n        mmengine.digit_version(compatible_version)[1]:\n    print(f'This project is only compatible with mmyolo {compatible_version} '\n          f'or lower. Please install the required version via:'\n          f'pip install mmyolo=={compatible_version}')\n\nfrom .bbox_keypoint_structure import *  # noqa\nfrom .coco_dataset import *  # noqa\nfrom .transforms import *  # noqa\n"
  },
  {
    "path": "projects/yolox_pose/datasets/bbox_keypoint_structure.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\nfrom typing import List, Optional, Sequence, Tuple, Type, TypeVar, Union\n\nimport numpy as np\nimport torch\nfrom mmdet.structures.bbox import HorizontalBoxes\nfrom torch import Tensor\n\nDeviceType = Union[str, torch.device]\nT = TypeVar('T')\nIndexType = Union[slice, int, list, torch.LongTensor, torch.cuda.LongTensor,\n                  torch.BoolTensor, torch.cuda.BoolTensor, np.ndarray]\n\n\nclass BBoxKeypoints(HorizontalBoxes):\n    \"\"\"The BBoxKeypoints class is a combination of bounding boxes and keypoints\n    representation. The box format used in BBoxKeypoints is the same as\n    HorizontalBoxes.\n\n    Args:\n        data (Tensor or np.ndarray): The box data with shape of\n            (N, 4).\n        keypoints (Tensor or np.ndarray): The keypoint data with shape of\n            (N, K, 2).\n        keypoints_visible (Tensor or np.ndarray): The visibility of keypoints\n            with shape of (N, K).\n        dtype (torch.dtype, Optional): data type of boxes. Defaults to None.\n        device (str or torch.device, Optional): device of boxes.\n            Default to None.\n        clone (bool): Whether clone ``boxes`` or not. Defaults to True.\n        mode (str, Optional): the mode of boxes. If it is 'cxcywh', the\n            `data` will be converted to 'xyxy' mode. Defaults to None.\n        flip_indices (list, Optional): The indices of keypoints when the\n            images is flipped. Defaults to None.\n\n    Notes:\n        N: the number of instances.\n        K: the number of keypoints.\n    \"\"\"\n\n    def __init__(self,\n                 data: Union[Tensor, np.ndarray],\n                 keypoints: Union[Tensor, np.ndarray],\n                 keypoints_visible: Union[Tensor, np.ndarray],\n                 dtype: Optional[torch.dtype] = None,\n                 device: Optional[DeviceType] = None,\n                 clone: bool = True,\n                 in_mode: Optional[str] = None,\n                 flip_indices: Optional[List] = None) -> None:\n\n        super().__init__(\n            data=data,\n            dtype=dtype,\n            device=device,\n            clone=clone,\n            in_mode=in_mode)\n\n        assert len(data) == len(keypoints)\n        assert len(data) == len(keypoints_visible)\n\n        assert keypoints.ndim == 3\n        assert keypoints_visible.ndim == 2\n\n        keypoints = torch.as_tensor(keypoints)\n        keypoints_visible = torch.as_tensor(keypoints_visible)\n\n        if device is not None:\n            keypoints = keypoints.to(device=device)\n            keypoints_visible = keypoints_visible.to(device=device)\n\n        if clone:\n            keypoints = keypoints.clone()\n            keypoints_visible = keypoints_visible.clone()\n\n        self.keypoints = keypoints\n        self.keypoints_visible = keypoints_visible\n        self.flip_indices = flip_indices\n\n    def flip_(self,\n              img_shape: Tuple[int, int],\n              direction: str = 'horizontal') -> None:\n        \"\"\"Flip boxes & kpts horizontally in-place.\n\n        Args:\n            img_shape (Tuple[int, int]): A tuple of image height and width.\n            direction (str): Flip direction, options are \"horizontal\",\n                \"vertical\" and \"diagonal\". Defaults to \"horizontal\"\n        \"\"\"\n        assert direction == 'horizontal'\n        super().flip_(img_shape, direction)\n        self.keypoints[..., 0] = img_shape[1] - self.keypoints[..., 0]\n        self.keypoints = self.keypoints[:, self.flip_indices]\n        self.keypoints_visible = self.keypoints_visible[:, self.flip_indices]\n\n    def translate_(self, distances: Tuple[float, float]) -> None:\n        \"\"\"Translate boxes and keypoints in-place.\n\n        Args:\n            distances (Tuple[float, float]): translate distances. The first\n                is horizontal distance and the second is vertical distance.\n        \"\"\"\n        boxes = self.tensor\n        assert len(distances) == 2\n        self.tensor = boxes + boxes.new_tensor(distances).repeat(2)\n        distances = self.keypoints.new_tensor(distances).reshape(1, 1, 2)\n        self.keypoints = self.keypoints + distances\n\n    def rescale_(self, scale_factor: Tuple[float, float]) -> None:\n        \"\"\"Rescale boxes & keypoints w.r.t. rescale_factor in-place.\n\n        Note:\n            Both ``rescale_`` and ``resize_`` will enlarge or shrink boxes\n            w.r.t ``scale_facotr``. The difference is that ``resize_`` only\n            changes the width and the height of boxes, but ``rescale_`` also\n            rescales the box centers simultaneously.\n\n        Args:\n            scale_factor (Tuple[float, float]): factors for scaling boxes.\n                The length should be 2.\n        \"\"\"\n        boxes = self.tensor\n        assert len(scale_factor) == 2\n\n        self.tensor = boxes * boxes.new_tensor(scale_factor).repeat(2)\n        scale_factor = self.keypoints.new_tensor(scale_factor).reshape(1, 1, 2)\n        self.keypoints = self.keypoints * scale_factor\n\n    def clip_(self, img_shape: Tuple[int, int]) -> None:\n        \"\"\"Clip bounding boxes and set invisible keypoints outside the image\n        boundary in-place.\n\n        Args:\n            img_shape (Tuple[int, int]): A tuple of image height and width.\n        \"\"\"\n        boxes = self.tensor\n        boxes[..., 0::2] = boxes[..., 0::2].clamp(0, img_shape[1])\n        boxes[..., 1::2] = boxes[..., 1::2].clamp(0, img_shape[0])\n\n        kpt_outside = torch.logical_or(\n            torch.logical_or(self.keypoints[..., 0] < 0,\n                             self.keypoints[..., 1] < 0),\n            torch.logical_or(self.keypoints[..., 0] > img_shape[1],\n                             self.keypoints[..., 1] > img_shape[0]))\n        self.keypoints_visible[kpt_outside] *= 0\n\n    def project_(self, homography_matrix: Union[Tensor, np.ndarray]) -> None:\n        \"\"\"Geometrically transform bounding boxes and keypoints in-place using\n        a homography matrix.\n\n        Args:\n            homography_matrix (Tensor or np.ndarray): A 3x3 tensor or ndarray\n                representing the homography matrix for the transformation.\n        \"\"\"\n        boxes = self.tensor\n        if isinstance(homography_matrix, np.ndarray):\n            homography_matrix = boxes.new_tensor(homography_matrix)\n\n        # Convert boxes to corners in homogeneous coordinates\n        corners = self.hbox2corner(boxes)\n        corners = torch.cat(\n            [corners, corners.new_ones(*corners.shape[:-1], 1)], dim=-1)\n\n        # Convert keypoints to homogeneous coordinates\n        keypoints = torch.cat([\n            self.keypoints,\n            self.keypoints.new_ones(*self.keypoints.shape[:-1], 1)\n        ],\n                              dim=-1)\n\n        # Transpose corners and keypoints for matrix multiplication\n        corners_T = torch.transpose(corners, -1, -2)\n        keypoints_T = torch.transpose(keypoints, -1, 0).contiguous().flatten(1)\n\n        # Apply homography matrix to corners and keypoints\n        corners_T = torch.matmul(homography_matrix, corners_T)\n        keypoints_T = torch.matmul(homography_matrix, keypoints_T)\n\n        # Transpose back to original shape\n        corners = torch.transpose(corners_T, -1, -2)\n        keypoints_T = keypoints_T.reshape(3, self.keypoints.shape[1], -1)\n        keypoints = torch.transpose(keypoints_T, -1, 0).contiguous()\n\n        # Convert corners and keypoints back to non-homogeneous coordinates\n        corners = corners[..., :2] / corners[..., 2:3]\n        keypoints = keypoints[..., :2] / keypoints[..., 2:3]\n\n        # Convert corners back to bounding boxes and update object attributes\n        self.tensor = self.corner2hbox(corners)\n        self.keypoints = keypoints\n\n    @classmethod\n    def cat(cls: Type[T], box_list: Sequence[T], dim: int = 0) -> T:\n        \"\"\"Cancatenates an instance list into one single instance. Similar to\n        ``torch.cat``.\n\n        Args:\n            box_list (Sequence[T]): A sequence of instances.\n            dim (int): The dimension over which the box and keypoint are\n                concatenated. Defaults to 0.\n\n        Returns:\n            T: Concatenated instance.\n        \"\"\"\n        assert isinstance(box_list, Sequence)\n        if len(box_list) == 0:\n            raise ValueError('box_list should not be a empty list.')\n\n        assert dim == 0\n        assert all(isinstance(boxes, cls) for boxes in box_list)\n\n        th_box_list = torch.cat([boxes.tensor for boxes in box_list], dim=dim)\n        th_kpt_list = torch.cat([boxes.keypoints for boxes in box_list],\n                                dim=dim)\n        th_kpt_vis_list = torch.cat(\n            [boxes.keypoints_visible for boxes in box_list], dim=dim)\n        flip_indices = box_list[0].flip_indices\n        return cls(\n            th_box_list,\n            th_kpt_list,\n            th_kpt_vis_list,\n            clone=False,\n            flip_indices=flip_indices)\n\n    def __getitem__(self: T, index: IndexType) -> T:\n        \"\"\"Rewrite getitem to protect the last dimension shape.\"\"\"\n        boxes = self.tensor\n        if isinstance(index, np.ndarray):\n            index = torch.as_tensor(index, device=self.device)\n        if isinstance(index, Tensor) and index.dtype == torch.bool:\n            assert index.dim() < boxes.dim()\n        elif isinstance(index, tuple):\n            assert len(index) < boxes.dim()\n            # `Ellipsis`(...) is commonly used in index like [None, ...].\n            # When `Ellipsis` is in index, it must be the last item.\n            if Ellipsis in index:\n                assert index[-1] is Ellipsis\n\n        boxes = boxes[index]\n        keypoints = self.keypoints[index]\n        keypoints_visible = self.keypoints_visible[index]\n        if boxes.dim() == 1:\n            boxes = boxes.reshape(1, -1)\n            keypoints = keypoints.reshape(1, -1, 2)\n            keypoints_visible = keypoints_visible.reshape(1, -1)\n        return type(self)(\n            boxes,\n            keypoints,\n            keypoints_visible,\n            flip_indices=self.flip_indices,\n            clone=False)\n\n    @property\n    def num_keypoints(self) -> Tensor:\n        \"\"\"Compute the number of visible keypoints for each object.\"\"\"\n        return self.keypoints_visible.sum(dim=1).int()\n\n    def __deepcopy__(self, memo):\n        \"\"\"Only clone the tensors when applying deepcopy.\"\"\"\n        cls = self.__class__\n        other = cls.__new__(cls)\n        memo[id(self)] = other\n        other.tensor = self.tensor.clone()\n        other.keypoints = self.keypoints.clone()\n        other.keypoints_visible = self.keypoints_visible.clone()\n        other.flip_indices = deepcopy(self.flip_indices)\n        return other\n\n    def clone(self: T) -> T:\n        \"\"\"Reload ``clone`` for tensors.\"\"\"\n        return type(self)(\n            self.tensor,\n            self.keypoints,\n            self.keypoints_visible,\n            flip_indices=self.flip_indices,\n            clone=True)\n\n    def to(self: T, *args, **kwargs) -> T:\n        \"\"\"Reload ``to`` for tensors.\"\"\"\n        return type(self)(\n            self.tensor.to(*args, **kwargs),\n            self.keypoints.to(*args, **kwargs),\n            self.keypoints_visible.to(*args, **kwargs),\n            flip_indices=self.flip_indices,\n            clone=False)\n"
  },
  {
    "path": "projects/yolox_pose/datasets/coco_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Any\n\nfrom mmengine.dataset import force_full_init\nfrom mmyolo.registry import DATASETS\n\nfrom mmpose.datasets import CocoDataset as MMPoseCocoDataset\n\n\n@DATASETS.register_module()\nclass CocoDataset(MMPoseCocoDataset):\n\n    @force_full_init\n    def prepare_data(self, idx) -> Any:\n        data_info = self.get_data_info(idx)\n        data_info['dataset'] = self\n        return self.pipeline(data_info)\n"
  },
  {
    "path": "projects/yolox_pose/datasets/transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Union\n\nimport numpy as np\nfrom mmcv.transforms import BaseTransform\nfrom mmdet.datasets.transforms import FilterAnnotations as FilterDetAnnotations\nfrom mmdet.datasets.transforms import PackDetInputs\nfrom mmdet.structures.bbox.box_type import autocast_box_type\nfrom mmyolo.registry import TRANSFORMS\n\nfrom .bbox_keypoint_structure import BBoxKeypoints\n\n\n@TRANSFORMS.register_module()\nclass PoseToDetConverter(BaseTransform):\n    \"\"\"This transform converts the pose data element into a format that is\n    suitable for the mmdet transforms.\"\"\"\n\n    def transform(self, results: dict) -> dict:\n\n        results['seg_map_path'] = None\n        results['height'] = results['img_shape'][0]\n        results['width'] = results['img_shape'][1]\n\n        num_instances = len(results.get('bbox', []))\n\n        if num_instances == 0:\n            results['bbox'] = np.empty((0, 4), dtype=np.float32)\n            results['keypoints'] = np.empty(\n                (0, len(results['flip_indices']), 2), dtype=np.float32)\n            results['keypoints_visible'] = np.empty(\n                (0, len(results['flip_indices'])), dtype=np.int32)\n            results['category_id'] = []\n\n        results['gt_bboxes'] = BBoxKeypoints(\n            data=results['bbox'],\n            keypoints=results['keypoints'],\n            keypoints_visible=results['keypoints_visible'],\n            flip_indices=results['flip_indices'],\n        )\n\n        results['gt_ignore_flags'] = np.array([False] * num_instances)\n        results['gt_bboxes_labels'] = np.array(results['category_id']) - 1\n\n        return results\n\n\n@TRANSFORMS.register_module()\nclass PackDetPoseInputs(PackDetInputs):\n    mapping_table = {\n        'gt_bboxes': 'bboxes',\n        'gt_bboxes_labels': 'labels',\n        'gt_masks': 'masks',\n        'gt_keypoints': 'keypoints',\n        'gt_keypoints_visible': 'keypoints_visible'\n    }\n\n    def __init__(self,\n                 meta_keys=('id', 'img_id', 'img_path', 'ori_shape',\n                            'img_shape', 'scale_factor', 'flip',\n                            'flip_direction', 'flip_indices', 'raw_ann_info'),\n                 pack_transformed=False):\n        self.meta_keys = meta_keys\n\n    def transform(self, results: dict) -> dict:\n        # Add keypoints and their visibility to the results dictionary\n        results['gt_keypoints'] = results['gt_bboxes'].keypoints\n        results['gt_keypoints_visible'] = results[\n            'gt_bboxes'].keypoints_visible\n\n        # Ensure all keys in `self.meta_keys` are in the `results` dictionary,\n        # which is necessary for `PackDetInputs` but not guaranteed during\n        # inference with an inferencer\n        for key in self.meta_keys:\n            if key not in results:\n                results[key] = None\n        return super().transform(results)\n\n\n@TRANSFORMS.register_module()\nclass FilterDetPoseAnnotations(FilterDetAnnotations):\n    \"\"\"Filter invalid annotations.\n\n    In addition to the conditions checked by ``FilterDetAnnotations``, this\n    filter adds a new condition requiring instances to have at least one\n    visible keypoints.\n    \"\"\"\n\n    @autocast_box_type()\n    def transform(self, results: dict) -> Union[dict, None]:\n        \"\"\"Transform function to filter annotations.\n\n        Args:\n            results (dict): Result dict.\n\n        Returns:\n            dict: Updated result dict.\n        \"\"\"\n        assert 'gt_bboxes' in results\n        gt_bboxes = results['gt_bboxes']\n        if gt_bboxes.shape[0] == 0:\n            return results\n\n        tests = []\n        if self.by_box:\n            tests.append(((gt_bboxes.widths > self.min_gt_bbox_wh[0]) &\n                          (gt_bboxes.heights > self.min_gt_bbox_wh[1]) &\n                          (gt_bboxes.num_keypoints > 0)).numpy())\n\n        if self.by_mask:\n            assert 'gt_masks' in results\n            gt_masks = results['gt_masks']\n            tests.append(gt_masks.areas >= self.min_gt_mask_area)\n\n        keep = tests[0]\n        for t in tests[1:]:\n            keep = keep & t\n\n        if not keep.any():\n            if self.keep_empty:\n                return None\n\n        keys = ('gt_bboxes', 'gt_bboxes_labels', 'gt_masks', 'gt_ignore_flags')\n        for key in keys:\n            if key in results:\n                results[key] = results[key][keep]\n\n        return results\n"
  },
  {
    "path": "projects/yolox_pose/models/__init__.py",
    "content": "import mmengine\nimport mmyolo\n\ncompatible_version = '0.5.0'\nif mmengine.digit_version(mmyolo.__version__)[1] > \\\n        mmengine.digit_version(compatible_version)[1]:\n    print(f'This project is only compatible with mmyolo {compatible_version} '\n          f'or lower. Please install the required version via:'\n          f'pip install mmyolo=={compatible_version}')\n\nfrom .assigner import *  # noqa\nfrom .data_preprocessor import *  # noqa\nfrom .oks_loss import *  # noqa\nfrom .utils import *  # noqa\nfrom .yolox_pose_head import *  # noqa\n"
  },
  {
    "path": "projects/yolox_pose/models/assigner.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional, Tuple\n\nimport torch\nimport torch.nn.functional as F\nfrom mmdet.models.task_modules.assigners import AssignResult, SimOTAAssigner\nfrom mmdet.utils import ConfigType\nfrom mmengine.structures import InstanceData\nfrom mmyolo.registry import MODELS, TASK_UTILS\nfrom torch import Tensor\n\nINF = 100000.0\nEPS = 1.0e-7\n\n\n@TASK_UTILS.register_module()\nclass PoseSimOTAAssigner(SimOTAAssigner):\n\n    def __init__(self,\n                 center_radius: float = 2.5,\n                 candidate_topk: int = 10,\n                 iou_weight: float = 3.0,\n                 cls_weight: float = 1.0,\n                 oks_weight: float = 0.0,\n                 vis_weight: float = 0.0,\n                 iou_calculator: ConfigType = dict(type='BboxOverlaps2D'),\n                 oks_calculator: ConfigType = dict(type='OksLoss')):\n        self.center_radius = center_radius\n        self.candidate_topk = candidate_topk\n        self.iou_weight = iou_weight\n        self.cls_weight = cls_weight\n        self.oks_weight = oks_weight\n        self.vis_weight = vis_weight\n\n        self.iou_calculator = TASK_UTILS.build(iou_calculator)\n        self.oks_calculator = MODELS.build(oks_calculator)\n\n    def assign(self,\n               pred_instances: InstanceData,\n               gt_instances: InstanceData,\n               gt_instances_ignore: Optional[InstanceData] = None,\n               **kwargs) -> AssignResult:\n        \"\"\"Assign gt to priors using SimOTA.\n\n        Args:\n            pred_instances (:obj:`InstanceData`): Instances of model\n                predictions. It includes ``priors``, and the priors can\n                be anchors or points, or the bboxes predicted by the\n                previous stage, has shape (n, 4). The bboxes predicted by\n                the current model or stage will be named ``bboxes``,\n                ``labels``, and ``scores``, the same as the ``InstanceData``\n                in other places.\n            gt_instances (:obj:`InstanceData`): Ground truth of instance\n                annotations. It usually includes ``bboxes``, with shape (k, 4),\n                and ``labels``, with shape (k, ).\n            gt_instances_ignore (:obj:`InstanceData`, optional): Instances\n                to be ignored during training. It includes ``bboxes``\n                attribute data that is ignored during training and testing.\n                Defaults to None.\n        Returns:\n            obj:`AssignResult`: The assigned result.\n        \"\"\"\n        gt_bboxes = gt_instances.bboxes\n        gt_labels = gt_instances.labels\n        gt_keypoints = gt_instances.keypoints\n        gt_keypoints_visible = gt_instances.keypoints_visible\n        num_gt = gt_bboxes.size(0)\n\n        decoded_bboxes = pred_instances.bboxes[..., :4]\n        pred_kpts = pred_instances.bboxes[..., 4:]\n        pred_kpts = pred_kpts.reshape(*pred_kpts.shape[:-1], -1, 3)\n        pred_kpts_vis = pred_kpts[..., -1]\n        pred_kpts = pred_kpts[..., :2]\n        pred_scores = pred_instances.scores\n        priors = pred_instances.priors\n        num_bboxes = decoded_bboxes.size(0)\n\n        # assign 0 by default\n        assigned_gt_inds = decoded_bboxes.new_full((num_bboxes, ),\n                                                   0,\n                                                   dtype=torch.long)\n        if num_gt == 0 or num_bboxes == 0:\n            # No ground truth or boxes, return empty assignment\n            max_overlaps = decoded_bboxes.new_zeros((num_bboxes, ))\n            assigned_labels = decoded_bboxes.new_full((num_bboxes, ),\n                                                      -1,\n                                                      dtype=torch.long)\n            return AssignResult(\n                num_gt, assigned_gt_inds, max_overlaps, labels=assigned_labels)\n\n        valid_mask, is_in_boxes_and_center = self.get_in_gt_and_in_center_info(\n            priors, gt_bboxes)\n        valid_decoded_bbox = decoded_bboxes[valid_mask]\n        valid_pred_scores = pred_scores[valid_mask]\n        valid_pred_kpts = pred_kpts[valid_mask]\n        valid_pred_kpts_vis = pred_kpts_vis[valid_mask]\n        num_valid = valid_decoded_bbox.size(0)\n        if num_valid == 0:\n            # No valid bboxes, return empty assignment\n            max_overlaps = decoded_bboxes.new_zeros((num_bboxes, ))\n            assigned_labels = decoded_bboxes.new_full((num_bboxes, ),\n                                                      -1,\n                                                      dtype=torch.long)\n            return AssignResult(\n                num_gt, assigned_gt_inds, max_overlaps, labels=assigned_labels)\n\n        cost_matrix = (~is_in_boxes_and_center) * INF\n\n        # calculate iou\n        pairwise_ious = self.iou_calculator(valid_decoded_bbox, gt_bboxes)\n        if self.iou_weight > 0:\n            iou_cost = -torch.log(pairwise_ious + EPS)\n            cost_matrix = cost_matrix + iou_cost * self.iou_weight\n\n        # calculate oks\n        pairwise_oks = self.oks_calculator.compute_oks(\n            valid_pred_kpts.unsqueeze(1),  # [num_valid, -1, k, 2]\n            gt_keypoints.unsqueeze(0),  # [1, num_gt, k, 2]\n            gt_keypoints_visible.unsqueeze(0),  # [1, num_gt, k]\n            bboxes=gt_bboxes.unsqueeze(0),  # [1, num_gt, 4]\n        )  # -> [num_valid, num_gt]\n        if self.oks_weight > 0:\n            oks_cost = -torch.log(pairwise_oks + EPS)\n            cost_matrix = cost_matrix + oks_cost * self.oks_weight\n\n        # calculate cls\n        if self.cls_weight > 0:\n            gt_onehot_label = (\n                F.one_hot(gt_labels.to(torch.int64),\n                          pred_scores.shape[-1]).float().unsqueeze(0).repeat(\n                              num_valid, 1, 1))\n\n            valid_pred_scores = valid_pred_scores.unsqueeze(1).repeat(\n                1, num_gt, 1)\n            # disable AMP autocast to avoid overflow\n            with torch.cuda.amp.autocast(enabled=False):\n                cls_cost = (\n                    F.binary_cross_entropy(\n                        valid_pred_scores.to(dtype=torch.float32),\n                        gt_onehot_label,\n                        reduction='none',\n                    ).sum(-1).to(dtype=valid_pred_scores.dtype))\n            cost_matrix = cost_matrix + cls_cost * self.cls_weight\n\n        # calculate vis\n        if self.vis_weight > 0:\n            valid_pred_kpts_vis = valid_pred_kpts_vis.sigmoid().unsqueeze(\n                1).repeat(1, num_gt, 1)  # [num_valid, 1, k]\n            gt_kpt_vis = gt_keypoints_visible.unsqueeze(\n                0).float()  # [1, num_gt, k]\n            with torch.cuda.amp.autocast(enabled=False):\n                vis_cost = (\n                    F.binary_cross_entropy(\n                        valid_pred_kpts_vis.to(dtype=torch.float32),\n                        gt_kpt_vis.repeat(num_valid, 1, 1),\n                        reduction='none',\n                    ).sum(-1).to(dtype=valid_pred_kpts_vis.dtype))\n            cost_matrix = cost_matrix + vis_cost * self.vis_weight\n\n        # mixed metric\n        pairwise_oks = pairwise_oks.pow(0.5)\n        matched_pred_oks, matched_gt_inds = \\\n            self.dynamic_k_matching(\n                cost_matrix, pairwise_ious, pairwise_oks, num_gt, valid_mask)\n\n        # convert to AssignResult format\n        assigned_gt_inds[valid_mask] = matched_gt_inds + 1\n        assigned_labels = assigned_gt_inds.new_full((num_bboxes, ), -1)\n        assigned_labels[valid_mask] = gt_labels[matched_gt_inds].long()\n        max_overlaps = assigned_gt_inds.new_full((num_bboxes, ),\n                                                 -INF,\n                                                 dtype=torch.float32)\n        max_overlaps[valid_mask] = matched_pred_oks\n        return AssignResult(\n            num_gt, assigned_gt_inds, max_overlaps, labels=assigned_labels)\n\n    def dynamic_k_matching(self, cost: Tensor, pairwise_ious: Tensor,\n                           pairwise_oks: Tensor, num_gt: int,\n                           valid_mask: Tensor) -> Tuple[Tensor, Tensor]:\n        \"\"\"Use IoU and matching cost to calculate the dynamic top-k positive\n        targets.\"\"\"\n        matching_matrix = torch.zeros_like(cost, dtype=torch.uint8)\n        # select candidate topk ious for dynamic-k calculation\n        candidate_topk = min(self.candidate_topk, pairwise_ious.size(0))\n        topk_ious, _ = torch.topk(pairwise_ious, candidate_topk, dim=0)\n        # calculate dynamic k for each gt\n        dynamic_ks = torch.clamp(topk_ious.sum(0).int(), min=1)\n        for gt_idx in range(num_gt):\n            _, pos_idx = torch.topk(\n                cost[:, gt_idx], k=dynamic_ks[gt_idx], largest=False)\n            matching_matrix[:, gt_idx][pos_idx] = 1\n\n        del topk_ious, dynamic_ks, pos_idx\n\n        prior_match_gt_mask = matching_matrix.sum(1) > 1\n        if prior_match_gt_mask.sum() > 0:\n            cost_min, cost_argmin = torch.min(\n                cost[prior_match_gt_mask, :], dim=1)\n            matching_matrix[prior_match_gt_mask, :] *= 0\n            matching_matrix[prior_match_gt_mask, cost_argmin] = 1\n        # get foreground mask inside box and center prior\n        fg_mask_inboxes = matching_matrix.sum(1) > 0\n        valid_mask[valid_mask.clone()] = fg_mask_inboxes\n\n        matched_gt_inds = matching_matrix[fg_mask_inboxes, :].argmax(1)\n        matched_pred_oks = (matching_matrix *\n                            pairwise_oks).sum(1)[fg_mask_inboxes]\n        return matched_pred_oks, matched_gt_inds\n"
  },
  {
    "path": "projects/yolox_pose/models/data_preprocessor.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\n\nfrom mmdet.models import BatchSyncRandomResize\nfrom mmyolo.registry import MODELS\nfrom torch import Tensor\n\nfrom mmpose.structures import PoseDataSample\n\n\n@MODELS.register_module()\nclass PoseBatchSyncRandomResize(BatchSyncRandomResize):\n    \"\"\"Batch random resize which synchronizes the random size across ranks.\n\n    This transform is similar to `mmdet.BatchSyncRandomResize`, but it also\n    rescales the keypoints coordinates simultaneously.\n    \"\"\"\n\n    def forward(self, inputs: Tensor, data_samples: List[PoseDataSample]\n                ) -> Tuple[Tensor, List[PoseDataSample]]:\n\n        inputs = inputs.float()\n        h, w = inputs.shape[-2:]\n        if self._input_size is None:\n            self._input_size = (h, w)\n        scale_y = self._input_size[0] / h\n        scale_x = self._input_size[1] / w\n        if scale_x != 1 or scale_y != 1:\n            for data_sample in data_samples:\n                data_sample.gt_instances.keypoints[..., 0] *= scale_x\n                data_sample.gt_instances.keypoints[..., 1] *= scale_y\n\n        return super().forward(inputs, data_samples)\n"
  },
  {
    "path": "projects/yolox_pose/models/oks_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import Optional\n\nimport torch\nimport torch.nn as nn\nfrom mmyolo.registry import MODELS\nfrom torch import Tensor\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\n\n\n@MODELS.register_module()\nclass OksLoss(nn.Module):\n    \"\"\"A PyTorch implementation of the Object Keypoint Similarity (OKS) loss as\n    described in the paper \"YOLO-Pose: Enhancing YOLO for Multi Person Pose\n    Estimation Using Object Keypoint Similarity Loss\" by Debapriya et al.\n    (2022).\n\n    The OKS loss is used for keypoint-based object recognition and consists\n    of a measure of the similarity between predicted and ground truth\n    keypoint locations, adjusted by the size of the object in the image.\n\n    The loss function takes as input the predicted keypoint locations, the\n    ground truth keypoint locations, a mask indicating which keypoints are\n    valid, and bounding boxes for the objects.\n\n    Args:\n        metainfo (Optional[str]): Path to a JSON file containing information\n            about the dataset's annotations.\n        loss_weight (float): Weight for the loss.\n    \"\"\"\n\n    def __init__(self,\n                 metainfo: Optional[str] = None,\n                 loss_weight: float = 1.0):\n        super().__init__()\n\n        if metainfo is not None:\n            metainfo = parse_pose_metainfo(dict(from_file=metainfo))\n            sigmas = metainfo.get('sigmas', None)\n            if sigmas is not None:\n                self.register_buffer('sigmas', torch.as_tensor(sigmas))\n        self.loss_weight = loss_weight\n\n    def forward(self,\n                output: Tensor,\n                target: Tensor,\n                target_weights: Tensor,\n                bboxes: Optional[Tensor] = None) -> Tensor:\n        oks = self.compute_oks(output, target, target_weights, bboxes)\n        loss = 1 - oks\n        return loss * self.loss_weight\n\n    def compute_oks(self,\n                    output: Tensor,\n                    target: Tensor,\n                    target_weights: Tensor,\n                    bboxes: Optional[Tensor] = None) -> Tensor:\n        \"\"\"Calculates the OKS loss.\n\n        Args:\n            output (Tensor): Predicted keypoints in shape N x k x 2, where N\n                is batch size, k is the number of keypoints, and 2 are the\n                xy coordinates.\n            target (Tensor): Ground truth keypoints in the same shape as\n                output.\n            target_weights (Tensor): Mask of valid keypoints in shape N x k,\n                with 1 for valid and 0 for invalid.\n            bboxes (Optional[Tensor]): Bounding boxes in shape N x 4,\n                where 4 are the xyxy coordinates.\n\n        Returns:\n            Tensor: The calculated OKS loss.\n        \"\"\"\n\n        dist = torch.norm(output - target, dim=-1)\n\n        if hasattr(self, 'sigmas'):\n            sigmas = self.sigmas.reshape(*((1, ) * (dist.ndim - 1)), -1)\n            dist = dist / sigmas\n        if bboxes is not None:\n            area = torch.norm(bboxes[..., 2:] - bboxes[..., :2], dim=-1)\n            dist = dist / area.clip(min=1e-8).unsqueeze(-1)\n\n        return (torch.exp(-dist.pow(2) / 2) * target_weights).sum(\n            dim=-1) / target_weights.sum(dim=-1).clip(min=1e-8)\n"
  },
  {
    "path": "projects/yolox_pose/models/utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import defaultdict\nfrom copy import deepcopy\nfrom typing import Any, Callable, Dict, Optional, Tuple\n\n\nclass OutputSaveObjectWrapper:\n    \"\"\"A wrapper class that saves the output of function calls on an object.\"\"\"\n\n    def __init__(self, obj: Any) -> None:\n        self.obj = obj\n        self.log = defaultdict(list)\n\n    def __getattr__(self, attr: str) -> Any:\n        \"\"\"Overrides the default behavior when an attribute is accessed.\n\n        - If the attribute is callable, hooks the attribute and saves the\n        returned value of the function call to the log.\n        - If the attribute is not callable, saves the attribute's value to the\n        log and returns the value.\n        \"\"\"\n        orig_attr = getattr(self.obj, attr)\n\n        if not callable(orig_attr):\n            self.log[attr].append(orig_attr)\n            return orig_attr\n\n        def hooked(*args: Tuple, **kwargs: Dict) -> Any:\n            \"\"\"The hooked function that logs the return value of the original\n            function.\"\"\"\n            result = orig_attr(*args, **kwargs)\n            self.log[attr].append(result)\n            return result\n\n        return hooked\n\n    def clear(self):\n        \"\"\"Clears the log of function call outputs.\"\"\"\n        self.log.clear()\n\n    def __deepcopy__(self, memo):\n        \"\"\"Only copy the object when applying deepcopy.\"\"\"\n        other = type(self)(deepcopy(self.obj))\n        memo[id(self)] = other\n        return other\n\n\nclass OutputSaveFunctionWrapper:\n    \"\"\"A class that wraps a function and saves its outputs.\n\n    This class can be used to decorate a function to save its outputs. It wraps\n    the function with a `__call__` method that calls the original function and\n    saves the results in a log attribute.\n\n    Args:\n        func (Callable): A function to wrap.\n        spec (Optional[Dict]): A dictionary of global variables to use as the\n            namespace for the wrapper. If `None`, the global namespace of the\n            original function is used.\n    \"\"\"\n\n    def __init__(self, func: Callable, spec: Optional[Dict]) -> None:\n        \"\"\"Initializes the OutputSaveFunctionWrapper instance.\"\"\"\n        assert callable(func)\n        self.log = []\n        self.func = func\n        self.func_name = func.__name__\n\n        if isinstance(spec, dict):\n            self.spec = spec\n        elif hasattr(func, '__globals__'):\n            self.spec = func.__globals__\n        else:\n            raise ValueError\n\n    def __call__(self, *args, **kwargs) -> Any:\n        \"\"\"Calls the wrapped function with the given arguments and saves the\n        results in the `log` attribute.\"\"\"\n        results = self.func(*args, **kwargs)\n        self.log.append(results)\n        return results\n\n    def __enter__(self) -> None:\n        \"\"\"Enters the context and sets the wrapped function to be a global\n        variable in the specified namespace.\"\"\"\n        self.spec[self.func_name] = self\n        return self.log\n\n    def __exit__(self, exc_type, exc_val, exc_tb) -> None:\n        \"\"\"Exits the context and resets the wrapped function to its original\n        value in the specified namespace.\"\"\"\n        self.spec[self.func_name] = self.func\n"
  },
  {
    "path": "projects/yolox_pose/models/yolox_pose_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom collections import defaultdict\nfrom typing import List, Optional, Sequence, Tuple, Union\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.ops import batched_nms\nfrom mmdet.models.utils import filter_scores_and_topk\nfrom mmdet.utils import ConfigType, OptInstanceList\nfrom mmengine.config import ConfigDict\nfrom mmengine.model import ModuleList, bias_init_with_prob\nfrom mmengine.structures import InstanceData\nfrom mmyolo.models.dense_heads import YOLOXHead, YOLOXHeadModule\nfrom mmyolo.registry import MODELS\nfrom torch import Tensor\n\nfrom .utils import OutputSaveFunctionWrapper, OutputSaveObjectWrapper\n\n\n@MODELS.register_module()\nclass YOLOXPoseHeadModule(YOLOXHeadModule):\n    \"\"\"YOLOXPoseHeadModule serves as a head module for `YOLOX-Pose`.\n\n    In comparison to `YOLOXHeadModule`, this module introduces branches for\n    keypoint prediction.\n    \"\"\"\n\n    def __init__(self, num_keypoints: int, *args, **kwargs):\n        self.num_keypoints = num_keypoints\n        super().__init__(*args, **kwargs)\n\n    def _init_layers(self):\n        \"\"\"Initializes the layers in the head module.\"\"\"\n        super()._init_layers()\n\n        # The pose branch requires additional layers for precise regression\n        self.stacked_convs *= 2\n\n        # Create separate layers for each level of feature maps\n        pose_convs, offsets_preds, vis_preds = [], [], []\n        for _ in self.featmap_strides:\n            pose_convs.append(self._build_stacked_convs())\n            offsets_preds.append(\n                nn.Conv2d(self.feat_channels, self.num_keypoints * 2, 1))\n            vis_preds.append(\n                nn.Conv2d(self.feat_channels, self.num_keypoints, 1))\n\n        self.multi_level_pose_convs = ModuleList(pose_convs)\n        self.multi_level_conv_offsets = ModuleList(offsets_preds)\n        self.multi_level_conv_vis = ModuleList(vis_preds)\n\n    def init_weights(self):\n        \"\"\"Initialize weights of the head.\"\"\"\n        super().init_weights()\n\n        # Use prior in model initialization to improve stability\n        bias_init = bias_init_with_prob(0.01)\n        for conv_vis in self.multi_level_conv_vis:\n            conv_vis.bias.data.fill_(bias_init)\n\n    def forward(self, x: Tuple[Tensor]) -> Tuple[List]:\n        \"\"\"Forward features from the upstream network.\"\"\"\n        offsets_pred, vis_pred = [], []\n        for i in range(len(x)):\n            pose_feat = self.multi_level_pose_convs[i](x[i])\n            offsets_pred.append(self.multi_level_conv_offsets[i](pose_feat))\n            vis_pred.append(self.multi_level_conv_vis[i](pose_feat))\n\n        return (*super().forward(x), offsets_pred, vis_pred)\n\n\n@MODELS.register_module()\nclass YOLOXPoseHead(YOLOXHead):\n    \"\"\"YOLOXPoseHead head used in `YOLO-Pose.\n\n    <https://arxiv.org/abs/2204.06806>`_.\n\n    Args:\n        loss_pose (ConfigDict, optional): Config of keypoint OKS loss.\n    \"\"\"\n\n    def __init__(\n        self,\n        loss_pose: Optional[ConfigType] = None,\n        *args,\n        **kwargs,\n    ):\n        super().__init__(*args, **kwargs)\n        self.loss_pose = MODELS.build(loss_pose)\n        self.num_keypoints = self.head_module.num_keypoints\n\n        # set up buffers to save variables generated in methods of\n        # the class's base class.\n        self._log = defaultdict(list)\n        self.sampler = OutputSaveObjectWrapper(self.sampler)\n\n        # ensure that the `sigmas` in self.assigner.oks_calculator\n        # is on the same device as the model\n        if hasattr(self.assigner, 'oks_calculator'):\n            self.add_module('assigner_oks_calculator',\n                            self.assigner.oks_calculator)\n\n    def _clear(self):\n        \"\"\"Clear variable buffers.\"\"\"\n        self.sampler.clear()\n        self._log.clear()\n\n    def loss_by_feat(self,\n                     cls_scores: Sequence[Tensor],\n                     bbox_preds: Sequence[Tensor],\n                     objectnesses: Sequence[Tensor],\n                     kpt_preds: Sequence[Tensor],\n                     vis_preds: Sequence[Tensor],\n                     batch_gt_instances: Sequence[InstanceData],\n                     batch_img_metas: Sequence[dict],\n                     batch_gt_instances_ignore: OptInstanceList = None\n                     ) -> dict:\n        \"\"\"Calculate the loss based on the features extracted by the detection\n        head.\n\n        In addition to the base class method, keypoint losses are also\n        calculated in this method.\n        \"\"\"\n\n        self._clear()\n\n        # collect keypoints coordinates and visibility from model predictions\n        kpt_preds = torch.cat([\n            kpt_pred.flatten(2).permute(0, 2, 1).contiguous()\n            for kpt_pred in kpt_preds\n        ],\n                              dim=1)\n\n        featmap_sizes = [cls_score.shape[2:] for cls_score in cls_scores]\n        mlvl_priors = self.prior_generator.grid_priors(\n            featmap_sizes,\n            dtype=cls_scores[0].dtype,\n            device=cls_scores[0].device,\n            with_stride=True)\n        grid_priors = torch.cat(mlvl_priors)\n\n        flatten_kpts = self.decode_pose(grid_priors[..., :2], kpt_preds,\n                                        grid_priors[..., 2])\n\n        vis_preds = torch.cat([\n            vis_pred.flatten(2).permute(0, 2, 1).contiguous()\n            for vis_pred in vis_preds\n        ],\n                              dim=1)\n\n        # compute detection losses and collect targets for keypoints\n        # predictions simultaneously\n        self._log['pred_keypoints'] = list(flatten_kpts.detach().split(\n            1, dim=0))\n        self._log['pred_keypoints_vis'] = list(vis_preds.detach().split(\n            1, dim=0))\n\n        losses = super().loss_by_feat(cls_scores, bbox_preds, objectnesses,\n                                      batch_gt_instances, batch_img_metas,\n                                      batch_gt_instances_ignore)\n\n        kpt_targets, vis_targets = [], []\n        sampling_results = self.sampler.log['sample']\n        sampling_result_idx = 0\n        for gt_instances in batch_gt_instances:\n            if len(gt_instances) > 0:\n                sampling_result = sampling_results[sampling_result_idx]\n                kpt_target = gt_instances['keypoints'][\n                    sampling_result.pos_assigned_gt_inds]\n                vis_target = gt_instances['keypoints_visible'][\n                    sampling_result.pos_assigned_gt_inds]\n                sampling_result_idx += 1\n                kpt_targets.append(kpt_target)\n                vis_targets.append(vis_target)\n\n        if len(kpt_targets) > 0:\n            kpt_targets = torch.cat(kpt_targets, 0)\n            vis_targets = torch.cat(vis_targets, 0)\n\n        # compute keypoint losses\n        if len(kpt_targets) > 0:\n            vis_targets = (vis_targets > 0).float()\n            pos_masks = torch.cat(self._log['foreground_mask'], 0)\n            bbox_targets = torch.cat(self._log['bbox_target'], 0)\n            loss_kpt = self.loss_pose(\n                flatten_kpts.view(-1, self.num_keypoints, 2)[pos_masks],\n                kpt_targets, vis_targets, bbox_targets)\n            loss_vis = self.loss_cls(\n                vis_preds.view(-1, self.num_keypoints)[pos_masks],\n                vis_targets) / vis_targets.sum()\n        else:\n            loss_kpt = kpt_preds.sum() * 0\n            loss_vis = vis_preds.sum() * 0\n\n        losses.update(dict(loss_kpt=loss_kpt, loss_vis=loss_vis))\n\n        self._clear()\n        return losses\n\n    @torch.no_grad()\n    def _get_targets_single(self,\n                            priors: Tensor,\n                            cls_preds: Tensor,\n                            decoded_bboxes: Tensor,\n                            objectness: Tensor,\n                            gt_instances: InstanceData,\n                            img_meta: dict,\n                            gt_instances_ignore: Optional[InstanceData] = None\n                            ) -> tuple:\n        \"\"\"Calculates targets for a single image, and saves them to the log.\n\n        This method is similar to the _get_targets_single method in the base\n        class, but additionally saves the foreground mask and bbox targets to\n        the log.\n        \"\"\"\n\n        # Construct a combined representation of bboxes and keypoints to\n        # ensure keypoints are also involved in the positive sample\n        # assignment process\n        kpt = self._log['pred_keypoints'].pop(0).squeeze(0)\n        kpt_vis = self._log['pred_keypoints_vis'].pop(0).squeeze(0)\n        kpt = torch.cat((kpt, kpt_vis.unsqueeze(-1)), dim=-1)\n        decoded_bboxes = torch.cat((decoded_bboxes, kpt.flatten(1)), dim=1)\n\n        targets = super()._get_targets_single(priors, cls_preds,\n                                              decoded_bboxes, objectness,\n                                              gt_instances, img_meta,\n                                              gt_instances_ignore)\n        self._log['foreground_mask'].append(targets[0])\n        self._log['bbox_target'].append(targets[3])\n        return targets\n\n    def predict_by_feat(self,\n                        cls_scores: List[Tensor],\n                        bbox_preds: List[Tensor],\n                        objectnesses: Optional[List[Tensor]] = None,\n                        kpt_preds: Optional[List[Tensor]] = None,\n                        vis_preds: Optional[List[Tensor]] = None,\n                        batch_img_metas: Optional[List[dict]] = None,\n                        cfg: Optional[ConfigDict] = None,\n                        rescale: bool = True,\n                        with_nms: bool = True) -> List[InstanceData]:\n        \"\"\"Transform a batch of output features extracted by the head into bbox\n        and keypoint results.\n\n        In addition to the base class method, keypoint predictions are also\n        calculated in this method.\n        \"\"\"\n\n        # calculate predicted bboxes and get the kept instances indices\n        with OutputSaveFunctionWrapper(\n                filter_scores_and_topk,\n                super().predict_by_feat.__globals__) as outputs_1:\n            with OutputSaveFunctionWrapper(\n                    batched_nms,\n                    super()._bbox_post_process.__globals__) as outputs_2:\n                results_list = super().predict_by_feat(cls_scores, bbox_preds,\n                                                       objectnesses,\n                                                       batch_img_metas, cfg,\n                                                       rescale, with_nms)\n                keep_indices_topk = [out[2] for out in outputs_1]\n                keep_indices_nms = [out[1] for out in outputs_2]\n\n        num_imgs = len(batch_img_metas)\n\n        # recover keypoints coordinates from model predictions\n        featmap_sizes = [vis_pred.shape[2:] for vis_pred in vis_preds]\n        priors = torch.cat(self.mlvl_priors)\n        strides = [\n            priors.new_full((featmap_size.numel() * self.num_base_priors, ),\n                            stride) for featmap_size, stride in zip(\n                                featmap_sizes, self.featmap_strides)\n        ]\n        strides = torch.cat(strides)\n        kpt_preds = torch.cat([\n            kpt_pred.permute(0, 2, 3, 1).reshape(\n                num_imgs, -1, self.num_keypoints * 2) for kpt_pred in kpt_preds\n        ],\n                              dim=1)\n        flatten_decoded_kpts = self.decode_pose(priors, kpt_preds, strides)\n\n        vis_preds = torch.cat([\n            vis_pred.permute(0, 2, 3, 1).reshape(\n                num_imgs, -1, self.num_keypoints) for vis_pred in vis_preds\n        ],\n                              dim=1).sigmoid()\n\n        # select keypoints predictions according to bbox scores and nms result\n        keep_indices_nms_idx = 0\n        for pred_instances, kpts, kpts_vis, img_meta, keep_idxs \\\n            in zip(\n                results_list, flatten_decoded_kpts, vis_preds,\n                batch_img_metas, keep_indices_topk):\n\n            pred_instances.bbox_scores = pred_instances.scores\n\n            if len(pred_instances) == 0:\n                pred_instances.keypoints = kpts[:0]\n                pred_instances.keypoint_scores = kpts_vis[:0]\n                continue\n\n            kpts = kpts[keep_idxs]\n            kpts_vis = kpts_vis[keep_idxs]\n\n            if rescale:\n                pad_param = img_meta.get('img_meta', None)\n                scale_factor = img_meta['scale_factor']\n                if pad_param is not None:\n                    kpts -= kpts.new_tensor([pad_param[2], pad_param[0]])\n                kpts /= kpts.new_tensor(scale_factor).repeat(\n                    (1, self.num_keypoints, 1))\n\n            keep_idxs_nms = keep_indices_nms[keep_indices_nms_idx]\n            kpts = kpts[keep_idxs_nms]\n            kpts_vis = kpts_vis[keep_idxs_nms]\n            keep_indices_nms_idx += 1\n\n            pred_instances.keypoints = kpts\n            pred_instances.keypoint_scores = kpts_vis\n\n        return results_list\n\n    def predict(self,\n                x: Tuple[Tensor],\n                batch_data_samples,\n                rescale: bool = False):\n        predictions = [\n            pred_instances.numpy() for pred_instances in super().predict(\n                x, batch_data_samples, rescale)\n        ]\n        return predictions\n\n    def decode_pose(self, grids: torch.Tensor, offsets: torch.Tensor,\n                    strides: Union[torch.Tensor, int]) -> torch.Tensor:\n        \"\"\"Decode regression offsets to keypoints.\n\n        Args:\n            grids (torch.Tensor): The coordinates of the feature map grids.\n            offsets (torch.Tensor): The predicted offset of each keypoint\n                relative to its corresponding grid.\n            strides (torch.Tensor | int): The stride of the feature map for\n                each instance.\n\n        Returns:\n            torch.Tensor: The decoded keypoints coordinates.\n        \"\"\"\n\n        if isinstance(strides, int):\n            strides = torch.tensor([strides]).to(offsets)\n\n        strides = strides.reshape(1, -1, 1, 1)\n        offsets = offsets.reshape(*offsets.shape[:2], -1, 2)\n        xy_coordinates = (offsets[..., :2] * strides) + grids.unsqueeze(1)\n        return xy_coordinates\n\n    @staticmethod\n    def gt_instances_preprocess(batch_gt_instances: List[InstanceData], *args,\n                                **kwargs) -> List[InstanceData]:\n        return batch_gt_instances\n"
  },
  {
    "path": "pytest.ini",
    "content": "[pytest]\naddopts = --xdoctest --xdoctest-style=auto\nnorecursedirs = .git ignore build __pycache__ data docker docs .eggs .mim tests/legacy\n\nfilterwarnings= default\n                ignore:.*No cfgstr given in Cacher constructor or call.*:Warning\n                ignore:.*Define the __nice__ method for.*:Warning\n"
  },
  {
    "path": "requirements/albu.txt",
    "content": "albumentations>=0.3.2 --no-binary qudida,albumentations\n"
  },
  {
    "path": "requirements/build.txt",
    "content": "# These must be installed before building mmpose\nnumpy\ntorch>=1.8\n"
  },
  {
    "path": "requirements/docs.txt",
    "content": "docutils==0.16.0\nmarkdown\nmyst-parser\n-e git+https://github.com/gaotongxiao/pytorch_sphinx_theme.git#egg=pytorch_sphinx_theme\nsphinx==4.5.0\nsphinx_copybutton\nsphinx_markdown_tables\nurllib3<2.0.0\n"
  },
  {
    "path": "requirements/mminstall.txt",
    "content": "mmcv>=2.0.0,<3.0.0\nmmdet>=3.0.0,<3.3.0\nmmengine>=0.4.0,<1.0.0\n"
  },
  {
    "path": "requirements/optional.txt",
    "content": "requests\n"
  },
  {
    "path": "requirements/poseval.txt",
    "content": "poseval@git+https://github.com/svenkreiss/poseval.git\nshapely==1.8.4\n"
  },
  {
    "path": "requirements/readthedocs.txt",
    "content": "mmcv>=2.0.0rc4\nmmengine>=0.6.0,<1.0.0\nmunkres\nregex\nscipy\ntitlecase\ntorch>1.6\ntorchvision\nxtcocotools>=1.13\n"
  },
  {
    "path": "requirements/runtime.txt",
    "content": "chumpy\njson_tricks\nmatplotlib\nmunkres\nnumpy\nopencv-python\npillow\nscipy\ntorchvision\nxtcocotools>=1.12\n"
  },
  {
    "path": "requirements/tests.txt",
    "content": "coverage\nflake8\ninterrogate\nisort==4.3.21\nparameterized\npytest\npytest-runner\nxdoctest>=0.10.0\nyapf\n"
  },
  {
    "path": "requirements.txt",
    "content": "-r requirements/build.txt\n-r requirements/runtime.txt\n-r requirements/tests.txt\n-r requirements/optional.txt\n"
  },
  {
    "path": "setup.cfg",
    "content": "[bdist_wheel]\nuniversal=1\n\n[aliases]\ntest=pytest\n\n[yapf]\nbased_on_style = pep8\nblank_line_before_nested_class_or_def = true\nsplit_before_expression_after_opening_paren = true\nsplit_penalty_import_names=0\nSPLIT_PENALTY_AFTER_OPENING_BRACKET=800\n\n[isort]\nline_length = 79\nmulti_line_output = 0\nextra_standard_library = pkg_resources,setuptools\nknown_first_party = mmpose\nknown_third_party = PIL,cv2,h5py,json_tricks,matplotlib,mmcv,munkres,numpy,pytest,pytorch_sphinx_theme,requests,scipy,seaborn,spacepy,titlecase,torch,torchvision,webcam_apis,xmltodict,xtcocotools\nno_lines_before = STDLIB,LOCALFOLDER\ndefault_section = THIRDPARTY\n\n[flake8]\nper-file-ignores =\n    mmpose/configs/*: F401,F403,F405\n    projects/*/configs/*: F401,F403,F405\n"
  },
  {
    "path": "setup.py",
    "content": "import os\nimport os.path as osp\nimport platform\nimport shutil\nimport sys\nimport warnings\nfrom setuptools import find_packages, setup\n\ntry:\n    import google.colab  # noqa\n    ON_COLAB = True\nexcept ImportError:\n    ON_COLAB = False\n\n\ndef readme():\n    with open('README.md', encoding='utf-8') as f:\n        content = f.read()\n    return content\n\n\nversion_file = 'mmpose/version.py'\n\n\ndef get_version():\n    with open(version_file, 'r') as f:\n        exec(compile(f.read(), version_file, 'exec'))\n    import sys\n\n    # return short version for sdist\n    if 'sdist' in sys.argv or 'bdist_wheel' in sys.argv:\n        return locals()['short_version']\n    else:\n        return locals()['__version__']\n\n\ndef parse_requirements(fname='requirements.txt', with_version=True):\n    \"\"\"Parse the package dependencies listed in a requirements file but strips\n    specific versioning information.\n\n    Args:\n        fname (str): path to requirements file\n        with_version (bool, default=False): if True include version specs\n\n    Returns:\n        List[str]: list of requirements items\n\n    CommandLine:\n        python -c \"import setup; print(setup.parse_requirements())\"\n    \"\"\"\n    import re\n    import sys\n    from os.path import exists\n    require_fpath = fname\n\n    def parse_line(line):\n        \"\"\"Parse information from a line in a requirements text file.\"\"\"\n        if line.startswith('-r '):\n            # Allow specifying requirements in other files\n            target = line.split(' ')[1]\n            for info in parse_require_file(target):\n                yield info\n        else:\n            info = {'line': line}\n            if line.startswith('-e '):\n                info['package'] = line.split('#egg=')[1]\n            elif '@git+' in line:\n                info['package'] = line\n            else:\n                # Remove versioning from the package\n                pat = '(' + '|'.join(['>=', '==', '>']) + ')'\n                parts = re.split(pat, line, maxsplit=1)\n                parts = [p.strip() for p in parts]\n\n                info['package'] = parts[0]\n                if len(parts) > 1:\n                    op, rest = parts[1:]\n                    if ';' in rest:\n                        # Handle platform specific dependencies\n                        # http://setuptools.readthedocs.io/en/latest/setuptools.html#declaring-platform-specific-dependencies\n                        version, platform_deps = map(str.strip,\n                                                     rest.split(';'))\n                        info['platform_deps'] = platform_deps\n                    else:\n                        version = rest  # NOQA\n                    info['version'] = (op, version)\n\n            if ON_COLAB and info['package'] == 'xtcocotools':\n                # Due to an incompatibility between the Colab platform and the\n                # pre-built xtcocotools PyPI package, it is necessary to\n                # compile xtcocotools from source on Colab.\n                info = dict(\n                    line=info['line'],\n                    package='xtcocotools@'\n                    'git+https://github.com/jin-s13/xtcocoapi')\n\n            yield info\n\n    def parse_require_file(fpath):\n        with open(fpath, 'r') as f:\n            for line in f.readlines():\n                line = line.strip()\n                if line and not line.startswith('#'):\n                    for info in parse_line(line):\n                        yield info\n\n    def gen_packages_items():\n        if exists(require_fpath):\n            for info in parse_require_file(require_fpath):\n                parts = [info['package']]\n                if with_version and 'version' in info:\n                    parts.extend(info['version'])\n                if not sys.version.startswith('3.4'):\n                    # apparently package_deps are broken in 3.4\n                    platform_deps = info.get('platform_deps')\n                    if platform_deps is not None:\n                        parts.append(';' + platform_deps)\n                item = ''.join(parts)\n                yield item\n\n    packages = list(gen_packages_items())\n    return packages\n\n\ndef add_mim_extension():\n    \"\"\"Add extra files that are required to support MIM into the package.\n\n    These files will be added by creating a symlink to the originals if the\n    package is installed in `editable` mode (e.g. pip install -e .), or by\n    copying from the originals otherwise.\n    \"\"\"\n\n    # parse installment mode\n    if 'develop' in sys.argv:\n        # installed by `pip install -e .`\n        if platform.system() == 'Windows':\n            mode = 'copy'\n        else:\n            mode = 'symlink'\n    elif 'sdist' in sys.argv or 'bdist_wheel' in sys.argv:\n        # installed by `pip install .`\n        # or create source distribution by `python setup.py sdist`\n        mode = 'copy'\n    else:\n        return\n\n    filenames = [\n        'tools', 'configs', 'demo', 'model-index.yml', 'dataset-index.yml'\n    ]\n    repo_path = osp.dirname(__file__)\n    mim_path = osp.join(repo_path, 'mmpose', '.mim')\n    os.makedirs(mim_path, exist_ok=True)\n\n    for filename in filenames:\n        if osp.exists(filename):\n            src_path = osp.join(repo_path, filename)\n            tar_path = osp.join(mim_path, filename)\n\n            if osp.isfile(tar_path) or osp.islink(tar_path):\n                os.remove(tar_path)\n            elif osp.isdir(tar_path):\n                shutil.rmtree(tar_path)\n\n            if mode == 'symlink':\n                src_relpath = osp.relpath(src_path, osp.dirname(tar_path))\n                os.symlink(src_relpath, tar_path)\n            elif mode == 'copy':\n                if osp.isfile(src_path):\n                    shutil.copyfile(src_path, tar_path)\n                elif osp.isdir(src_path):\n                    shutil.copytree(src_path, tar_path)\n                else:\n                    warnings.warn(f'Cannot copy file {src_path}.')\n            else:\n                raise ValueError(f'Invalid mode {mode}')\n\n\nif __name__ == '__main__':\n    add_mim_extension()\n    setup(\n        name='mmpose',\n        version=get_version(),\n        description='OpenMMLab Pose Estimation Toolbox and Benchmark.',\n        author='MMPose Contributors',\n        author_email='openmmlab@gmail.com',\n        keywords='computer vision, pose estimation',\n        long_description=readme(),\n        long_description_content_type='text/markdown',\n        packages=find_packages(exclude=('configs', 'tools', 'demo')),\n        include_package_data=True,\n        package_data={'mmpose.ops': ['*/*.so']},\n        classifiers=[\n            'Development Status :: 4 - Beta',\n            'License :: OSI Approved :: Apache Software License',\n            'Operating System :: OS Independent',\n            'Programming Language :: Python :: 3',\n            'Programming Language :: Python :: 3.7',\n            'Programming Language :: Python :: 3.8',\n            'Programming Language :: Python :: 3.9',\n        ],\n        url='https://github.com/open-mmlab/mmpose',\n        license='Apache License 2.0',\n        python_requires='>=3.7',\n        install_requires=parse_requirements('requirements/runtime.txt'),\n        extras_require={\n            'all': parse_requirements('requirements.txt'),\n            'tests': parse_requirements('requirements/tests.txt'),\n            'optional': parse_requirements('requirements/optional.txt'),\n            'mim': parse_requirements('requirements/mminstall.txt'),\n        },\n        zip_safe=False)\n"
  },
  {
    "path": "tests/data/300vw/001/annot/000006.pts",
    "content": "version: 1\r\nn_points: 68\r\n{\r\n743.224 197.764\r\n744.067 213.767\r\n747.494 229.362\r\n752.659 245.009\r\n758.92 259.223\r\n767.901 272.356\r\n778.802 283.44\r\n791.215 292.702\r\n805.644 296.179\r\n822.777 294.269\r\n840.544 285.779\r\n855.834 273.961\r\n867.449 258.999\r\n873.996 241.046\r\n876.935 222.009\r\n878.567 202.398\r\n878.29 182.498\r\n744.007 167.503\r\n750.098 162.094\r\n758.537 160.906\r\n767.509 162.778\r\n775.861 167.055\r\n801.008 165.555\r\n812.685 160.407\r\n825.422 158.165\r\n838.176 160.521\r\n849.128 166.753\r\n789.759 186.16\r\n789.699 198.174\r\n789.273 210.165\r\n788.975 222.281\r\n782.603 232.478\r\n787.429 234.27\r\n792.678 235.337\r\n798.527 234.133\r\n804.664 232.902\r\n755.736 189.198\r\n761.237 184.449\r\n769.829 184.474\r\n778 190.301\r\n769.807 192.891\r\n761.326 193.176\r\n811.185 189.658\r\n818.224 183.243\r\n827.82 183.095\r\n836.647 187.198\r\n829.057 191.518\r\n819.507 191.948\r\n778.412 257.689\r\n782.738 250.599\r\n789.035 246.573\r\n794.615 248.185\r\n800.403 246.606\r\n811.204 250.488\r\n822.537 256.574\r\n813.083 264.925\r\n803.39 268.215\r\n796.966 268.73\r\n790.759 267.758\r\n784.142 264.276\r\n782.377 257.528\r\n789.969 255.358\r\n795.418 255.634\r\n801.363 255.421\r\n817.652 256.63\r\n801.613 256.589\r\n795.658 256.775\r\n790.094 256.132\r\n}\r\n"
  },
  {
    "path": "tests/data/300vw/001/annot/000009.pts",
    "content": "version: 1\r\nn_points: 68\r\n{\r\n742.873 203.975\r\n743.86 219.009\r\n747.556 233.644\r\n752.945 248.605\r\n758.873 262.435\r\n767.402 275.713\r\n778.158 286.99\r\n790.906 296.386\r\n805.448 299.882\r\n823.054 297.715\r\n841.765 288.765\r\n857.714 276.621\r\n869.301 261.256\r\n875.322 243.141\r\n877.652 224.024\r\n878.624 204.199\r\n877.759 184.091\r\n739.839 173.49\r\n745.097 169.057\r\n752.507 168.519\r\n760.509 170.747\r\n768.073 174.906\r\n791.577 172.962\r\n803.164 167.369\r\n816.229 164.505\r\n829.601 166.297\r\n841.772 171.687\r\n781.866 193.207\r\n781.874 205.541\r\n781.423 217.922\r\n781.105 230.353\r\n777.568 240.329\r\n781.547 242.003\r\n786.186 242.803\r\n791.695 241.762\r\n797.794 240.677\r\n751.554 195.364\r\n756.158 190.45\r\n764.343 190.443\r\n772.432 196.54\r\n764.574 199.384\r\n756.473 199.727\r\n804.344 195.462\r\n810.661 188.458\r\n820.197 188.077\r\n829.408 192.078\r\n821.842 196.959\r\n812.389 197.654\r\n777.821 266.056\r\n779.868 259.244\r\n784.392 255.175\r\n789.378 256.665\r\n794.399 255.071\r\n805.22 258.831\r\n817.54 264.382\r\n807.933 271.958\r\n798.515 274.526\r\n792.885 274.904\r\n787.314 273.956\r\n782.133 270.936\r\n781.614 265.715\r\n785.822 264.012\r\n790.616 264.186\r\n795.84 263.973\r\n812.474 264.499\r\n796.13 262.77\r\n790.946 262.751\r\n786.04 262.145\r\n}\r\n"
  },
  {
    "path": "tests/data/300vw/401/annot/000731.pts",
    "content": "version: 1.0\r\nn_points: 68\r\n{\r\n354.326810 277.170196\r\n356.862516 297.896319\r\n360.708857 321.402933\r\n366.772339 344.811744\r\n375.576753 367.589576\r\n388.959244 386.799754\r\n407.262945 401.811444\r\n428.068560 412.214259\r\n453.614796 416.691435\r\n471.226590 411.577691\r\n484.005875 396.976013\r\n494.537085 376.929648\r\n502.043375 358.298449\r\n508.351854 337.612143\r\n513.750512 315.400709\r\n517.398128 293.446696\r\n519.878097 269.587778\r\n401.071060 289.120463\r\n415.868158 283.175462\r\n431.633197 280.639818\r\n447.288182 280.860303\r\n462.502056 283.726681\r\n493.759549 279.708941\r\n501.023665 273.761758\r\n509.227751 268.874220\r\n517.254018 266.415103\r\n522.849079 267.392002\r\n483.202797 299.142724\r\n485.261679 313.765218\r\n487.619687 327.980627\r\n490.111994 342.128622\r\n462.545119 348.143214\r\n473.539324 350.954483\r\n484.012453 351.175083\r\n491.398925 348.749592\r\n495.698470 344.339799\r\n415.040415 304.069825\r\n427.740254 304.565914\r\n438.181828 303.487879\r\n449.618639 300.557420\r\n438.347956 305.781678\r\n427.813322 306.703437\r\n492.929038 293.082034\r\n501.907509 291.762309\r\n510.255618 289.897320\r\n516.708942 286.473615\r\n510.344380 291.584684\r\n501.907485 293.272054\r\n431.746485 373.402051\r\n449.048791 371.628950\r\n465.248833 370.765301\r\n471.581789 371.573768\r\n478.582506 369.215815\r\n484.976525 368.995428\r\n492.130309 368.389324\r\n485.662685 378.849941\r\n478.521143 384.643953\r\n470.975365 386.597756\r\n462.553999 386.328249\r\n448.270860 382.261998\r\n434.809022 374.014486\r\n464.103456 376.087702\r\n471.312425 376.020313\r\n478.521168 374.807624\r\n489.607029 369.877287\r\n478.184380 376.222430\r\n471.312350 377.165647\r\n463.901645 377.165623\r\n}\r\n"
  },
  {
    "path": "tests/data/300vw/401/annot/000732.pts",
    "content": "version: 1\nn_points: 68\n{\n363.817 271.708\n364.252 298.829\n365.968 325.877\n370.470 351.633\n381.256 375.027\n397.661 394.398\n417.463 409.304\n438.872 420.327\n460.669 420.571\n478.411 411.705\n487.951 392.441\n496.754 372.500\n504.338 353.575\n509.906 335.599\n514.506 317.927\n516.599 300.991\n515.792 284.064\n404.467 290.300\n418.546 282.394\n434.658 278.447\n450.617 278.359\n465.479 282.345\n496.947 282.828\n503.613 274.821\n511.716 269.283\n520.833 266.200\n527.099 269.220\n481.812 299.263\n483.596 314.370\n485.608 329.230\n487.438 344.276\n462.064 350.710\n471.954 354.403\n481.878 355.891\n489.689 352.322\n494.701 346.437\n419.526 304.128\n432.296 302.727\n442.685 299.918\n451.791 301.013\n442.576 304.957\n432.247 306.164\n493.153 294.574\n502.979 291.036\n511.389 289.049\n517.585 288.486\n511.946 293.834\n503.509 295.495\n434.752 372.539\n452.756 370.355\n467.045 368.214\n474.267 369.293\n480.141 366.373\n484.881 365.139\n488.812 365.241\n483.252 374.699\n478.597 382.170\n471.995 385.121\n464.377 385.874\n450.608 382.911\n440.029 373.013\n466.575 374.235\n473.917 373.978\n479.839 371.716\n484.497 367.569\n478.771 372.052\n472.793 375.438\n465.679 376.251\n}\n"
  },
  {
    "path": "tests/data/300vw/anno_300vw.json",
    "content": "{\n    \"images\": [\n        {\n            \"file_name\": \"001/imgs/000006.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 0\n        },\n        {\n            \"file_name\": \"001/imgs/000009.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 1\n        },\n        {\n            \"file_name\": \"401/imgs/000732.jpg\",\n            \"height\": 512,\n            \"width\": 700,\n            \"id\": 2\n        }\n    ],\n    \"annotations\": [\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 68,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"keypoints\": [\n                743.224,\n                197.764,\n                1,\n                744.067,\n                213.767,\n                1,\n                747.494,\n                229.362,\n                1,\n                752.659,\n                245.009,\n                1,\n                758.92,\n                259.223,\n                1,\n                767.901,\n                272.356,\n                1,\n                778.802,\n                283.44,\n                1,\n                791.215,\n                292.702,\n                1,\n                805.644,\n                296.179,\n                1,\n                822.777,\n                294.269,\n                1,\n                840.544,\n                285.779,\n                1,\n                855.834,\n                273.961,\n                1,\n                867.449,\n                258.999,\n                1,\n                873.996,\n                241.046,\n                1,\n                876.935,\n                222.009,\n                1,\n                878.567,\n                202.398,\n                1,\n                878.29,\n                182.498,\n                1,\n                744.007,\n                167.503,\n                1,\n                750.098,\n                162.094,\n                1,\n                758.537,\n                160.906,\n                1,\n                767.509,\n                162.778,\n                1,\n                775.861,\n                167.055,\n                1,\n                801.008,\n                165.555,\n                1,\n                812.685,\n                160.407,\n                1,\n                825.422,\n                158.165,\n                1,\n                838.176,\n                160.521,\n                1,\n                849.128,\n                166.753,\n                1,\n                789.759,\n                186.16,\n                1,\n                789.699,\n                198.174,\n                1,\n                789.273,\n                210.165,\n                1,\n                788.975,\n                222.281,\n                1,\n                782.603,\n                232.478,\n                1,\n                787.429,\n                234.27,\n                1,\n                792.678,\n                235.337,\n                1,\n                798.527,\n                234.133,\n                1,\n                804.664,\n                232.902,\n                1,\n                755.736,\n                189.198,\n                1,\n                761.237,\n                184.449,\n                1,\n                769.829,\n                184.474,\n                1,\n                778.0,\n                190.301,\n                1,\n                769.807,\n                192.891,\n                1,\n                761.326,\n                193.176,\n                1,\n                811.185,\n                189.658,\n                1,\n                818.224,\n                183.243,\n                1,\n                827.82,\n                183.095,\n                1,\n                836.647,\n                187.198,\n                1,\n                829.057,\n                191.518,\n                1,\n                819.507,\n                191.948,\n                1,\n                778.412,\n                257.689,\n                1,\n                782.738,\n                250.599,\n                1,\n                789.035,\n                246.573,\n                1,\n                794.615,\n                248.185,\n                1,\n                800.403,\n                246.606,\n                1,\n                811.204,\n                250.488,\n                1,\n                822.537,\n                256.574,\n                1,\n                813.083,\n                264.925,\n                1,\n                803.39,\n                268.215,\n                1,\n                796.966,\n                268.73,\n                1,\n                790.759,\n                267.758,\n                1,\n                784.142,\n                264.276,\n                1,\n                782.377,\n                257.528,\n                1,\n                789.969,\n                255.358,\n                1,\n                795.418,\n                255.634,\n                1,\n                801.363,\n                255.421,\n                1,\n                817.652,\n                256.63,\n                1,\n                801.613,\n                256.589,\n                1,\n                795.658,\n                256.775,\n                1,\n                790.094,\n                256.132,\n                1\n            ],\n            \"scale\": 0.695,\n            \"area\": 18679.22880199999,\n            \"center\": [\n                810.8955000000001,\n                227.17199999999997\n            ],\n            \"image_id\": 0,\n            \"id\": 0\n        },\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 68,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"keypoints\": [\n                742.873,\n                203.975,\n                1,\n                743.86,\n                219.009,\n                1,\n                747.556,\n                233.644,\n                1,\n                752.945,\n                248.605,\n                1,\n                758.873,\n                262.435,\n                1,\n                767.402,\n                275.713,\n                1,\n                778.158,\n                286.99,\n                1,\n                790.906,\n                296.386,\n                1,\n                805.448,\n                299.882,\n                1,\n                823.054,\n                297.715,\n                1,\n                841.765,\n                288.765,\n                1,\n                857.714,\n                276.621,\n                1,\n                869.301,\n                261.256,\n                1,\n                875.322,\n                243.141,\n                1,\n                877.652,\n                224.024,\n                1,\n                878.624,\n                204.199,\n                1,\n                877.759,\n                184.091,\n                1,\n                739.839,\n                173.49,\n                1,\n                745.097,\n                169.057,\n                1,\n                752.507,\n                168.519,\n                1,\n                760.509,\n                170.747,\n                1,\n                768.073,\n                174.906,\n                1,\n                791.577,\n                172.962,\n                1,\n                803.164,\n                167.369,\n                1,\n                816.229,\n                164.505,\n                1,\n                829.601,\n                166.297,\n                1,\n                841.772,\n                171.687,\n                1,\n                781.866,\n                193.207,\n                1,\n                781.874,\n                205.541,\n                1,\n                781.423,\n                217.922,\n                1,\n                781.105,\n                230.353,\n                1,\n                777.568,\n                240.329,\n                1,\n                781.547,\n                242.003,\n                1,\n                786.186,\n                242.803,\n                1,\n                791.695,\n                241.762,\n                1,\n                797.794,\n                240.677,\n                1,\n                751.554,\n                195.364,\n                1,\n                756.158,\n                190.45,\n                1,\n                764.343,\n                190.443,\n                1,\n                772.432,\n                196.54,\n                1,\n                764.574,\n                199.384,\n                1,\n                756.473,\n                199.727,\n                1,\n                804.344,\n                195.462,\n                1,\n                810.661,\n                188.458,\n                1,\n                820.197,\n                188.077,\n                1,\n                829.408,\n                192.078,\n                1,\n                821.842,\n                196.959,\n                1,\n                812.389,\n                197.654,\n                1,\n                777.821,\n                266.056,\n                1,\n                779.868,\n                259.244,\n                1,\n                784.392,\n                255.175,\n                1,\n                789.378,\n                256.665,\n                1,\n                794.399,\n                255.071,\n                1,\n                805.22,\n                258.831,\n                1,\n                817.54,\n                264.382,\n                1,\n                807.933,\n                271.958,\n                1,\n                798.515,\n                274.526,\n                1,\n                792.885,\n                274.904,\n                1,\n                787.314,\n                273.956,\n                1,\n                782.133,\n                270.936,\n                1,\n                781.614,\n                265.715,\n                1,\n                785.822,\n                264.012,\n                1,\n                790.616,\n                264.186,\n                1,\n                795.84,\n                263.973,\n                1,\n                812.474,\n                264.499,\n                1,\n                796.13,\n                262.77,\n                1,\n                790.946,\n                262.751,\n                1,\n                786.04,\n                262.145,\n                1\n            ],\n            \"scale\": 0.695,\n            \"area\": 18788.296945,\n            \"center\": [\n                809.2315000000001,\n                232.1935\n            ],\n            \"image_id\": 1,\n            \"id\": 1\n        },\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 68,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"keypoints\": [\n                363.817,\n                271.708,\n                1,\n                364.252,\n                298.829,\n                1,\n                365.968,\n                325.877,\n                1,\n                370.47,\n                351.633,\n                1,\n                381.256,\n                375.027,\n                1,\n                397.661,\n                394.398,\n                1,\n                417.463,\n                409.304,\n                1,\n                438.872,\n                420.327,\n                1,\n                460.669,\n                420.571,\n                1,\n                478.411,\n                411.705,\n                1,\n                487.951,\n                392.441,\n                1,\n                496.754,\n                372.5,\n                1,\n                504.338,\n                353.575,\n                1,\n                509.906,\n                335.599,\n                1,\n                514.506,\n                317.927,\n                1,\n                516.599,\n                300.991,\n                1,\n                515.792,\n                284.064,\n                1,\n                404.467,\n                290.3,\n                1,\n                418.546,\n                282.394,\n                1,\n                434.658,\n                278.447,\n                1,\n                450.617,\n                278.359,\n                1,\n                465.479,\n                282.345,\n                1,\n                496.947,\n                282.828,\n                1,\n                503.613,\n                274.821,\n                1,\n                511.716,\n                269.283,\n                1,\n                520.833,\n                266.2,\n                1,\n                527.099,\n                269.22,\n                1,\n                481.812,\n                299.263,\n                1,\n                483.596,\n                314.37,\n                1,\n                485.608,\n                329.23,\n                1,\n                487.438,\n                344.276,\n                1,\n                462.064,\n                350.71,\n                1,\n                471.954,\n                354.403,\n                1,\n                481.878,\n                355.891,\n                1,\n                489.689,\n                352.322,\n                1,\n                494.701,\n                346.437,\n                1,\n                419.526,\n                304.128,\n                1,\n                432.296,\n                302.727,\n                1,\n                442.685,\n                299.918,\n                1,\n                451.791,\n                301.013,\n                1,\n                442.576,\n                304.957,\n                1,\n                432.247,\n                306.164,\n                1,\n                493.153,\n                294.574,\n                1,\n                502.979,\n                291.036,\n                1,\n                511.389,\n                289.049,\n                1,\n                517.585,\n                288.486,\n                1,\n                511.946,\n                293.834,\n                1,\n                503.509,\n                295.495,\n                1,\n                434.752,\n                372.539,\n                1,\n                452.756,\n                370.355,\n                1,\n                467.045,\n                368.214,\n                1,\n                474.267,\n                369.293,\n                1,\n                480.141,\n                366.373,\n                1,\n                484.881,\n                365.139,\n                1,\n                488.812,\n                365.241,\n                1,\n                483.252,\n                374.699,\n                1,\n                478.597,\n                382.17,\n                1,\n                471.995,\n                385.121,\n                1,\n                464.377,\n                385.874,\n                1,\n                450.608,\n                382.911,\n                1,\n                440.029,\n                373.013,\n                1,\n                466.575,\n                374.235,\n                1,\n                473.917,\n                373.978,\n                1,\n                479.839,\n                371.716,\n                1,\n                484.497,\n                367.569,\n                1,\n                478.771,\n                372.052,\n                1,\n                472.793,\n                375.438,\n                1,\n                465.679,\n                376.251,\n                1\n            ],\n            \"scale\": 0.82,\n            \"area\": 25206.00562200001,\n            \"center\": [\n                445.458,\n                343.3855\n            ],\n            \"image_id\": 2,\n            \"id\": 2\n        }\n    ],\n    \"categories\": [\n        {\n            \"id\": 1,\n            \"name\": \"person\"\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/300w/test_300w.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"face\",\n            \"keypoints\": [],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 197,\n            \"file_name\": \"indoor_029.png\",\n            \"height\": 845,\n            \"width\": 960\n        },\n        {\n            \"id\": 565,\n            \"file_name\": \"indoor_020.png\",\n            \"height\": 768,\n            \"width\": 726\n        }\n    ],\n    \"annotations\": [\n        {\n            \"image_id\": 197,\n            \"id\": 197,\n            \"keypoints\": [\n                268.0,\n                398.882,\n                1,\n                285.21,\n                470.547,\n                1,\n                303.994,\n                540.61,\n                1,\n                332.8,\n                611.274,\n                1,\n                376.829,\n                659.993,\n                1,\n                428.904,\n                701.529,\n                1,\n                493.765,\n                726.48,\n                1,\n                566.941,\n                741.209,\n                1,\n                615.5,\n                733.248,\n                1,\n                660.628,\n                711.888,\n                1,\n                693.575,\n                666.8610000000001,\n                1,\n                707.9989999999998,\n                602.151,\n                1,\n                710.0010000000002,\n                540.7090000000002,\n                1,\n                710.702,\n                482.586,\n                1,\n                705.705,\n                430.128,\n                1,\n                698.574,\n                376.051,\n                1,\n                687.17,\n                325.797,\n                1,\n                335.426,\n                370.217,\n                1,\n                352.01,\n                339.706,\n                1,\n                400.98800000000006,\n                317.285,\n                1,\n                449.164,\n                310.243,\n                1,\n                493.34,\n                314.9120000000001,\n                1,\n                548.874,\n                304.259,\n                1,\n                572.625,\n                284.111,\n                1,\n                609.946,\n                265.0,\n                1,\n                650.465,\n                269.886,\n                1,\n                672.5269999999998,\n                287.694,\n                1,\n                531.823,\n                349.5019999999999,\n                1,\n                543.992,\n                387.47,\n                1,\n                557.0459999999998,\n                425.639,\n                1,\n                570.283,\n                465.089,\n                1,\n                521.077,\n                509.142,\n                1,\n                543.5830000000002,\n                511.647,\n                1,\n                569.154,\n                510.935,\n                1,\n                589.758,\n                504.75,\n                1,\n                607.544,\n                494.626,\n                1,\n                372.146,\n                389.57,\n                1,\n                399.878,\n                370.642,\n                1,\n                431.883,\n                359.838,\n                1,\n                465.725,\n                371.503,\n                1,\n                437.99,\n                384.279,\n                1,\n                406.296,\n                393.511,\n                1,\n                571.331,\n                349.968,\n                1,\n                599.158,\n                324.208,\n                1,\n                630.259,\n                318.067,\n                1,\n                656.076,\n                327.782,\n                1,\n                635.32,\n                340.57199999999995,\n                1,\n                607.295,\n                346.391,\n                1,\n                479.066,\n                604.947,\n                1,\n                519.818,\n                577.8,\n                1,\n                547.948,\n                566.137,\n                1,\n                572.52,\n                568.232,\n                1,\n                594.948,\n                556.586,\n                1,\n                621.335,\n                562.737,\n                1,\n                653.6,\n                571.3580000000002,\n                1,\n                623.72,\n                596.32,\n                1,\n                606.549,\n                604.577,\n                1,\n                578.673,\n                606.798,\n                1,\n                554.4830000000002,\n                609.318,\n                1,\n                525.276,\n                609.497,\n                1,\n                494.741,\n                601.097,\n                1,\n                549.953,\n                585.0319999999998,\n                1,\n                573.969,\n                584.442,\n                1,\n                599.372,\n                575.65,\n                1,\n                640.35,\n                573.788,\n                1,\n                599.372,\n                575.65,\n                1,\n                573.969,\n                584.442,\n                1,\n                549.953,\n                585.0319999999998,\n                1\n            ],\n            \"num_keypoints\": 68,\n            \"bbox\": [\n                223.7298,\n                217.3791,\n                531.2424000000001,\n                571.4508\n            ],\n            \"iscrowd\": 0,\n            \"area\": 303578.89447392005,\n            \"category_id\": 1,\n            \"center\": [\n                489.5,\n                503.5\n            ],\n            \"scale\": 2.385\n        },\n        {\n            \"image_id\": 565,\n            \"id\": 565,\n            \"keypoints\": [\n                70.0,\n                292.332,\n                1,\n                85.978,\n                359.108,\n                1,\n                106.67,\n                442.2480000000001,\n                1,\n                132.174,\n                524.227,\n                1,\n                170.87900000000005,\n                587.591,\n                1,\n                220.419,\n                640.665,\n                1,\n                275.329,\n                686.7510000000002,\n                1,\n                345.149,\n                712.11,\n                1,\n                415.072,\n                700.013,\n                1,\n                455.739,\n                681.039,\n                1,\n                491.441,\n                646.908,\n                1,\n                522.22,\n                601.67,\n                1,\n                545.278,\n                556.815,\n                1,\n                570.101,\n                495.899,\n                1,\n                588.304,\n                413.976,\n                1,\n                595.136,\n                343.6280000000001,\n                1,\n                590.716,\n                280.211,\n                1,\n                118.878,\n                305.308,\n                1,\n                158.248,\n                281.872,\n                1,\n                202.699,\n                284.469,\n                1,\n                246.669,\n                294.941,\n                1,\n                294.485,\n                316.657,\n                1,\n                387.621,\n                306.5490000000001,\n                1,\n                437.315,\n                274.369,\n                1,\n                483.305,\n                246.679,\n                1,\n                531.807,\n                219.0,\n                1,\n                574.753,\n                226.314,\n                1,\n                350.492,\n                372.72,\n                1,\n                354.8180000000001,\n                422.627,\n                1,\n                358.916,\n                467.076,\n                1,\n                364.204,\n                508.283,\n                1,\n                303.536,\n                510.181,\n                1,\n                332.565,\n                524.2280000000002,\n                1,\n                361.282,\n                537.337,\n                1,\n                385.853,\n                530.722,\n                1,\n                410.586,\n                512.7090000000002,\n                1,\n                171.577,\n                361.551,\n                1,\n                203.614,\n                344.588,\n                1,\n                246.448,\n                345.9380000000001,\n                1,\n                288.441,\n                368.74300000000005,\n                1,\n                246.677,\n                376.513,\n                1,\n                202.377,\n                382.091,\n                1,\n                411.996,\n                361.712,\n                1,\n                445.408,\n                332.093,\n                1,\n                485.232,\n                319.01,\n                1,\n                518.47,\n                328.7990000000001,\n                1,\n                492.908,\n                360.212,\n                1,\n                447.886,\n                364.719,\n                1,\n                256.704,\n                564.955,\n                1,\n                306.255,\n                569.807,\n                1,\n                333.68,\n                566.9019999999998,\n                1,\n                360.689,\n                571.737,\n                1,\n                391.088,\n                565.381,\n                1,\n                426.92,\n                559.18,\n                1,\n                476.772,\n                545.14,\n                1,\n                429.904,\n                606.391,\n                1,\n                398.257,\n                628.13,\n                1,\n                361.86,\n                635.736,\n                1,\n                332.214,\n                631.4259999999998,\n                1,\n                300.871,\n                615.508,\n                1,\n                271.028,\n                570.685,\n                1,\n                333.764,\n                594.513,\n                1,\n                360.897,\n                597.525,\n                1,\n                391.282,\n                594.612,\n                1,\n                467.095,\n                554.192,\n                1,\n                391.282,\n                594.612,\n                1,\n                360.897,\n                597.525,\n                1,\n                333.764,\n                594.513,\n                1\n            ],\n            \"num_keypoints\": 68,\n            \"bbox\": [\n                17.486400000000003,\n                169.689,\n                630.1632,\n                591.7320000000001\n            ],\n            \"iscrowd\": 0,\n            \"area\": 372887.7306624,\n            \"category_id\": 1,\n            \"center\": [\n                333.0,\n                466.0\n            ],\n            \"scale\": 2.63\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/300wlp/test_300wlp.json",
    "content": "{\"info\": {\"description\": \"LaPa Generated by MMPose Team\", \"version\": 1.0, \"year\": \"2023\", \"date_created\": \"2023/09/20\"}, \"images\": [{\"id\": 1, \"file_name\": \"AFW_134212_1_0.jpg\", \"height\": 450, \"width\": 450}, {\"id\": 2, \"file_name\": \"AFW_134212_2_0.jpg\", \"height\": 450, \"width\": 450}], \"annotations\": [{\"keypoints\": [144.78085327148438, 253.39178466796875, 2.0, 143.70928955078125, 275.5905456542969, 2.0, 147.26495361328125, 292.55340576171875, 2.0, 154.74082946777344, 307.56976318359375, 2.0, 164.7685089111328, 325.37213134765625, 2.0, 175.56622314453125, 341.6143798828125, 2.0, 183.95713806152344, 350.2955322265625, 2.0, 191.24447631835938, 364.373291015625, 2.0, 212.22702026367188, 373.85772705078125, 2.0, 238.06739807128906, 365.5926513671875, 2.0, 262.0357971191406, 350.78265380859375, 2.0, 281.9491882324219, 335.1942138671875, 2.0, 297.3870849609375, 316.2213134765625, 2.0, 305.5174560546875, 296.20111083984375, 2.0, 310.0191650390625, 278.38665771484375, 2.0, 313.570556640625, 257.59332275390625, 2.0, 314.68060302734375, 234.81509399414062, 2.0, 141.07717895507812, 233.8748016357422, 2.0, 142.4314727783203, 231.93350219726562, 2.0, 149.53399658203125, 232.0662384033203, 2.0, 158.13735961914062, 234.31857299804688, 2.0, 167.29750061035156, 237.67184448242188, 2.0, 205.59320068359375, 234.99285888671875, 2.0, 216.04824829101562, 229.73251342773438, 2.0, 229.51547241210938, 225.43397521972656, 2.0, 245.78271484375, 224.81817626953125, 2.0, 261.8216552734375, 228.80909729003906, 2.0, 186.61602783203125, 257.0625, 2.0, 183.9759979248047, 273.16412353515625, 2.0, 180.80419921875, 288.9212646484375, 2.0, 181.61343383789062, 300.6891174316406, 2.0, 180.70370483398438, 302.4509582519531, 2.0, 184.2169189453125, 305.52349853515625, 2.0, 190.96376037597656, 307.95452880859375, 2.0, 199.12416076660156, 305.3871765136719, 2.0, 206.879150390625, 302.37335205078125, 2.0, 154.32986450195312, 249.83685302734375, 2.0, 156.83566284179688, 248.1170654296875, 2.0, 166.4077911376953, 247.8013916015625, 2.0, 177.58078002929688, 251.6158905029297, 2.0, 168.43463134765625, 254.5105743408203, 2.0, 159.2126007080078, 254.42872619628906, 2.0, 216.7241973876953, 250.81556701660156, 2.0, 224.13780212402344, 246.13824462890625, 2.0, 234.09474182128906, 245.99227905273438, 2.0, 245.9826202392578, 248.45945739746094, 2.0, 236.0019989013672, 253.0175323486328, 2.0, 224.37583923339844, 253.48345947265625, 2.0, 175.86959838867188, 319.50311279296875, 2.0, 179.09326171875, 319.59539794921875, 2.0, 187.91131591796875, 319.067138671875, 2.0, 193.9979248046875, 320.62445068359375, 2.0, 200.40106201171875, 319.33489990234375, 2.0, 217.08116149902344, 320.4862976074219, 2.0, 233.78671264648438, 322.4403076171875, 2.0, 219.32835388183594, 334.7911376953125, 2.0, 208.45263671875, 340.60760498046875, 2.0, 198.55410766601562, 341.6135559082031, 2.0, 189.62986755371094, 339.7992858886719, 2.0, 183.0074462890625, 332.94818115234375, 2.0, 178.17086791992188, 319.563232421875, 2.0, 188.85269165039062, 324.1929931640625, 2.0, 196.60971069335938, 325.0108642578125, 2.0, 205.92147827148438, 324.99169921875, 2.0, 231.7099609375, 322.35394287109375, 2.0, 206.32933044433594, 331.2320556640625, 2.0, 197.35250854492188, 331.98333740234375, 2.0, 189.53477478027344, 330.077392578125, 2.0], \"image_id\": 1, \"id\": 1, \"num_keypoints\": 68, \"bbox\": [141.07717895507812, 224.81817626953125, 173.60342407226562, 149.03955078125], \"iscrowd\": 0, \"area\": 25873, \"category_id\": 1}, {\"keypoints\": [135.04940795898438, 222.4427947998047, 2.0, 135.0158233642578, 245.55397033691406, 2.0, 136.51287841796875, 266.4256896972656, 2.0, 138.80328369140625, 286.6426086425781, 2.0, 144.32032775878906, 310.9339294433594, 2.0, 157.32864379882812, 334.45831298828125, 2.0, 174.5981903076172, 352.64923095703125, 2.0, 196.57693481445312, 368.895751953125, 2.0, 223.50587463378906, 378.31634521484375, 2.0, 251.17575073242188, 369.77850341796875, 2.0, 267.59075927734375, 355.8761901855469, 2.0, 280.4201965332031, 341.2083740234375, 2.0, 293.03106689453125, 321.76690673828125, 2.0, 301.7103576660156, 299.455078125, 2.0, 306.847412109375, 279.4398193359375, 2.0, 312.0267639160156, 260.4844970703125, 2.0, 314.9190673828125, 240.6781768798828, 2.0, 170.3564453125, 224.36227416992188, 2.0, 183.98776245117188, 220.8751220703125, 2.0, 199.30447387695312, 221.02830505371094, 2.0, 212.521484375, 223.36888122558594, 2.0, 223.74468994140625, 226.60350036621094, 2.0, 268.19195556640625, 228.3536376953125, 2.0, 278.82196044921875, 226.323486328125, 2.0, 289.98040771484375, 224.9724884033203, 2.0, 301.55609130859375, 226.1953887939453, 2.0, 308.71484375, 230.00015258789062, 2.0, 244.0289764404297, 256.7021484375, 2.0, 244.56097412109375, 275.8743896484375, 2.0, 244.62387084960938, 293.44793701171875, 2.0, 243.3439483642578, 305.9898376464844, 2.0, 222.41458129882812, 304.99017333984375, 2.0, 229.01458740234375, 308.64453125, 2.0, 237.42706298828125, 312.08013916015625, 2.0, 245.45481872558594, 310.38775634765625, 2.0, 250.5335693359375, 307.69195556640625, 2.0, 187.56089782714844, 246.6132049560547, 2.0, 197.1554412841797, 247.3951416015625, 2.0, 208.1782989501953, 248.00457763671875, 2.0, 217.29855346679688, 250.23162841796875, 2.0, 208.33084106445312, 253.25308227539062, 2.0, 196.66152954101562, 252.4826202392578, 2.0, 262.341064453125, 251.73179626464844, 2.0, 273.3721618652344, 250.15658569335938, 2.0, 284.34228515625, 250.62045288085938, 2.0, 290.07666015625, 250.62611389160156, 2.0, 282.4354248046875, 255.56341552734375, 2.0, 271.82550048828125, 255.81756591796875, 2.0, 199.1420135498047, 325.15618896484375, 2.0, 213.11370849609375, 323.486328125, 2.0, 227.83006286621094, 322.69268798828125, 2.0, 234.6953582763672, 325.06048583984375, 2.0, 241.50355529785156, 324.013916015625, 2.0, 252.42141723632812, 327.2342834472656, 2.0, 258.1256408691406, 331.502685546875, 2.0, 248.24850463867188, 341.65667724609375, 2.0, 238.77732849121094, 347.1531982421875, 2.0, 228.27822875976562, 347.7994384765625, 2.0, 218.2596435546875, 345.81182861328125, 2.0, 209.1992645263672, 338.6329345703125, 2.0, 202.04551696777344, 325.17730712890625, 2.0, 222.98101806640625, 328.13006591796875, 2.0, 232.16001892089844, 329.54791259765625, 2.0, 240.60108947753906, 329.82879638671875, 2.0, 256.0614929199219, 331.196044921875, 2.0, 238.20115661621094, 336.92901611328125, 2.0, 229.0829315185547, 337.291015625, 2.0, 220.1124267578125, 335.1085510253906, 2.0], \"image_id\": 2, \"id\": 2, \"num_keypoints\": 68, \"bbox\": [135.0158233642578, 220.8751220703125, 179.9032440185547, 157.44122314453125], \"iscrowd\": 0, \"area\": 28324, \"category_id\": 1}], \"categories\": [{\"supercategory\": \"person\", \"id\": 1, \"name\": \"face\", \"keypoints\": [], \"skeleton\": []}]}"
  },
  {
    "path": "tests/data/aflw/test_aflw.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"face\",\n            \"keypoints\": [],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 3,\n            \"file_name\": \"image22568.jpg\",\n            \"height\": 1280,\n            \"width\": 853\n        },\n        {\n            \"id\": 68,\n            \"file_name\": \"image04476.jpg\",\n            \"height\": 500,\n            \"width\": 439\n        }\n    ],\n    \"annotations\": [\n        {\n            \"image_id\": 3,\n            \"id\": 3,\n            \"keypoints\": [\n                337.28341384863,\n                205.78904991948002,\n                1,\n                370.46215780998,\n                203.18679549113997,\n                1,\n                400.38808373591,\n                210.99355877617,\n                1,\n                481.70853462158,\n                217.49919484702,\n                1,\n                518.7906602254401,\n                210.99355877617,\n                1,\n                549.3671497584501,\n                223.35426731079,\n                1,\n                359.40257648952996,\n                253.28019323671,\n                1,\n                391.28019323671,\n                254.58132045089002,\n                1,\n                419.25442834138,\n                261.08695652174,\n                1,\n                479.10628019324,\n                259.78582930757005,\n                1,\n                507.08051529790976,\n                255.88244766506,\n                1,\n                533.10305958132,\n                258.4847020934,\n                1,\n                404.29146537842,\n                323.54106280192997,\n                1,\n                443.32528180354007,\n                338.5040257649,\n                1,\n                483.66022544283,\n                327.44444444444,\n                1,\n                381.52173913043,\n                374.28502415459,\n                1,\n                443.32528180354007,\n                376.23671497584996,\n                1,\n                507.73107890499,\n                372.98389694042,\n                1,\n                451.0,\n                478.0,\n                1\n            ],\n            \"num_keypoints\": 19,\n            \"bbox\": [\n                316.07504025764797,\n                175.70547504025396,\n                254.50048309178408,\n                329.7758454106321\n            ],\n            \"iscrowd\": 0,\n            \"area\": 83928.11196900737,\n            \"category_id\": 1,\n            \"center\": [\n                449.0,\n                321.0\n            ],\n            \"scale\": 1.81,\n            \"box_size\": 362.0\n        },\n        {\n            \"image_id\": 68,\n            \"id\": 68,\n            \"keypoints\": [\n                126.64745330811,\n                157.27305603027,\n                1,\n                134.30273752013,\n                153.39452495973998,\n                1,\n                145.34465026855,\n                153.01428222656,\n                1,\n                165.48123168945,\n                146.28958129883,\n                1,\n                181.7833404541,\n                140.24139404297,\n                1,\n                198.6918182373,\n                143.05288696289,\n                1,\n                133.90043640137,\n                167.45462036133,\n                1,\n                141.77455716586002,\n                165.24637681158995,\n                1,\n                148.98872785829,\n                163.70048309178998,\n                1,\n                174.96592712402,\n                157.80386352539,\n                1,\n                185.42395019531003,\n                155.1201171875,\n                1,\n                194.88919067383,\n                154.83345031738,\n                1,\n                145.87278582931,\n                188.89049919485,\n                1,\n                152.59581320451,\n                177.61352657005,\n                1,\n                174.75362318841,\n                185.34299516908,\n                1,\n                145.63929146538,\n                213.68438003221002,\n                1,\n                161.87117552335,\n                211.3655394525,\n                1,\n                187.12077294686,\n                207.24315619968002,\n                1,\n                166.0,\n                244.0,\n                1\n            ],\n            \"num_keypoints\": 19,\n            \"bbox\": [\n                119.443016815191,\n                129.865533447267,\n                86.453237915028,\n                124.51032714843598\n            ],\n            \"iscrowd\": 0,\n            \"area\": 10764.320935841704,\n            \"category_id\": 1,\n            \"center\": [\n                166.0,\n                185.0\n            ],\n            \"scale\": 0.64,\n            \"box_size\": 128.0\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/aic/test_aic.json",
    "content": "{\n    \"info\": {\n        \"description\": \"MMPose example aic dataset\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/08/25\"\n    },\n    \"licenses\": [\n        {\n            \"url\": \"\",\n            \"id\": 1,\n            \"name\": \"\"\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"Right Shoulder\",\n                \"Right Elbow\",\n                \"Right Wrist\",\n                \"Left Shoulder\",\n                \"Left Elbow\",\n                \"Left Wrist\",\n                \"Right Hip\",\n                \"Right Knee\",\n                \"Right Ankle\",\n                \"Left Hip\",\n                \"Left Knee\",\n                \"Left Ankle\",\n                \"Head top\",\n                \"Neck\"\n            ],\n            \"skeleton\": [\n                [\n                    3,\n                    2\n                ],\n                [\n                    2,\n                    1\n                ],\n                [\n                    1,\n                    14\n                ],\n                [\n                    14,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    5,\n                    6\n                ],\n                [\n                    9,\n                    8\n                ],\n                [\n                    8,\n                    7\n                ],\n                [\n                    7,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    1,\n                    7\n                ],\n                [\n                    4,\n                    10\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"url\": \"http://www.sinaimg.cn/dy/slidenews/4_img/2013_47/704_1154733_789201.jpg\",\n            \"file_name\": \"054d9ce9201beffc76e5ff2169d2af2f027002ca.jpg\",\n            \"height\": 600,\n            \"width\": 900,\n            \"id\": 1\n        },\n        {\n            \"url\": \"http://www.sinaimg.cn/dy/slidenews/2_img/2015_26/820_1533617_599302.jpg\",\n            \"file_name\": \"fa436c914fe4a8ec1ec5474af4d3820b84d17561.jpg\",\n            \"height\": 596,\n            \"width\": 900,\n            \"id\": 2\n        },\n        {\n            \"url\": \"http://www.sinaimg.cn/dy/slidenews/2_img/2016_39/730_1947359_260964.jpg\",\n            \"file_name\": \"ff945ae2e729f24eea992814639d59b3bdec8bd8.jpg\",\n            \"height\": 641,\n            \"width\": 950,\n            \"id\": 3\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox\": [\n                279,\n                55,\n                213,\n                544\n            ],\n            \"keypoints\": [\n                313,\n                201,\n                2,\n                312,\n                313,\n                1,\n                320,\n                424,\n                2,\n                406,\n                197,\n                1,\n                431,\n                286,\n                1,\n                459,\n                269,\n                2,\n                375,\n                447,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                416,\n                441,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                395,\n                74,\n                2,\n                372,\n                170,\n                2\n            ],\n            \"num_keypoints\": 10,\n            \"image_id\": 1,\n            \"category_id\": 1,\n            \"id\": 4\n        },\n        {\n            \"bbox\": [\n                541,\n                131,\n                329,\n                468\n            ],\n            \"keypoints\": [\n                637,\n                374,\n                1,\n                626,\n                509,\n                2,\n                0,\n                0,\n                0,\n                755,\n                347,\n                2,\n                728,\n                538,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                604,\n                169,\n                2,\n                674,\n                290,\n                2\n            ],\n            \"num_keypoints\": 6,\n            \"image_id\": 1,\n            \"category_id\": 1,\n            \"id\": 5\n        },\n        {\n            \"bbox\": [\n                88,\n                7,\n                252,\n                592\n            ],\n            \"keypoints\": [\n                144,\n                180,\n                2,\n                171,\n                325,\n                1,\n                256,\n                428,\n                1,\n                265,\n                196,\n                2,\n                297,\n                311,\n                2,\n                300,\n                412,\n                2,\n                178,\n                476,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                253,\n                474,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                220,\n                23,\n                2,\n                205,\n                133,\n                2\n            ],\n            \"num_keypoints\": 10,\n            \"image_id\": 1,\n            \"category_id\": 1,\n            \"id\": 6\n        },\n        {\n            \"bbox\": [\n                497,\n                179,\n                401,\n                416\n            ],\n            \"keypoints\": [\n                692,\n                332,\n                1,\n                587,\n                430,\n                2,\n                612,\n                552,\n                1,\n                657,\n                422,\n                2,\n                533,\n                571,\n                2,\n                621,\n                450,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                564,\n                212,\n                2,\n                656,\n                362,\n                2\n            ],\n            \"num_keypoints\": 8,\n            \"image_id\": 2,\n            \"category_id\": 1,\n            \"id\": 7\n        },\n        {\n            \"bbox\": [\n                336,\n                26,\n                177,\n                254\n            ],\n            \"keypoints\": [\n                368,\n                142,\n                2,\n                365,\n                237,\n                1,\n                415,\n                271,\n                1,\n                487,\n                147,\n                2,\n                493,\n                240,\n                2,\n                431,\n                265,\n                2,\n                393,\n                296,\n                1,\n                326,\n                306,\n                1,\n                339,\n                390,\n                1,\n                449,\n                297,\n                1,\n                373,\n                315,\n                1,\n                376,\n                389,\n                1,\n                435,\n                43,\n                2,\n                430,\n                131,\n                2\n            ],\n            \"num_keypoints\": 14,\n            \"image_id\": 2,\n            \"category_id\": 1,\n            \"id\": 8\n        },\n        {\n            \"bbox\": [\n                0,\n                109,\n                473,\n                486\n            ],\n            \"keypoints\": [\n                68,\n                333,\n                2,\n                215,\n                408,\n                2,\n                376,\n                427,\n                2,\n                169,\n                280,\n                1,\n                166,\n                386,\n                1,\n                146,\n                462,\n                2,\n                39,\n                545,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                136,\n                515,\n                1,\n                292,\n                531,\n                1,\n                0,\n                0,\n                0,\n                181,\n                147,\n                2,\n                127,\n                269,\n                2\n            ],\n            \"num_keypoints\": 11,\n            \"image_id\": 2,\n            \"category_id\": 1,\n            \"id\": 9\n        },\n        {\n            \"bbox\": [\n                681,\n                3,\n                267,\n                607\n            ],\n            \"keypoints\": [\n                846,\n                98,\n                1,\n                862,\n                223,\n                1,\n                794,\n                282,\n                2,\n                824,\n                134,\n                2,\n                875,\n                241,\n                2,\n                842,\n                329,\n                2,\n                903,\n                296,\n                1,\n                766,\n                397,\n                1,\n                777,\n                562,\n                2,\n                886,\n                299,\n                2,\n                757,\n                399,\n                2,\n                871,\n                514,\n                2,\n                761,\n                29,\n                2,\n                813,\n                87,\n                2\n            ],\n            \"num_keypoints\": 14,\n            \"image_id\": 3,\n            \"category_id\": 1,\n            \"id\": 10\n        },\n        {\n            \"bbox\": [\n                484,\n                7,\n                162,\n                481\n            ],\n            \"keypoints\": [\n                544,\n                96,\n                2,\n                506,\n                161,\n                2,\n                542,\n                208,\n                2,\n                606,\n                93,\n                2,\n                615,\n                151,\n                1,\n                622,\n                187,\n                2,\n                571,\n                251,\n                2,\n                553,\n                361,\n                2,\n                556,\n                458,\n                2,\n                591,\n                251,\n                1,\n                581,\n                363,\n                2,\n                587,\n                456,\n                2,\n                587,\n                21,\n                2,\n                578,\n                80,\n                2\n            ],\n            \"num_keypoints\": 14,\n            \"image_id\": 3,\n            \"category_id\": 1,\n            \"id\": 11\n        },\n        {\n            \"bbox\": [\n                33,\n                73,\n                493,\n                566\n            ],\n            \"keypoints\": [\n                254,\n                203,\n                2,\n                169,\n                203,\n                2,\n                111,\n                187,\n                2,\n                391,\n                204,\n                2,\n                425,\n                276,\n                2,\n                475,\n                346,\n                2,\n                272,\n                376,\n                2,\n                185,\n                485,\n                2,\n                126,\n                607,\n                1,\n                357,\n                383,\n                2,\n                359,\n                459,\n                2,\n                350,\n                561,\n                2,\n                338,\n                111,\n                2,\n                325,\n                180,\n                1\n            ],\n            \"num_keypoints\": 14,\n            \"image_id\": 3,\n            \"category_id\": 1,\n            \"id\": 12\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/ak/test_animalkingdom.json",
    "content": "{\n    \"info\": {\n        \"description\": \"[CVPR 2022] Animal Kingdom\",\n        \"url\": \"https://sutdcv.github.io/Animal-Kingdom\",\n        \"version\": \"1.0 (2022-06)\",\n        \"year\": 2022,\n        \"contributor\": \"Singapore University of Technology and Design, Singapore. Xun Long Ng, Kian Eng Ong, Qichen Zheng, Yun Ni, Si Yong Yeo, Jun Liu.\",\n        \"date_created\": \"2022-06\"\n    },\n    \"licenses\": [\n        {\n            \"url\": \"\",\n            \"id\": 1,\n            \"name\": \"\"\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 1,\n            \"file_name\": \"AAOYRUDX/AAOYRUDX_f000027.jpg\",\n            \"width\": 640,\n            \"height\": 360\n        },\n        {\n            \"id\": 2,\n            \"file_name\": \"AAOYRUDX/AAOYRUDX_f000028.jpg\",\n            \"width\": 640,\n            \"height\": 360\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"AK_Animal\",\n            \"id\": 1,\n            \"name\": \"Amphibian\",\n            \"keypoints\": [\n                \"Head_Mid_Top\",\n                \"Eye_Left\",\n                \"Eye_Right\",\n                \"Mouth_Front_Top\",\n                \"Mouth_Back_Left\",\n                \"Mouth_Back_Right\",\n                \"Mouth_Front_Bottom\",\n                \"Shoulder_Left\",\n                \"Shoulder_Right\",\n                \"Elbow_Left\",\n                \"Elbow_Right\",\n                \"Wrist_Left\",\n                \"Wrist_Right\",\n                \"Torso_Mid_Back\",\n                \"Hip_Left\",\n                \"Hip_Right\",\n                \"Knee_Left\",\n                \"Knee_Right\",\n                \"Ankle_Left \",\n                \"Ankle_Right\",\n                \"Tail_Top_Back\",\n                \"Tail_Mid_Back\",\n                \"Tail_End_Back\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    0\n                ],\n                [\n                    2,\n                    0\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    6\n                ],\n                [\n                    0,\n                    7\n                ],\n                [\n                    0,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    10,\n                    12\n                ],\n                [\n                    0,\n                    13\n                ],\n                [\n                    13,\n                    20\n                ],\n                [\n                    20,\n                    14\n                ],\n                [\n                    20,\n                    15\n                ],\n                [\n                    14,\n                    16\n                ],\n                [\n                    15,\n                    17\n                ],\n                [\n                    16,\n                    18\n                ],\n                [\n                    17,\n                    19\n                ],\n                [\n                    20,\n                    21\n                ],\n                [\n                    21,\n                    22\n                ]\n            ],\n            \"flip_pairs\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    16,\n                    17\n                ],\n                [\n                    18,\n                    19\n                ]\n            ],\n            \"upper_body_ids\": [\n                0,\n                1,\n                2,\n                3,\n                4,\n                5,\n                6,\n                7,\n                8,\n                9,\n                10,\n                11,\n                12,\n                13\n            ],\n            \"lower_body_ids\": [\n                14,\n                15,\n                16,\n                17,\n                18,\n                19,\n                20,\n                21,\n                22\n            ]\n        },\n        {\n            \"supercategory\": \"AK_Animal\",\n            \"id\": 2,\n            \"name\": \"Bird\",\n            \"keypoints\": [\n                \"Head_Mid_Top\",\n                \"Eye_Left\",\n                \"Eye_Right\",\n                \"Mouth_Front_Top\",\n                \"Mouth_Back_Left\",\n                \"Mouth_Back_Right\",\n                \"Mouth_Front_Bottom\",\n                \"Shoulder_Left\",\n                \"Shoulder_Right\",\n                \"Elbow_Left\",\n                \"Elbow_Right\",\n                \"Wrist_Left\",\n                \"Wrist_Right\",\n                \"Torso_Mid_Back\",\n                \"Hip_Left\",\n                \"Hip_Right\",\n                \"Knee_Left\",\n                \"Knee_Right\",\n                \"Ankle_Left \",\n                \"Ankle_Right\",\n                \"Tail_Top_Back\",\n                \"Tail_Mid_Back\",\n                \"Tail_End_Back\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    0\n                ],\n                [\n                    2,\n                    0\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    6\n                ],\n                [\n                    0,\n                    7\n                ],\n                [\n                    0,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    10,\n                    12\n                ],\n                [\n                    0,\n                    13\n                ],\n                [\n                    13,\n                    20\n                ],\n                [\n                    20,\n                    14\n                ],\n                [\n                    20,\n                    15\n                ],\n                [\n                    14,\n                    16\n                ],\n                [\n                    15,\n                    17\n                ],\n                [\n                    16,\n                    18\n                ],\n                [\n                    17,\n                    19\n                ],\n                [\n                    20,\n                    21\n                ],\n                [\n                    21,\n                    22\n                ]\n            ],\n            \"flip_pairs\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    16,\n                    17\n                ],\n                [\n                    18,\n                    19\n                ]\n            ],\n            \"upper_body_ids\": [\n                0,\n                1,\n                2,\n                3,\n                4,\n                5,\n                6,\n                7,\n                8,\n                9,\n                10,\n                11,\n                12,\n                13\n            ],\n            \"lower_body_ids\": [\n                14,\n                15,\n                16,\n                17,\n                18,\n                19,\n                20,\n                21,\n                22\n            ]\n        }\n    ],\n    \"annotations\": [\n        {\n            \"id\": 1,\n            \"image_id\": 1,\n            \"category_id\": 4,\n            \"animal_parent_class\": \"Mammal\",\n            \"animal_class\": \"Mammal\",\n            \"animal_subclass\": \"Elephant\",\n            \"animal\": \"Elephant\",\n            \"protocol\": \"ak_P1\",\n            \"train_test\": \"test\",\n            \"area\": 7984.8320733706605,\n            \"scale\": 0.6674772036000001,\n            \"center\": [\n                229.7435897436,\n                202.4316109422\n            ],\n            \"bbox\": [\n                199.6111111111,\n                136.1838905775,\n                60.26495726500002,\n                132.4954407295\n            ],\n            \"iscrowd\": 0,\n            \"num_keypoints\": 6,\n            \"keypoints\": [\n                220.9914529915,\n                135.6838905775,\n                1.0,\n                238.4957264957,\n                151.0030395137,\n                1.0,\n                199.1111111111,\n                153.1914893617,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                260.3760683761,\n                154.2857142857,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                250.5299145299,\n                195.8662613982,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                251.6239316239,\n                269.179331307,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0\n            ]\n        },\n        {\n            \"id\": 2,\n            \"image_id\": 2,\n            \"category_id\": 4,\n            \"animal_parent_class\": \"Mammal\",\n            \"animal_class\": \"Mammal\",\n            \"animal_subclass\": \"Elephant\",\n            \"animal\": \"Elephant\",\n            \"protocol\": \"ak_P1\",\n            \"train_test\": \"test\",\n            \"area\": 7984.8320733706605,\n            \"scale\": 0.6674772036000001,\n            \"center\": [\n                229.7435897436,\n                202.4316109422\n            ],\n            \"bbox\": [\n                199.6111111111,\n                136.1838905775,\n                60.26495726500002,\n                132.4954407295\n            ],\n            \"iscrowd\": 0,\n            \"num_keypoints\": 6,\n            \"keypoints\": [\n                220.9914529915,\n                135.6838905775,\n                1.0,\n                238.4957264957,\n                151.0030395137,\n                1.0,\n                199.1111111111,\n                153.1914893617,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                260.3760683761,\n                154.2857142857,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                250.5299145299,\n                195.8662613982,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                251.6239316239,\n                269.179331307,\n                1.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0,\n                -1.0,\n                -1.0,\n                0.0\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/animalpose/test_animalpose.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"animal\",\n            \"id\": 1,\n            \"name\": \"cat\",\n            \"keypoints\": [\n                \"L_Eye\",\n                \"R_Eye\",\n                \"L_EarBase\",\n                \"R_EarBase\",\n                \"Nose\",\n                \"Throat\",\n                \"TailBase\",\n                \"Withers\",\n                \"L_F_Elbow\",\n                \"R_F_Elbow\",\n                \"L_B_Elbow\",\n                \"R_B_Elbow\",\n                \"L_F_Knee\",\n                \"R_F_Knee\",\n                \"L_B_Knee\",\n                \"R_B_Knee\",\n                \"L_F_Paw\",\n                \"R_F_Paw\",\n                \"L_B_Paw\",\n                \"R_B_Paw\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    1,\n                    5\n                ],\n                [\n                    2,\n                    5\n                ],\n                [\n                    5,\n                    6\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    6,\n                    9\n                ],\n                [\n                    9,\n                    13\n                ],\n                [\n                    13,\n                    17\n                ],\n                [\n                    6,\n                    10\n                ],\n                [\n                    10,\n                    14\n                ],\n                [\n                    14,\n                    18\n                ],\n                [\n                    7,\n                    11\n                ],\n                [\n                    11,\n                    15\n                ],\n                [\n                    15,\n                    19\n                ],\n                [\n                    7,\n                    12\n                ],\n                [\n                    12,\n                    16\n                ],\n                [\n                    16,\n                    20\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 110,\n            \"file_name\": \"ca110.jpeg\",\n            \"height\": 240,\n            \"width\": 300\n        },\n        {\n            \"id\": 3105,\n            \"file_name\": \"ho105.jpeg\",\n            \"height\": 255,\n            \"width\": 300\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                117.0,\n                95.0,\n                2.0,\n                85.0,\n                102.0,\n                2.0,\n                115.0,\n                56.0,\n                2.0,\n                62.0,\n                78.0,\n                2.0,\n                102.0,\n                109.0,\n                2.0,\n                104.0,\n                130.0,\n                2.0,\n                235.0,\n                163.0,\n                2.0,\n                144.0,\n                53.0,\n                2.0,\n                123.0,\n                142.0,\n                2.0,\n                40.0,\n                161.0,\n                2.0,\n                182.0,\n                160.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                115.0,\n                186.0,\n                2.0,\n                64.0,\n                192.0,\n                2.0,\n                189.0,\n                195.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                84.0,\n                214.0,\n                2.0,\n                53.0,\n                209.0,\n                2.0,\n                146.0,\n                206.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 110,\n            \"id\": 129,\n            \"num_keypoints\": 17,\n            \"bbox\": [\n                13.0,\n                36.0,\n                284.0,\n                192.0\n            ],\n            \"iscrowd\": 0,\n            \"area\": 54528.0,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                54.0,\n                36.0,\n                2.0,\n                42.0,\n                33.0,\n                2.0,\n                65.0,\n                21.0,\n                2.0,\n                51.0,\n                18.0,\n                2.0,\n                30.0,\n                59.0,\n                2.0,\n                57.0,\n                62.0,\n                2.0,\n                203.0,\n                109.0,\n                2.0,\n                104.0,\n                82.0,\n                2.0,\n                73.0,\n                141.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                195.0,\n                157.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                73.0,\n                185.0,\n                2.0,\n                81.0,\n                183.0,\n                2.0,\n                225.0,\n                204.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                62.0,\n                221.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                249.0,\n                242.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 3105,\n            \"id\": 583,\n            \"num_keypoints\": 15,\n            \"bbox\": [\n                23.0,\n                9.0,\n                256.0,\n                240.0\n            ],\n            \"iscrowd\": 0,\n            \"area\": 61440.0,\n            \"category_id\": 1\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/ap10k/test_ap10k.json",
    "content": "{\n    \"info\":{\n        \"description\":\"AP-10k\",\n        \"url\":\"https://github.com/AlexTheBad/AP-10K\",\n        \"version\":\"1.0\",\n        \"year\":2021,\n        \"contributor\":\"AP-10k Team\",\n        \"date_created\":\"2021/07/01\"\n    },\n    \"licenses\":[\n        {\n            \"id\":1,\n            \"name\":\"The MIT License\",\n            \"url\":\"https://www.mit.edu/~amini/LICENSE.md\"\n        }\n    ],\n    \"images\":[\n        {\n            \"license\":1,\n            \"id\":37516,\n            \"file_name\":\"000000037516.jpg\",\n            \"width\":1200,\n            \"height\":867,\n            \"background\":5\n        },\n        {\n            \"license\":1,\n            \"id\":4,\n            \"file_name\":\"000000000004.jpg\",\n            \"width\":1024,\n            \"height\":683,\n            \"background\":1\n        }\n    ],\n    \"annotations\":[\n        {\n            \"id\":9284,\n            \"image_id\":37516,\n            \"category_id\":26,\n            \"bbox\":[\n                66,\n                192,\n                1092,\n                512\n            ],\n            \"area\":559104,\n            \"iscrowd\":0,\n            \"num_keypoints\":16,\n            \"keypoints\":[\n                134,\n                415,\n                2,\n                0,\n                0,\n                0,\n                94,\n                475,\n                2,\n                302,\n                330,\n                2,\n                890,\n                287,\n                2,\n                414,\n                470,\n                2,\n                414,\n                554,\n                2,\n                396,\n                624,\n                2,\n                302,\n                466,\n                2,\n                230,\n                515,\n                2,\n                214,\n                623,\n                2,\n                838,\n                422,\n                2,\n                946,\n                511,\n                2,\n                936,\n                628,\n                2,\n                708,\n                442,\n                2,\n                698,\n                555,\n                2,\n                636,\n                602,\n                2\n            ]\n        },\n        {\n            \"id\":6,\n            \"image_id\":4,\n            \"category_id\":1,\n            \"bbox\":[\n                408,\n                197,\n                429,\n                341\n            ],\n            \"area\":146289,\n            \"iscrowd\":0,\n            \"num_keypoints\":16,\n            \"keypoints\":[\n                488,\n                443,\n                2,\n                0,\n                0,\n                0,\n                466,\n                499,\n                2,\n                600,\n                307,\n                2,\n                787,\n                255,\n                2,\n                643,\n                369,\n                2,\n                660,\n                438,\n                2,\n                684,\n                514,\n                2,\n                592,\n                380,\n                2,\n                594,\n                443,\n                2,\n                591,\n                520,\n                2,\n                757,\n                350,\n                2,\n                778,\n                408,\n                2,\n                772,\n                513,\n                2,\n                729,\n                352,\n                2,\n                778,\n                400,\n                2,\n                765,\n                497,\n                2\n            ]\n        }\n    ],\n    \"categories\":[\n        {\n            \"id\":1,\n            \"name\":\"antelope\",\n            \"supercategory\":\"Bovidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":2,\n            \"name\":\"argali sheep\",\n            \"supercategory\":\"Bovidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":3,\n            \"name\":\"bison\",\n            \"supercategory\":\"Bovidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":4,\n            \"name\":\"buffalo\",\n            \"supercategory\":\"Bovidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":5,\n            \"name\":\"cow\",\n            \"supercategory\":\"Bovidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":6,\n            \"name\":\"sheep\",\n            \"supercategory\":\"Bovidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":7,\n            \"name\":\"arctic fox\",\n            \"supercategory\":\"Canidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":8,\n            \"name\":\"dog\",\n            \"supercategory\":\"Canidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":9,\n            \"name\":\"fox\",\n            \"supercategory\":\"Canidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":10,\n            \"name\":\"wolf\",\n            \"supercategory\":\"Canidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":11,\n            \"name\":\"beaver\",\n            \"supercategory\":\"Castoridae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":12,\n            \"name\":\"alouatta\",\n            \"supercategory\":\"Cercopithecidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":13,\n            \"name\":\"monkey\",\n            \"supercategory\":\"Cercopithecidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":14,\n            \"name\":\"noisy night monkey\",\n            \"supercategory\":\"Cercopithecidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":15,\n            \"name\":\"spider monkey\",\n            \"supercategory\":\"Cercopithecidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":16,\n            \"name\":\"uakari\",\n            \"supercategory\":\"Cercopithecidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":17,\n            \"name\":\"deer\",\n            \"supercategory\":\"Cervidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":18,\n            \"name\":\"moose\",\n            \"supercategory\":\"Cervidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":19,\n            \"name\":\"hamster\",\n            \"supercategory\":\"Cricetidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":20,\n            \"name\":\"elephant\",\n            \"supercategory\":\"Elephantidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":21,\n            \"name\":\"horse\",\n            \"supercategory\":\"Equidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":22,\n            \"name\":\"zebra\",\n            \"supercategory\":\"Equidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":23,\n            \"name\":\"bobcat\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":24,\n            \"name\":\"cat\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":25,\n            \"name\":\"cheetah\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":26,\n            \"name\":\"jaguar\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":27,\n            \"name\":\"king cheetah\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":28,\n            \"name\":\"leopard\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":29,\n            \"name\":\"lion\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":30,\n            \"name\":\"panther\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":31,\n            \"name\":\"snow leopard\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":32,\n            \"name\":\"tiger\",\n            \"supercategory\":\"Felidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":33,\n            \"name\":\"giraffe\",\n            \"supercategory\":\"Giraffidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":34,\n            \"name\":\"hippo\",\n            \"supercategory\":\"Hippopotamidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":35,\n            \"name\":\"chimpanzee\",\n            \"supercategory\":\"Hominidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":36,\n            \"name\":\"gorilla\",\n            \"supercategory\":\"Hominidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":37,\n            \"name\":\"orangutan\",\n            \"supercategory\":\"Hominidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":38,\n            \"name\":\"rabbit\",\n            \"supercategory\":\"Leporidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":39,\n            \"name\":\"skunk\",\n            \"supercategory\":\"Mephitidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":40,\n            \"name\":\"mouse\",\n            \"supercategory\":\"Muridae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":41,\n            \"name\":\"rat\",\n            \"supercategory\":\"Muridae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":42,\n            \"name\":\"otter\",\n            \"supercategory\":\"Mustelidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":43,\n            \"name\":\"weasel\",\n            \"supercategory\":\"Mustelidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":44,\n            \"name\":\"raccoon\",\n            \"supercategory\":\"Procyonidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":45,\n            \"name\":\"rhino\",\n            \"supercategory\":\"Rhinocerotidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":46,\n            \"name\":\"marmot\",\n            \"supercategory\":\"Sciuridae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":47,\n            \"name\":\"squirrel\",\n            \"supercategory\":\"Sciuridae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":48,\n            \"name\":\"pig\",\n            \"supercategory\":\"Suidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":49,\n            \"name\":\"mole\",\n            \"supercategory\":\"Talpidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":50,\n            \"name\":\"black bear\",\n            \"supercategory\":\"Ursidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":51,\n            \"name\":\"brown bear\",\n            \"supercategory\":\"Ursidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":52,\n            \"name\":\"panda\",\n            \"supercategory\":\"Ursidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":53,\n            \"name\":\"polar bear\",\n            \"supercategory\":\"Ursidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        },\n        {\n            \"id\":54,\n            \"name\":\"bat\",\n            \"supercategory\":\"Vespertilionidae\",\n            \"keypoints\":[\n                \"left_eye\",\n                \"right_eye\",\n                \"nose\",\n                \"neck\",\n                \"root_of_tail\",\n                \"left_shoulder\",\n                \"left_elbow\",\n                \"left_front_paw\",\n                \"right_shoulder\",\n                \"right_elbow\",\n                \"right_front_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\"\n            ],\n            \"skeleton\":[\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    4,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    5,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    5,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ]\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/atrw/test_atrw.json",
    "content": "{\n    \"categories\": [\n        {\n            \"keypoints\": [\n                \"left_ear\",\n                \"right_ear\",\n                \"nose\",\n                \"right_shoulder\",\n                \"right_front_paw\",\n                \"left_shoulder\",\n                \"left_front_paw\",\n                \"right_hip\",\n                \"right_knee\",\n                \"right_back_paw\",\n                \"left_hip\",\n                \"left_knee\",\n                \"left_back_paw\",\n                \"tail\",\n                \"center\"\n            ],\n            \"name\": \"tiger\",\n            \"skeleton\": [\n                [\n                    0,\n                    2\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    2,\n                    14\n                ],\n                [\n                    5,\n                    6\n                ],\n                [\n                    5,\n                    14\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    3,\n                    14\n                ],\n                [\n                    13,\n                    14\n                ],\n                [\n                    9,\n                    8\n                ],\n                [\n                    8,\n                    7\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    12,\n                    11\n                ],\n                [\n                    11,\n                    10\n                ],\n                [\n                    10,\n                    13\n                ]\n            ],\n            \"id\": 1\n        }\n    ],\n    \"images\": [\n        {\n            \"width\": 1239,\n            \"height\": 731,\n            \"file_name\": \"003464.jpg\",\n            \"id\": 3464\n        },\n        {\n            \"width\": 925,\n            \"height\": 1080,\n            \"file_name\": \"000061.jpg\",\n            \"id\": 61\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox\": [\n                0,\n                0,\n                1239,\n                731\n            ],\n            \"category_id\": 1,\n            \"keypoints\": [\n                225,\n                215,\n                2,\n                285,\n                194,\n                2,\n                191,\n                368,\n                2,\n                417,\n                428,\n                2,\n                308,\n                594,\n                2,\n                536,\n                401,\n                2,\n                642,\n                638,\n                2,\n                893,\n                419,\n                2,\n                974,\n                494,\n                2,\n                885,\n                584,\n                2,\n                925,\n                328,\n                2,\n                1065,\n                419,\n                2,\n                1050,\n                583,\n                2,\n                994,\n                186,\n                2,\n                592,\n                277,\n                2\n            ],\n            \"num_keypoints\": 15,\n            \"image_id\": 3464,\n            \"id\": 3464,\n            \"area\": 905709,\n            \"iscrowd\": 0\n        },\n        {\n            \"bbox\": [\n                0,\n                0,\n                925,\n                1080\n            ],\n            \"category_id\": 1,\n            \"keypoints\": [\n                324,\n                571,\n                2,\n                158,\n                568,\n                2,\n                246,\n                806,\n                2,\n                217,\n                806,\n                2,\n                359,\n                805,\n                2,\n                447,\n                657,\n                2,\n                362,\n                911,\n                2,\n                539,\n                546,\n                2,\n                369,\n                552,\n                2,\n                546,\n                612,\n                2,\n                638,\n                358,\n                2,\n                722,\n                332,\n                2,\n                712,\n                507,\n                2,\n                593,\n                121,\n                2,\n                419,\n                463,\n                2\n            ],\n            \"num_keypoints\": 15,\n            \"image_id\": 61,\n            \"id\": 61,\n            \"area\": 999000,\n            \"iscrowd\": 0\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/campus/calibration_campus.json",
    "content": "{\n  \"0\": {\n    \"R\": [\n      [\n        0.9998819135498813,\n        -0.007627303394110196,\n        -0.013341034396255802\n      ],\n      [\n        -0.01412240122676837,\n        -0.11375390190151916,\n        -0.9934085803866252\n      ],\n      [\n        0.00605943391894462,\n        0.9934796797343738,\n        -0.11384818494586636\n      ]\n    ],\n    \"T\": [\n      [\n        1774.8953318252247\n      ],\n      [\n        -5051.695948238737\n      ],\n      [\n        1923.3559877015355\n      ]\n    ],\n    \"fx\": 437.9852173913044,\n    \"fy\": 437.9852173913044,\n    \"cx\": 185.3596,\n    \"cy\": 139.2537,\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ]\n  },\n  \"1\": {\n    \"R\": [\n      [\n        -0.04633107785835382,\n        -0.9988140384937536,\n        0.014964883303310195\n      ],\n      [\n        -0.13065076504992335,\n        -0.008793265243184023,\n        -0.9913894573164639\n      ],\n      [\n        0.9903452977706073,\n        -0.04788731558734052,\n        -0.1300884168152014\n      ]\n    ],\n    \"T\": [\n      [\n        -6240.579909342256\n      ],\n      [\n        5247.348264374987\n      ],\n      [\n        1947.3802148598609\n      ]\n    ],\n    \"fx\": 430.03326086956525,\n    \"fy\": 430.03326086956525,\n    \"cx\": 184.0583,\n    \"cy\": 130.7467,\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ]\n  },\n  \"2\": {\n    \"R\": [\n      [\n        0.5386991962445586,\n        0.8424723621738047,\n        -0.006595069276080057\n      ],\n      [\n        0.10782367722838201,\n        -0.07670471706694504,\n        -0.9912065581949252\n      ],\n      [\n        -0.835570003407504,\n        0.5332510715910186,\n        -0.13215923748499042\n      ]\n    ],\n    \"T\": [\n      [\n        11943.56106545541\n      ],\n      [\n        -1803.8527374133198\n      ],\n      [\n        1973.3939116534714\n      ]\n    ],\n    \"fx\": 700.9856521739131,\n    \"fy\": 700.9856521739131,\n    \"cx\": 167.59475,\n    \"cy\": 142.0545,\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ]\n  }\n}"
  },
  {
    "path": "tests/data/coco/test_coco.json",
    "content": "{\n    \"info\": {\n        \"description\": \"For testing COCO dataset only.\",\n        \"year\": 2020,\n        \"date_created\": \"2020/06/20\"\n    },\n    \"licenses\": [\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc-sa/2.0/\",\n            \"id\": 1,\n            \"name\": \"Attribution-NonCommercial-ShareAlike License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc/2.0/\",\n            \"id\": 2,\n            \"name\": \"Attribution-NonCommercial License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc-nd/2.0/\",\n            \"id\": 3,\n            \"name\": \"Attribution-NonCommercial-NoDerivs License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by/2.0/\",\n            \"id\": 4,\n            \"name\": \"Attribution License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-sa/2.0/\",\n            \"id\": 5,\n            \"name\": \"Attribution-ShareAlike License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nd/2.0/\",\n            \"id\": 6,\n            \"name\": \"Attribution-NoDerivs License\"\n        },\n        {\n            \"url\": \"http://flickr.com/commons/usage/\",\n            \"id\": 7,\n            \"name\": \"No known copyright restrictions\"\n        },\n        {\n            \"url\": \"http://www.usa.gov/copyright.shtml\",\n            \"id\": 8,\n            \"name\": \"United States Government Work\"\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"left_eye\",\n                \"right_eye\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"license\": 4,\n            \"file_name\": \"000000000785.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000000785.jpg\",\n            \"height\": 425,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 21:22:42\",\n            \"flickr_url\": \"http://farm8.staticflickr.com/7015/6795644157_f019453ae7_z.jpg\",\n            \"id\": 785\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000040083.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000040083.jpg\",\n            \"height\": 333,\n            \"width\": 500,\n            \"date_captured\": \"2013-11-18 03:30:24\",\n            \"flickr_url\": \"http://farm1.staticflickr.com/116/254881838_e21c6d17b8_z.jpg\",\n            \"id\": 40083\n        },\n        {\n            \"license\": 1,\n            \"file_name\": \"000000196141.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000196141.jpg\",\n            \"height\": 429,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-22 22:37:15\",\n            \"flickr_url\": \"http://farm4.staticflickr.com/3310/3611902235_57d4ae496d_z.jpg\",\n            \"id\": 196141\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000197388.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000197388.jpg\",\n            \"height\": 392,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 20:10:37\",\n            \"flickr_url\": \"http://farm9.staticflickr.com/8375/8507321836_5b8b13188f_z.jpg\",\n            \"id\": 197388\n        }\n    ],\n    \"annotations\": [\n        {\n            \"segmentation\": [\n                [\n                    353.37,\n                    67.65,\n                    358.15,\n                    52.37,\n                    362.92,\n                    47.59,\n                    374.38,\n                    44.73,\n                    389.66,\n                    52.37,\n                    389.66,\n                    67.65,\n                    389.66,\n                    76.25,\n                    393.48,\n                    83.89,\n                    396.35,\n                    88.66,\n                    397.3,\n                    91.53,\n                    406.85,\n                    99.17,\n                    413.54,\n                    104.9,\n                    451.74,\n                    148.83,\n                    458.43,\n                    153.6,\n                    462.25,\n                    166.02,\n                    467.02,\n                    173.66,\n                    463.2,\n                    181.3,\n                    449.83,\n                    183.21,\n                    448.88,\n                    191.81,\n                    455.56,\n                    226.19,\n                    448.88,\n                    254.84,\n                    453.65,\n                    286.36,\n                    475.62,\n                    323.6,\n                    491.85,\n                    361.81,\n                    494.72,\n                    382.82,\n                    494.72,\n                    382.82,\n                    499.49,\n                    391.41,\n                    416.4,\n                    391.41,\n                    424.04,\n                    383.77,\n                    439.33,\n                    374.22,\n                    445.06,\n                    360.85,\n                    436.46,\n                    334.11,\n                    421.18,\n                    303.55,\n                    416.4,\n                    289.22,\n                    409.72,\n                    268.21,\n                    396.35,\n                    280.63,\n                    405.9,\n                    298.77,\n                    417.36,\n                    324.56,\n                    425,\n                    349.39,\n                    425,\n                    357.99,\n                    419.27,\n                    360.85,\n                    394.44,\n                    367.54,\n                    362.92,\n                    370.4,\n                    346.69,\n                    367.54,\n                    360.06,\n                    362.76,\n                    369.61,\n                    360.85,\n                    382.98,\n                    340.8,\n                    355.28,\n                    271.08,\n                    360.06,\n                    266.3,\n                    386.8,\n                    219.5,\n                    368.65,\n                    162.2,\n                    348.6,\n                    175.57,\n                    309.44,\n                    187.03,\n                    301.8,\n                    192.76,\n                    288.43,\n                    193.72,\n                    282.7,\n                    193.72,\n                    280.79,\n                    187.03,\n                    280.79,\n                    174.62,\n                    287.47,\n                    171.75,\n                    291.29,\n                    171.75,\n                    295.11,\n                    171.75,\n                    306.57,\n                    166.98,\n                    312.3,\n                    165.07,\n                    345.73,\n                    142.14,\n                    350.51,\n                    117.31,\n                    350.51,\n                    102.03,\n                    350.51,\n                    90.57,\n                    353.37,\n                    65.74\n                ]\n            ],\n            \"num_keypoints\": 17,\n            \"area\": 27789.11055,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                367,\n                81,\n                2,\n                374,\n                73,\n                2,\n                360,\n                75,\n                2,\n                386,\n                78,\n                2,\n                356,\n                81,\n                2,\n                399,\n                108,\n                2,\n                358,\n                129,\n                2,\n                433,\n                142,\n                2,\n                341,\n                159,\n                2,\n                449,\n                165,\n                2,\n                309,\n                178,\n                2,\n                424,\n                203,\n                2,\n                393,\n                214,\n                2,\n                429,\n                294,\n                2,\n                367,\n                273,\n                2,\n                466,\n                362,\n                2,\n                396,\n                341,\n                2\n            ],\n            \"image_id\": 785,\n            \"bbox\": [\n                280.79,\n                44.73,\n                218.7,\n                346.68\n            ],\n            \"category_id\": 1,\n            \"id\": 442619\n        },\n        {\n            \"segmentation\": [\n                [\n                    98.56,\n                    273.72,\n                    132.9,\n                    267,\n                    140.37,\n                    281.93,\n                    165.75,\n                    285.66,\n                    156.79,\n                    264.01,\n                    170.23,\n                    261.02,\n                    177.7,\n                    272.97,\n                    182.18,\n                    279.69,\n                    200.85,\n                    268.49,\n                    212.79,\n                    255.05,\n                    188.9,\n                    256.54,\n                    164.26,\n                    240.12,\n                    139.62,\n                    212.49,\n                    109.01,\n                    221.45,\n                    103.04,\n                    220.71,\n                    122.45,\n                    202.04,\n                    113.49,\n                    196.07,\n                    96.32,\n                    168.44,\n                    97.06,\n                    162.47,\n                    110.5,\n                    136.34,\n                    112,\n                    124.39,\n                    91.09,\n                    110.95,\n                    80.64,\n                    114.68,\n                    71.68,\n                    131.86,\n                    62.72,\n                    147.54,\n                    57.49,\n                    156.5,\n                    48.53,\n                    168.44,\n                    41.07,\n                    180.39,\n                    38.08,\n                    193.08,\n                    40.32,\n                    205.03,\n                    47.04,\n                    213.24,\n                    54.5,\n                    216.23,\n                    82.13,\n                    252.06,\n                    91.09,\n                    271.48\n                ]\n            ],\n            \"num_keypoints\": 14,\n            \"area\": 11025.219,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                99,\n                144,\n                2,\n                104,\n                141,\n                2,\n                96,\n                137,\n                2,\n                0,\n                0,\n                0,\n                78,\n                133,\n                2,\n                56,\n                161,\n                2,\n                81,\n                162,\n                2,\n                0,\n                0,\n                0,\n                103,\n                208,\n                2,\n                116,\n                204,\n                2,\n                0,\n                0,\n                0,\n                57,\n                246,\n                1,\n                82,\n                259,\n                1,\n                137,\n                219,\n                2,\n                138,\n                247,\n                2,\n                177,\n                256,\n                2,\n                158,\n                296,\n                1\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                38.08,\n                110.95,\n                174.71,\n                174.71\n            ],\n            \"category_id\": 1,\n            \"id\": 198196\n        },\n        {\n            \"segmentation\": [\n                [\n                    257.76,\n                    288.05,\n                    273.4,\n                    258.26,\n                    325.55,\n                    253.79,\n                    335.23,\n                    232.93,\n                    326.3,\n                    186.74,\n                    333.74,\n                    177.05,\n                    327.79,\n                    153.21,\n                    333.74,\n                    142.04,\n                    344.17,\n                    139.06,\n                    353.11,\n                    139.06,\n                    359.07,\n                    145.02,\n                    360.56,\n                    148.74,\n                    362.05,\n                    168.86,\n                    388.87,\n                    197.17,\n                    397.81,\n                    276.88,\n                    372.48,\n                    293.27\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 10171.9544,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                343,\n                164,\n                2,\n                348,\n                160,\n                2,\n                340,\n                160,\n                2,\n                359,\n                163,\n                2,\n                332,\n                164,\n                2,\n                370,\n                189,\n                2,\n                334,\n                190,\n                2,\n                358,\n                236,\n                2,\n                348,\n                234,\n                2,\n                339,\n                270,\n                2,\n                330,\n                262,\n                2,\n                378,\n                262,\n                2,\n                343,\n                254,\n                2,\n                338,\n                280,\n                2,\n                283,\n                272,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                257.76,\n                139.06,\n                140.05,\n                154.21\n            ],\n            \"category_id\": 1,\n            \"id\": 230195\n        },\n        {\n            \"segmentation\": [\n                [\n                    285.37,\n                    126.5,\n                    281.97,\n                    127.72,\n                    280.76,\n                    132.33,\n                    280.76,\n                    136.46,\n                    275.17,\n                    143.26,\n                    275.9,\n                    158.08,\n                    277.6,\n                    164.4,\n                    278.33,\n                    173.87,\n                    278.33,\n                    183.83,\n                    279.79,\n                    191.11,\n                    281.97,\n                    194.76,\n                    284.89,\n                    192.09,\n                    284.89,\n                    186.99,\n                    284.89,\n                    181.16,\n                    284.64,\n                    177.51,\n                    285.86,\n                    173.87\n                ]\n            ],\n            \"num_keypoints\": 0,\n            \"area\": 491.2669,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                275.17,\n                126.5,\n                10.69,\n                68.26\n            ],\n            \"category_id\": 1,\n            \"id\": 1202706\n        },\n        {\n            \"segmentation\": [\n                [\n                    339.34,\n                    107.97,\n                    338.38,\n                    102.19,\n                    339.34,\n                    91.58,\n                    335.49,\n                    84.84,\n                    326.81,\n                    74.23,\n                    312.35,\n                    74.23,\n                    301.75,\n                    74.23,\n                    295,\n                    86.76,\n                    295,\n                    93.51,\n                    292.11,\n                    99.3,\n                    287.29,\n                    102.19,\n                    291.14,\n                    107.01,\n                    295,\n                    107.01,\n                    295.96,\n                    112.79,\n                    301.75,\n                    115.69,\n                    305.6,\n                    119.54,\n                    307.53,\n                    123.4,\n                    317.17,\n                    123.4,\n                    311.39,\n                    129.18,\n                    286.32,\n                    139.79,\n                    274.75,\n                    139.79,\n                    264.15,\n                    138.82,\n                    262.22,\n                    144.61,\n                    261.26,\n                    147.5,\n                    253.54,\n                    147.5,\n                    247.76,\n                    150.39,\n                    249.69,\n                    159.07,\n                    256.44,\n                    161,\n                    262.22,\n                    161,\n                    268,\n                    161,\n                    276.68,\n                    161.96,\n                    284.39,\n                    168.71,\n                    293.07,\n                    174.49,\n                    301.75,\n                    174.49,\n                    308.49,\n                    169.67,\n                    308.49,\n                    188.95,\n                    311.39,\n                    194.74,\n                    312.35,\n                    208.23,\n                    307.53,\n                    221.73,\n                    297.89,\n                    229.44,\n                    281.5,\n                    250.65,\n                    269.93,\n                    262.22,\n                    278.61,\n                    320.06,\n                    281.5,\n                    331.63,\n                    276.68,\n                    338.38,\n                    270.9,\n                    349.95,\n                    262.22,\n                    356.7,\n                    253.54,\n                    359.59,\n                    253.54,\n                    365.37,\n                    274.75,\n                    365.37,\n                    291.14,\n                    365.37,\n                    306.57,\n                    359.59,\n                    303.67,\n                    352.84,\n                    297.89,\n                    340.31,\n                    293.07,\n                    318.13,\n                    295,\n                    294.03,\n                    293.07,\n                    278.61,\n                    294.03,\n                    270.9,\n                    305.6,\n                    259.33,\n                    313.31,\n                    299.82,\n                    319.1,\n                    309.46,\n                    341.27,\n                    317.17,\n                    384.65,\n                    330.67,\n                    387.55,\n                    335.49,\n                    383.69,\n                    341.27,\n                    397.19,\n                    350.91,\n                    398.15,\n                    363.44,\n                    398.15,\n                    375.01,\n                    405.86,\n                    374.05,\n                    409.72,\n                    357.66,\n                    411.65,\n                    342.24,\n                    416.47,\n                    328.74,\n                    417.43,\n                    321.03,\n                    410.68,\n                    319.1,\n                    401.04,\n                    318.13,\n                    392.37,\n                    318.13,\n                    382.73,\n                    314.28,\n                    348.98,\n                    300.78,\n                    339.34,\n                    293.07,\n                    334.52,\n                    285.36,\n                    340.31,\n                    259.33,\n                    340.31,\n                    246.8,\n                    340.31,\n                    242.94,\n                    350.91,\n                    228.48,\n                    358.62,\n                    214.98,\n                    355.22,\n                    204.32,\n                    357.05,\n                    196.11,\n                    361.61,\n                    188.82,\n                    361.61,\n                    181.97,\n                    365.26,\n                    165.63,\n                    367.54,\n                    139.18,\n                    366.17,\n                    123.68,\n                    361.15,\n                    112.73,\n                    353.86,\n                    107.72,\n                    351.58,\n                    105.89,\n                    344.74,\n                    105.89,\n                    340.18,\n                    109.08\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 17123.92955,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                297,\n                111,\n                2,\n                299,\n                106,\n                2,\n                0,\n                0,\n                0,\n                314,\n                108,\n                2,\n                0,\n                0,\n                0,\n                329,\n                141,\n                2,\n                346,\n                125,\n                2,\n                295,\n                164,\n                2,\n                323,\n                130,\n                2,\n                266,\n                155,\n                2,\n                279,\n                143,\n                2,\n                329,\n                225,\n                2,\n                331,\n                221,\n                2,\n                327,\n                298,\n                2,\n                283,\n                269,\n                2,\n                398,\n                327,\n                2,\n                288,\n                349,\n                2\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                247.76,\n                74.23,\n                169.67,\n                300.78\n            ],\n            \"category_id\": 1,\n            \"id\": 460541\n        },\n        {\n            \"segmentation\": [\n                [\n                    578.76,\n                    112.4,\n                    589.39,\n                    100.81,\n                    589.39,\n                    99.84,\n                    596.16,\n                    116.27,\n                    603.89,\n                    122.07,\n                    603.89,\n                    138.49,\n                    598.09,\n                    159.75,\n                    597.12,\n                    181,\n                    594.22,\n                    191.63,\n                    589.39,\n                    212.89,\n                    583.59,\n                    208.06,\n                    583.59,\n                    206.13,\n                    582.63,\n                    200.33,\n                    582.63,\n                    193.57,\n                    582.63,\n                    182.94,\n                    575.86,\n                    181,\n                    567.17,\n                    197.43,\n                    571.03,\n                    203.23,\n                    567.17,\n                    207.09,\n                    555.57,\n                    208.06,\n                    562.34,\n                    200.33,\n                    565.24,\n                    190.67,\n                    565.24,\n                    173.27,\n                    566.2,\n                    163.61,\n                    568.14,\n                    156.85,\n                    570.07,\n                    148.15,\n                    566.2,\n                    143.32,\n                    565.24,\n                    133.66,\n                    575.86,\n                    118.2\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 2789.0208,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                589,\n                113,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                595,\n                112,\n                1,\n                584,\n                110,\n                2,\n                598,\n                123,\n                2,\n                579,\n                119,\n                2,\n                594,\n                141,\n                2,\n                570,\n                137,\n                2,\n                576,\n                135,\n                2,\n                585,\n                139,\n                2,\n                590,\n                157,\n                2,\n                574,\n                156,\n                2,\n                589,\n                192,\n                2,\n                565,\n                189,\n                1,\n                587,\n                222,\n                1,\n                557,\n                219,\n                1\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                555.57,\n                99.84,\n                48.32,\n                113.05\n            ],\n            \"category_id\": 1,\n            \"id\": 488308\n        },\n        {\n            \"segmentation\": [\n                [\n                    446.96,\n                    73.13,\n                    445.81,\n                    77.71,\n                    443.33,\n                    78.29,\n                    441.61,\n                    81.72,\n                    441.23,\n                    84.58,\n                    440.85,\n                    90.5,\n                    442.19,\n                    94.32,\n                    443.52,\n                    97.18,\n                    443.52,\n                    102.33,\n                    442.57,\n                    105.58,\n                    446.58,\n                    105.19,\n                    447.15,\n                    99.85,\n                    447.53,\n                    94.89,\n                    446,\n                    93.55,\n                    446.38,\n                    92.03,\n                    453.64,\n                    92.41,\n                    454.02,\n                    94.51,\n                    457.64,\n                    94.51,\n                    455.74,\n                    88.4,\n                    455.35,\n                    82.29,\n                    453.64,\n                    78.48,\n                    451.92,\n                    77.71,\n                    452.87,\n                    74.47,\n                    450.58,\n                    73.13\n                ]\n            ],\n            \"num_keypoints\": 0,\n            \"area\": 285.7906,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                440.85,\n                73.13,\n                16.79,\n                32.45\n            ],\n            \"category_id\": 1,\n            \"id\": 508900\n        },\n        {\n            \"segmentation\": [\n                [\n                    497.15,\n                    413.95,\n                    531.55,\n                    417.68,\n                    548.74,\n                    411.7,\n                    551.74,\n                    403.48,\n                    546.5,\n                    394.5,\n                    543.51,\n                    386.28,\n                    571.93,\n                    390.76,\n                    574.92,\n                    391.51,\n                    579.4,\n                    409.46,\n                    605.58,\n                    409.46,\n                    615.3,\n                    408.71,\n                    607.07,\n                    389.27,\n                    598.1,\n                    381.79,\n                    607.82,\n                    366.83,\n                    607.82,\n                    352.63,\n                    610.06,\n                    338.42,\n                    619.04,\n                    345.15,\n                    631,\n                    344.4,\n                    630.25,\n                    336.92,\n                    626.51,\n                    318.98,\n                    616.05,\n                    286.07,\n                    598.85,\n                    263.64,\n                    585.39,\n                    257.66,\n                    593.61,\n                    244.2,\n                    601.09,\n                    235.97,\n                    596.6,\n                    219.52,\n                    587.63,\n                    211.29,\n                    577.91,\n                    208.3,\n                    563.7,\n                    206.81,\n                    556.22,\n                    214.29,\n                    548,\n                    217.28,\n                    539.77,\n                    229.99,\n                    539.77,\n                    241.95,\n                    539.02,\n                    247.19,\n                    523.32,\n                    247.19,\n                    503.88,\n                    254.67,\n                    485.93,\n                    254.67,\n                    479.95,\n                    248.68,\n                    473.22,\n                    241.21,\n                    485.93,\n                    227,\n                    477.7,\n                    215.78,\n                    457.51,\n                    215.78,\n                    453.77,\n                    235.22,\n                    463.5,\n                    246.44,\n                    465.74,\n                    261.4,\n                    490.42,\n                    274.11,\n                    501.63,\n                    275.6,\n                    504.62,\n                    286.07,\n                    519.58,\n                    286.07,\n                    522.57,\n                    292.06,\n                    512.85,\n                    310,\n                    515.09,\n                    330.94,\n                    530.05,\n                    343.65,\n                    505.37,\n                    341.41,\n                    479.95,\n                    339.91,\n                    465.74,\n                    346.64,\n                    463.5,\n                    358.61,\n                    473.97,\n                    381.04,\n                    485.18,\n                    390.02,\n                    501.63,\n                    398.99,\n                    504.62,\n                    404.22,\n                    491.16,\n                    412.45,\n                    495.65,\n                    417.68\n                ]\n            ],\n            \"num_keypoints\": 12,\n            \"area\": 21608.94075,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                552,\n                234,\n                2,\n                0,\n                0,\n                0,\n                531,\n                262,\n                2,\n                600,\n                283,\n                2,\n                480,\n                260,\n                2,\n                622,\n                336,\n                2,\n                466,\n                242,\n                2,\n                0,\n                0,\n                0,\n                546,\n                365,\n                2,\n                592,\n                371,\n                2,\n                470,\n                351,\n                2,\n                551,\n                330,\n                2,\n                519,\n                394,\n                2,\n                589,\n                391,\n                2\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                453.77,\n                206.81,\n                177.23,\n                210.87\n            ],\n            \"category_id\": 1,\n            \"id\": 1717641\n        },\n        {\n            \"segmentation\": [\n                [\n                    58.93,\n                    163.67,\n                    47.18,\n                    161.59,\n                    36.12,\n                    93.86,\n                    41.65,\n                    82.8,\n                    40.27,\n                    69.66,\n                    50.64,\n                    67.59,\n                    55.48,\n                    73.81,\n                    63.08,\n                    92.47,\n                    66.53,\n                    99.38,\n                    65.15,\n                    109.06,\n                    61,\n                    127.03,\n                    59.62,\n                    162.97\n                ]\n            ],\n            \"num_keypoints\": 17,\n            \"area\": 1870.14015,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                48,\n                79,\n                2,\n                50,\n                77,\n                2,\n                46,\n                77,\n                2,\n                54,\n                78,\n                2,\n                45,\n                78,\n                2,\n                57,\n                90,\n                2,\n                42,\n                90,\n                2,\n                63,\n                103,\n                2,\n                42,\n                105,\n                2,\n                56,\n                113,\n                2,\n                49,\n                112,\n                2,\n                55,\n                117,\n                2,\n                44,\n                117,\n                2,\n                55,\n                140,\n                2,\n                47,\n                140,\n                2,\n                56,\n                160,\n                2,\n                49,\n                159,\n                2\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                36.12,\n                67.59,\n                30.41,\n                96.08\n            ],\n            \"category_id\": 1,\n            \"id\": 1724673\n        },\n        {\n            \"segmentation\": [\n                [\n                    139.41,\n                    321.58,\n                    144.78,\n                    326.56,\n                    196.92,\n                    314.68,\n                    196.16,\n                    309.31,\n                    207.28,\n                    292.05,\n                    213.03,\n                    284,\n                    228.75,\n                    270.2,\n                    233.35,\n                    261.38,\n                    244.47,\n                    252.56,\n                    254.44,\n                    237.61,\n                    267.86,\n                    215.37,\n                    272.08,\n                    212.68,\n                    285.5,\n                    232.62,\n                    294.7,\n                    250.64,\n                    295.08,\n                    264.06,\n                    290.87,\n                    277.87,\n                    290.87,\n                    286.3,\n                    289.71,\n                    298.19,\n                    281.66,\n                    318.89,\n                    282.05,\n                    334.23,\n                    295.08,\n                    340.37,\n                    315.02,\n                    343.82,\n                    314.25,\n                    336.53,\n                    310.42,\n                    330.4,\n                    301.98,\n                    322.34,\n                    304.29,\n                    310.84,\n                    304.67,\n                    302.79,\n                    306.2,\n                    292.05,\n                    311.19,\n                    275.56,\n                    313.87,\n                    251.79,\n                    311.19,\n                    234.54,\n                    312.72,\n                    224.57,\n                    310.42,\n                    212.3,\n                    307.74,\n                    201.56,\n                    306.2,\n                    193.51,\n                    306.59,\n                    183.16,\n                    310.04,\n                    177.41,\n                    314.64,\n                    173.19,\n                    316.94,\n                    171.65,\n                    328.06,\n                    163.99,\n                    337.64,\n                    157.85,\n                    343.4,\n                    159.77,\n                    346.46,\n                    166.67,\n                    346.85,\n                    170.5,\n                    346.46,\n                    179.71,\n                    346.85,\n                    188.53,\n                    346.85,\n                    191.98,\n                    344.55,\n                    198.11,\n                    342.25,\n                    203.48,\n                    338.41,\n                    208.46,\n                    335.34,\n                    212.68,\n                    335.34,\n                    217.67,\n                    343.01,\n                    222.65,\n                    354.9,\n                    210.76,\n                    359.12,\n                    196.19,\n                    361.8,\n                    173.19,\n                    361.42,\n                    161.69,\n                    356.43,\n                    150.18,\n                    344.93,\n                    135.61,\n                    343.01,\n                    132.93,\n                    345.31,\n                    126.41,\n                    345.7,\n                    124.88,\n                    343.4,\n                    115.29,\n                    340.33,\n                    104.17,\n                    337.26,\n                    102.25,\n                    330.36,\n                    103.4,\n                    326.14,\n                    106.09,\n                    320.01,\n                    111.07,\n                    314.64,\n                    119.89,\n                    310.42,\n                    121.04,\n                    292.02,\n                    121.81,\n                    279.75,\n                    127.94,\n                    244.09,\n                    138.68,\n                    240.25,\n                    142.51,\n                    238.72,\n                    154.4,\n                    239.1,\n                    163.6,\n                    239.87,\n                    173.96,\n                    241.79,\n                    181.24,\n                    248.3,\n                    192.36,\n                    240.25,\n                    206.55,\n                    236.42,\n                    219.2,\n                    229.9,\n                    236.45,\n                    225.3,\n                    247.57,\n                    218.4,\n                    254.48,\n                    208.81,\n                    265.6,\n                    202.29,\n                    278.25,\n                    195.39,\n                    285.92,\n                    188.49,\n                    292.05,\n                    183.5,\n                    295.89,\n                    176.6,\n                    302.41,\n                    172,\n                    308.54,\n                    167.78,\n                    313.14,\n                    146.31,\n                    318.89\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 14250.29385,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                334,\n                135,\n                2,\n                340,\n                129,\n                2,\n                331,\n                129,\n                2,\n                0,\n                0,\n                0,\n                319,\n                123,\n                2,\n                340,\n                146,\n                2,\n                292,\n                133,\n                2,\n                353,\n                164,\n                2,\n                246,\n                144,\n                2,\n                354,\n                197,\n                2,\n                250,\n                185,\n                2,\n                293,\n                197,\n                2,\n                265,\n                187,\n                2,\n                305,\n                252,\n                2,\n                231,\n                254,\n                2,\n                293,\n                321,\n                2,\n                193,\n                297,\n                2\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                139.41,\n                102.25,\n                222.39,\n                241.57\n            ],\n            \"category_id\": 1,\n            \"id\": 437295\n        },\n        {\n            \"segmentation\": [\n                [\n                    287.17,\n                    121.42,\n                    294.22,\n                    106.44,\n                    302.15,\n                    116.13,\n                    303.03,\n                    121.42\n                ],\n                [\n                    297.74,\n                    99.39,\n                    310.08,\n                    76.49,\n                    326.81,\n                    76.49,\n                    329.46,\n                    67.68,\n                    337.38,\n                    61.52,\n                    346.19,\n                    62.4,\n                    353.24,\n                    65.92,\n                    353.24,\n                    76.49,\n                    355.88,\n                    84.42,\n                    359.41,\n                    87.94,\n                    362.05,\n                    96.75,\n                    354.12,\n                    139.04,\n                    349.72,\n                    142.56,\n                    345.31,\n                    139.92,\n                    349.72,\n                    117.89,\n                    348.84,\n                    108.2,\n                    345.31,\n                    113.49,\n                    336.5,\n                    101.16,\n                    325.93,\n                    110.85,\n                    311.84,\n                    123.18\n                ],\n                [\n                    324.17,\n                    176.91,\n                    332.1,\n                    191.89,\n                    328.58,\n                    198.94,\n                    327.69,\n                    205.98,\n                    333.86,\n                    213.03,\n                    337.38,\n                    227.13,\n                    332.98,\n                    227.13,\n                    319.77,\n                    219.2,\n                    313.6,\n                    211.27\n                ],\n                [\n                    332.98,\n                    165.46,\n                    341.79,\n                    161.06,\n                    336.5,\n                    174.27,\n                    333.86,\n                    186.6,\n                    326.81,\n                    176.03\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 3404.869,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                345,\n                92,\n                2,\n                350,\n                87,\n                2,\n                341,\n                87,\n                2,\n                0,\n                0,\n                0,\n                330,\n                83,\n                2,\n                357,\n                94,\n                2,\n                316,\n                92,\n                2,\n                357,\n                104,\n                2,\n                291,\n                123,\n                1,\n                351,\n                133,\n                2,\n                281,\n                136,\n                1,\n                326,\n                131,\n                1,\n                305,\n                128,\n                1,\n                336,\n                152,\n                1,\n                303,\n                171,\n                1,\n                318,\n                206,\n                2,\n                294,\n                211,\n                1\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                287.17,\n                61.52,\n                74.88,\n                165.61\n            ],\n            \"category_id\": 1,\n            \"id\": 467657\n        },\n        {\n            \"segmentation\": [\n                [\n                    547.95,\n                    201.57,\n                    546.73,\n                    190.62,\n                    547.95,\n                    181.49,\n                    547.95,\n                    169.31,\n                    547.95,\n                    156.53,\n                    546.73,\n                    144.36,\n                    544.3,\n                    139.49,\n                    540.04,\n                    132.19,\n                    540.04,\n                    121.84,\n                    542.47,\n                    107.24,\n                    544.3,\n                    99.33,\n                    548.56,\n                    88.98,\n                    561.95,\n                    78.03,\n                    572.29,\n                    71.33,\n                    572.29,\n                    71.33,\n                    572.29,\n                    65.25,\n                    574.12,\n                    51.86,\n                    583.86,\n                    48.81,\n                    592.99,\n                    48.81,\n                    597.86,\n                    57.33,\n                    599.07,\n                    64.64,\n                    608.2,\n                    76.81,\n                    614.9,\n                    82.89,\n                    620.98,\n                    89.59,\n                    628.89,\n                    93.24,\n                    636.81,\n                    101.76,\n                    640,\n                    109.67,\n                    640,\n                    115.76,\n                    640,\n                    127.93,\n                    620.37,\n                    111.5,\n                    619.16,\n                    111.5,\n                    618.55,\n                    112.11,\n                    608.2,\n                    105.41,\n                    600.9,\n                    119.41,\n                    592.99,\n                    131.58,\n                    596.03,\n                    148.01,\n                    605.16,\n                    162.01,\n                    612.46,\n                    190.01,\n                    614.9,\n                    204.61,\n                    606.98,\n                    216.78,\n                    603.94,\n                    226.52,\n                    606.38,\n                    239.91,\n                    605.16,\n                    256.95,\n                    604.55,\n                    264.26,\n                    602.12,\n                    271.56,\n                    586.29,\n                    272.17,\n                    584.47,\n                    255.13,\n                    588.73,\n                    237.48,\n                    592.99,\n                    221.65,\n                    596.64,\n                    207.05,\n                    596.64,\n                    197.31,\n                    594.2,\n                    186.96,\n                    584.47,\n                    172.36,\n                    577.77,\n                    166.27,\n                    570.47,\n                    170.53,\n                    558.91,\n                    179.66,\n                    555.86,\n                    192.44,\n                    548.56,\n                    198.53,\n                    547.95,\n                    198.53\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 8913.98475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                591,\n                78,\n                2,\n                594,\n                74,\n                2,\n                586,\n                74,\n                2,\n                0,\n                0,\n                0,\n                573,\n                70,\n                2,\n                598,\n                86,\n                2,\n                566,\n                93,\n                2,\n                626,\n                105,\n                2,\n                546,\n                126,\n                2,\n                0,\n                0,\n                0,\n                561,\n                150,\n                2,\n                582,\n                150,\n                2,\n                557,\n                154,\n                2,\n                606,\n                194,\n                2,\n                558,\n                209,\n                1,\n                591,\n                252,\n                2,\n                539,\n                262,\n                1\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                540.04,\n                48.81,\n                99.96,\n                223.36\n            ],\n            \"category_id\": 1,\n            \"id\": 531914\n        },\n        {\n            \"segmentation\": [\n                [\n                    561.51,\n                    385.38,\n                    572.11,\n                    352.71,\n                    570.34,\n                    317.4,\n                    559.75,\n                    282.08,\n                    552.68,\n                    267.07,\n                    565.93,\n                    236.17,\n                    583.59,\n                    236.17,\n                    602.13,\n                    260.01,\n                    614.49,\n                    286.5,\n                    628.61,\n                    302.39,\n                    639.21,\n                    281.2,\n                    614.49,\n                    251.18,\n                    588,\n                    218.51,\n                    595.95,\n                    202.62,\n                    594.18,\n                    185.85,\n                    580.05,\n                    170.84,\n                    562.4,\n                    179.67,\n                    557.98,\n                    198.21,\n                    554.45,\n                    202.62,\n                    532.38,\n                    199.97,\n                    525.32,\n                    202.62,\n                    511.19,\n                    229.11,\n                    493.53,\n                    256.48,\n                    484.7,\n                    276.78,\n                    451.15,\n                    323.58,\n                    423.78,\n                    338.59,\n                    388.47,\n                    373.9,\n                    372.58,\n                    387.14,\n                    396.41,\n                    388.03,\n                    418.49,\n                    367.72,\n                    450.27,\n                    345.65,\n                    501.48,\n                    306.8,\n                    520.02,\n                    301.5,\n                    552.68,\n                    340.35,\n                    543.86,\n                    369.49\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 14267.20475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                580,\n                211,\n                2,\n                586,\n                206,\n                2,\n                574,\n                204,\n                2,\n                0,\n                0,\n                0,\n                562,\n                198,\n                2,\n                584,\n                220,\n                2,\n                529,\n                215,\n                2,\n                599,\n                242,\n                2,\n                512,\n                260,\n                2,\n                619,\n                274,\n                2,\n                538,\n                285,\n                2,\n                537,\n                288,\n                2,\n                506,\n                277,\n                2,\n                562,\n                332,\n                2,\n                452,\n                332,\n                2,\n                550,\n                387,\n                1,\n                402,\n                371,\n                2\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                372.58,\n                170.84,\n                266.63,\n                217.19\n            ],\n            \"category_id\": 1,\n            \"id\": 533949\n        },\n        {\n            \"segmentation\": [\n                [\n                    2.03,\n                    75.18,\n                    10.85,\n                    70.58,\n                    16.99,\n                    65.59,\n                    17.75,\n                    55.24,\n                    20.05,\n                    50.25,\n                    29.64,\n                    43.74,\n                    37.31,\n                    47.57,\n                    41.52,\n                    53.7,\n                    43.83,\n                    64.82,\n                    53.03,\n                    70.19,\n                    61.85,\n                    77.09,\n                    72.58,\n                    87.06,\n                    74.88,\n                    79.01,\n                    78.72,\n                    73.64,\n                    86.39,\n                    77.86,\n                    90.6,\n                    90.13,\n                    86,\n                    93.2,\n                    82.17,\n                    102.4,\n                    75.27,\n                    106.24,\n                    68.75,\n                    104.7,\n                    50.34,\n                    90.9,\n                    43.06,\n                    112.37,\n                    40.76,\n                    123.11,\n                    42.29,\n                    130.78,\n                    48.04,\n                    161.83,\n                    52.26,\n                    190.59,\n                    50.73,\n                    210.15,\n                    44.21,\n                    245.04,\n                    50.34,\n                    256.16,\n                    53.03,\n                    261.53,\n                    47.28,\n                    263.83,\n                    40.37,\n                    263.83,\n                    31.56,\n                    260.76,\n                    28.1,\n                    256.16,\n                    26.95,\n                    244.65,\n                    29.25,\n                    233.54,\n                    32.71,\n                    223.95,\n                    33.09,\n                    213.98,\n                    32.32,\n                    206.31,\n                    32.71,\n                    194.81,\n                    33.09,\n                    185.61,\n                    24.65,\n                    177.17,\n                    16.99,\n                    161.45,\n                    13.53,\n                    176.02,\n                    10.85,\n                    206.31,\n                    1.65,\n                    231.62,\n                    1.65,\n                    235.84,\n                    0.5,\n                    146.88,\n                    0.88,\n                    122.34,\n                    1.65,\n                    75.56\n                ]\n            ],\n            \"num_keypoints\": 13,\n            \"area\": 8260.75085,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                36,\n                79,\n                2,\n                40,\n                74,\n                2,\n                31,\n                75,\n                2,\n                0,\n                0,\n                0,\n                19,\n                69,\n                2,\n                45,\n                77,\n                2,\n                2,\n                89,\n                2,\n                74,\n                99,\n                2,\n                0,\n                0,\n                0,\n                78,\n                92,\n                2,\n                0,\n                0,\n                0,\n                33,\n                149,\n                2,\n                7,\n                153,\n                2,\n                44,\n                196,\n                2,\n                2,\n                205,\n                2,\n                35,\n                245,\n                2,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                0.5,\n                43.74,\n                90.1,\n                220.09\n            ],\n            \"category_id\": 1,\n            \"id\": 543117\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/coco/test_coco_det_AP_H_56.json",
    "content": "[\n    {\n        \"bbox\": [\n            277.1183158543966,\n            45.699667786163765,\n            225.09126579259754,\n            333.5602652943344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.9999731779098511\n    },\n    {\n        \"bbox\": [\n            281.950178384611,\n            44.56940615106412,\n            212.94084624881856,\n            344.98328732330305\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.30122078732076535\n    },\n    {\n        \"bbox\": [\n            268.01163251716935,\n            43.98534000198524,\n            238.46561540311666,\n            341.79494090239166\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.09537058952055945\n    },\n    {\n        \"bbox\": [\n            286.24685022227766,\n            41.757854101745124,\n            223.83092714841916,\n            338.2323329803221\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.02974060317622316\n    },\n    {\n        \"bbox\": [\n            262.7942371596824,\n            63.5024099030928,\n            3.164080328447767,\n            4.2931809049024\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.01697496324777603\n    },\n    {\n        \"bbox\": [\n            460.79934160584526,\n            54.24632570186816,\n            3.1264258976875112,\n            5.30507188737684\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.011266417550507977\n    },\n    {\n        \"bbox\": [\n            457.74867915702885,\n            54.642754761043186,\n            3.1463156275978577,\n            5.30487109975607\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.009877337450527405\n    },\n    {\n        \"bbox\": [\n            283.6326909128262,\n            48.41948428440242,\n            208.11973684568892,\n            329.94523003138954\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.009197559746208601\n    },\n    {\n        \"bbox\": [\n            207.3711401479468,\n            63.36160650309581,\n            2.93447433643874,\n            3.468569626452343\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.008295997977256775\n    },\n    {\n        \"bbox\": [\n            458.51562228937183,\n            59.46703918462182,\n            3.272054625157523,\n            4.619048555254508\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.008173274752520696\n    },\n    {\n        \"bbox\": [\n            461.08150984219986,\n            58.545150021384245,\n            3.249185872840485,\n            5.844152786677249\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.007174033771332924\n    },\n    {\n        \"bbox\": [\n            259.83498140597413,\n            62.3517572900752,\n            2.9195241669668235,\n            4.559862560086913\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.006377489306032658\n    },\n    {\n        \"bbox\": [\n            206.80460173580252,\n            62.5220090883142,\n            3.1584765729102457,\n            3.520867237953432\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.005891890564944476\n    },\n    {\n        \"bbox\": [\n            459.5511247244534,\n            54.89593493663015,\n            3.230180209185619,\n            5.595806307593442\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.005863019167811413\n    },\n    {\n        \"bbox\": [\n            457.2902794671802,\n            58.740074277713674,\n            3.316325358758718,\n            5.415639229745793\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.005827399869551478\n    },\n    {\n        \"bbox\": [\n            262.6182415084011,\n            62.83701378140133,\n            3.0697625867510396,\n            4.148177980683975\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.005008531179775657\n    },\n    {\n        \"bbox\": [\n            209.95621769919438,\n            63.58898404912936,\n            3.097942773760309,\n            3.9870186328652224\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.004536413883644729\n    },\n    {\n        \"bbox\": [\n            459.25342388420654,\n            59.04022778823142,\n            3.6918324658356596,\n            6.2054702421954175\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.00384555541357817\n    },\n    {\n        \"bbox\": [\n            208.42983867925258,\n            62.66620641784881,\n            2.939843970544956,\n            3.5128275773914908\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.003631657359987463\n    },\n    {\n        \"bbox\": [\n            213.41976294267863,\n            62.71431286477077,\n            2.528260915549936,\n            3.4008991982205927\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.0033746918197721243\n    },\n    {\n        \"bbox\": [\n            161.97753405615518,\n            61.730313756833205,\n            2.8917805026908923,\n            4.075206275914702\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.003240120830014348\n    },\n    {\n        \"bbox\": [\n            457.5244691894709,\n            54.70691525725411,\n            6.2095088496953394,\n            8.39989354390223\n        ],\n        \"category_id\": 1,\n        \"image_id\": 785,\n        \"score\": 0.0028898494491729535\n    },\n    {\n        \"bbox\": [\n            376.9178826443722,\n            172.73052709081233,\n            261.25961331942824,\n            215.58502374291808\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.9999579191207886\n    },\n    {\n        \"bbox\": [\n            163.9687616410633,\n            80.41943032016765,\n            200.19976794356094,\n            259.2492676442412\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.9999035596847534\n    },\n    {\n        \"bbox\": [\n            1.218278714743892,\n            47.45300387559155,\n            90.54113395922819,\n            220.98988830655202\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.9998950958251953\n    },\n    {\n        \"bbox\": [\n            542.055600304138,\n            50.78951110214531,\n            97.65374183236963,\n            187.04227881069528\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.9867184565824798\n    },\n    {\n        \"bbox\": [\n            281.8670596900398,\n            58.53450299402189,\n            82.11294655596839,\n            86.20744367046282\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.9736837699533164\n    },\n    {\n        \"bbox\": [\n            279.94252362290945,\n            59.89339467038772,\n            81.61478084086349,\n            147.45283612214442\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.5819535544584765\n    },\n    {\n        \"bbox\": [\n            535.4019505240893,\n            48.1844256878009,\n            105.27804947591062,\n            239.31002317693435\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.4461107432274131\n    },\n    {\n        \"bbox\": [\n            168.57347257788564,\n            103.56636286623898,\n            188.67170536354314,\n            230.37891238088162\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.3492993107937081\n    },\n    {\n        \"bbox\": [\n            372.0082417618134,\n            163.99891619439003,\n            236.90653900133447,\n            224.81380141719242\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.32743142104478484\n    },\n    {\n        \"bbox\": [\n            1.388905257619702,\n            35.86500152126901,\n            87.67960208998994,\n            220.4727970838673\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.31936580857404523\n    },\n    {\n        \"bbox\": [\n            283.65021434011885,\n            57.518455359834334,\n            81.08575097216988,\n            85.11418577738398\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.1897958763078807\n    },\n    {\n        \"bbox\": [\n            543.1779979060689,\n            37.87532382036906,\n            94.66280745251572,\n            191.29243939893223\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.17261266781373394\n    },\n    {\n        \"bbox\": [\n            258.5633408567725,\n            60.27068241963883,\n            102.3686462123,\n            151.42071713691902\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.13677866226510016\n    },\n    {\n        \"bbox\": [\n            380.00719017305823,\n            181.1782438214781,\n            257.505490623621,\n            199.13011090655024\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.12246560363252844\n    },\n    {\n        \"bbox\": [\n            177.40899563109633,\n            78.35446740631232,\n            189.53651142957023,\n            263.45315194093274\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.1013108540546625\n    },\n    {\n        \"bbox\": [\n            0.7289829477709847,\n            43.73276160140667,\n            85.41587076323728,\n            221.3344387113314\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.09960434746646744\n    },\n    {\n        \"bbox\": [\n            461.84120081448543,\n            144.75681027711394,\n            7.162490813687327,\n            8.531497919325176\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.08173750340938568\n    },\n    {\n        \"bbox\": [\n            296.17189402683806,\n            85.73360082440907,\n            62.47594584815931,\n            130.1418854933646\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.0717465542448663\n    },\n    {\n        \"bbox\": [\n            539.1454728501081,\n            43.14242476252679,\n            100.3810332864756,\n            247.18086755992118\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.06011599272181979\n    },\n    {\n        \"bbox\": [\n            277.97115514687323,\n            62.833796387748365,\n            85.73469418408934,\n            109.64015622069529\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.0423359872651069\n    },\n    {\n        \"bbox\": [\n            462.1613388043361,\n            146.12331612284657,\n            4.619414527763752,\n            5.653142729845399\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.03960325857728385\n    },\n    {\n        \"bbox\": [\n            365.7412020686737,\n            174.63881714430087,\n            251.65152786857914,\n            216.71453560361638\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.03937998874316995\n    },\n    {\n        \"bbox\": [\n            3.4297732174796693,\n            45.43705430480154,\n            92.63472057783511,\n            222.82923167372067\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.033127322744961746\n    },\n    {\n        \"bbox\": [\n            169.87771310995316,\n            89.66612191248007,\n            182.26201179942262,\n            244.24356591209786\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.03232751908601077\n    },\n    {\n        \"bbox\": [\n            236.36941077406334,\n            63.89780825602214,\n            126.04036089393139,\n            167.83640884370914\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.026460597694444848\n    },\n    {\n        \"bbox\": [\n            306.015998970117,\n            102.95796459236254,\n            50.95681252313989,\n            115.84925059311661\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.02226386399182351\n    },\n    {\n        \"bbox\": [\n            537.318841521999,\n            51.127194758764055,\n            100.70779100270272,\n            184.38821643554354\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.021828400794543387\n    },\n    {\n        \"bbox\": [\n            462.4003780259345,\n            145.2270003005055,\n            5.570865375100425,\n            6.968161205149954\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.017564592704083917\n    },\n    {\n        \"bbox\": [\n            284.4247396061427,\n            58.40109305610073,\n            77.51981649355616,\n            85.87582588813615\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.015670991050973693\n    },\n    {\n        \"bbox\": [\n            381.11136505330313,\n            182.22526492755827,\n            252.6961926281694,\n            195.18863447956443\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.012290037721773745\n    },\n    {\n        \"bbox\": [\n            159.00697010469204,\n            66.94814529991709,\n            208.17784842532066,\n            275.3418926190766\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.010543055168754003\n    },\n    {\n        \"bbox\": [\n            0.0,\n            41.78049849392192,\n            88.22526407776418,\n            228.8951048951705\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.009550385293192926\n    },\n    {\n        \"bbox\": [\n            577.9447869595953,\n            225.0889245399691,\n            34.613561069282355,\n            45.224848999211105\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.009009368302155088\n    },\n    {\n        \"bbox\": [\n            461.84120081448543,\n            144.75681027711394,\n            7.162490813687327,\n            8.531497919325176\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.008478489359995936\n    },\n    {\n        \"bbox\": [\n            536.7620147243282,\n            50.12388034294447,\n            103.91798527567175,\n            227.99503472686746\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.0070238283037164315\n    },\n    {\n        \"bbox\": [\n            324.4889601722706,\n            132.0053388533619,\n            33.860410488241655,\n            86.62326758044719\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.006766568381450841\n    },\n    {\n        \"bbox\": [\n            246.15395215941302,\n            55.57516986353281,\n            114.57893265029415,\n            151.51097731653135\n        ],\n        \"category_id\": 1,\n        \"image_id\": 197388,\n        \"score\": 0.00619416668365814\n    },\n    {\n        \"bbox\": [\n            38.32789823729127,\n            112.41407584232527,\n            174.68030024685248,\n            169.5690071995081\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.9999903440475464\n    },\n    {\n        \"bbox\": [\n            273.75504650493133,\n            127.03007800217645,\n            13.119059034012025,\n            66.89919582171933\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.9987139701843262\n    },\n    {\n        \"bbox\": [\n            281.037309318129,\n            138.89800552022552,\n            115.77299430404673,\n            161.8925392525125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.9967334429627354\n    },\n    {\n        \"bbox\": [\n            122.98736914581909,\n            149.19548926043387,\n            13.238023418245518,\n            13.251921410601938\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.7115740632536128\n    },\n    {\n        \"bbox\": [\n            134.73643174966296,\n            136.1444006258907,\n            11.484101688887165,\n            24.515063595289917\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.6175192526221182\n    },\n    {\n        \"bbox\": [\n            244.00963353440733,\n            141.97232651644495,\n            149.05240181123492,\n            151.9715830001215\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.4946145965118973\n    },\n    {\n        \"bbox\": [\n            275.164993708296,\n            126.95531864312014,\n            13.321305363409294,\n            66.11390534184258\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.4050845742423741\n    },\n    {\n        \"bbox\": [\n            42.96185669219733,\n            122.34524983009223,\n            160.1285645732864,\n            161.9463250366397\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.353162111215626\n    },\n    {\n        \"bbox\": [\n            119.6385577246031,\n            155.7402521228216,\n            13.35265116435049,\n            26.52128467487711\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.28122130800324224\n    },\n    {\n        \"bbox\": [\n            134.01278713702155,\n            135.5395238881317,\n            11.64567949798922,\n            24.682523935864452\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.19370334661431887\n    },\n    {\n        \"bbox\": [\n            124.09760300731958,\n            148.1338264630807,\n            11.235262772767982,\n            13.52837293393398\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.176868630098971\n    },\n    {\n        \"bbox\": [\n            218.7332213212989,\n            140.0443329358783,\n            180.4683469351732,\n            156.8554518569021\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.16822000522327524\n    },\n    {\n        \"bbox\": [\n            270.92053528959764,\n            133.3265646431611,\n            13.58464710826729,\n            56.339971422777694\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.1562438273124175\n    },\n    {\n        \"bbox\": [\n            37.809250550065954,\n            105.79757078726388,\n            182.54979468741817,\n            184.99414098124603\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.14206553007930756\n    },\n    {\n        \"bbox\": [\n            131.5670033941938,\n            158.319905396887,\n            9.554075877756475,\n            21.518604078379468\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.1142622835492838\n    },\n    {\n        \"bbox\": [\n            127.07848171294685,\n            138.86839277431187,\n            17.235128293754656,\n            44.84156945207431\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.09938282001938761\n    },\n    {\n        \"bbox\": [\n            275.15638186104223,\n            133.5832174441871,\n            10.20764095132887,\n            60.2529082432996\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.08779323860838567\n    },\n    {\n        \"bbox\": [\n            118.09746041875155,\n            153.9768088492941,\n            17.64612772931838,\n            33.0168198306535\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.08400380428176607\n    },\n    {\n        \"bbox\": [\n            129.65247011589898,\n            146.21014275291188,\n            9.816644995735373,\n            16.98788352109895\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.07980794934855787\n    },\n    {\n        \"bbox\": [\n            271.7621155363754,\n            144.86674821981342,\n            124.64715453387907,\n            156.9482558015152\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.07801336023989208\n    },\n    {\n        \"bbox\": [\n            122.31437055574987,\n            149.80085696138593,\n            14.266245774025762,\n            12.463835012516398\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.06346535355569785\n    },\n    {\n        \"bbox\": [\n            34.56564215631444,\n            135.92815585957712,\n            177.51220438385354,\n            164.41951766953704\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.0485074333765967\n    },\n    {\n        \"bbox\": [\n            136.7368415229119,\n            137.89135149894196,\n            9.122227037700043,\n            22.213023488378155\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.04772781404400169\n    },\n    {\n        \"bbox\": [\n            123.3235499944418,\n            150.25321417348,\n            15.765761854272228,\n            36.16957895970921\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.04220727754152085\n    },\n    {\n        \"bbox\": [\n            271.90779626938615,\n            128.14539407135078,\n            15.405080085072711,\n            64.71005682344074\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.04092462762153748\n    },\n    {\n        \"bbox\": [\n            114.0193235709124,\n            155.5618252886575,\n            9.112663847332854,\n            14.913955482463706\n        ],\n        \"category_id\": 1,\n        \"image_id\": 40083,\n        \"score\": 0.040561411233867466\n    },\n    {\n        \"bbox\": [\n            246.79480278830977,\n            74.45452361185933,\n            168.83467296399175,\n            294.5553838783887\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.9998471736907959\n    },\n    {\n        \"bbox\": [\n            449.91721482790945,\n            204.96684769367067,\n            185.0938399278399,\n            209.68341364145596\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.9993680119514465\n    },\n    {\n        \"bbox\": [\n            551.8933527530817,\n            98.62668626165973,\n            53.015730818431166,\n            114.70768739332982\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.9989681245939074\n    },\n    {\n        \"bbox\": [\n            36.629787184254866,\n            68.37446568096026,\n            33.14949933628988,\n            95.8618173172063\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.9987284541130066\n    },\n    {\n        \"bbox\": [\n            440.89995321368673,\n            70.30641025016695,\n            19.43814726089363,\n            37.077964642141026\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.9947758913040161\n    },\n    {\n        \"bbox\": [\n            601.8062068801571,\n            88.95295148681318,\n            16.128385553229577,\n            24.398472250098138\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.7787292817106939\n    },\n    {\n        \"bbox\": [\n            443.0809847626748,\n            71.63759967713678,\n            13.50749833723944,\n            32.66811758890536\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.4904795373325092\n    },\n    {\n        \"bbox\": [\n            396.569778686132,\n            70.2787260371438,\n            13.479104730026052,\n            31.759617864735645\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.4112498931182214\n    },\n    {\n        \"bbox\": [\n            38.70719296509935,\n            70.61443452888409,\n            28.17963315510066,\n            92.31016180688292\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.3796398182128506\n    },\n    {\n        \"bbox\": [\n            609.3142175988798,\n            93.72376246104807,\n            19.058191027280486,\n            20.77005778794522\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.370328633830097\n    },\n    {\n        \"bbox\": [\n            548.7095132625554,\n            98.39472701114634,\n            53.25156101474022,\n            116.43788199987897\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.33102923130101364\n    },\n    {\n        \"bbox\": [\n            455.5297663676009,\n            206.88078209027378,\n            175.70291860814734,\n            199.34403654904446\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.3069290034626759\n    },\n    {\n        \"bbox\": [\n            250.74661573104714,\n            87.13280710904513,\n            167.45142937734437,\n            278.3106151544837\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.30579873324356427\n    },\n    {\n        \"bbox\": [\n            440.7002672189753,\n            69.17369758813695,\n            14.444703091985616,\n            37.00946842030504\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.25331338842056605\n    },\n    {\n        \"bbox\": [\n            614.9353977385917,\n            95.74403799582933,\n            11.596245346674664,\n            17.631981747095708\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.22204102380904406\n    },\n    {\n        \"bbox\": [\n            400.60963922399134,\n            70.43862641691737,\n            8.331775245023891,\n            35.000620170929324\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.20590268390631786\n    },\n    {\n        \"bbox\": [\n            602.6848618804396,\n            88.3983294514046,\n            15.524266109773862,\n            24.329680417924536\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.1935096033322262\n    },\n    {\n        \"bbox\": [\n            453.62495235047044,\n            80.93588476309868,\n            8.634490931609093,\n            24.416622635007826\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.13682630359796108\n    },\n    {\n        \"bbox\": [\n            438.1383792082668,\n            71.62832244418284,\n            13.671594135308055,\n            34.59094773941301\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.12521365808926627\n    },\n    {\n        \"bbox\": [\n            37.07150693742372,\n            71.09337416480857,\n            29.051661261168164,\n            90.74910484197981\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.11572668958758377\n    },\n    {\n        \"bbox\": [\n            612.4694532238449,\n            94.33977605307147,\n            11.44235234183725,\n            18.834863504196264\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.1118136151149066\n    },\n    {\n        \"bbox\": [\n            601.3005939432458,\n            93.44761682206529,\n            12.158258551431686,\n            21.16533746684057\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.10474070969851616\n    },\n    {\n        \"bbox\": [\n            552.5681619230662,\n            93.99774029686462,\n            52.01820025716597,\n            118.51885706193504\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.10326196808658804\n    },\n    {\n        \"bbox\": [\n            398.5848517781443,\n            73.06106969434823,\n            9.784228227546066,\n            31.1350301063286\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.09513584625155845\n    },\n    {\n        \"bbox\": [\n            447.4145013754455,\n            199.11669450357687,\n            182.9378852593169,\n            211.20266858232594\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.09457972184460144\n    },\n    {\n        \"bbox\": [\n            242.46158239970538,\n            71.50036639162563,\n            171.43617162489392,\n            297.42260463621386\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.09176039055855717\n    },\n    {\n        \"bbox\": [\n            597.2197814264931,\n            82.37761224901661,\n            11.327105500584025,\n            31.481263735129318\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.08028100931968704\n    },\n    {\n        \"bbox\": [\n            599.0760153957814,\n            81.53235136929479,\n            7.865899180085421,\n            9.27911853791521\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.06306317158251058\n    },\n    {\n        \"bbox\": [\n            458.0528386594554,\n            76.79036559159022,\n            7.6005536116708186,\n            25.915126727881812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.06281862376239655\n    },\n    {\n        \"bbox\": [\n            446.7096696323964,\n            70.72615937722122,\n            12.841618701895356,\n            34.64495922754935\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.061957712774678333\n    },\n    {\n        \"bbox\": [\n            435.5707540307205,\n            72.6766990179972,\n            9.948115403515544,\n            29.835360002866068\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.05090554307604889\n    },\n    {\n        \"bbox\": [\n            395.9134672120448,\n            68.37234648135498,\n            13.313090353344592,\n            35.21000811416911\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.048676813090792935\n    },\n    {\n        \"bbox\": [\n            441.55283109201787,\n            70.93636919677598,\n            12.61247065074889,\n            34.04032271350583\n        ],\n        \"category_id\": 1,\n        \"image_id\": 196141,\n        \"score\": 0.041175731433019114\n    }\n]\n"
  },
  {
    "path": "tests/data/coco/test_coco_wholebody.json",
    "content": "{\n    \"info\": {\n        \"description\": \"COCO-WholeBody sample\",\n        \"url\": \"https://github.com/jin-s13/COCO-WholeBody\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/09/18\"\n    },\n    \"licenses\": [\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc-sa/2.0/\",\n            \"id\": 1,\n            \"name\": \"Attribution-NonCommercial-ShareAlike License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc/2.0/\",\n            \"id\": 2,\n            \"name\": \"Attribution-NonCommercial License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc-nd/2.0/\",\n            \"id\": 3,\n            \"name\": \"Attribution-NonCommercial-NoDerivs License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by/2.0/\",\n            \"id\": 4,\n            \"name\": \"Attribution License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-sa/2.0/\",\n            \"id\": 5,\n            \"name\": \"Attribution-ShareAlike License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nd/2.0/\",\n            \"id\": 6,\n            \"name\": \"Attribution-NoDerivs License\"\n        },\n        {\n            \"url\": \"http://flickr.com/commons/usage/\",\n            \"id\": 7,\n            \"name\": \"No known copyright restrictions\"\n        },\n        {\n            \"url\": \"http://www.usa.gov/copyright.shtml\",\n            \"id\": 8,\n            \"name\": \"United States Government Work\"\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"left_eye\",\n                \"right_eye\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"license\": 4,\n            \"file_name\": \"000000000785.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000000785.jpg\",\n            \"height\": 425,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 21:22:42\",\n            \"flickr_url\": \"http://farm8.staticflickr.com/7015/6795644157_f019453ae7_z.jpg\",\n            \"id\": 785\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000040083.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000040083.jpg\",\n            \"height\": 333,\n            \"width\": 500,\n            \"date_captured\": \"2013-11-18 03:30:24\",\n            \"flickr_url\": \"http://farm1.staticflickr.com/116/254881838_e21c6d17b8_z.jpg\",\n            \"id\": 40083\n        },\n        {\n            \"license\": 1,\n            \"file_name\": \"000000196141.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000196141.jpg\",\n            \"height\": 429,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-22 22:37:15\",\n            \"flickr_url\": \"http://farm4.staticflickr.com/3310/3611902235_57d4ae496d_z.jpg\",\n            \"id\": 196141\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000197388.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000197388.jpg\",\n            \"height\": 392,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 20:10:37\",\n            \"flickr_url\": \"http://farm9.staticflickr.com/8375/8507321836_5b8b13188f_z.jpg\",\n            \"id\": 197388\n        }\n    ],\n    \"annotations\": [\n        {\n            \"segmentation\": [\n                [\n                    353.37,\n                    67.65,\n                    358.15,\n                    52.37,\n                    362.92,\n                    47.59,\n                    374.38,\n                    44.73,\n                    389.66,\n                    52.37,\n                    389.66,\n                    67.65,\n                    389.66,\n                    76.25,\n                    393.48,\n                    83.89,\n                    396.35,\n                    88.66,\n                    397.3,\n                    91.53,\n                    406.85,\n                    99.17,\n                    413.54,\n                    104.9,\n                    451.74,\n                    148.83,\n                    458.43,\n                    153.6,\n                    462.25,\n                    166.02,\n                    467.02,\n                    173.66,\n                    463.2,\n                    181.3,\n                    449.83,\n                    183.21,\n                    448.88,\n                    191.81,\n                    455.56,\n                    226.19,\n                    448.88,\n                    254.84,\n                    453.65,\n                    286.36,\n                    475.62,\n                    323.6,\n                    491.85,\n                    361.81,\n                    494.72,\n                    382.82,\n                    494.72,\n                    382.82,\n                    499.49,\n                    391.41,\n                    416.4,\n                    391.41,\n                    424.04,\n                    383.77,\n                    439.33,\n                    374.22,\n                    445.06,\n                    360.85,\n                    436.46,\n                    334.11,\n                    421.18,\n                    303.55,\n                    416.4,\n                    289.22,\n                    409.72,\n                    268.21,\n                    396.35,\n                    280.63,\n                    405.9,\n                    298.77,\n                    417.36,\n                    324.56,\n                    425,\n                    349.39,\n                    425,\n                    357.99,\n                    419.27,\n                    360.85,\n                    394.44,\n                    367.54,\n                    362.92,\n                    370.4,\n                    346.69,\n                    367.54,\n                    360.06,\n                    362.76,\n                    369.61,\n                    360.85,\n                    382.98,\n                    340.8,\n                    355.28,\n                    271.08,\n                    360.06,\n                    266.3,\n                    386.8,\n                    219.5,\n                    368.65,\n                    162.2,\n                    348.6,\n                    175.57,\n                    309.44,\n                    187.03,\n                    301.8,\n                    192.76,\n                    288.43,\n                    193.72,\n                    282.7,\n                    193.72,\n                    280.79,\n                    187.03,\n                    280.79,\n                    174.62,\n                    287.47,\n                    171.75,\n                    291.29,\n                    171.75,\n                    295.11,\n                    171.75,\n                    306.57,\n                    166.98,\n                    312.3,\n                    165.07,\n                    345.73,\n                    142.14,\n                    350.51,\n                    117.31,\n                    350.51,\n                    102.03,\n                    350.51,\n                    90.57,\n                    353.37,\n                    65.74\n                ]\n            ],\n            \"num_keypoints\": 17,\n            \"area\": 27789.11055,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                367,\n                81,\n                2,\n                374,\n                73,\n                2,\n                360,\n                75,\n                2,\n                386,\n                78,\n                2,\n                356,\n                81,\n                2,\n                399,\n                108,\n                2,\n                358,\n                129,\n                2,\n                433,\n                142,\n                2,\n                341,\n                159,\n                2,\n                449,\n                165,\n                2,\n                309,\n                178,\n                2,\n                424,\n                203,\n                2,\n                393,\n                214,\n                2,\n                429,\n                294,\n                2,\n                367,\n                273,\n                2,\n                466,\n                362,\n                2,\n                396,\n                341,\n                2\n            ],\n            \"image_id\": 785,\n            \"bbox\": [\n                280.79,\n                44.73,\n                218.7,\n                346.68\n            ],\n            \"category_id\": 1,\n            \"id\": 442619,\n            \"face_box\": [\n                358.2,\n                69.86,\n                26.360000000000014,\n                25.849999999999994\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                280.43,\n                173.12,\n                27.860000000000014,\n                24.849999999999994\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                304.10366,\n                181.75134,\n                1,\n                300.70183,\n                182.77567,\n                1,\n                297.3,\n                183.8,\n                1,\n                294.7,\n                186.5,\n                1,\n                290.1,\n                187.8,\n                1,\n                290.9,\n                176.6,\n                1,\n                287.5,\n                176.0,\n                1,\n                285.5,\n                178.4,\n                1,\n                286.4,\n                182.4,\n                1,\n                288.8,\n                179.4,\n                1,\n                285.0,\n                181.0,\n                1,\n                287.3,\n                186.1,\n                1,\n                291.8,\n                189.5,\n                1,\n                287.7,\n                182.7,\n                1,\n                283.8,\n                184.1,\n                1,\n                286.5,\n                189.1,\n                1,\n                290.0,\n                192.0,\n                1,\n                286.7,\n                185.3,\n                1,\n                282.8,\n                187.4,\n                1,\n                284.8,\n                191.6,\n                1,\n                288.4,\n                194.5,\n                1\n            ],\n            \"face_kpts\": [\n                355.823,\n                75.36,\n                1.0,\n                356.354,\n                79.0837,\n                1.0,\n                357.244,\n                82.7374,\n                1.0,\n                358.518,\n                86.2722,\n                1.0,\n                360.146,\n                89.6578,\n                1.0,\n                362.266,\n                92.7538,\n                1.0,\n                365.004,\n                95.3223,\n                1.0,\n                368.487,\n                96.6454,\n                1.0,\n                372.191,\n                96.1419,\n                1.0,\n                375.644,\n                94.6832,\n                1.0,\n                378.601,\n                92.3665,\n                1.0,\n                381.101,\n                89.5662,\n                1.0,\n                382.903,\n                86.2741,\n                1.0,\n                383.896,\n                82.6509,\n                1.0,\n                384.075,\n                78.9011,\n                1.0,\n                384.1,\n                75.1408,\n                1.0,\n                383.903,\n                71.3861,\n                1.0,\n                357.084,\n                72.9743,\n                1.0,\n                358.602,\n                71.7848,\n                1.0,\n                360.42,\n                71.3443,\n                1.0,\n                362.377,\n                71.1566,\n                1.0,\n                364.36,\n                71.1889,\n                1.0,\n                368.971,\n                70.4992,\n                1.0,\n                370.945,\n                69.8179,\n                1.0,\n                373.001,\n                69.3543,\n                1.0,\n                375.14,\n                69.2666,\n                1.0,\n                377.358,\n                69.8865,\n                1.0,\n                366.57,\n                73.9588,\n                1.0,\n                366.734,\n                76.1499,\n                1.0,\n                366.88,\n                78.3018,\n                1.0,\n                366.99,\n                80.4957,\n                1.0,\n                365.104,\n                82.5589,\n                1.0,\n                366.308,\n                82.8331,\n                1.0,\n                367.645,\n                82.8037,\n                1.0,\n                369.172,\n                82.2061,\n                1.0,\n                370.693,\n                81.6521,\n                1.0,\n                358.705,\n                75.4542,\n                1.0,\n                360.294,\n                74.0903,\n                1.0,\n                362.376,\n                73.8423,\n                1.0,\n                364.302,\n                74.6834,\n                1.0,\n                362.543,\n                75.568,\n                1.0,\n                360.612,\n                75.8883,\n                1.0,\n                369.771,\n                73.7734,\n                1.0,\n                371.409,\n                72.2638,\n                1.0,\n                373.615,\n                71.9502,\n                1.0,\n                375.722,\n                72.7144,\n                1.0,\n                373.888,\n                73.699,\n                1.0,\n                371.835,\n                74.0238,\n                1.0,\n                363.184,\n                86.9317,\n                1.0,\n                364.788,\n                85.4484,\n                1.0,\n                367.021,\n                84.7474,\n                1.0,\n                368.048,\n                84.5364,\n                1.0,\n                369.083,\n                84.3709,\n                1.0,\n                372.183,\n                84.0529,\n                1.0,\n                375.083,\n                84.8901,\n                1.0,\n                373.687,\n                87.0735,\n                1.0,\n                371.644,\n                88.8121,\n                1.0,\n                369.024,\n                89.6982,\n                1.0,\n                366.67,\n                89.6039,\n                1.0,\n                364.721,\n                88.606,\n                1.0,\n                363.588,\n                86.903,\n                1.0,\n                365.723,\n                85.8496,\n                1.0,\n                368.184,\n                85.2863,\n                1.0,\n                371.444,\n                84.8294,\n                1.0,\n                374.647,\n                85.0454,\n                1.0,\n                372.166,\n                87.2914,\n                1.0,\n                368.81,\n                88.3791,\n                1.0,\n                365.965,\n                88.3238,\n                1.0\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": true,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                439,\n                378,\n                2,\n                446,\n                380,\n                2,\n                479,\n                370,\n                2,\n                377,\n                359,\n                2,\n                376,\n                358,\n                2,\n                413,\n                353,\n                2\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    98.56,\n                    273.72,\n                    132.9,\n                    267,\n                    140.37,\n                    281.93,\n                    165.75,\n                    285.66,\n                    156.79,\n                    264.01,\n                    170.23,\n                    261.02,\n                    177.7,\n                    272.97,\n                    182.18,\n                    279.69,\n                    200.85,\n                    268.49,\n                    212.79,\n                    255.05,\n                    188.9,\n                    256.54,\n                    164.26,\n                    240.12,\n                    139.62,\n                    212.49,\n                    109.01,\n                    221.45,\n                    103.04,\n                    220.71,\n                    122.45,\n                    202.04,\n                    113.49,\n                    196.07,\n                    96.32,\n                    168.44,\n                    97.06,\n                    162.47,\n                    110.5,\n                    136.34,\n                    112,\n                    124.39,\n                    91.09,\n                    110.95,\n                    80.64,\n                    114.68,\n                    71.68,\n                    131.86,\n                    62.72,\n                    147.54,\n                    57.49,\n                    156.5,\n                    48.53,\n                    168.44,\n                    41.07,\n                    180.39,\n                    38.08,\n                    193.08,\n                    40.32,\n                    205.03,\n                    47.04,\n                    213.24,\n                    54.5,\n                    216.23,\n                    82.13,\n                    252.06,\n                    91.09,\n                    271.48\n                ]\n            ],\n            \"num_keypoints\": 14,\n            \"area\": 11025.219,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                99,\n                144,\n                2,\n                104,\n                141,\n                2,\n                96,\n                137,\n                2,\n                0,\n                0,\n                0,\n                78,\n                133,\n                2,\n                56,\n                161,\n                2,\n                81,\n                162,\n                2,\n                0,\n                0,\n                0,\n                103,\n                208,\n                2,\n                116,\n                204,\n                2,\n                0,\n                0,\n                0,\n                57,\n                246,\n                1,\n                82,\n                259,\n                1,\n                137,\n                219,\n                2,\n                138,\n                247,\n                2,\n                177,\n                256,\n                2,\n                158,\n                296,\n                1\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                38.08,\n                110.95,\n                174.71,\n                174.71\n            ],\n            \"category_id\": 1,\n            \"id\": 198196,\n            \"face_box\": [\n                79.19,\n                131.64,\n                29.290000000000006,\n                28.480000000000018\n            ],\n            \"lefthand_box\": [\n                104.83,\n                196.48,\n                16.400000000000006,\n                15.810000000000002\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                109.88978,\n                204.46047,\n                1,\n                113.101195,\n                201.939065,\n                1,\n                116.31261,\n                199.41766,\n                1,\n                113.19977,\n                199.3139,\n                1,\n                109.8794,\n                200.24775,\n                1,\n                117.86903,\n                199.10638,\n                2,\n                113.9261,\n                199.00262,\n                2,\n                109.56812,\n                198.48381,\n                2,\n                106.6628,\n                198.38004999999998,\n                1,\n                117.1427,\n                202.32298,\n                2,\n                111.2283,\n                201.80417,\n                2,\n                107.07784000000001,\n                201.38913,\n                2,\n                103.65371999999999,\n                201.18161,\n                1,\n                116.52013,\n                205.95463,\n                2,\n                112.5772,\n                205.53958,\n                2,\n                107.59665,\n                204.39821,\n                2,\n                104.27629,\n                203.77564,\n                2,\n                116.41637,\n                209.69004,\n                2,\n                112.16215,\n                209.48252,\n                2,\n                108.73803000000001,\n                208.34114,\n                2,\n                105.72895,\n                206.68096,\n                2\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                82.9654,\n                131.144,\n                1.0,\n                81.8046,\n                134.328,\n                1.0,\n                80.7007,\n                137.531,\n                1.0,\n                79.8836,\n                140.818,\n                1.0,\n                79.734,\n                144.196,\n                1.0,\n                80.4763,\n                147.486,\n                1.0,\n                82.0188,\n                150.498,\n                1.0,\n                84.2352,\n                153.057,\n                1.0,\n                86.8081,\n                155.258,\n                1.0,\n                89.652,\n                157.095,\n                1.0,\n                92.9128,\n                157.812,\n                1.0,\n                95.962,\n                156.474,\n                1.0,\n                98.5377,\n                154.281,\n                1.0,\n                100.557,\n                151.568,\n                1.0,\n                102.508,\n                148.799,\n                1.0,\n                103.987,\n                145.756,\n                1.0,\n                105.345,\n                142.655,\n                1.0,\n                93.6074,\n                132.13,\n                1.0,\n                95.8108,\n                132.112,\n                1.0,\n                97.7956,\n                132.618,\n                1.0,\n                99.6897,\n                133.398,\n                1.0,\n                101.364,\n                134.432,\n                1.0,\n                105.0,\n                136.896,\n                1.0,\n                105.708,\n                137.334,\n                1.0,\n                106.267,\n                137.852,\n                1.0,\n                106.759,\n                138.404,\n                1.0,\n                107.013,\n                139.401,\n                1.0,\n                100.904,\n                139.994,\n                1.0,\n                100.551,\n                142.0,\n                1.0,\n                100.202,\n                143.956,\n                1.0,\n                99.8116,\n                145.919,\n                1.0,\n                94.7941,\n                146.187,\n                1.0,\n                95.9823,\n                147.027,\n                1.0,\n                97.3054,\n                147.849,\n                1.0,\n                98.2362,\n                148.403,\n                1.0,\n                99.2812,\n                148.491,\n                1.0,\n                93.151,\n                135.98,\n                1.0,\n                94.9184,\n                136.187,\n                1.0,\n                96.5441,\n                136.903,\n                1.0,\n                97.6034,\n                138.308,\n                1.0,\n                95.8998,\n                138.017,\n                1.0,\n                94.3941,\n                137.178,\n                1.0,\n                102.085,\n                141.003,\n                1.0,\n                103.379,\n                141.05,\n                1.0,\n                104.485,\n                141.71,\n                1.0,\n                104.899,\n                142.915,\n                1.0,\n                103.704,\n                142.739,\n                1.0,\n                102.729,\n                142.026,\n                1.0,\n                89.8433,\n                148.685,\n                1.0,\n                92.6494,\n                149.006,\n                1.0,\n                95.2801,\n                149.78,\n                1.0,\n                96.1096,\n                150.259,\n                1.0,\n                96.7411,\n                150.719,\n                1.0,\n                97.3853,\n                151.82,\n                1.0,\n                97.337,\n                153.217,\n                1.0,\n                96.5124,\n                153.108,\n                1.0,\n                95.6091,\n                152.796,\n                1.0,\n                94.7518,\n                152.399,\n                1.0,\n                93.0313,\n                151.317,\n                1.0,\n                91.3461,\n                150.149,\n                1.0,\n                90.24,\n                148.802,\n                1.0,\n                92.9121,\n                149.883,\n                1.0,\n                95.4213,\n                151.204,\n                1.0,\n                96.3082,\n                152.03,\n                1.0,\n                97.1377,\n                152.997,\n                1.0,\n                96.3098,\n                152.035,\n                1.0,\n                95.406,\n                151.234,\n                1.0,\n                92.8725,\n                149.984,\n                1.0\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": false,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                208.16049,\n                257.42419,\n                2.0,\n                205.8824,\n                259.13276,\n                2.0,\n                183.38626,\n                275.93367,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    257.76,\n                    288.05,\n                    273.4,\n                    258.26,\n                    325.55,\n                    253.79,\n                    335.23,\n                    232.93,\n                    326.3,\n                    186.74,\n                    333.74,\n                    177.05,\n                    327.79,\n                    153.21,\n                    333.74,\n                    142.04,\n                    344.17,\n                    139.06,\n                    353.11,\n                    139.06,\n                    359.07,\n                    145.02,\n                    360.56,\n                    148.74,\n                    362.05,\n                    168.86,\n                    388.87,\n                    197.17,\n                    397.81,\n                    276.88,\n                    372.48,\n                    293.27\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 10171.9544,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                343,\n                164,\n                2,\n                348,\n                160,\n                2,\n                340,\n                160,\n                2,\n                359,\n                163,\n                2,\n                332,\n                164,\n                2,\n                370,\n                189,\n                2,\n                334,\n                190,\n                2,\n                358,\n                236,\n                2,\n                348,\n                234,\n                2,\n                339,\n                270,\n                2,\n                330,\n                262,\n                2,\n                378,\n                262,\n                2,\n                343,\n                254,\n                2,\n                338,\n                280,\n                2,\n                283,\n                272,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                257.76,\n                139.06,\n                140.05,\n                154.21\n            ],\n            \"category_id\": 1,\n            \"id\": 230195,\n            \"face_box\": [\n                333.96,\n                154.32,\n                23.28000000000003,\n                26.79000000000002\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                333.383,\n                160.62,\n                1.0,\n                333.607,\n                163.811,\n                1.0,\n                334.137,\n                166.965,\n                1.0,\n                334.934,\n                170.062,\n                1.0,\n                336.036,\n                173.062,\n                1.0,\n                337.69,\n                175.794,\n                1.0,\n                340.01,\n                177.986,\n                1.0,\n                342.889,\n                179.347,\n                1.0,\n                346.063,\n                179.445,\n                1.0,\n                349.16,\n                178.674,\n                1.0,\n                351.892,\n                177.033,\n                1.0,\n                354.132,\n                174.761,\n                1.0,\n                355.652,\n                171.957,\n                1.0,\n                356.482,\n                168.871,\n                1.0,\n                356.751,\n                165.691,\n                1.0,\n                356.914,\n                162.496,\n                1.0,\n                356.913,\n                159.299,\n                1.0,\n                335.435,\n                157.491,\n                1.0,\n                336.759,\n                156.383,\n                1.0,\n                338.264,\n                155.821,\n                1.0,\n                339.903,\n                155.445,\n                1.0,\n                341.565,\n                155.312,\n                1.0,\n                345.805,\n                155.039,\n                1.0,\n                347.424,\n                154.896,\n                1.0,\n                349.044,\n                154.957,\n                1.0,\n                350.677,\n                155.266,\n                1.0,\n                352.333,\n                156.08,\n                1.0,\n                343.65,\n                159.186,\n                1.0,\n                343.687,\n                161.041,\n                1.0,\n                343.68,\n                162.886,\n                1.0,\n                343.657,\n                164.752,\n                1.0,\n                341.61,\n                167.049,\n                1.0,\n                342.69,\n                167.145,\n                1.0,\n                343.906,\n                167.123,\n                1.0,\n                345.179,\n                166.907,\n                1.0,\n                346.456,\n                166.707,\n                1.0,\n                336.707,\n                159.932,\n                1.0,\n                338.078,\n                158.999,\n                1.0,\n                339.726,\n                158.864,\n                1.0,\n                341.204,\n                159.605,\n                1.0,\n                339.755,\n                160.185,\n                1.0,\n                338.21,\n                160.321,\n                1.0,\n                346.612,\n                159.27,\n                1.0,\n                348.028,\n                158.307,\n                1.0,\n                349.739,\n                158.245,\n                1.0,\n                351.302,\n                158.965,\n                1.0,\n                349.802,\n                159.575,\n                1.0,\n                348.188,\n                159.642,\n                1.0,\n                340.049,\n                171.873,\n                1.0,\n                341.307,\n                170.304,\n                1.0,\n                343.097,\n                169.499,\n                1.0,\n                343.987,\n                169.41,\n                1.0,\n                344.876,\n                169.314,\n                1.0,\n                346.909,\n                169.61,\n                1.0,\n                348.603,\n                170.874,\n                1.0,\n                347.548,\n                172.219,\n                1.0,\n                346.133,\n                173.242,\n                1.0,\n                344.378,\n                173.742,\n                1.0,\n                342.683,\n                173.666,\n                1.0,\n                341.218,\n                173.038,\n                1.0,\n                340.398,\n                171.815,\n                1.0,\n                342.1,\n                170.752,\n                1.0,\n                344.043,\n                170.287,\n                1.0,\n                346.21,\n                170.271,\n                1.0,\n                348.214,\n                170.913,\n                1.0,\n                346.462,\n                171.947,\n                1.0,\n                344.283,\n                172.468,\n                1.0,\n                342.246,\n                172.507,\n                1.0\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": false,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    285.37,\n                    126.5,\n                    281.97,\n                    127.72,\n                    280.76,\n                    132.33,\n                    280.76,\n                    136.46,\n                    275.17,\n                    143.26,\n                    275.9,\n                    158.08,\n                    277.6,\n                    164.4,\n                    278.33,\n                    173.87,\n                    278.33,\n                    183.83,\n                    279.79,\n                    191.11,\n                    281.97,\n                    194.76,\n                    284.89,\n                    192.09,\n                    284.89,\n                    186.99,\n                    284.89,\n                    181.16,\n                    284.64,\n                    177.51,\n                    285.86,\n                    173.87\n                ]\n            ],\n            \"num_keypoints\": 0,\n            \"area\": 491.2669,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                275.17,\n                126.5,\n                10.69,\n                68.26\n            ],\n            \"category_id\": 1,\n            \"id\": 1202706,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": false,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    339.34,\n                    107.97,\n                    338.38,\n                    102.19,\n                    339.34,\n                    91.58,\n                    335.49,\n                    84.84,\n                    326.81,\n                    74.23,\n                    312.35,\n                    74.23,\n                    301.75,\n                    74.23,\n                    295,\n                    86.76,\n                    295,\n                    93.51,\n                    292.11,\n                    99.3,\n                    287.29,\n                    102.19,\n                    291.14,\n                    107.01,\n                    295,\n                    107.01,\n                    295.96,\n                    112.79,\n                    301.75,\n                    115.69,\n                    305.6,\n                    119.54,\n                    307.53,\n                    123.4,\n                    317.17,\n                    123.4,\n                    311.39,\n                    129.18,\n                    286.32,\n                    139.79,\n                    274.75,\n                    139.79,\n                    264.15,\n                    138.82,\n                    262.22,\n                    144.61,\n                    261.26,\n                    147.5,\n                    253.54,\n                    147.5,\n                    247.76,\n                    150.39,\n                    249.69,\n                    159.07,\n                    256.44,\n                    161,\n                    262.22,\n                    161,\n                    268,\n                    161,\n                    276.68,\n                    161.96,\n                    284.39,\n                    168.71,\n                    293.07,\n                    174.49,\n                    301.75,\n                    174.49,\n                    308.49,\n                    169.67,\n                    308.49,\n                    188.95,\n                    311.39,\n                    194.74,\n                    312.35,\n                    208.23,\n                    307.53,\n                    221.73,\n                    297.89,\n                    229.44,\n                    281.5,\n                    250.65,\n                    269.93,\n                    262.22,\n                    278.61,\n                    320.06,\n                    281.5,\n                    331.63,\n                    276.68,\n                    338.38,\n                    270.9,\n                    349.95,\n                    262.22,\n                    356.7,\n                    253.54,\n                    359.59,\n                    253.54,\n                    365.37,\n                    274.75,\n                    365.37,\n                    291.14,\n                    365.37,\n                    306.57,\n                    359.59,\n                    303.67,\n                    352.84,\n                    297.89,\n                    340.31,\n                    293.07,\n                    318.13,\n                    295,\n                    294.03,\n                    293.07,\n                    278.61,\n                    294.03,\n                    270.9,\n                    305.6,\n                    259.33,\n                    313.31,\n                    299.82,\n                    319.1,\n                    309.46,\n                    341.27,\n                    317.17,\n                    384.65,\n                    330.67,\n                    387.55,\n                    335.49,\n                    383.69,\n                    341.27,\n                    397.19,\n                    350.91,\n                    398.15,\n                    363.44,\n                    398.15,\n                    375.01,\n                    405.86,\n                    374.05,\n                    409.72,\n                    357.66,\n                    411.65,\n                    342.24,\n                    416.47,\n                    328.74,\n                    417.43,\n                    321.03,\n                    410.68,\n                    319.1,\n                    401.04,\n                    318.13,\n                    392.37,\n                    318.13,\n                    382.73,\n                    314.28,\n                    348.98,\n                    300.78,\n                    339.34,\n                    293.07,\n                    334.52,\n                    285.36,\n                    340.31,\n                    259.33,\n                    340.31,\n                    246.8,\n                    340.31,\n                    242.94,\n                    350.91,\n                    228.48,\n                    358.62,\n                    214.98,\n                    355.22,\n                    204.32,\n                    357.05,\n                    196.11,\n                    361.61,\n                    188.82,\n                    361.61,\n                    181.97,\n                    365.26,\n                    165.63,\n                    367.54,\n                    139.18,\n                    366.17,\n                    123.68,\n                    361.15,\n                    112.73,\n                    353.86,\n                    107.72,\n                    351.58,\n                    105.89,\n                    344.74,\n                    105.89,\n                    340.18,\n                    109.08\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 17123.92955,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                297,\n                111,\n                2,\n                299,\n                106,\n                2,\n                0,\n                0,\n                0,\n                314,\n                108,\n                2,\n                0,\n                0,\n                0,\n                329,\n                141,\n                2,\n                346,\n                125,\n                2,\n                295,\n                164,\n                2,\n                323,\n                130,\n                2,\n                266,\n                155,\n                2,\n                279,\n                143,\n                2,\n                329,\n                225,\n                2,\n                331,\n                221,\n                2,\n                327,\n                298,\n                2,\n                283,\n                269,\n                2,\n                398,\n                327,\n                2,\n                288,\n                349,\n                2\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                247.76,\n                74.23,\n                169.67,\n                300.78\n            ],\n            \"category_id\": 1,\n            \"id\": 460541,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                249.12,\n                146.31,\n                19.920000000000016,\n                15.819999999999993\n            ],\n            \"righthand_box\": [\n                262.82,\n                139.96,\n                18.930000000000007,\n                14.679999999999978\n            ],\n            \"lefthand_kpts\": [\n                265.1,\n                155.9,\n                1,\n                260.05,\n                152.25,\n                1,\n                255.0,\n                148.6,\n                1,\n                250.6,\n                148.6,\n                1,\n                249.1,\n                151.0,\n                1,\n                253.4,\n                158.9,\n                1,\n                251.9,\n                155.1,\n                1,\n                252.0,\n                151.9,\n                1,\n                252.9,\n                150.0,\n                1,\n                257.4,\n                157.9,\n                1,\n                256.7,\n                154.2,\n                1,\n                256.3,\n                151.6,\n                1,\n                256.9,\n                149.3,\n                1,\n                260.2,\n                156.5,\n                1,\n                260.1,\n                153.0,\n                1,\n                259.9,\n                150.7,\n                1,\n                260.2,\n                148.7,\n                1,\n                262.8,\n                154.8,\n                1,\n                262.7,\n                152.5,\n                1,\n                262.7,\n                150.9,\n                1,\n                262.6,\n                148.8,\n                1\n            ],\n            \"righthand_kpts\": [\n                280.8,\n                146.5,\n                1,\n                275.4,\n                149.15,\n                1,\n                270.0,\n                151.8,\n                1,\n                266.2,\n                152.2,\n                1,\n                263.5,\n                151.9,\n                1,\n                266.6,\n                142.5,\n                1,\n                263.6,\n                147.0,\n                1,\n                264.9,\n                151.0,\n                1,\n                268.5,\n                152.9,\n                1,\n                270.6,\n                142.0,\n                1,\n                267.9,\n                146.0,\n                1,\n                269.4,\n                149.6,\n                1,\n                272.5,\n                151.5,\n                1,\n                273.8,\n                142.1,\n                1,\n                272.2,\n                146.0,\n                1,\n                274.2,\n                149.1,\n                1,\n                276.5,\n                149.6,\n                1,\n                277.4,\n                142.3,\n                1,\n                276.6,\n                145.2,\n                1,\n                277.6,\n                148.3,\n                1,\n                279.4,\n                148.6,\n                1\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": true,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                401.79499,\n                364.28207,\n                2.0,\n                407.21854,\n                361.57029,\n                2.0,\n                407.21854,\n                325.86523,\n                2.0,\n                257.16687,\n                361.57029,\n                2.0,\n                258.52276,\n                361.11833,\n                2.0,\n                297.84353,\n                355.69477,\n                2.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    578.76,\n                    112.4,\n                    589.39,\n                    100.81,\n                    589.39,\n                    99.84,\n                    596.16,\n                    116.27,\n                    603.89,\n                    122.07,\n                    603.89,\n                    138.49,\n                    598.09,\n                    159.75,\n                    597.12,\n                    181,\n                    594.22,\n                    191.63,\n                    589.39,\n                    212.89,\n                    583.59,\n                    208.06,\n                    583.59,\n                    206.13,\n                    582.63,\n                    200.33,\n                    582.63,\n                    193.57,\n                    582.63,\n                    182.94,\n                    575.86,\n                    181,\n                    567.17,\n                    197.43,\n                    571.03,\n                    203.23,\n                    567.17,\n                    207.09,\n                    555.57,\n                    208.06,\n                    562.34,\n                    200.33,\n                    565.24,\n                    190.67,\n                    565.24,\n                    173.27,\n                    566.2,\n                    163.61,\n                    568.14,\n                    156.85,\n                    570.07,\n                    148.15,\n                    566.2,\n                    143.32,\n                    565.24,\n                    133.66,\n                    575.86,\n                    118.2\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 2789.0208,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                589,\n                113,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                595,\n                112,\n                1,\n                584,\n                110,\n                2,\n                598,\n                123,\n                2,\n                579,\n                119,\n                2,\n                594,\n                141,\n                2,\n                570,\n                137,\n                2,\n                576,\n                135,\n                2,\n                585,\n                139,\n                2,\n                590,\n                157,\n                2,\n                574,\n                156,\n                2,\n                589,\n                192,\n                2,\n                565,\n                189,\n                1,\n                587,\n                222,\n                1,\n                557,\n                219,\n                1\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                555.57,\n                99.84,\n                48.32,\n                113.05\n            ],\n            \"category_id\": 1,\n            \"id\": 488308,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                568.2,\n                130.89,\n                10.75,\n                11.130000000000024\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                578.8,\n                135.7,\n                2,\n                577.55,\n                134.35,\n                2,\n                576.3,\n                133.0,\n                1,\n                574.6,\n                134.1,\n                1,\n                574.0,\n                135.5,\n                1,\n                574.3,\n                132.9,\n                2,\n                572.0,\n                132.4,\n                2,\n                570.3,\n                131.8,\n                2,\n                568.9,\n                130.7,\n                2,\n                573.3,\n                134.4,\n                2,\n                570.9,\n                134.0,\n                2,\n                569.5,\n                133.9,\n                2,\n                568.2,\n                133.8,\n                2,\n                572.8,\n                135.7,\n                2,\n                572.6,\n                138.3,\n                2,\n                574.1,\n                139.4,\n                2,\n                576.2,\n                139.4,\n                1,\n                574.4,\n                138.0,\n                2,\n                575.4,\n                139.5,\n                2,\n                576.3,\n                140.2,\n                2,\n                577.6,\n                140.8,\n                2\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": false,\n            \"foot_valid\": false,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    446.96,\n                    73.13,\n                    445.81,\n                    77.71,\n                    443.33,\n                    78.29,\n                    441.61,\n                    81.72,\n                    441.23,\n                    84.58,\n                    440.85,\n                    90.5,\n                    442.19,\n                    94.32,\n                    443.52,\n                    97.18,\n                    443.52,\n                    102.33,\n                    442.57,\n                    105.58,\n                    446.58,\n                    105.19,\n                    447.15,\n                    99.85,\n                    447.53,\n                    94.89,\n                    446,\n                    93.55,\n                    446.38,\n                    92.03,\n                    453.64,\n                    92.41,\n                    454.02,\n                    94.51,\n                    457.64,\n                    94.51,\n                    455.74,\n                    88.4,\n                    455.35,\n                    82.29,\n                    453.64,\n                    78.48,\n                    451.92,\n                    77.71,\n                    452.87,\n                    74.47,\n                    450.58,\n                    73.13\n                ]\n            ],\n            \"num_keypoints\": 0,\n            \"area\": 285.7906,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                440.85,\n                73.13,\n                16.79,\n                32.45\n            ],\n            \"category_id\": 1,\n            \"id\": 508900,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": false,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    497.15,\n                    413.95,\n                    531.55,\n                    417.68,\n                    548.74,\n                    411.7,\n                    551.74,\n                    403.48,\n                    546.5,\n                    394.5,\n                    543.51,\n                    386.28,\n                    571.93,\n                    390.76,\n                    574.92,\n                    391.51,\n                    579.4,\n                    409.46,\n                    605.58,\n                    409.46,\n                    615.3,\n                    408.71,\n                    607.07,\n                    389.27,\n                    598.1,\n                    381.79,\n                    607.82,\n                    366.83,\n                    607.82,\n                    352.63,\n                    610.06,\n                    338.42,\n                    619.04,\n                    345.15,\n                    631,\n                    344.4,\n                    630.25,\n                    336.92,\n                    626.51,\n                    318.98,\n                    616.05,\n                    286.07,\n                    598.85,\n                    263.64,\n                    585.39,\n                    257.66,\n                    593.61,\n                    244.2,\n                    601.09,\n                    235.97,\n                    596.6,\n                    219.52,\n                    587.63,\n                    211.29,\n                    577.91,\n                    208.3,\n                    563.7,\n                    206.81,\n                    556.22,\n                    214.29,\n                    548,\n                    217.28,\n                    539.77,\n                    229.99,\n                    539.77,\n                    241.95,\n                    539.02,\n                    247.19,\n                    523.32,\n                    247.19,\n                    503.88,\n                    254.67,\n                    485.93,\n                    254.67,\n                    479.95,\n                    248.68,\n                    473.22,\n                    241.21,\n                    485.93,\n                    227,\n                    477.7,\n                    215.78,\n                    457.51,\n                    215.78,\n                    453.77,\n                    235.22,\n                    463.5,\n                    246.44,\n                    465.74,\n                    261.4,\n                    490.42,\n                    274.11,\n                    501.63,\n                    275.6,\n                    504.62,\n                    286.07,\n                    519.58,\n                    286.07,\n                    522.57,\n                    292.06,\n                    512.85,\n                    310,\n                    515.09,\n                    330.94,\n                    530.05,\n                    343.65,\n                    505.37,\n                    341.41,\n                    479.95,\n                    339.91,\n                    465.74,\n                    346.64,\n                    463.5,\n                    358.61,\n                    473.97,\n                    381.04,\n                    485.18,\n                    390.02,\n                    501.63,\n                    398.99,\n                    504.62,\n                    404.22,\n                    491.16,\n                    412.45,\n                    495.65,\n                    417.68\n                ]\n            ],\n            \"num_keypoints\": 12,\n            \"area\": 21608.94075,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                552,\n                234,\n                2,\n                0,\n                0,\n                0,\n                531,\n                262,\n                2,\n                600,\n                283,\n                2,\n                480,\n                260,\n                2,\n                622,\n                336,\n                2,\n                466,\n                242,\n                2,\n                0,\n                0,\n                0,\n                546,\n                365,\n                2,\n                592,\n                371,\n                2,\n                470,\n                351,\n                2,\n                551,\n                330,\n                2,\n                519,\n                394,\n                2,\n                589,\n                391,\n                2\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                453.77,\n                206.81,\n                177.23,\n                210.87\n            ],\n            \"category_id\": 1,\n            \"id\": 1717641,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                498.08009,\n                412.23863,\n                2.0,\n                541.66626,\n                400.39384,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                602.22109,\n                403.58794,\n                2.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    58.93,\n                    163.67,\n                    47.18,\n                    161.59,\n                    36.12,\n                    93.86,\n                    41.65,\n                    82.8,\n                    40.27,\n                    69.66,\n                    50.64,\n                    67.59,\n                    55.48,\n                    73.81,\n                    63.08,\n                    92.47,\n                    66.53,\n                    99.38,\n                    65.15,\n                    109.06,\n                    61,\n                    127.03,\n                    59.62,\n                    162.97\n                ]\n            ],\n            \"num_keypoints\": 17,\n            \"area\": 1870.14015,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                48,\n                79,\n                2,\n                50,\n                77,\n                2,\n                46,\n                77,\n                2,\n                54,\n                78,\n                2,\n                45,\n                78,\n                2,\n                57,\n                90,\n                2,\n                42,\n                90,\n                2,\n                63,\n                103,\n                2,\n                42,\n                105,\n                2,\n                56,\n                113,\n                2,\n                49,\n                112,\n                2,\n                55,\n                117,\n                2,\n                44,\n                117,\n                2,\n                55,\n                140,\n                2,\n                47,\n                140,\n                2,\n                56,\n                160,\n                2,\n                49,\n                159,\n                2\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                36.12,\n                67.59,\n                30.41,\n                96.08\n            ],\n            \"category_id\": 1,\n            \"id\": 1724673,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                44.4,\n                162.6,\n                2.0,\n                43.4,\n                161.5,\n                2.0,\n                51.7,\n                160.7,\n                2.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    139.41,\n                    321.58,\n                    144.78,\n                    326.56,\n                    196.92,\n                    314.68,\n                    196.16,\n                    309.31,\n                    207.28,\n                    292.05,\n                    213.03,\n                    284,\n                    228.75,\n                    270.2,\n                    233.35,\n                    261.38,\n                    244.47,\n                    252.56,\n                    254.44,\n                    237.61,\n                    267.86,\n                    215.37,\n                    272.08,\n                    212.68,\n                    285.5,\n                    232.62,\n                    294.7,\n                    250.64,\n                    295.08,\n                    264.06,\n                    290.87,\n                    277.87,\n                    290.87,\n                    286.3,\n                    289.71,\n                    298.19,\n                    281.66,\n                    318.89,\n                    282.05,\n                    334.23,\n                    295.08,\n                    340.37,\n                    315.02,\n                    343.82,\n                    314.25,\n                    336.53,\n                    310.42,\n                    330.4,\n                    301.98,\n                    322.34,\n                    304.29,\n                    310.84,\n                    304.67,\n                    302.79,\n                    306.2,\n                    292.05,\n                    311.19,\n                    275.56,\n                    313.87,\n                    251.79,\n                    311.19,\n                    234.54,\n                    312.72,\n                    224.57,\n                    310.42,\n                    212.3,\n                    307.74,\n                    201.56,\n                    306.2,\n                    193.51,\n                    306.59,\n                    183.16,\n                    310.04,\n                    177.41,\n                    314.64,\n                    173.19,\n                    316.94,\n                    171.65,\n                    328.06,\n                    163.99,\n                    337.64,\n                    157.85,\n                    343.4,\n                    159.77,\n                    346.46,\n                    166.67,\n                    346.85,\n                    170.5,\n                    346.46,\n                    179.71,\n                    346.85,\n                    188.53,\n                    346.85,\n                    191.98,\n                    344.55,\n                    198.11,\n                    342.25,\n                    203.48,\n                    338.41,\n                    208.46,\n                    335.34,\n                    212.68,\n                    335.34,\n                    217.67,\n                    343.01,\n                    222.65,\n                    354.9,\n                    210.76,\n                    359.12,\n                    196.19,\n                    361.8,\n                    173.19,\n                    361.42,\n                    161.69,\n                    356.43,\n                    150.18,\n                    344.93,\n                    135.61,\n                    343.01,\n                    132.93,\n                    345.31,\n                    126.41,\n                    345.7,\n                    124.88,\n                    343.4,\n                    115.29,\n                    340.33,\n                    104.17,\n                    337.26,\n                    102.25,\n                    330.36,\n                    103.4,\n                    326.14,\n                    106.09,\n                    320.01,\n                    111.07,\n                    314.64,\n                    119.89,\n                    310.42,\n                    121.04,\n                    292.02,\n                    121.81,\n                    279.75,\n                    127.94,\n                    244.09,\n                    138.68,\n                    240.25,\n                    142.51,\n                    238.72,\n                    154.4,\n                    239.1,\n                    163.6,\n                    239.87,\n                    173.96,\n                    241.79,\n                    181.24,\n                    248.3,\n                    192.36,\n                    240.25,\n                    206.55,\n                    236.42,\n                    219.2,\n                    229.9,\n                    236.45,\n                    225.3,\n                    247.57,\n                    218.4,\n                    254.48,\n                    208.81,\n                    265.6,\n                    202.29,\n                    278.25,\n                    195.39,\n                    285.92,\n                    188.49,\n                    292.05,\n                    183.5,\n                    295.89,\n                    176.6,\n                    302.41,\n                    172,\n                    308.54,\n                    167.78,\n                    313.14,\n                    146.31,\n                    318.89\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 14250.29385,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                334,\n                135,\n                2,\n                340,\n                129,\n                2,\n                331,\n                129,\n                2,\n                0,\n                0,\n                0,\n                319,\n                123,\n                2,\n                340,\n                146,\n                2,\n                292,\n                133,\n                2,\n                353,\n                164,\n                2,\n                246,\n                144,\n                2,\n                354,\n                197,\n                2,\n                250,\n                185,\n                2,\n                293,\n                197,\n                2,\n                265,\n                187,\n                2,\n                305,\n                252,\n                2,\n                231,\n                254,\n                2,\n                293,\n                321,\n                2,\n                193,\n                297,\n                2\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                139.41,\n                102.25,\n                222.39,\n                241.57\n            ],\n            \"category_id\": 1,\n            \"id\": 437295,\n            \"face_box\": [\n                320.23,\n                123.84,\n                21.049999999999955,\n                23.5\n            ],\n            \"lefthand_box\": [\n                333.65,\n                198.45,\n                23.150000000000034,\n                23.57000000000002\n            ],\n            \"righthand_box\": [\n                247.5,\n                184.92,\n                23.30000000000001,\n                22.360000000000014\n            ],\n            \"lefthand_kpts\": [\n                353.87482,\n                196.49984999999998,\n                1,\n                349.01957500000003,\n                201.76511,\n                1,\n                344.16433,\n                207.03037,\n                1,\n                340.81534,\n                210.64729,\n                1,\n                337.46165,\n                216.59183000000002,\n                1,\n                346.65868,\n                216.02586,\n                1,\n                342.27241,\n                219.28019999999998,\n                1,\n                337.88613,\n                219.70467,\n                1,\n                334.4903,\n                218.57273,\n                1,\n                345.5,\n                215.0,\n                1,\n                342.27241,\n                217.72377,\n                1,\n                338.73509,\n                218.00675999999999,\n                1,\n                334.77329,\n                216.30885,\n                1,\n                343.7,\n                213.8,\n                1,\n                341.42345,\n                215.74288,\n                1,\n                338.73509,\n                215.60138,\n                1,\n                335.62225,\n                213.76198,\n                1,\n                342.4139,\n                212.63003,\n                1,\n                340.85748,\n                213.76198,\n                1,\n                338.87658,\n                214.04496,\n                1,\n                337.17867,\n                213.76198,\n                1\n            ],\n            \"righthand_kpts\": [\n                249.4,\n                180.4,\n                1,\n                254.3,\n                184.9,\n                1,\n                259.2,\n                189.4,\n                1,\n                259.3,\n                192.1,\n                1,\n                258.2,\n                194.9,\n                1,\n                254.9,\n                193.2,\n                1,\n                255.9,\n                192.3,\n                1,\n                255.9,\n                190.5,\n                1,\n                255.4,\n                188.5,\n                1,\n                252.2,\n                194.0,\n                1,\n                253.2,\n                193.6,\n                1,\n                253.2,\n                191.1,\n                1,\n                252.9,\n                188.8,\n                1,\n                249.4,\n                193.6,\n                1,\n                250.4,\n                193.6,\n                1,\n                250.4,\n                191.3,\n                1,\n                249.9,\n                188.7,\n                1,\n                247.1,\n                192.2,\n                1,\n                248.0,\n                192.2,\n                1,\n                247.9,\n                190.3,\n                1,\n                247.5,\n                188.3,\n                1\n            ],\n            \"face_kpts\": [\n                319.681,\n                126.613,\n                1.0,\n                319.155,\n                129.261,\n                1.0,\n                318.92,\n                131.954,\n                1.0,\n                319.187,\n                134.631,\n                1.0,\n                319.707,\n                137.271,\n                1.0,\n                320.991,\n                139.649,\n                1.0,\n                322.846,\n                141.606,\n                1.0,\n                325.009,\n                143.216,\n                1.0,\n                327.359,\n                144.544,\n                1.0,\n                329.907,\n                145.384,\n                1.0,\n                332.347,\n                144.347,\n                1.0,\n                334.268,\n                142.449,\n                1.0,\n                335.767,\n                140.222,\n                1.0,\n                336.675,\n                137.69,\n                1.0,\n                337.019,\n                135.009,\n                1.0,\n                336.982,\n                132.311,\n                1.0,\n                337.13,\n                129.618,\n                1.0,\n                328.503,\n                125.823,\n                1.0,\n                329.531,\n                125.489,\n                1.0,\n                330.619,\n                125.626,\n                1.0,\n                331.573,\n                125.909,\n                1.0,\n                332.529,\n                126.431,\n                1.0,\n                334.479,\n                127.459,\n                1.0,\n                334.815,\n                127.43,\n                1.0,\n                335.157,\n                127.316,\n                1.0,\n                335.52,\n                127.327,\n                1.0,\n                335.949,\n                127.701,\n                1.0,\n                332.762,\n                129.334,\n                1.0,\n                333.168,\n                130.389,\n                1.0,\n                333.603,\n                131.342,\n                1.0,\n                333.928,\n                132.331,\n                1.0,\n                331.671,\n                134.291,\n                1.0,\n                332.232,\n                134.389,\n                1.0,\n                332.931,\n                134.487,\n                1.0,\n                333.332,\n                134.463,\n                1.0,\n                333.645,\n                134.212,\n                1.0,\n                329.271,\n                128.208,\n                1.0,\n                329.963,\n                128.464,\n                1.0,\n                330.676,\n                128.659,\n                1.0,\n                331.392,\n                128.839,\n                1.0,\n                330.672,\n                128.659,\n                1.0,\n                330.003,\n                128.334,\n                1.0,\n                333.792,\n                129.611,\n                1.0,\n                334.158,\n                129.741,\n                1.0,\n                334.546,\n                129.765,\n                1.0,\n                334.878,\n                129.954,\n                1.0,\n                334.523,\n                129.822,\n                1.0,\n                334.161,\n                129.704,\n                1.0,\n                327.38,\n                138.818,\n                1.0,\n                329.757,\n                138.136,\n                1.0,\n                332.086,\n                137.874,\n                1.0,\n                332.75,\n                138.208,\n                1.0,\n                333.221,\n                138.515,\n                1.0,\n                334.495,\n                139.634,\n                1.0,\n                335.213,\n                141.054,\n                1.0,\n                334.12,\n                140.754,\n                1.0,\n                333.208,\n                140.234,\n                1.0,\n                332.2,\n                139.888,\n                1.0,\n                330.765,\n                139.414,\n                1.0,\n                329.069,\n                139.351,\n                1.0,\n                327.561,\n                138.814,\n                1.0,\n                329.88,\n                138.346,\n                1.0,\n                332.517,\n                138.668,\n                1.0,\n                334.031,\n                139.589,\n                1.0,\n                335.123,\n                140.862,\n                1.0,\n                333.726,\n                140.572,\n                1.0,\n                332.203,\n                140.032,\n                1.0,\n                329.731,\n                139.403,\n                1.0\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": true,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                300.24175,\n                336.83838,\n                2.0,\n                306.59015,\n                335.34464,\n                2.0,\n                290.07408,\n                326.47826,\n                2.0,\n                182.60972,\n                314.05885,\n                2.0,\n                175.88789,\n                305.84328,\n                2.0,\n                189.70499,\n                302.48236,\n                2.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    287.17,\n                    121.42,\n                    294.22,\n                    106.44,\n                    302.15,\n                    116.13,\n                    303.03,\n                    121.42\n                ],\n                [\n                    297.74,\n                    99.39,\n                    310.08,\n                    76.49,\n                    326.81,\n                    76.49,\n                    329.46,\n                    67.68,\n                    337.38,\n                    61.52,\n                    346.19,\n                    62.4,\n                    353.24,\n                    65.92,\n                    353.24,\n                    76.49,\n                    355.88,\n                    84.42,\n                    359.41,\n                    87.94,\n                    362.05,\n                    96.75,\n                    354.12,\n                    139.04,\n                    349.72,\n                    142.56,\n                    345.31,\n                    139.92,\n                    349.72,\n                    117.89,\n                    348.84,\n                    108.2,\n                    345.31,\n                    113.49,\n                    336.5,\n                    101.16,\n                    325.93,\n                    110.85,\n                    311.84,\n                    123.18\n                ],\n                [\n                    324.17,\n                    176.91,\n                    332.1,\n                    191.89,\n                    328.58,\n                    198.94,\n                    327.69,\n                    205.98,\n                    333.86,\n                    213.03,\n                    337.38,\n                    227.13,\n                    332.98,\n                    227.13,\n                    319.77,\n                    219.2,\n                    313.6,\n                    211.27\n                ],\n                [\n                    332.98,\n                    165.46,\n                    341.79,\n                    161.06,\n                    336.5,\n                    174.27,\n                    333.86,\n                    186.6,\n                    326.81,\n                    176.03\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 3404.869,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                345,\n                92,\n                2,\n                350,\n                87,\n                2,\n                341,\n                87,\n                2,\n                0,\n                0,\n                0,\n                330,\n                83,\n                2,\n                357,\n                94,\n                2,\n                316,\n                92,\n                2,\n                357,\n                104,\n                2,\n                291,\n                123,\n                1,\n                351,\n                133,\n                2,\n                281,\n                136,\n                1,\n                326,\n                131,\n                1,\n                305,\n                128,\n                1,\n                336,\n                152,\n                1,\n                303,\n                171,\n                1,\n                318,\n                206,\n                2,\n                294,\n                211,\n                1\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                287.17,\n                61.52,\n                74.88,\n                165.61\n            ],\n            \"category_id\": 1,\n            \"id\": 467657,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                322.595,\n                216.245,\n                2.0,\n                327.23077,\n                215.42692,\n                2.0,\n                316.81553,\n                207.67155,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    547.95,\n                    201.57,\n                    546.73,\n                    190.62,\n                    547.95,\n                    181.49,\n                    547.95,\n                    169.31,\n                    547.95,\n                    156.53,\n                    546.73,\n                    144.36,\n                    544.3,\n                    139.49,\n                    540.04,\n                    132.19,\n                    540.04,\n                    121.84,\n                    542.47,\n                    107.24,\n                    544.3,\n                    99.33,\n                    548.56,\n                    88.98,\n                    561.95,\n                    78.03,\n                    572.29,\n                    71.33,\n                    572.29,\n                    71.33,\n                    572.29,\n                    65.25,\n                    574.12,\n                    51.86,\n                    583.86,\n                    48.81,\n                    592.99,\n                    48.81,\n                    597.86,\n                    57.33,\n                    599.07,\n                    64.64,\n                    608.2,\n                    76.81,\n                    614.9,\n                    82.89,\n                    620.98,\n                    89.59,\n                    628.89,\n                    93.24,\n                    636.81,\n                    101.76,\n                    640,\n                    109.67,\n                    640,\n                    115.76,\n                    640,\n                    127.93,\n                    620.37,\n                    111.5,\n                    619.16,\n                    111.5,\n                    618.55,\n                    112.11,\n                    608.2,\n                    105.41,\n                    600.9,\n                    119.41,\n                    592.99,\n                    131.58,\n                    596.03,\n                    148.01,\n                    605.16,\n                    162.01,\n                    612.46,\n                    190.01,\n                    614.9,\n                    204.61,\n                    606.98,\n                    216.78,\n                    603.94,\n                    226.52,\n                    606.38,\n                    239.91,\n                    605.16,\n                    256.95,\n                    604.55,\n                    264.26,\n                    602.12,\n                    271.56,\n                    586.29,\n                    272.17,\n                    584.47,\n                    255.13,\n                    588.73,\n                    237.48,\n                    592.99,\n                    221.65,\n                    596.64,\n                    207.05,\n                    596.64,\n                    197.31,\n                    594.2,\n                    186.96,\n                    584.47,\n                    172.36,\n                    577.77,\n                    166.27,\n                    570.47,\n                    170.53,\n                    558.91,\n                    179.66,\n                    555.86,\n                    192.44,\n                    548.56,\n                    198.53,\n                    547.95,\n                    198.53\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 8913.98475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                591,\n                78,\n                2,\n                594,\n                74,\n                2,\n                586,\n                74,\n                2,\n                0,\n                0,\n                0,\n                573,\n                70,\n                2,\n                598,\n                86,\n                2,\n                566,\n                93,\n                2,\n                626,\n                105,\n                2,\n                546,\n                126,\n                2,\n                0,\n                0,\n                0,\n                561,\n                150,\n                2,\n                582,\n                150,\n                2,\n                557,\n                154,\n                2,\n                606,\n                194,\n                2,\n                558,\n                209,\n                1,\n                591,\n                252,\n                2,\n                539,\n                262,\n                1\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                540.04,\n                48.81,\n                99.96,\n                223.36\n            ],\n            \"category_id\": 1,\n            \"id\": 531914,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                557.05,\n                149.73,\n                19.879999999999995,\n                21.76000000000002\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                565.0,\n                153.0,\n                0.08773341029882431,\n                568.0,\n                156.0,\n                0.04602484405040741,\n                571.0,\n                159.0,\n                0.04602484405040741,\n                573.0,\n                161.0,\n                0.06972061097621918,\n                575.0,\n                164.0,\n                0.06297813355922699,\n                569.0,\n                158.0,\n                0.294232040643692,\n                570.0,\n                162.0,\n                0.26472434401512146,\n                570.0,\n                166.0,\n                0.2826344072818756,\n                571.0,\n                171.0,\n                0.374575674533844,\n                565.0,\n                159.0,\n                0.2154899388551712,\n                566.0,\n                162.0,\n                0.21613340079784393,\n                566.0,\n                164.0,\n                0.2544613480567932,\n                567.0,\n                168.0,\n                0.31771761178970337,\n                562.0,\n                160.0,\n                0.23286579549312592,\n                563.0,\n                166.0,\n                0.1579097956418991,\n                564.0,\n                166.0,\n                0.17961391806602478,\n                564.0,\n                166.0,\n                0.17504136264324188,\n                559.0,\n                160.0,\n                0.3428754508495331,\n                559.0,\n                162.0,\n                0.2897874116897583,\n                561.0,\n                165.0,\n                0.24125981330871582,\n                562.0,\n                166.0,\n                0.20118576288223267\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": true,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                599.72032,\n                264.75714,\n                2.0,\n                603.91172,\n                265.80499,\n                2.0,\n                585.74897,\n                265.10642,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    561.51,\n                    385.38,\n                    572.11,\n                    352.71,\n                    570.34,\n                    317.4,\n                    559.75,\n                    282.08,\n                    552.68,\n                    267.07,\n                    565.93,\n                    236.17,\n                    583.59,\n                    236.17,\n                    602.13,\n                    260.01,\n                    614.49,\n                    286.5,\n                    628.61,\n                    302.39,\n                    639.21,\n                    281.2,\n                    614.49,\n                    251.18,\n                    588,\n                    218.51,\n                    595.95,\n                    202.62,\n                    594.18,\n                    185.85,\n                    580.05,\n                    170.84,\n                    562.4,\n                    179.67,\n                    557.98,\n                    198.21,\n                    554.45,\n                    202.62,\n                    532.38,\n                    199.97,\n                    525.32,\n                    202.62,\n                    511.19,\n                    229.11,\n                    493.53,\n                    256.48,\n                    484.7,\n                    276.78,\n                    451.15,\n                    323.58,\n                    423.78,\n                    338.59,\n                    388.47,\n                    373.9,\n                    372.58,\n                    387.14,\n                    396.41,\n                    388.03,\n                    418.49,\n                    367.72,\n                    450.27,\n                    345.65,\n                    501.48,\n                    306.8,\n                    520.02,\n                    301.5,\n                    552.68,\n                    340.35,\n                    543.86,\n                    369.49\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 14267.20475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                580,\n                211,\n                2,\n                586,\n                206,\n                2,\n                574,\n                204,\n                2,\n                0,\n                0,\n                0,\n                562,\n                198,\n                2,\n                584,\n                220,\n                2,\n                529,\n                215,\n                2,\n                599,\n                242,\n                2,\n                512,\n                260,\n                2,\n                619,\n                274,\n                2,\n                538,\n                285,\n                2,\n                537,\n                288,\n                2,\n                506,\n                277,\n                2,\n                562,\n                332,\n                2,\n                452,\n                332,\n                2,\n                550,\n                387,\n                1,\n                402,\n                371,\n                2\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                372.58,\n                170.84,\n                266.63,\n                217.19\n            ],\n            \"category_id\": 1,\n            \"id\": 533949,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                615.22,\n                271.56,\n                22.139999999999986,\n                28.839999999999975\n            ],\n            \"righthand_box\": [\n                538.83,\n                283.74,\n                25.639999999999986,\n                30.659999999999968\n            ],\n            \"lefthand_kpts\": [\n                620.284,\n                274.54006,\n                1,\n                621.65135,\n                282.30908999999997,\n                1,\n                623.0187,\n                290.07812,\n                1,\n                625.38048,\n                294.55308,\n                1,\n                628.86101,\n                298.90373999999997,\n                1,\n                630.22836,\n                289.20799,\n                1,\n                634.57901,\n                292.43991,\n                1,\n                633.08736,\n                295.54752,\n                1,\n                628.6124,\n                295.42321,\n                1,\n                632.46584,\n                286.5976,\n                1,\n                631.3,\n                291.9,\n                1,\n                627.7,\n                291.6,\n                1,\n                625.6,\n                288.9,\n                1,\n                633.7,\n                284.2,\n                1,\n                632.3,\n                288.0,\n                1,\n                629.1,\n                288.0,\n                1,\n                627.0,\n                285.9,\n                1,\n                633.2,\n                280.4,\n                1,\n                632.8,\n                283.6,\n                1,\n                630.8,\n                284.4,\n                1,\n                629.1,\n                283.2,\n                1\n            ],\n            \"righthand_kpts\": [\n                544.0,\n                291.0,\n                0.09089653939008713,\n                551.0,\n                291.0,\n                0.041192591190338135,\n                558.0,\n                291.0,\n                0.041192591190338135,\n                559.0,\n                294.0,\n                0.056781601160764694,\n                563.0,\n                298.0,\n                0.2960541546344757,\n                559.0,\n                296.0,\n                0.18105527758598328,\n                562.0,\n                301.0,\n                0.12244582921266556,\n                559.0,\n                308.0,\n                0.05529222637414932,\n                564.0,\n                306.0,\n                0.05997529253363609,\n                555.0,\n                299.0,\n                0.18805834650993347,\n                556.0,\n                302.0,\n                0.1534559577703476,\n                555.0,\n                306.0,\n                0.20564205944538116,\n                556.0,\n                309.0,\n                0.06228385493159294,\n                550.0,\n                300.0,\n                0.1409723311662674,\n                550.0,\n                301.0,\n                0.2223101258277893,\n                551.0,\n                305.0,\n                0.2001882642507553,\n                553.0,\n                308.0,\n                0.1712668538093567,\n                545.0,\n                302.0,\n                0.1908813714981079,\n                546.0,\n                304.0,\n                0.13619276881217957,\n                547.0,\n                306.0,\n                0.19773860275745392,\n                549.0,\n                308.0,\n                0.1341865360736847\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": true,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                375.00826,\n                386.35839,\n                2.0,\n                399.52454,\n                375.91627,\n                2.0\n            ]\n        },\n        {\n            \"segmentation\": [\n                [\n                    2.03,\n                    75.18,\n                    10.85,\n                    70.58,\n                    16.99,\n                    65.59,\n                    17.75,\n                    55.24,\n                    20.05,\n                    50.25,\n                    29.64,\n                    43.74,\n                    37.31,\n                    47.57,\n                    41.52,\n                    53.7,\n                    43.83,\n                    64.82,\n                    53.03,\n                    70.19,\n                    61.85,\n                    77.09,\n                    72.58,\n                    87.06,\n                    74.88,\n                    79.01,\n                    78.72,\n                    73.64,\n                    86.39,\n                    77.86,\n                    90.6,\n                    90.13,\n                    86,\n                    93.2,\n                    82.17,\n                    102.4,\n                    75.27,\n                    106.24,\n                    68.75,\n                    104.7,\n                    50.34,\n                    90.9,\n                    43.06,\n                    112.37,\n                    40.76,\n                    123.11,\n                    42.29,\n                    130.78,\n                    48.04,\n                    161.83,\n                    52.26,\n                    190.59,\n                    50.73,\n                    210.15,\n                    44.21,\n                    245.04,\n                    50.34,\n                    256.16,\n                    53.03,\n                    261.53,\n                    47.28,\n                    263.83,\n                    40.37,\n                    263.83,\n                    31.56,\n                    260.76,\n                    28.1,\n                    256.16,\n                    26.95,\n                    244.65,\n                    29.25,\n                    233.54,\n                    32.71,\n                    223.95,\n                    33.09,\n                    213.98,\n                    32.32,\n                    206.31,\n                    32.71,\n                    194.81,\n                    33.09,\n                    185.61,\n                    24.65,\n                    177.17,\n                    16.99,\n                    161.45,\n                    13.53,\n                    176.02,\n                    10.85,\n                    206.31,\n                    1.65,\n                    231.62,\n                    1.65,\n                    235.84,\n                    0.5,\n                    146.88,\n                    0.88,\n                    122.34,\n                    1.65,\n                    75.56\n                ]\n            ],\n            \"num_keypoints\": 13,\n            \"area\": 8260.75085,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                36,\n                79,\n                2,\n                40,\n                74,\n                2,\n                31,\n                75,\n                2,\n                0,\n                0,\n                0,\n                19,\n                69,\n                2,\n                45,\n                77,\n                2,\n                2,\n                89,\n                2,\n                74,\n                99,\n                2,\n                0,\n                0,\n                0,\n                78,\n                92,\n                2,\n                0,\n                0,\n                0,\n                33,\n                149,\n                2,\n                7,\n                153,\n                2,\n                44,\n                196,\n                2,\n                2,\n                205,\n                2,\n                35,\n                245,\n                2,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                0.5,\n                43.74,\n                90.1,\n                220.09\n            ],\n            \"category_id\": 1,\n            \"id\": 543117,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_kpts\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true,\n            \"foot_kpts\": [\n                43.80826,\n                259.40011,\n                2.0,\n                48.63752,\n                257.67537,\n                2.0,\n                32.08007,\n                256.29558,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/coco/test_keypoint_partition_metric.json",
    "content": "{\n    \"info\": {\n        \"description\": \"COCO-WholeBody sample\",\n        \"url\": \"https://github.com/jin-s13/COCO-WholeBody\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/09/18\"\n    },\n    \"licenses\": [\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc-sa/2.0/\",\n            \"id\": 1,\n            \"name\": \"Attribution-NonCommercial-ShareAlike License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc/2.0/\",\n            \"id\": 2,\n            \"name\": \"Attribution-NonCommercial License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nc-nd/2.0/\",\n            \"id\": 3,\n            \"name\": \"Attribution-NonCommercial-NoDerivs License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by/2.0/\",\n            \"id\": 4,\n            \"name\": \"Attribution License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-sa/2.0/\",\n            \"id\": 5,\n            \"name\": \"Attribution-ShareAlike License\"\n        },\n        {\n            \"url\": \"http://creativecommons.org/licenses/by-nd/2.0/\",\n            \"id\": 6,\n            \"name\": \"Attribution-NoDerivs License\"\n        },\n        {\n            \"url\": \"http://flickr.com/commons/usage/\",\n            \"id\": 7,\n            \"name\": \"No known copyright restrictions\"\n        },\n        {\n            \"url\": \"http://www.usa.gov/copyright.shtml\",\n            \"id\": 8,\n            \"name\": \"United States Government Work\"\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"left_eye\",\n                \"right_eye\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"license\": 4,\n            \"file_name\": \"000000000785.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000000785.jpg\",\n            \"height\": 425,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 21:22:42\",\n            \"flickr_url\": \"http://farm8.staticflickr.com/7015/6795644157_f019453ae7_z.jpg\",\n            \"id\": 785\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000040083.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000040083.jpg\",\n            \"height\": 333,\n            \"width\": 500,\n            \"date_captured\": \"2013-11-18 03:30:24\",\n            \"flickr_url\": \"http://farm1.staticflickr.com/116/254881838_e21c6d17b8_z.jpg\",\n            \"id\": 40083\n        },\n        {\n            \"license\": 1,\n            \"file_name\": \"000000196141.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000196141.jpg\",\n            \"height\": 429,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-22 22:37:15\",\n            \"flickr_url\": \"http://farm4.staticflickr.com/3310/3611902235_57d4ae496d_z.jpg\",\n            \"id\": 196141\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000197388.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000197388.jpg\",\n            \"height\": 392,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 20:10:37\",\n            \"flickr_url\": \"http://farm9.staticflickr.com/8375/8507321836_5b8b13188f_z.jpg\",\n            \"id\": 197388\n        }\n    ],\n    \"annotations\": [\n        {\n            \"segmentation\": [\n                [\n                    353.37,\n                    67.65,\n                    358.15,\n                    52.37,\n                    362.92,\n                    47.59,\n                    374.38,\n                    44.73,\n                    389.66,\n                    52.37,\n                    389.66,\n                    67.65,\n                    389.66,\n                    76.25,\n                    393.48,\n                    83.89,\n                    396.35,\n                    88.66,\n                    397.3,\n                    91.53,\n                    406.85,\n                    99.17,\n                    413.54,\n                    104.9,\n                    451.74,\n                    148.83,\n                    458.43,\n                    153.6,\n                    462.25,\n                    166.02,\n                    467.02,\n                    173.66,\n                    463.2,\n                    181.3,\n                    449.83,\n                    183.21,\n                    448.88,\n                    191.81,\n                    455.56,\n                    226.19,\n                    448.88,\n                    254.84,\n                    453.65,\n                    286.36,\n                    475.62,\n                    323.6,\n                    491.85,\n                    361.81,\n                    494.72,\n                    382.82,\n                    494.72,\n                    382.82,\n                    499.49,\n                    391.41,\n                    416.4,\n                    391.41,\n                    424.04,\n                    383.77,\n                    439.33,\n                    374.22,\n                    445.06,\n                    360.85,\n                    436.46,\n                    334.11,\n                    421.18,\n                    303.55,\n                    416.4,\n                    289.22,\n                    409.72,\n                    268.21,\n                    396.35,\n                    280.63,\n                    405.9,\n                    298.77,\n                    417.36,\n                    324.56,\n                    425,\n                    349.39,\n                    425,\n                    357.99,\n                    419.27,\n                    360.85,\n                    394.44,\n                    367.54,\n                    362.92,\n                    370.4,\n                    346.69,\n                    367.54,\n                    360.06,\n                    362.76,\n                    369.61,\n                    360.85,\n                    382.98,\n                    340.8,\n                    355.28,\n                    271.08,\n                    360.06,\n                    266.3,\n                    386.8,\n                    219.5,\n                    368.65,\n                    162.2,\n                    348.6,\n                    175.57,\n                    309.44,\n                    187.03,\n                    301.8,\n                    192.76,\n                    288.43,\n                    193.72,\n                    282.7,\n                    193.72,\n                    280.79,\n                    187.03,\n                    280.79,\n                    174.62,\n                    287.47,\n                    171.75,\n                    291.29,\n                    171.75,\n                    295.11,\n                    171.75,\n                    306.57,\n                    166.98,\n                    312.3,\n                    165.07,\n                    345.73,\n                    142.14,\n                    350.51,\n                    117.31,\n                    350.51,\n                    102.03,\n                    350.51,\n                    90.57,\n                    353.37,\n                    65.74\n                ]\n            ],\n            \"num_keypoints\": 112,\n            \"area\": 27789.11055,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                367,\n                81,\n                2,\n                374,\n                73,\n                2,\n                360,\n                75,\n                2,\n                386,\n                78,\n                2,\n                356,\n                81,\n                2,\n                399,\n                108,\n                2,\n                358,\n                129,\n                2,\n                433,\n                142,\n                2,\n                341,\n                159,\n                2,\n                449,\n                165,\n                2,\n                309,\n                178,\n                2,\n                424,\n                203,\n                2,\n                393,\n                214,\n                2,\n                429,\n                294,\n                2,\n                367,\n                273,\n                2,\n                466,\n                362,\n                2,\n                396,\n                341,\n                2,\n                439,\n                378,\n                2,\n                446,\n                380,\n                2,\n                479,\n                370,\n                2,\n                377,\n                359,\n                2,\n                376,\n                358,\n                2,\n                413,\n                353,\n                2,\n                355.823,\n                75.36,\n                1.0,\n                356.354,\n                79.0837,\n                1.0,\n                357.244,\n                82.7374,\n                1.0,\n                358.518,\n                86.2722,\n                1.0,\n                360.146,\n                89.6578,\n                1.0,\n                362.266,\n                92.7538,\n                1.0,\n                365.004,\n                95.3223,\n                1.0,\n                368.487,\n                96.6454,\n                1.0,\n                372.191,\n                96.1419,\n                1.0,\n                375.644,\n                94.6832,\n                1.0,\n                378.601,\n                92.3665,\n                1.0,\n                381.101,\n                89.5662,\n                1.0,\n                382.903,\n                86.2741,\n                1.0,\n                383.896,\n                82.6509,\n                1.0,\n                384.075,\n                78.9011,\n                1.0,\n                384.1,\n                75.1408,\n                1.0,\n                383.903,\n                71.3861,\n                1.0,\n                357.084,\n                72.9743,\n                1.0,\n                358.602,\n                71.7848,\n                1.0,\n                360.42,\n                71.3443,\n                1.0,\n                362.377,\n                71.1566,\n                1.0,\n                364.36,\n                71.1889,\n                1.0,\n                368.971,\n                70.4992,\n                1.0,\n                370.945,\n                69.8179,\n                1.0,\n                373.001,\n                69.3543,\n                1.0,\n                375.14,\n                69.2666,\n                1.0,\n                377.358,\n                69.8865,\n                1.0,\n                366.57,\n                73.9588,\n                1.0,\n                366.734,\n                76.1499,\n                1.0,\n                366.88,\n                78.3018,\n                1.0,\n                366.99,\n                80.4957,\n                1.0,\n                365.104,\n                82.5589,\n                1.0,\n                366.308,\n                82.8331,\n                1.0,\n                367.645,\n                82.8037,\n                1.0,\n                369.172,\n                82.2061,\n                1.0,\n                370.693,\n                81.6521,\n                1.0,\n                358.705,\n                75.4542,\n                1.0,\n                360.294,\n                74.0903,\n                1.0,\n                362.376,\n                73.8423,\n                1.0,\n                364.302,\n                74.6834,\n                1.0,\n                362.543,\n                75.568,\n                1.0,\n                360.612,\n                75.8883,\n                1.0,\n                369.771,\n                73.7734,\n                1.0,\n                371.409,\n                72.2638,\n                1.0,\n                373.615,\n                71.9502,\n                1.0,\n                375.722,\n                72.7144,\n                1.0,\n                373.888,\n                73.699,\n                1.0,\n                371.835,\n                74.0238,\n                1.0,\n                363.184,\n                86.9317,\n                1.0,\n                364.788,\n                85.4484,\n                1.0,\n                367.021,\n                84.7474,\n                1.0,\n                368.048,\n                84.5364,\n                1.0,\n                369.083,\n                84.3709,\n                1.0,\n                372.183,\n                84.0529,\n                1.0,\n                375.083,\n                84.8901,\n                1.0,\n                373.687,\n                87.0735,\n                1.0,\n                371.644,\n                88.8121,\n                1.0,\n                369.024,\n                89.6982,\n                1.0,\n                366.67,\n                89.6039,\n                1.0,\n                364.721,\n                88.606,\n                1.0,\n                363.588,\n                86.903,\n                1.0,\n                365.723,\n                85.8496,\n                1.0,\n                368.184,\n                85.2863,\n                1.0,\n                371.444,\n                84.8294,\n                1.0,\n                374.647,\n                85.0454,\n                1.0,\n                372.166,\n                87.2914,\n                1.0,\n                368.81,\n                88.3791,\n                1.0,\n                365.965,\n                88.3238,\n                1.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                304.10366,\n                181.75134,\n                1,\n                300.70183,\n                182.77567,\n                1,\n                297.3,\n                183.8,\n                1,\n                294.7,\n                186.5,\n                1,\n                290.1,\n                187.8,\n                1,\n                290.9,\n                176.6,\n                1,\n                287.5,\n                176.0,\n                1,\n                285.5,\n                178.4,\n                1,\n                286.4,\n                182.4,\n                1,\n                288.8,\n                179.4,\n                1,\n                285.0,\n                181.0,\n                1,\n                287.3,\n                186.1,\n                1,\n                291.8,\n                189.5,\n                1,\n                287.7,\n                182.7,\n                1,\n                283.8,\n                184.1,\n                1,\n                286.5,\n                189.1,\n                1,\n                290.0,\n                192.0,\n                1,\n                286.7,\n                185.3,\n                1,\n                282.8,\n                187.4,\n                1,\n                284.8,\n                191.6,\n                1,\n                288.4,\n                194.5,\n                1\n            ],\n            \"image_id\": 785,\n            \"bbox\": [\n                280.79,\n                44.73,\n                218.7,\n                346.68\n            ],\n            \"category_id\": 1,\n            \"id\": 442619,\n            \"face_box\": [\n                358.2,\n                69.86,\n                26.360000000000014,\n                25.849999999999994\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                280.43,\n                173.12,\n                27.860000000000014,\n                24.849999999999994\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": true,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    98.56,\n                    273.72,\n                    132.9,\n                    267,\n                    140.37,\n                    281.93,\n                    165.75,\n                    285.66,\n                    156.79,\n                    264.01,\n                    170.23,\n                    261.02,\n                    177.7,\n                    272.97,\n                    182.18,\n                    279.69,\n                    200.85,\n                    268.49,\n                    212.79,\n                    255.05,\n                    188.9,\n                    256.54,\n                    164.26,\n                    240.12,\n                    139.62,\n                    212.49,\n                    109.01,\n                    221.45,\n                    103.04,\n                    220.71,\n                    122.45,\n                    202.04,\n                    113.49,\n                    196.07,\n                    96.32,\n                    168.44,\n                    97.06,\n                    162.47,\n                    110.5,\n                    136.34,\n                    112,\n                    124.39,\n                    91.09,\n                    110.95,\n                    80.64,\n                    114.68,\n                    71.68,\n                    131.86,\n                    62.72,\n                    147.54,\n                    57.49,\n                    156.5,\n                    48.53,\n                    168.44,\n                    41.07,\n                    180.39,\n                    38.08,\n                    193.08,\n                    40.32,\n                    205.03,\n                    47.04,\n                    213.24,\n                    54.5,\n                    216.23,\n                    82.13,\n                    252.06,\n                    91.09,\n                    271.48\n                ]\n            ],\n            \"num_keypoints\": 106,\n            \"area\": 11025.219,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                99,\n                144,\n                2,\n                104,\n                141,\n                2,\n                96,\n                137,\n                2,\n                0,\n                0,\n                0,\n                78,\n                133,\n                2,\n                56,\n                161,\n                2,\n                81,\n                162,\n                2,\n                0,\n                0,\n                0,\n                103,\n                208,\n                2,\n                116,\n                204,\n                2,\n                0,\n                0,\n                0,\n                57,\n                246,\n                1,\n                82,\n                259,\n                1,\n                137,\n                219,\n                2,\n                138,\n                247,\n                2,\n                177,\n                256,\n                2,\n                158,\n                296,\n                1,\n                208.16049,\n                257.42419,\n                2.0,\n                205.8824,\n                259.13276,\n                2.0,\n                183.38626,\n                275.93367,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                82.9654,\n                131.144,\n                1.0,\n                81.8046,\n                134.328,\n                1.0,\n                80.7007,\n                137.531,\n                1.0,\n                79.8836,\n                140.818,\n                1.0,\n                79.734,\n                144.196,\n                1.0,\n                80.4763,\n                147.486,\n                1.0,\n                82.0188,\n                150.498,\n                1.0,\n                84.2352,\n                153.057,\n                1.0,\n                86.8081,\n                155.258,\n                1.0,\n                89.652,\n                157.095,\n                1.0,\n                92.9128,\n                157.812,\n                1.0,\n                95.962,\n                156.474,\n                1.0,\n                98.5377,\n                154.281,\n                1.0,\n                100.557,\n                151.568,\n                1.0,\n                102.508,\n                148.799,\n                1.0,\n                103.987,\n                145.756,\n                1.0,\n                105.345,\n                142.655,\n                1.0,\n                93.6074,\n                132.13,\n                1.0,\n                95.8108,\n                132.112,\n                1.0,\n                97.7956,\n                132.618,\n                1.0,\n                99.6897,\n                133.398,\n                1.0,\n                101.364,\n                134.432,\n                1.0,\n                105.0,\n                136.896,\n                1.0,\n                105.708,\n                137.334,\n                1.0,\n                106.267,\n                137.852,\n                1.0,\n                106.759,\n                138.404,\n                1.0,\n                107.013,\n                139.401,\n                1.0,\n                100.904,\n                139.994,\n                1.0,\n                100.551,\n                142.0,\n                1.0,\n                100.202,\n                143.956,\n                1.0,\n                99.8116,\n                145.919,\n                1.0,\n                94.7941,\n                146.187,\n                1.0,\n                95.9823,\n                147.027,\n                1.0,\n                97.3054,\n                147.849,\n                1.0,\n                98.2362,\n                148.403,\n                1.0,\n                99.2812,\n                148.491,\n                1.0,\n                93.151,\n                135.98,\n                1.0,\n                94.9184,\n                136.187,\n                1.0,\n                96.5441,\n                136.903,\n                1.0,\n                97.6034,\n                138.308,\n                1.0,\n                95.8998,\n                138.017,\n                1.0,\n                94.3941,\n                137.178,\n                1.0,\n                102.085,\n                141.003,\n                1.0,\n                103.379,\n                141.05,\n                1.0,\n                104.485,\n                141.71,\n                1.0,\n                104.899,\n                142.915,\n                1.0,\n                103.704,\n                142.739,\n                1.0,\n                102.729,\n                142.026,\n                1.0,\n                89.8433,\n                148.685,\n                1.0,\n                92.6494,\n                149.006,\n                1.0,\n                95.2801,\n                149.78,\n                1.0,\n                96.1096,\n                150.259,\n                1.0,\n                96.7411,\n                150.719,\n                1.0,\n                97.3853,\n                151.82,\n                1.0,\n                97.337,\n                153.217,\n                1.0,\n                96.5124,\n                153.108,\n                1.0,\n                95.6091,\n                152.796,\n                1.0,\n                94.7518,\n                152.399,\n                1.0,\n                93.0313,\n                151.317,\n                1.0,\n                91.3461,\n                150.149,\n                1.0,\n                90.24,\n                148.802,\n                1.0,\n                92.9121,\n                149.883,\n                1.0,\n                95.4213,\n                151.204,\n                1.0,\n                96.3082,\n                152.03,\n                1.0,\n                97.1377,\n                152.997,\n                1.0,\n                96.3098,\n                152.035,\n                1.0,\n                95.406,\n                151.234,\n                1.0,\n                92.8725,\n                149.984,\n                1.0,\n                109.88978,\n                204.46047,\n                1,\n                113.101195,\n                201.939065,\n                1,\n                116.31261,\n                199.41766,\n                1,\n                113.19977,\n                199.3139,\n                1,\n                109.8794,\n                200.24775,\n                1,\n                117.86903,\n                199.10638,\n                2,\n                113.9261,\n                199.00262,\n                2,\n                109.56812,\n                198.48381,\n                2,\n                106.6628,\n                198.38004999999998,\n                1,\n                117.1427,\n                202.32298,\n                2,\n                111.2283,\n                201.80417,\n                2,\n                107.07784000000001,\n                201.38913,\n                2,\n                103.65371999999999,\n                201.18161,\n                1,\n                116.52013,\n                205.95463,\n                2,\n                112.5772,\n                205.53958,\n                2,\n                107.59665,\n                204.39821,\n                2,\n                104.27629,\n                203.77564,\n                2,\n                116.41637,\n                209.69004,\n                2,\n                112.16215,\n                209.48252,\n                2,\n                108.73803000000001,\n                208.34114,\n                2,\n                105.72895,\n                206.68096,\n                2,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                38.08,\n                110.95,\n                174.71,\n                174.71\n            ],\n            \"category_id\": 1,\n            \"id\": 198196,\n            \"face_box\": [\n                79.19,\n                131.64,\n                29.290000000000006,\n                28.480000000000018\n            ],\n            \"lefthand_box\": [\n                104.83,\n                196.48,\n                16.400000000000006,\n                15.810000000000002\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": false,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    257.76,\n                    288.05,\n                    273.4,\n                    258.26,\n                    325.55,\n                    253.79,\n                    335.23,\n                    232.93,\n                    326.3,\n                    186.74,\n                    333.74,\n                    177.05,\n                    327.79,\n                    153.21,\n                    333.74,\n                    142.04,\n                    344.17,\n                    139.06,\n                    353.11,\n                    139.06,\n                    359.07,\n                    145.02,\n                    360.56,\n                    148.74,\n                    362.05,\n                    168.86,\n                    388.87,\n                    197.17,\n                    397.81,\n                    276.88,\n                    372.48,\n                    293.27\n                ]\n            ],\n            \"num_keypoints\": 83,\n            \"area\": 10171.9544,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                343,\n                164,\n                2,\n                348,\n                160,\n                2,\n                340,\n                160,\n                2,\n                359,\n                163,\n                2,\n                332,\n                164,\n                2,\n                370,\n                189,\n                2,\n                334,\n                190,\n                2,\n                358,\n                236,\n                2,\n                348,\n                234,\n                2,\n                339,\n                270,\n                2,\n                330,\n                262,\n                2,\n                378,\n                262,\n                2,\n                343,\n                254,\n                2,\n                338,\n                280,\n                2,\n                283,\n                272,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                333.383,\n                160.62,\n                1.0,\n                333.607,\n                163.811,\n                1.0,\n                334.137,\n                166.965,\n                1.0,\n                334.934,\n                170.062,\n                1.0,\n                336.036,\n                173.062,\n                1.0,\n                337.69,\n                175.794,\n                1.0,\n                340.01,\n                177.986,\n                1.0,\n                342.889,\n                179.347,\n                1.0,\n                346.063,\n                179.445,\n                1.0,\n                349.16,\n                178.674,\n                1.0,\n                351.892,\n                177.033,\n                1.0,\n                354.132,\n                174.761,\n                1.0,\n                355.652,\n                171.957,\n                1.0,\n                356.482,\n                168.871,\n                1.0,\n                356.751,\n                165.691,\n                1.0,\n                356.914,\n                162.496,\n                1.0,\n                356.913,\n                159.299,\n                1.0,\n                335.435,\n                157.491,\n                1.0,\n                336.759,\n                156.383,\n                1.0,\n                338.264,\n                155.821,\n                1.0,\n                339.903,\n                155.445,\n                1.0,\n                341.565,\n                155.312,\n                1.0,\n                345.805,\n                155.039,\n                1.0,\n                347.424,\n                154.896,\n                1.0,\n                349.044,\n                154.957,\n                1.0,\n                350.677,\n                155.266,\n                1.0,\n                352.333,\n                156.08,\n                1.0,\n                343.65,\n                159.186,\n                1.0,\n                343.687,\n                161.041,\n                1.0,\n                343.68,\n                162.886,\n                1.0,\n                343.657,\n                164.752,\n                1.0,\n                341.61,\n                167.049,\n                1.0,\n                342.69,\n                167.145,\n                1.0,\n                343.906,\n                167.123,\n                1.0,\n                345.179,\n                166.907,\n                1.0,\n                346.456,\n                166.707,\n                1.0,\n                336.707,\n                159.932,\n                1.0,\n                338.078,\n                158.999,\n                1.0,\n                339.726,\n                158.864,\n                1.0,\n                341.204,\n                159.605,\n                1.0,\n                339.755,\n                160.185,\n                1.0,\n                338.21,\n                160.321,\n                1.0,\n                346.612,\n                159.27,\n                1.0,\n                348.028,\n                158.307,\n                1.0,\n                349.739,\n                158.245,\n                1.0,\n                351.302,\n                158.965,\n                1.0,\n                349.802,\n                159.575,\n                1.0,\n                348.188,\n                159.642,\n                1.0,\n                340.049,\n                171.873,\n                1.0,\n                341.307,\n                170.304,\n                1.0,\n                343.097,\n                169.499,\n                1.0,\n                343.987,\n                169.41,\n                1.0,\n                344.876,\n                169.314,\n                1.0,\n                346.909,\n                169.61,\n                1.0,\n                348.603,\n                170.874,\n                1.0,\n                347.548,\n                172.219,\n                1.0,\n                346.133,\n                173.242,\n                1.0,\n                344.378,\n                173.742,\n                1.0,\n                342.683,\n                173.666,\n                1.0,\n                341.218,\n                173.038,\n                1.0,\n                340.398,\n                171.815,\n                1.0,\n                342.1,\n                170.752,\n                1.0,\n                344.043,\n                170.287,\n                1.0,\n                346.21,\n                170.271,\n                1.0,\n                348.214,\n                170.913,\n                1.0,\n                346.462,\n                171.947,\n                1.0,\n                344.283,\n                172.468,\n                1.0,\n                342.246,\n                172.507,\n                1.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                257.76,\n                139.06,\n                140.05,\n                154.21\n            ],\n            \"category_id\": 1,\n            \"id\": 230195,\n            \"face_box\": [\n                333.96,\n                154.32,\n                23.28000000000003,\n                26.79000000000002\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": false\n        },\n        {\n            \"segmentation\": [\n                [\n                    285.37,\n                    126.5,\n                    281.97,\n                    127.72,\n                    280.76,\n                    132.33,\n                    280.76,\n                    136.46,\n                    275.17,\n                    143.26,\n                    275.9,\n                    158.08,\n                    277.6,\n                    164.4,\n                    278.33,\n                    173.87,\n                    278.33,\n                    183.83,\n                    279.79,\n                    191.11,\n                    281.97,\n                    194.76,\n                    284.89,\n                    192.09,\n                    284.89,\n                    186.99,\n                    284.89,\n                    181.16,\n                    284.64,\n                    177.51,\n                    285.86,\n                    173.87\n                ]\n            ],\n            \"num_keypoints\": 0,\n            \"area\": 491.2669,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                275.17,\n                126.5,\n                10.69,\n                68.26\n            ],\n            \"category_id\": 1,\n            \"id\": 1202706,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": false\n        },\n        {\n            \"segmentation\": [\n                [\n                    339.34,\n                    107.97,\n                    338.38,\n                    102.19,\n                    339.34,\n                    91.58,\n                    335.49,\n                    84.84,\n                    326.81,\n                    74.23,\n                    312.35,\n                    74.23,\n                    301.75,\n                    74.23,\n                    295,\n                    86.76,\n                    295,\n                    93.51,\n                    292.11,\n                    99.3,\n                    287.29,\n                    102.19,\n                    291.14,\n                    107.01,\n                    295,\n                    107.01,\n                    295.96,\n                    112.79,\n                    301.75,\n                    115.69,\n                    305.6,\n                    119.54,\n                    307.53,\n                    123.4,\n                    317.17,\n                    123.4,\n                    311.39,\n                    129.18,\n                    286.32,\n                    139.79,\n                    274.75,\n                    139.79,\n                    264.15,\n                    138.82,\n                    262.22,\n                    144.61,\n                    261.26,\n                    147.5,\n                    253.54,\n                    147.5,\n                    247.76,\n                    150.39,\n                    249.69,\n                    159.07,\n                    256.44,\n                    161,\n                    262.22,\n                    161,\n                    268,\n                    161,\n                    276.68,\n                    161.96,\n                    284.39,\n                    168.71,\n                    293.07,\n                    174.49,\n                    301.75,\n                    174.49,\n                    308.49,\n                    169.67,\n                    308.49,\n                    188.95,\n                    311.39,\n                    194.74,\n                    312.35,\n                    208.23,\n                    307.53,\n                    221.73,\n                    297.89,\n                    229.44,\n                    281.5,\n                    250.65,\n                    269.93,\n                    262.22,\n                    278.61,\n                    320.06,\n                    281.5,\n                    331.63,\n                    276.68,\n                    338.38,\n                    270.9,\n                    349.95,\n                    262.22,\n                    356.7,\n                    253.54,\n                    359.59,\n                    253.54,\n                    365.37,\n                    274.75,\n                    365.37,\n                    291.14,\n                    365.37,\n                    306.57,\n                    359.59,\n                    303.67,\n                    352.84,\n                    297.89,\n                    340.31,\n                    293.07,\n                    318.13,\n                    295,\n                    294.03,\n                    293.07,\n                    278.61,\n                    294.03,\n                    270.9,\n                    305.6,\n                    259.33,\n                    313.31,\n                    299.82,\n                    319.1,\n                    309.46,\n                    341.27,\n                    317.17,\n                    384.65,\n                    330.67,\n                    387.55,\n                    335.49,\n                    383.69,\n                    341.27,\n                    397.19,\n                    350.91,\n                    398.15,\n                    363.44,\n                    398.15,\n                    375.01,\n                    405.86,\n                    374.05,\n                    409.72,\n                    357.66,\n                    411.65,\n                    342.24,\n                    416.47,\n                    328.74,\n                    417.43,\n                    321.03,\n                    410.68,\n                    319.1,\n                    401.04,\n                    318.13,\n                    392.37,\n                    318.13,\n                    382.73,\n                    314.28,\n                    348.98,\n                    300.78,\n                    339.34,\n                    293.07,\n                    334.52,\n                    285.36,\n                    340.31,\n                    259.33,\n                    340.31,\n                    246.8,\n                    340.31,\n                    242.94,\n                    350.91,\n                    228.48,\n                    358.62,\n                    214.98,\n                    355.22,\n                    204.32,\n                    357.05,\n                    196.11,\n                    361.61,\n                    188.82,\n                    361.61,\n                    181.97,\n                    365.26,\n                    165.63,\n                    367.54,\n                    139.18,\n                    366.17,\n                    123.68,\n                    361.15,\n                    112.73,\n                    353.86,\n                    107.72,\n                    351.58,\n                    105.89,\n                    344.74,\n                    105.89,\n                    340.18,\n                    109.08\n                ]\n            ],\n            \"num_keypoints\": 63,\n            \"area\": 17123.92955,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                297,\n                111,\n                2,\n                299,\n                106,\n                2,\n                0,\n                0,\n                0,\n                314,\n                108,\n                2,\n                0,\n                0,\n                0,\n                329,\n                141,\n                2,\n                346,\n                125,\n                2,\n                295,\n                164,\n                2,\n                323,\n                130,\n                2,\n                266,\n                155,\n                2,\n                279,\n                143,\n                2,\n                329,\n                225,\n                2,\n                331,\n                221,\n                2,\n                327,\n                298,\n                2,\n                283,\n                269,\n                2,\n                398,\n                327,\n                2,\n                288,\n                349,\n                2,\n                401.79499,\n                364.28207,\n                2.0,\n                407.21854,\n                361.57029,\n                2.0,\n                407.21854,\n                325.86523,\n                2.0,\n                257.16687,\n                361.57029,\n                2.0,\n                258.52276,\n                361.11833,\n                2.0,\n                297.84353,\n                355.69477,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                265.1,\n                155.9,\n                1,\n                260.05,\n                152.25,\n                1,\n                255.0,\n                148.6,\n                1,\n                250.6,\n                148.6,\n                1,\n                249.1,\n                151.0,\n                1,\n                253.4,\n                158.9,\n                1,\n                251.9,\n                155.1,\n                1,\n                252.0,\n                151.9,\n                1,\n                252.9,\n                150.0,\n                1,\n                257.4,\n                157.9,\n                1,\n                256.7,\n                154.2,\n                1,\n                256.3,\n                151.6,\n                1,\n                256.9,\n                149.3,\n                1,\n                260.2,\n                156.5,\n                1,\n                260.1,\n                153.0,\n                1,\n                259.9,\n                150.7,\n                1,\n                260.2,\n                148.7,\n                1,\n                262.8,\n                154.8,\n                1,\n                262.7,\n                152.5,\n                1,\n                262.7,\n                150.9,\n                1,\n                262.6,\n                148.8,\n                1,\n                280.8,\n                146.5,\n                1,\n                275.4,\n                149.15,\n                1,\n                270.0,\n                151.8,\n                1,\n                266.2,\n                152.2,\n                1,\n                263.5,\n                151.9,\n                1,\n                266.6,\n                142.5,\n                1,\n                263.6,\n                147.0,\n                1,\n                264.9,\n                151.0,\n                1,\n                268.5,\n                152.9,\n                1,\n                270.6,\n                142.0,\n                1,\n                267.9,\n                146.0,\n                1,\n                269.4,\n                149.6,\n                1,\n                272.5,\n                151.5,\n                1,\n                273.8,\n                142.1,\n                1,\n                272.2,\n                146.0,\n                1,\n                274.2,\n                149.1,\n                1,\n                276.5,\n                149.6,\n                1,\n                277.4,\n                142.3,\n                1,\n                276.6,\n                145.2,\n                1,\n                277.6,\n                148.3,\n                1,\n                279.4,\n                148.6,\n                1\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                247.76,\n                74.23,\n                169.67,\n                300.78\n            ],\n            \"category_id\": 1,\n            \"id\": 460541,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                249.12,\n                146.31,\n                19.920000000000016,\n                15.819999999999993\n            ],\n            \"righthand_box\": [\n                262.82,\n                139.96,\n                18.930000000000007,\n                14.679999999999978\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": true,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    578.76,\n                    112.4,\n                    589.39,\n                    100.81,\n                    589.39,\n                    99.84,\n                    596.16,\n                    116.27,\n                    603.89,\n                    122.07,\n                    603.89,\n                    138.49,\n                    598.09,\n                    159.75,\n                    597.12,\n                    181,\n                    594.22,\n                    191.63,\n                    589.39,\n                    212.89,\n                    583.59,\n                    208.06,\n                    583.59,\n                    206.13,\n                    582.63,\n                    200.33,\n                    582.63,\n                    193.57,\n                    582.63,\n                    182.94,\n                    575.86,\n                    181,\n                    567.17,\n                    197.43,\n                    571.03,\n                    203.23,\n                    567.17,\n                    207.09,\n                    555.57,\n                    208.06,\n                    562.34,\n                    200.33,\n                    565.24,\n                    190.67,\n                    565.24,\n                    173.27,\n                    566.2,\n                    163.61,\n                    568.14,\n                    156.85,\n                    570.07,\n                    148.15,\n                    566.2,\n                    143.32,\n                    565.24,\n                    133.66,\n                    575.86,\n                    118.2\n                ]\n            ],\n            \"num_keypoints\": 36,\n            \"area\": 2789.0208,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                589,\n                113,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                595,\n                112,\n                1,\n                584,\n                110,\n                2,\n                598,\n                123,\n                2,\n                579,\n                119,\n                2,\n                594,\n                141,\n                2,\n                570,\n                137,\n                2,\n                576,\n                135,\n                2,\n                585,\n                139,\n                2,\n                590,\n                157,\n                2,\n                574,\n                156,\n                2,\n                589,\n                192,\n                2,\n                565,\n                189,\n                1,\n                587,\n                222,\n                1,\n                557,\n                219,\n                1,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                578.8,\n                135.7,\n                2,\n                577.55,\n                134.35,\n                2,\n                576.3,\n                133.0,\n                1,\n                574.6,\n                134.1,\n                1,\n                574.0,\n                135.5,\n                1,\n                574.3,\n                132.9,\n                2,\n                572.0,\n                132.4,\n                2,\n                570.3,\n                131.8,\n                2,\n                568.9,\n                130.7,\n                2,\n                573.3,\n                134.4,\n                2,\n                570.9,\n                134.0,\n                2,\n                569.5,\n                133.9,\n                2,\n                568.2,\n                133.8,\n                2,\n                572.8,\n                135.7,\n                2,\n                572.6,\n                138.3,\n                2,\n                574.1,\n                139.4,\n                2,\n                576.2,\n                139.4,\n                1,\n                574.4,\n                138.0,\n                2,\n                575.4,\n                139.5,\n                2,\n                576.3,\n                140.2,\n                2,\n                577.6,\n                140.8,\n                2,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                555.57,\n                99.84,\n                48.32,\n                113.05\n            ],\n            \"category_id\": 1,\n            \"id\": 488308,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                568.2,\n                130.89,\n                10.75,\n                11.130000000000024\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": false,\n            \"foot_valid\": false\n        },\n        {\n            \"segmentation\": [\n                [\n                    446.96,\n                    73.13,\n                    445.81,\n                    77.71,\n                    443.33,\n                    78.29,\n                    441.61,\n                    81.72,\n                    441.23,\n                    84.58,\n                    440.85,\n                    90.5,\n                    442.19,\n                    94.32,\n                    443.52,\n                    97.18,\n                    443.52,\n                    102.33,\n                    442.57,\n                    105.58,\n                    446.58,\n                    105.19,\n                    447.15,\n                    99.85,\n                    447.53,\n                    94.89,\n                    446,\n                    93.55,\n                    446.38,\n                    92.03,\n                    453.64,\n                    92.41,\n                    454.02,\n                    94.51,\n                    457.64,\n                    94.51,\n                    455.74,\n                    88.4,\n                    455.35,\n                    82.29,\n                    453.64,\n                    78.48,\n                    451.92,\n                    77.71,\n                    452.87,\n                    74.47,\n                    450.58,\n                    73.13\n                ]\n            ],\n            \"num_keypoints\": 0,\n            \"area\": 285.7906,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                440.85,\n                73.13,\n                16.79,\n                32.45\n            ],\n            \"category_id\": 1,\n            \"id\": 508900,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": false\n        },\n        {\n            \"segmentation\": [\n                [\n                    497.15,\n                    413.95,\n                    531.55,\n                    417.68,\n                    548.74,\n                    411.7,\n                    551.74,\n                    403.48,\n                    546.5,\n                    394.5,\n                    543.51,\n                    386.28,\n                    571.93,\n                    390.76,\n                    574.92,\n                    391.51,\n                    579.4,\n                    409.46,\n                    605.58,\n                    409.46,\n                    615.3,\n                    408.71,\n                    607.07,\n                    389.27,\n                    598.1,\n                    381.79,\n                    607.82,\n                    366.83,\n                    607.82,\n                    352.63,\n                    610.06,\n                    338.42,\n                    619.04,\n                    345.15,\n                    631,\n                    344.4,\n                    630.25,\n                    336.92,\n                    626.51,\n                    318.98,\n                    616.05,\n                    286.07,\n                    598.85,\n                    263.64,\n                    585.39,\n                    257.66,\n                    593.61,\n                    244.2,\n                    601.09,\n                    235.97,\n                    596.6,\n                    219.52,\n                    587.63,\n                    211.29,\n                    577.91,\n                    208.3,\n                    563.7,\n                    206.81,\n                    556.22,\n                    214.29,\n                    548,\n                    217.28,\n                    539.77,\n                    229.99,\n                    539.77,\n                    241.95,\n                    539.02,\n                    247.19,\n                    523.32,\n                    247.19,\n                    503.88,\n                    254.67,\n                    485.93,\n                    254.67,\n                    479.95,\n                    248.68,\n                    473.22,\n                    241.21,\n                    485.93,\n                    227,\n                    477.7,\n                    215.78,\n                    457.51,\n                    215.78,\n                    453.77,\n                    235.22,\n                    463.5,\n                    246.44,\n                    465.74,\n                    261.4,\n                    490.42,\n                    274.11,\n                    501.63,\n                    275.6,\n                    504.62,\n                    286.07,\n                    519.58,\n                    286.07,\n                    522.57,\n                    292.06,\n                    512.85,\n                    310,\n                    515.09,\n                    330.94,\n                    530.05,\n                    343.65,\n                    505.37,\n                    341.41,\n                    479.95,\n                    339.91,\n                    465.74,\n                    346.64,\n                    463.5,\n                    358.61,\n                    473.97,\n                    381.04,\n                    485.18,\n                    390.02,\n                    501.63,\n                    398.99,\n                    504.62,\n                    404.22,\n                    491.16,\n                    412.45,\n                    495.65,\n                    417.68\n                ]\n            ],\n            \"num_keypoints\": 15,\n            \"area\": 21608.94075,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                552,\n                234,\n                2,\n                0,\n                0,\n                0,\n                531,\n                262,\n                2,\n                600,\n                283,\n                2,\n                480,\n                260,\n                2,\n                622,\n                336,\n                2,\n                466,\n                242,\n                2,\n                0,\n                0,\n                0,\n                546,\n                365,\n                2,\n                592,\n                371,\n                2,\n                470,\n                351,\n                2,\n                551,\n                330,\n                2,\n                519,\n                394,\n                2,\n                589,\n                391,\n                2,\n                0.0,\n                0.0,\n                0.0,\n                498.08009,\n                412.23863,\n                2.0,\n                541.66626,\n                400.39384,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                602.22109,\n                403.58794,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                453.77,\n                206.81,\n                177.23,\n                210.87\n            ],\n            \"category_id\": 1,\n            \"id\": 1717641,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    58.93,\n                    163.67,\n                    47.18,\n                    161.59,\n                    36.12,\n                    93.86,\n                    41.65,\n                    82.8,\n                    40.27,\n                    69.66,\n                    50.64,\n                    67.59,\n                    55.48,\n                    73.81,\n                    63.08,\n                    92.47,\n                    66.53,\n                    99.38,\n                    65.15,\n                    109.06,\n                    61,\n                    127.03,\n                    59.62,\n                    162.97\n                ]\n            ],\n            \"num_keypoints\": 20,\n            \"area\": 1870.14015,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                48,\n                79,\n                2,\n                50,\n                77,\n                2,\n                46,\n                77,\n                2,\n                54,\n                78,\n                2,\n                45,\n                78,\n                2,\n                57,\n                90,\n                2,\n                42,\n                90,\n                2,\n                63,\n                103,\n                2,\n                42,\n                105,\n                2,\n                56,\n                113,\n                2,\n                49,\n                112,\n                2,\n                55,\n                117,\n                2,\n                44,\n                117,\n                2,\n                55,\n                140,\n                2,\n                47,\n                140,\n                2,\n                56,\n                160,\n                2,\n                49,\n                159,\n                2,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                44.4,\n                162.6,\n                2.0,\n                43.4,\n                161.5,\n                2.0,\n                51.7,\n                160.7,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                36.12,\n                67.59,\n                30.41,\n                96.08\n            ],\n            \"category_id\": 1,\n            \"id\": 1724673,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    139.41,\n                    321.58,\n                    144.78,\n                    326.56,\n                    196.92,\n                    314.68,\n                    196.16,\n                    309.31,\n                    207.28,\n                    292.05,\n                    213.03,\n                    284,\n                    228.75,\n                    270.2,\n                    233.35,\n                    261.38,\n                    244.47,\n                    252.56,\n                    254.44,\n                    237.61,\n                    267.86,\n                    215.37,\n                    272.08,\n                    212.68,\n                    285.5,\n                    232.62,\n                    294.7,\n                    250.64,\n                    295.08,\n                    264.06,\n                    290.87,\n                    277.87,\n                    290.87,\n                    286.3,\n                    289.71,\n                    298.19,\n                    281.66,\n                    318.89,\n                    282.05,\n                    334.23,\n                    295.08,\n                    340.37,\n                    315.02,\n                    343.82,\n                    314.25,\n                    336.53,\n                    310.42,\n                    330.4,\n                    301.98,\n                    322.34,\n                    304.29,\n                    310.84,\n                    304.67,\n                    302.79,\n                    306.2,\n                    292.05,\n                    311.19,\n                    275.56,\n                    313.87,\n                    251.79,\n                    311.19,\n                    234.54,\n                    312.72,\n                    224.57,\n                    310.42,\n                    212.3,\n                    307.74,\n                    201.56,\n                    306.2,\n                    193.51,\n                    306.59,\n                    183.16,\n                    310.04,\n                    177.41,\n                    314.64,\n                    173.19,\n                    316.94,\n                    171.65,\n                    328.06,\n                    163.99,\n                    337.64,\n                    157.85,\n                    343.4,\n                    159.77,\n                    346.46,\n                    166.67,\n                    346.85,\n                    170.5,\n                    346.46,\n                    179.71,\n                    346.85,\n                    188.53,\n                    346.85,\n                    191.98,\n                    344.55,\n                    198.11,\n                    342.25,\n                    203.48,\n                    338.41,\n                    208.46,\n                    335.34,\n                    212.68,\n                    335.34,\n                    217.67,\n                    343.01,\n                    222.65,\n                    354.9,\n                    210.76,\n                    359.12,\n                    196.19,\n                    361.8,\n                    173.19,\n                    361.42,\n                    161.69,\n                    356.43,\n                    150.18,\n                    344.93,\n                    135.61,\n                    343.01,\n                    132.93,\n                    345.31,\n                    126.41,\n                    345.7,\n                    124.88,\n                    343.4,\n                    115.29,\n                    340.33,\n                    104.17,\n                    337.26,\n                    102.25,\n                    330.36,\n                    103.4,\n                    326.14,\n                    106.09,\n                    320.01,\n                    111.07,\n                    314.64,\n                    119.89,\n                    310.42,\n                    121.04,\n                    292.02,\n                    121.81,\n                    279.75,\n                    127.94,\n                    244.09,\n                    138.68,\n                    240.25,\n                    142.51,\n                    238.72,\n                    154.4,\n                    239.1,\n                    163.6,\n                    239.87,\n                    173.96,\n                    241.79,\n                    181.24,\n                    248.3,\n                    192.36,\n                    240.25,\n                    206.55,\n                    236.42,\n                    219.2,\n                    229.9,\n                    236.45,\n                    225.3,\n                    247.57,\n                    218.4,\n                    254.48,\n                    208.81,\n                    265.6,\n                    202.29,\n                    278.25,\n                    195.39,\n                    285.92,\n                    188.49,\n                    292.05,\n                    183.5,\n                    295.89,\n                    176.6,\n                    302.41,\n                    172,\n                    308.54,\n                    167.78,\n                    313.14,\n                    146.31,\n                    318.89\n                ]\n            ],\n            \"num_keypoints\": 132,\n            \"area\": 14250.29385,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                334,\n                135,\n                2,\n                340,\n                129,\n                2,\n                331,\n                129,\n                2,\n                0,\n                0,\n                0,\n                319,\n                123,\n                2,\n                340,\n                146,\n                2,\n                292,\n                133,\n                2,\n                353,\n                164,\n                2,\n                246,\n                144,\n                2,\n                354,\n                197,\n                2,\n                250,\n                185,\n                2,\n                293,\n                197,\n                2,\n                265,\n                187,\n                2,\n                305,\n                252,\n                2,\n                231,\n                254,\n                2,\n                293,\n                321,\n                2,\n                193,\n                297,\n                2,\n                300.24175,\n                336.83838,\n                2.0,\n                306.59015,\n                335.34464,\n                2.0,\n                290.07408,\n                326.47826,\n                2.0,\n                182.60972,\n                314.05885,\n                2.0,\n                175.88789,\n                305.84328,\n                2.0,\n                189.70499,\n                302.48236,\n                2.0,\n                319.681,\n                126.613,\n                1.0,\n                319.155,\n                129.261,\n                1.0,\n                318.92,\n                131.954,\n                1.0,\n                319.187,\n                134.631,\n                1.0,\n                319.707,\n                137.271,\n                1.0,\n                320.991,\n                139.649,\n                1.0,\n                322.846,\n                141.606,\n                1.0,\n                325.009,\n                143.216,\n                1.0,\n                327.359,\n                144.544,\n                1.0,\n                329.907,\n                145.384,\n                1.0,\n                332.347,\n                144.347,\n                1.0,\n                334.268,\n                142.449,\n                1.0,\n                335.767,\n                140.222,\n                1.0,\n                336.675,\n                137.69,\n                1.0,\n                337.019,\n                135.009,\n                1.0,\n                336.982,\n                132.311,\n                1.0,\n                337.13,\n                129.618,\n                1.0,\n                328.503,\n                125.823,\n                1.0,\n                329.531,\n                125.489,\n                1.0,\n                330.619,\n                125.626,\n                1.0,\n                331.573,\n                125.909,\n                1.0,\n                332.529,\n                126.431,\n                1.0,\n                334.479,\n                127.459,\n                1.0,\n                334.815,\n                127.43,\n                1.0,\n                335.157,\n                127.316,\n                1.0,\n                335.52,\n                127.327,\n                1.0,\n                335.949,\n                127.701,\n                1.0,\n                332.762,\n                129.334,\n                1.0,\n                333.168,\n                130.389,\n                1.0,\n                333.603,\n                131.342,\n                1.0,\n                333.928,\n                132.331,\n                1.0,\n                331.671,\n                134.291,\n                1.0,\n                332.232,\n                134.389,\n                1.0,\n                332.931,\n                134.487,\n                1.0,\n                333.332,\n                134.463,\n                1.0,\n                333.645,\n                134.212,\n                1.0,\n                329.271,\n                128.208,\n                1.0,\n                329.963,\n                128.464,\n                1.0,\n                330.676,\n                128.659,\n                1.0,\n                331.392,\n                128.839,\n                1.0,\n                330.672,\n                128.659,\n                1.0,\n                330.003,\n                128.334,\n                1.0,\n                333.792,\n                129.611,\n                1.0,\n                334.158,\n                129.741,\n                1.0,\n                334.546,\n                129.765,\n                1.0,\n                334.878,\n                129.954,\n                1.0,\n                334.523,\n                129.822,\n                1.0,\n                334.161,\n                129.704,\n                1.0,\n                327.38,\n                138.818,\n                1.0,\n                329.757,\n                138.136,\n                1.0,\n                332.086,\n                137.874,\n                1.0,\n                332.75,\n                138.208,\n                1.0,\n                333.221,\n                138.515,\n                1.0,\n                334.495,\n                139.634,\n                1.0,\n                335.213,\n                141.054,\n                1.0,\n                334.12,\n                140.754,\n                1.0,\n                333.208,\n                140.234,\n                1.0,\n                332.2,\n                139.888,\n                1.0,\n                330.765,\n                139.414,\n                1.0,\n                329.069,\n                139.351,\n                1.0,\n                327.561,\n                138.814,\n                1.0,\n                329.88,\n                138.346,\n                1.0,\n                332.517,\n                138.668,\n                1.0,\n                334.031,\n                139.589,\n                1.0,\n                335.123,\n                140.862,\n                1.0,\n                333.726,\n                140.572,\n                1.0,\n                332.203,\n                140.032,\n                1.0,\n                329.731,\n                139.403,\n                1.0,\n                353.87482,\n                196.49984999999998,\n                1,\n                349.01957500000003,\n                201.76511,\n                1,\n                344.16433,\n                207.03037,\n                1,\n                340.81534,\n                210.64729,\n                1,\n                337.46165,\n                216.59183000000002,\n                1,\n                346.65868,\n                216.02586,\n                1,\n                342.27241,\n                219.28019999999998,\n                1,\n                337.88613,\n                219.70467,\n                1,\n                334.4903,\n                218.57273,\n                1,\n                345.5,\n                215.0,\n                1,\n                342.27241,\n                217.72377,\n                1,\n                338.73509,\n                218.00675999999999,\n                1,\n                334.77329,\n                216.30885,\n                1,\n                343.7,\n                213.8,\n                1,\n                341.42345,\n                215.74288,\n                1,\n                338.73509,\n                215.60138,\n                1,\n                335.62225,\n                213.76198,\n                1,\n                342.4139,\n                212.63003,\n                1,\n                340.85748,\n                213.76198,\n                1,\n                338.87658,\n                214.04496,\n                1,\n                337.17867,\n                213.76198,\n                1,\n                249.4,\n                180.4,\n                1,\n                254.3,\n                184.9,\n                1,\n                259.2,\n                189.4,\n                1,\n                259.3,\n                192.1,\n                1,\n                258.2,\n                194.9,\n                1,\n                254.9,\n                193.2,\n                1,\n                255.9,\n                192.3,\n                1,\n                255.9,\n                190.5,\n                1,\n                255.4,\n                188.5,\n                1,\n                252.2,\n                194.0,\n                1,\n                253.2,\n                193.6,\n                1,\n                253.2,\n                191.1,\n                1,\n                252.9,\n                188.8,\n                1,\n                249.4,\n                193.6,\n                1,\n                250.4,\n                193.6,\n                1,\n                250.4,\n                191.3,\n                1,\n                249.9,\n                188.7,\n                1,\n                247.1,\n                192.2,\n                1,\n                248.0,\n                192.2,\n                1,\n                247.9,\n                190.3,\n                1,\n                247.5,\n                188.3,\n                1\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                139.41,\n                102.25,\n                222.39,\n                241.57\n            ],\n            \"category_id\": 1,\n            \"id\": 437295,\n            \"face_box\": [\n                320.23,\n                123.84,\n                21.049999999999955,\n                23.5\n            ],\n            \"lefthand_box\": [\n                333.65,\n                198.45,\n                23.150000000000034,\n                23.57000000000002\n            ],\n            \"righthand_box\": [\n                247.5,\n                184.92,\n                23.30000000000001,\n                22.360000000000014\n            ],\n            \"face_valid\": true,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": true,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    287.17,\n                    121.42,\n                    294.22,\n                    106.44,\n                    302.15,\n                    116.13,\n                    303.03,\n                    121.42\n                ],\n                [\n                    297.74,\n                    99.39,\n                    310.08,\n                    76.49,\n                    326.81,\n                    76.49,\n                    329.46,\n                    67.68,\n                    337.38,\n                    61.52,\n                    346.19,\n                    62.4,\n                    353.24,\n                    65.92,\n                    353.24,\n                    76.49,\n                    355.88,\n                    84.42,\n                    359.41,\n                    87.94,\n                    362.05,\n                    96.75,\n                    354.12,\n                    139.04,\n                    349.72,\n                    142.56,\n                    345.31,\n                    139.92,\n                    349.72,\n                    117.89,\n                    348.84,\n                    108.2,\n                    345.31,\n                    113.49,\n                    336.5,\n                    101.16,\n                    325.93,\n                    110.85,\n                    311.84,\n                    123.18\n                ],\n                [\n                    324.17,\n                    176.91,\n                    332.1,\n                    191.89,\n                    328.58,\n                    198.94,\n                    327.69,\n                    205.98,\n                    333.86,\n                    213.03,\n                    337.38,\n                    227.13,\n                    332.98,\n                    227.13,\n                    319.77,\n                    219.2,\n                    313.6,\n                    211.27\n                ],\n                [\n                    332.98,\n                    165.46,\n                    341.79,\n                    161.06,\n                    336.5,\n                    174.27,\n                    333.86,\n                    186.6,\n                    326.81,\n                    176.03\n                ]\n            ],\n            \"num_keypoints\": 19,\n            \"area\": 3404.869,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                345,\n                92,\n                2,\n                350,\n                87,\n                2,\n                341,\n                87,\n                2,\n                0,\n                0,\n                0,\n                330,\n                83,\n                2,\n                357,\n                94,\n                2,\n                316,\n                92,\n                2,\n                357,\n                104,\n                2,\n                291,\n                123,\n                1,\n                351,\n                133,\n                2,\n                281,\n                136,\n                1,\n                326,\n                131,\n                1,\n                305,\n                128,\n                1,\n                336,\n                152,\n                1,\n                303,\n                171,\n                1,\n                318,\n                206,\n                2,\n                294,\n                211,\n                1,\n                322.595,\n                216.245,\n                2.0,\n                327.23077,\n                215.42692,\n                2.0,\n                316.81553,\n                207.67155,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                287.17,\n                61.52,\n                74.88,\n                165.61\n            ],\n            \"category_id\": 1,\n            \"id\": 467657,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    547.95,\n                    201.57,\n                    546.73,\n                    190.62,\n                    547.95,\n                    181.49,\n                    547.95,\n                    169.31,\n                    547.95,\n                    156.53,\n                    546.73,\n                    144.36,\n                    544.3,\n                    139.49,\n                    540.04,\n                    132.19,\n                    540.04,\n                    121.84,\n                    542.47,\n                    107.24,\n                    544.3,\n                    99.33,\n                    548.56,\n                    88.98,\n                    561.95,\n                    78.03,\n                    572.29,\n                    71.33,\n                    572.29,\n                    71.33,\n                    572.29,\n                    65.25,\n                    574.12,\n                    51.86,\n                    583.86,\n                    48.81,\n                    592.99,\n                    48.81,\n                    597.86,\n                    57.33,\n                    599.07,\n                    64.64,\n                    608.2,\n                    76.81,\n                    614.9,\n                    82.89,\n                    620.98,\n                    89.59,\n                    628.89,\n                    93.24,\n                    636.81,\n                    101.76,\n                    640,\n                    109.67,\n                    640,\n                    115.76,\n                    640,\n                    127.93,\n                    620.37,\n                    111.5,\n                    619.16,\n                    111.5,\n                    618.55,\n                    112.11,\n                    608.2,\n                    105.41,\n                    600.9,\n                    119.41,\n                    592.99,\n                    131.58,\n                    596.03,\n                    148.01,\n                    605.16,\n                    162.01,\n                    612.46,\n                    190.01,\n                    614.9,\n                    204.61,\n                    606.98,\n                    216.78,\n                    603.94,\n                    226.52,\n                    606.38,\n                    239.91,\n                    605.16,\n                    256.95,\n                    604.55,\n                    264.26,\n                    602.12,\n                    271.56,\n                    586.29,\n                    272.17,\n                    584.47,\n                    255.13,\n                    588.73,\n                    237.48,\n                    592.99,\n                    221.65,\n                    596.64,\n                    207.05,\n                    596.64,\n                    197.31,\n                    594.2,\n                    186.96,\n                    584.47,\n                    172.36,\n                    577.77,\n                    166.27,\n                    570.47,\n                    170.53,\n                    558.91,\n                    179.66,\n                    555.86,\n                    192.44,\n                    548.56,\n                    198.53,\n                    547.95,\n                    198.53\n                ]\n            ],\n            \"num_keypoints\": 39,\n            \"area\": 8913.98475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                591,\n                78,\n                2,\n                594,\n                74,\n                2,\n                586,\n                74,\n                2,\n                0,\n                0,\n                0,\n                573,\n                70,\n                2,\n                598,\n                86,\n                2,\n                566,\n                93,\n                2,\n                626,\n                105,\n                2,\n                546,\n                126,\n                2,\n                0,\n                0,\n                0,\n                561,\n                150,\n                2,\n                582,\n                150,\n                2,\n                557,\n                154,\n                2,\n                606,\n                194,\n                2,\n                558,\n                209,\n                1,\n                591,\n                252,\n                2,\n                539,\n                262,\n                1,\n                599.72032,\n                264.75714,\n                2.0,\n                603.91172,\n                265.80499,\n                2.0,\n                585.74897,\n                265.10642,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                565.0,\n                153.0,\n                0.08773341029882431,\n                568.0,\n                156.0,\n                0.04602484405040741,\n                571.0,\n                159.0,\n                0.04602484405040741,\n                573.0,\n                161.0,\n                0.06972061097621918,\n                575.0,\n                164.0,\n                0.06297813355922699,\n                569.0,\n                158.0,\n                0.294232040643692,\n                570.0,\n                162.0,\n                0.26472434401512146,\n                570.0,\n                166.0,\n                0.2826344072818756,\n                571.0,\n                171.0,\n                0.374575674533844,\n                565.0,\n                159.0,\n                0.2154899388551712,\n                566.0,\n                162.0,\n                0.21613340079784393,\n                566.0,\n                164.0,\n                0.2544613480567932,\n                567.0,\n                168.0,\n                0.31771761178970337,\n                562.0,\n                160.0,\n                0.23286579549312592,\n                563.0,\n                166.0,\n                0.1579097956418991,\n                564.0,\n                166.0,\n                0.17961391806602478,\n                564.0,\n                166.0,\n                0.17504136264324188,\n                559.0,\n                160.0,\n                0.3428754508495331,\n                559.0,\n                162.0,\n                0.2897874116897583,\n                561.0,\n                165.0,\n                0.24125981330871582,\n                562.0,\n                166.0,\n                0.20118576288223267\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                540.04,\n                48.81,\n                99.96,\n                223.36\n            ],\n            \"category_id\": 1,\n            \"id\": 531914,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                557.05,\n                149.73,\n                19.879999999999995,\n                21.76000000000002\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": true,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    561.51,\n                    385.38,\n                    572.11,\n                    352.71,\n                    570.34,\n                    317.4,\n                    559.75,\n                    282.08,\n                    552.68,\n                    267.07,\n                    565.93,\n                    236.17,\n                    583.59,\n                    236.17,\n                    602.13,\n                    260.01,\n                    614.49,\n                    286.5,\n                    628.61,\n                    302.39,\n                    639.21,\n                    281.2,\n                    614.49,\n                    251.18,\n                    588,\n                    218.51,\n                    595.95,\n                    202.62,\n                    594.18,\n                    185.85,\n                    580.05,\n                    170.84,\n                    562.4,\n                    179.67,\n                    557.98,\n                    198.21,\n                    554.45,\n                    202.62,\n                    532.38,\n                    199.97,\n                    525.32,\n                    202.62,\n                    511.19,\n                    229.11,\n                    493.53,\n                    256.48,\n                    484.7,\n                    276.78,\n                    451.15,\n                    323.58,\n                    423.78,\n                    338.59,\n                    388.47,\n                    373.9,\n                    372.58,\n                    387.14,\n                    396.41,\n                    388.03,\n                    418.49,\n                    367.72,\n                    450.27,\n                    345.65,\n                    501.48,\n                    306.8,\n                    520.02,\n                    301.5,\n                    552.68,\n                    340.35,\n                    543.86,\n                    369.49\n                ]\n            ],\n            \"num_keypoints\": 60,\n            \"area\": 14267.20475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                580,\n                211,\n                2,\n                586,\n                206,\n                2,\n                574,\n                204,\n                2,\n                0,\n                0,\n                0,\n                562,\n                198,\n                2,\n                584,\n                220,\n                2,\n                529,\n                215,\n                2,\n                599,\n                242,\n                2,\n                512,\n                260,\n                2,\n                619,\n                274,\n                2,\n                538,\n                285,\n                2,\n                537,\n                288,\n                2,\n                506,\n                277,\n                2,\n                562,\n                332,\n                2,\n                452,\n                332,\n                2,\n                550,\n                387,\n                1,\n                402,\n                371,\n                2,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                375.00826,\n                386.35839,\n                2.0,\n                399.52454,\n                375.91627,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                620.284,\n                274.54006,\n                1,\n                621.65135,\n                282.30908999999997,\n                1,\n                623.0187,\n                290.07812,\n                1,\n                625.38048,\n                294.55308,\n                1,\n                628.86101,\n                298.90373999999997,\n                1,\n                630.22836,\n                289.20799,\n                1,\n                634.57901,\n                292.43991,\n                1,\n                633.08736,\n                295.54752,\n                1,\n                628.6124,\n                295.42321,\n                1,\n                632.46584,\n                286.5976,\n                1,\n                631.3,\n                291.9,\n                1,\n                627.7,\n                291.6,\n                1,\n                625.6,\n                288.9,\n                1,\n                633.7,\n                284.2,\n                1,\n                632.3,\n                288.0,\n                1,\n                629.1,\n                288.0,\n                1,\n                627.0,\n                285.9,\n                1,\n                633.2,\n                280.4,\n                1,\n                632.8,\n                283.6,\n                1,\n                630.8,\n                284.4,\n                1,\n                629.1,\n                283.2,\n                1,\n                544.0,\n                291.0,\n                0.09089653939008713,\n                551.0,\n                291.0,\n                0.041192591190338135,\n                558.0,\n                291.0,\n                0.041192591190338135,\n                559.0,\n                294.0,\n                0.056781601160764694,\n                563.0,\n                298.0,\n                0.2960541546344757,\n                559.0,\n                296.0,\n                0.18105527758598328,\n                562.0,\n                301.0,\n                0.12244582921266556,\n                559.0,\n                308.0,\n                0.05529222637414932,\n                564.0,\n                306.0,\n                0.05997529253363609,\n                555.0,\n                299.0,\n                0.18805834650993347,\n                556.0,\n                302.0,\n                0.1534559577703476,\n                555.0,\n                306.0,\n                0.20564205944538116,\n                556.0,\n                309.0,\n                0.06228385493159294,\n                550.0,\n                300.0,\n                0.1409723311662674,\n                550.0,\n                301.0,\n                0.2223101258277893,\n                551.0,\n                305.0,\n                0.2001882642507553,\n                553.0,\n                308.0,\n                0.1712668538093567,\n                545.0,\n                302.0,\n                0.1908813714981079,\n                546.0,\n                304.0,\n                0.13619276881217957,\n                547.0,\n                306.0,\n                0.19773860275745392,\n                549.0,\n                308.0,\n                0.1341865360736847\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                372.58,\n                170.84,\n                266.63,\n                217.19\n            ],\n            \"category_id\": 1,\n            \"id\": 533949,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                615.22,\n                271.56,\n                22.139999999999986,\n                28.839999999999975\n            ],\n            \"righthand_box\": [\n                538.83,\n                283.74,\n                25.639999999999986,\n                30.659999999999968\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": true,\n            \"righthand_valid\": true,\n            \"foot_valid\": true\n        },\n        {\n            \"segmentation\": [\n                [\n                    2.03,\n                    75.18,\n                    10.85,\n                    70.58,\n                    16.99,\n                    65.59,\n                    17.75,\n                    55.24,\n                    20.05,\n                    50.25,\n                    29.64,\n                    43.74,\n                    37.31,\n                    47.57,\n                    41.52,\n                    53.7,\n                    43.83,\n                    64.82,\n                    53.03,\n                    70.19,\n                    61.85,\n                    77.09,\n                    72.58,\n                    87.06,\n                    74.88,\n                    79.01,\n                    78.72,\n                    73.64,\n                    86.39,\n                    77.86,\n                    90.6,\n                    90.13,\n                    86,\n                    93.2,\n                    82.17,\n                    102.4,\n                    75.27,\n                    106.24,\n                    68.75,\n                    104.7,\n                    50.34,\n                    90.9,\n                    43.06,\n                    112.37,\n                    40.76,\n                    123.11,\n                    42.29,\n                    130.78,\n                    48.04,\n                    161.83,\n                    52.26,\n                    190.59,\n                    50.73,\n                    210.15,\n                    44.21,\n                    245.04,\n                    50.34,\n                    256.16,\n                    53.03,\n                    261.53,\n                    47.28,\n                    263.83,\n                    40.37,\n                    263.83,\n                    31.56,\n                    260.76,\n                    28.1,\n                    256.16,\n                    26.95,\n                    244.65,\n                    29.25,\n                    233.54,\n                    32.71,\n                    223.95,\n                    33.09,\n                    213.98,\n                    32.32,\n                    206.31,\n                    32.71,\n                    194.81,\n                    33.09,\n                    185.61,\n                    24.65,\n                    177.17,\n                    16.99,\n                    161.45,\n                    13.53,\n                    176.02,\n                    10.85,\n                    206.31,\n                    1.65,\n                    231.62,\n                    1.65,\n                    235.84,\n                    0.5,\n                    146.88,\n                    0.88,\n                    122.34,\n                    1.65,\n                    75.56\n                ]\n            ],\n            \"num_keypoints\": 16,\n            \"area\": 8260.75085,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                36,\n                79,\n                2,\n                40,\n                74,\n                2,\n                31,\n                75,\n                2,\n                0,\n                0,\n                0,\n                19,\n                69,\n                2,\n                45,\n                77,\n                2,\n                2,\n                89,\n                2,\n                74,\n                99,\n                2,\n                0,\n                0,\n                0,\n                78,\n                92,\n                2,\n                0,\n                0,\n                0,\n                33,\n                149,\n                2,\n                7,\n                153,\n                2,\n                44,\n                196,\n                2,\n                2,\n                205,\n                2,\n                35,\n                245,\n                2,\n                0,\n                0,\n                0,\n                43.80826,\n                259.40011,\n                2.0,\n                48.63752,\n                257.67537,\n                2.0,\n                32.08007,\n                256.29558,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                0.5,\n                43.74,\n                90.1,\n                220.09\n            ],\n            \"category_id\": 1,\n            \"id\": 543117,\n            \"face_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"lefthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"righthand_box\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"face_valid\": false,\n            \"lefthand_valid\": false,\n            \"righthand_valid\": false,\n            \"foot_valid\": true\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/cofw/test_cofw.json",
    "content": "{\n    \"info\": {\n        \"description\": \"MMPose example COFW dataset\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/12/31\"\n    },\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"face\",\n            \"keypoints\": [],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 1766,\n            \"file_name\": \"001766.jpg\",\n            \"height\": 322,\n            \"width\": 235\n        },\n        {\n            \"id\": 1805,\n            \"file_name\": \"001805.jpg\",\n            \"height\": 253,\n            \"width\": 352\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                46.562534549474826,\n                120.07575548185008,\n                2.0,\n                131.52522111663905,\n                115.97127786990977,\n                2.0,\n                65.8535793255943,\n                118.02351667587989,\n                2.0,\n                105.66701216141516,\n                114.73993458632765,\n                2.0,\n                56.41328081813161,\n                110.63545697438737,\n                2.0,\n                56.41328081813161,\n                118.43396443707394,\n                2.0,\n                119.62223604201218,\n                111.45635249677541,\n                2.0,\n                119.62223604201218,\n                117.61306891468585,\n                2.0,\n                51.89835544499728,\n                144.29217339229783,\n                2.0,\n                129.06253454947486,\n                143.88172563110376,\n                2.0,\n                72.83119126589278,\n                145.9339644370739,\n                2.0,\n                108.12969872857936,\n                143.47127786990976,\n                2.0,\n                62.980444997236056,\n                136.0832181684172,\n                2.0,\n                60.928206191265936,\n                148.3966510042381,\n                2.0,\n                120.03268380320623,\n                136.90411369080527,\n                2.0,\n                120.44313156440026,\n                147.16530772065602,\n                2.0,\n                65.44313156440026,\n                143.06083010871572,\n                2.0,\n                120.44313156440026,\n                143.06083010871572,\n                2.0,\n                65.44313156440026,\n                184.10560622811872,\n                2.0,\n                103.61477335544504,\n                183.69515846692468,\n                2.0,\n                78.5774599226092,\n                180.0011286161784,\n                2.0,\n                79.80880320619127,\n                190.26232264602916,\n                2.0,\n                60.928206191265936,\n                212.8369495117008,\n                1.0,\n                116.74910171365397,\n                214.4787405564769,\n                1.0,\n                83.50283305693756,\n                207.5011286161784,\n                1.0,\n                83.91328081813161,\n                211.19515846692468,\n                1.0,\n                88.83865395245994,\n                232.94888981020827,\n                1.0,\n                88.83865395245994,\n                239.92650175050676,\n                1.0,\n                94.99537037037038,\n                271.120531601253,\n                2.0\n            ],\n            \"image_id\": 1766,\n            \"id\": 1766,\n            \"num_keypoints\": 29,\n            \"bbox\": [\n                38.0,\n                102.0,\n                105.0,\n                180.0\n            ],\n            \"iscrowd\": 0,\n            \"area\": 18900.0,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                111.02581748226716,\n                99.60260061678404,\n                1.0,\n                203.48326006615514,\n                99.60260061678402,\n                2.0,\n                138.9556699294833,\n                104.89964159815261,\n                1.0,\n                158.69918631458435,\n                101.04724815715728,\n                2.0,\n                124.02764534562637,\n                98.6395022565352,\n                1.0,\n                124.50919452575083,\n                102.49189569753052,\n                1.0,\n                178.44270269968544,\n                92.37936291491776,\n                2.0,\n                178.92425187980987,\n                97.19485471616193,\n                2.0,\n                116.80440764376011,\n                115.9752727410142,\n                1.0,\n                192.40762892329354,\n                115.9752727410142,\n                2.0,\n                137.02947320898565,\n                120.30921536213394,\n                2.0,\n                165.44087483632623,\n                119.82766618200952,\n                2.0,\n                125.47229288599961,\n                114.04907602051652,\n                1.0,\n                126.43539124624846,\n                120.30921536213394,\n                1.0,\n                180.3688994201831,\n                107.78893667889912,\n                2.0,\n                180.3688994201831,\n                118.8645678217607,\n                2.0,\n                125.95384206612407,\n                118.38301864163628,\n                1.0,\n                180.85044860030752,\n                115.01217438076534,\n                2.0,\n                132.69553058786587,\n                149.68371534972337,\n                2.0,\n                162.0700305754553,\n                152.09146125034545,\n                2.0,\n                143.77116173072744,\n                147.7575186292257,\n                2.0,\n                144.2527109108519,\n                157.388502231714,\n                2.0,\n                132.21398140774147,\n                168.4641333745756,\n                1.0,\n                184.22129286117845,\n                167.9825841944512,\n                2.0,\n                149.06820271209602,\n                165.09328911370469,\n                2.0,\n                150.51285025246932,\n                170.3903300950733,\n                2.0,\n                151.95749779284256,\n                182.42905959818367,\n                2.0,\n                153.4021453332158,\n                188.6891989398011,\n                2.0,\n                155.32834205371347,\n                218.54524810751494,\n                2.0\n            ],\n            \"image_id\": 1805,\n            \"id\": 1805,\n            \"num_keypoints\": 29,\n            \"bbox\": [\n                102.0,\n                83.0,\n                112.0,\n                146.0\n            ],\n            \"iscrowd\": 0,\n            \"area\": 16352.0,\n            \"category_id\": 1\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/crowdpose/test_crowdpose.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\",\n                \"head\",\n                \"neck\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"file_name\": \"106848.jpg\",\n            \"id\": 106848,\n            \"height\": 425,\n            \"width\": 640,\n            \"crowdIndex\": 0.33\n        },\n        {\n            \"file_name\": \"103319.jpg\",\n            \"id\": 103319,\n            \"height\": 480,\n            \"width\": 640,\n            \"crowdIndex\": 0.39\n        }\n    ],\n    \"annotations\": [\n        {\n            \"num_keypoints\": 5,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                208,\n                108,\n                2,\n                0,\n                0,\n                0,\n                278,\n                158,\n                2,\n                262,\n                206,\n                2,\n                348,\n                98,\n                2,\n                0,\n                0,\n                0,\n                173,\n                299,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                256,\n                27,\n                1,\n                220,\n                89,\n                1\n            ],\n            \"image_id\": 106848,\n            \"bbox\": [\n                106.01,\n                13.43,\n                273.15,\n                352.42\n            ],\n            \"category_id\": 1,\n            \"id\": 123803\n        },\n        {\n            \"num_keypoints\": 0,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 106848,\n            \"bbox\": [\n                108.5,\n                96.78,\n                35.46,\n                30.23\n            ],\n            \"category_id\": 1,\n            \"id\": 131039\n        },\n        {\n            \"num_keypoints\": 10,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                482,\n                129,\n                2,\n                364,\n                126,\n                2,\n                513,\n                213,\n                2,\n                339,\n                163,\n                2,\n                431,\n                210,\n                2,\n                276,\n                163,\n                1,\n                440,\n                308,\n                2,\n                371,\n                304,\n                1,\n                432,\n                419,\n                1,\n                366,\n                419,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                407,\n                29,\n                1,\n                420,\n                110,\n                1\n            ],\n            \"image_id\": 106848,\n            \"bbox\": [\n                281.51,\n                21.92,\n                244.5,\n                349.72\n            ],\n            \"category_id\": 1,\n            \"id\": 147481\n        },\n        {\n            \"num_keypoints\": 12,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                388,\n                205,\n                2,\n                344,\n                211,\n                2,\n                407,\n                249,\n                2,\n                337,\n                256,\n                2,\n                393,\n                278,\n                2,\n                336,\n                290,\n                2,\n                390,\n                293,\n                2,\n                354,\n                294,\n                2,\n                387,\n                354,\n                2,\n                351,\n                357,\n                2,\n                380,\n                390,\n                2,\n                359,\n                408,\n                1,\n                351,\n                163,\n                1,\n                364,\n                198,\n                1\n            ],\n            \"image_id\": 103319,\n            \"bbox\": [\n                316.76,\n                157.3,\n                100.54,\n                247.56\n            ],\n            \"category_id\": 1,\n            \"id\": 127068\n        },\n        {\n            \"num_keypoints\": 12,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                350,\n                145,\n                2,\n                300,\n                145,\n                2,\n                352,\n                190,\n                1,\n                299,\n                180,\n                2,\n                322,\n                163,\n                2,\n                291,\n                217,\n                2,\n                346,\n                232,\n                1,\n                314,\n                232,\n                2,\n                346,\n                283,\n                1,\n                310,\n                284,\n                2,\n                345,\n                346,\n                1,\n                305,\n                344,\n                2,\n                312,\n                106,\n                1,\n                323,\n                137,\n                1\n            ],\n            \"image_id\": 103319,\n            \"bbox\": [\n                279.68,\n                102.17,\n                81.13,\n                255.49\n            ],\n            \"category_id\": 1,\n            \"id\": 129014\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/crowdpose/test_crowdpose_det_AP_40.json",
    "content": "[\n    {\n        \"bbox\": [\n            120.36583709716797,\n            30.521512985229492,\n            244.14288330078125,\n            328.944580078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 106848,\n        \"score\": 0.9999284744262695\n    },\n    {\n        \"bbox\": [\n            326.6805725097656,\n            30.76219940185547,\n            209.03128051757812,\n            327.80035400390625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 106848,\n        \"score\": 0.9993789196014404\n    },\n    {\n        \"bbox\": [\n            109.94915008544922,\n            95.794677734375,\n            32.249656677246094,\n            26.97345733642578\n        ],\n        \"category_id\": 1,\n        \"image_id\": 106848,\n        \"score\": 0.9997813105583191\n    },\n    {\n        \"bbox\": [\n            315.21368408203125,\n            149.79432678222656,\n            100.7252197265625,\n            259.96405029296875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 103319,\n        \"score\": 0.9998345375061035\n    },\n    {\n        \"bbox\": [\n            282.7766418457031,\n            100.75929260253906,\n            76.44869995117188,\n            261.6209716796875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 103319,\n        \"score\": 0.9998021721839905\n    },\n    {\n        \"bbox\": [\n            -0.10778862237930298,\n            238.81455993652344,\n            38.23238754272461,\n            99.21165466308594\n        ],\n        \"category_id\": 1,\n        \"image_id\": 103319,\n        \"score\": 0.9673888683319092\n    }\n]\n"
  },
  {
    "path": "tests/data/deepfasion2/deepfasion2.json",
    "content": "{\n  \"info\": \"\",\n  \"licenses\": \"\",\n  \"images\": [\n    {\n      \"coco_url\": \"\",\n      \"date_captured\": \"\",\n      \"file_name\": \"000264.jpg\",\n      \"flickr_url\": \"\",\n      \"id\": 264,\n      \"license\": 0,\n      \"width\": 750,\n      \"height\": 750\n    },\n    {\n      \"coco_url\": \"\",\n      \"date_captured\": \"\",\n      \"file_name\": \"000265.jpg\",\n      \"flickr_url\": \"\",\n      \"id\": 265,\n      \"license\": 0,\n      \"width\": 750,\n      \"height\": 750\n    }\n  ],\n  \"annotations\": [\n    {\n      \"area\": 402069,\n      \"bbox\": [\n        103,\n        80,\n        601,\n        669\n      ],\n      \"category_id\": 11,\n      \"id\": 429,\n      \"pair_id\": 22,\n      \"image_id\": 264,\n      \"iscrowd\": 0,\n      \"style\": 1,\n      \"num_keypoints\": 28,\n      \"keypoints\": [\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        417.0,\n        107.0,\n        1.0,\n        307.0,\n        87.0,\n        2.0,\n        349.0,\n        118.0,\n        2.0,\n        405.0,\n        131.0,\n        2.0,\n        461.0,\n        133.0,\n        2.0,\n        504.0,\n        116.0,\n        2.0,\n        242.0,\n        112.0,\n        2.0,\n        209.0,\n        208.0,\n        2.0,\n        182.0,\n        284.0,\n        2.0,\n        142.0,\n        331.0,\n        2.0,\n        121.0,\n        376.0,\n        2.0,\n        274.0,\n        440.0,\n        2.0,\n        277.0,\n        388.0,\n        2.0,\n        259.0,\n        345.0,\n        2.0,\n        263.0,\n        282.0,\n        1.0,\n        266.0,\n        222.0,\n        1.0,\n        258.0,\n        246.0,\n        2.0,\n        259.0,\n        318.0,\n        2.0,\n        249.0,\n        412.0,\n        1.0,\n        202.0,\n        579.0,\n        1.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        566.0,\n        593.0,\n        2.0,\n        532.0,\n        435.0,\n        2.0,\n        527.0,\n        355.0,\n        2.0,\n        540.0,\n        289.0,\n        2.0,\n        542.0,\n        271.0,\n        2.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        573.0,\n        479.0,\n        2.0,\n        698.0,\n        403.0,\n        2.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        594.0,\n        151.0,\n        2.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0\n      ],\n      \"segmentation\": [\n        [\n          345.05,\n          120.04,\n          321.68,\n          101.99,\n          308.4,\n          87.04,\n          295.88,\n          91.41,\n          267.98,\n          97.61,\n          250.24,\n          109.15,\n          234.6,\n          130.26,\n          224.23,\n          161.09,\n          212.72,\n          198.51,\n          193.23,\n          252.37,\n          183.68,\n          279.52,\n          164.61,\n          297.25,\n          133.78,\n          341.78,\n          118.78,\n          373.07,\n          120.42,\n          381.12,\n          142.25,\n          390.36,\n          147.3,\n          396.65,\n          166.82,\n          412.43,\n          186.56,\n          425.17,\n          206.63,\n          432.42,\n          206.48,\n          422.24,\n          272.85,\n          442.95,\n          230.31,\n          484.86,\n          202.28,\n          579.98,\n          198.77,\n          649.55,\n          195.22,\n          697.46,\n          196.55,\n          740.97,\n          208.78,\n          750.0,\n          310.72,\n          749.0,\n          439.41,\n          749.2,\n          562.85,\n          749.18,\n          578.32,\n          739.97,\n          574.34,\n          685.58,\n          562.73,\n          564.57,\n          545.52,\n          474.66,\n          536.85,\n          436.58,\n          546.89,\n          450.73,\n          559.79,\n          470.3,\n          564.49,\n          478.28,\n          571.67,\n          479.65,\n          579.75,\n          484.9,\n          611.0,\n          467.77,\n          640.13,\n          458.35,\n          635.77,\n          445.53,\n          671.39,\n          430.58,\n          697.71,\n          414.0,\n          697.93,\n          397.2,\n          691.25,\n          349.8,\n          680.6,\n          307.09,\n          664.02,\n          293.31,\n          645.57,\n          286.35,\n          619.11,\n          282.39,\n          620.03,\n          237.9,\n          611.34,\n          191.23,\n          602.52,\n          164.16,\n          590.09,\n          149.08,\n          553.5,\n          136.68,\n          523.0,\n          129.71,\n          512.15,\n          122.14,\n          502.99,\n          116.17,\n          473.33,\n          129.07,\n          412.19,\n          129.14,\n          403.58,\n          124.73,\n          386.42,\n          126.75\n        ]\n      ]\n    },\n    {\n      \"area\": 288806,\n      \"bbox\": [\n        178,\n        62,\n        421,\n        686\n      ],\n      \"category_id\": 11,\n      \"id\": 430,\n      \"pair_id\": 22,\n      \"image_id\": 265,\n      \"iscrowd\": 0,\n      \"style\": 2,\n      \"num_keypoints\": 31,\n      \"keypoints\": [\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        361.0,\n        71.0,\n        1.0,\n        282.0,\n        74.0,\n        2.0,\n        316.0,\n        90.0,\n        2.0,\n        361.0,\n        96.0,\n        2.0,\n        406.0,\n        98.0,\n        2.0,\n        438.0,\n        77.0,\n        2.0,\n        231.0,\n        100.0,\n        2.0,\n        210.0,\n        184.0,\n        2.0,\n        200.0,\n        252.0,\n        2.0,\n        186.0,\n        297.0,\n        2.0,\n        178.0,\n        331.0,\n        2.0,\n        264.0,\n        361.0,\n        1.0,\n        275.0,\n        311.0,\n        1.0,\n        272.0,\n        269.0,\n        1.0,\n        268.0,\n        228.0,\n        1.0,\n        263.0,\n        188.0,\n        1.0,\n        247.0,\n        209.0,\n        2.0,\n        258.0,\n        265.0,\n        2.0,\n        273.0,\n        320.0,\n        2.0,\n        256.0,\n        517.0,\n        1.0,\n        273.0,\n        710.0,\n        2.0,\n        384.0,\n        731.0,\n        2.0,\n        506.0,\n        713.0,\n        2.0,\n        496.0,\n        510.0,\n        2.0,\n        453.0,\n        318.0,\n        2.0,\n        471.0,\n        268.0,\n        2.0,\n        477.0,\n        213.0,\n        2.0,\n        456.0,\n        181.0,\n        1.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        508.0,\n        342.0,\n        2.0,\n        596.0,\n        267.0,\n        2.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        489.0,\n        75.0,\n        1.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0,\n        0.0\n      ],\n      \"segmentation\": [\n        [\n          438,\n          77,\n          406,\n          98,\n          361,\n          96,\n          316,\n          90,\n          282,\n          74,\n          231,\n          100,\n          210,\n          184,\n          200,\n          252,\n          186,\n          297,\n          178,\n          331,\n          264,\n          361,\n          275,\n          311,\n          272,\n          269,\n          268,\n          228,\n          263,\n          188,\n          247,\n          209,\n          258,\n          265,\n          273,\n          320,\n          256,\n          517,\n          273,\n          710,\n          384,\n          731,\n          506,\n          713,\n          496,\n          510,\n          453,\n          318,\n          471,\n          268,\n          477,\n          213,\n          456,\n          181,\n          508,\n          342,\n          596,\n          267,\n          489,\n          75,\n          438,\n          77\n        ],\n        [\n          231,\n          100,\n          210,\n          184,\n          200,\n          252,\n          186,\n          297,\n          178,\n          331,\n          264,\n          361,\n          275,\n          311,\n          272,\n          269,\n          268,\n          228,\n          263,\n          188,\n          231,\n          100\n        ],\n        [\n          456,\n          181,\n          508,\n          342,\n          596,\n          267,\n          489,\n          75,\n          456,\n          181\n        ],\n        [\n          200,\n          252,\n          186,\n          297,\n          178,\n          331,\n          264,\n          361,\n          275,\n          311,\n          272,\n          269,\n          200,\n          252\n        ]\n      ],\n      \"images\": [\n        {\n          \"coco_url\": \"\",\n          \"date_captured\": \"\",\n          \"file_name\": \"000264.jpg\",\n          \"flickr_url\": \"\",\n          \"id\": 264,\n          \"license\": 0,\n          \"width\": 750,\n          \"height\": 750\n        },\n        {\n          \"coco_url\": \"\",\n          \"date_captured\": \"\",\n          \"file_name\": \"000265.jpg\",\n          \"flickr_url\": \"\",\n          \"id\": 265,\n          \"license\": 0,\n          \"width\": 750,\n          \"height\": 750\n        }\n      ]\n    }\n  ],\n  \"categories\": [\n    {\n      \"id\": 11,\n      \"name\": \"long_sleeved_dress\",\n      \"supercategory\": \"clothes\",\n      \"keypoints\": [\n        \"1\",\n        \"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\",\n        \"23\",\n        \"24\",\n        \"25\",\n        \"26\",\n        \"27\",\n        \"28\",\n        \"29\",\n        \"30\",\n        \"31\",\n        \"32\",\n        \"33\",\n        \"34\",\n        \"35\",\n        \"36\",\n        \"37\",\n        \"38\",\n        \"39\",\n        \"40\",\n        \"41\",\n        \"42\",\n        \"43\",\n        \"44\",\n        \"45\",\n        \"46\",\n        \"47\",\n        \"48\",\n        \"49\",\n        \"50\",\n        \"51\",\n        \"52\",\n        \"53\",\n        \"54\",\n        \"55\",\n        \"56\",\n        \"57\",\n        \"58\",\n        \"59\",\n        \"60\",\n        \"61\",\n        \"62\",\n        \"63\",\n        \"64\",\n        \"65\",\n        \"66\",\n        \"67\",\n        \"68\",\n        \"69\",\n        \"70\",\n        \"71\",\n        \"72\",\n        \"73\",\n        \"74\",\n        \"75\",\n        \"76\",\n        \"77\",\n        \"78\",\n        \"79\",\n        \"80\",\n        \"81\",\n        \"82\",\n        \"83\",\n        \"84\",\n        \"85\",\n        \"86\",\n        \"87\",\n        \"88\",\n        \"89\",\n        \"90\",\n        \"91\",\n        \"92\",\n        \"93\",\n        \"94\",\n        \"95\",\n        \"96\",\n        \"97\",\n        \"98\",\n        \"99\",\n        \"100\",\n        \"101\",\n        \"102\",\n        \"103\",\n        \"104\",\n        \"105\",\n        \"106\",\n        \"107\",\n        \"108\",\n        \"109\",\n        \"110\",\n        \"111\",\n        \"112\",\n        \"113\",\n        \"114\",\n        \"115\",\n        \"116\",\n        \"117\",\n        \"118\",\n        \"119\",\n        \"120\",\n        \"121\",\n        \"122\",\n        \"123\",\n        \"124\",\n        \"125\",\n        \"126\",\n        \"127\",\n        \"128\",\n        \"129\",\n        \"130\",\n        \"131\",\n        \"132\",\n        \"133\",\n        \"134\",\n        \"135\",\n        \"136\",\n        \"137\",\n        \"138\",\n        \"139\",\n        \"140\",\n        \"141\",\n        \"142\",\n        \"143\",\n        \"144\",\n        \"145\",\n        \"146\",\n        \"147\",\n        \"148\",\n        \"149\",\n        \"150\",\n        \"151\",\n        \"152\",\n        \"153\",\n        \"154\",\n        \"155\",\n        \"156\",\n        \"157\",\n        \"158\",\n        \"159\",\n        \"160\",\n        \"161\",\n        \"162\",\n        \"163\",\n        \"164\",\n        \"165\",\n        \"166\",\n        \"167\",\n        \"168\",\n        \"169\",\n        \"170\",\n        \"171\",\n        \"172\",\n        \"173\",\n        \"174\",\n        \"175\",\n        \"176\",\n        \"177\",\n        \"178\",\n        \"179\",\n        \"180\",\n        \"181\",\n        \"182\",\n        \"183\",\n        \"184\",\n        \"185\",\n        \"186\",\n        \"187\",\n        \"188\",\n        \"189\",\n        \"190\",\n        \"191\",\n        \"192\",\n        \"193\",\n        \"194\",\n        \"195\",\n        \"196\",\n        \"197\",\n        \"198\",\n        \"199\",\n        \"200\",\n        \"201\",\n        \"202\",\n        \"203\",\n        \"204\",\n        \"205\",\n        \"206\",\n        \"207\",\n        \"208\",\n        \"209\",\n        \"210\",\n        \"211\",\n        \"212\",\n        \"213\",\n        \"214\",\n        \"215\",\n        \"216\",\n        \"217\",\n        \"218\",\n        \"219\",\n        \"220\",\n        \"221\",\n        \"222\",\n        \"223\",\n        \"224\",\n        \"225\",\n        \"226\",\n        \"227\",\n        \"228\",\n        \"229\",\n        \"230\",\n        \"231\",\n        \"232\",\n        \"233\",\n        \"234\",\n        \"235\",\n        \"236\",\n        \"237\",\n        \"238\",\n        \"239\",\n        \"240\",\n        \"241\",\n        \"242\",\n        \"243\",\n        \"244\",\n        \"245\",\n        \"246\",\n        \"247\",\n        \"248\",\n        \"249\",\n        \"250\",\n        \"251\",\n        \"252\",\n        \"253\",\n        \"254\",\n        \"255\",\n        \"256\",\n        \"257\",\n        \"258\",\n        \"259\",\n        \"260\",\n        \"261\",\n        \"262\",\n        \"263\",\n        \"264\",\n        \"265\",\n        \"266\",\n        \"267\",\n        \"268\",\n        \"269\",\n        \"270\",\n        \"271\",\n        \"272\",\n        \"273\",\n        \"274\",\n        \"275\",\n        \"276\",\n        \"277\",\n        \"278\",\n        \"279\",\n        \"280\",\n        \"281\",\n        \"282\",\n        \"283\",\n        \"284\",\n        \"285\",\n        \"286\",\n        \"287\",\n        \"288\",\n        \"289\",\n        \"290\",\n        \"291\",\n        \"292\",\n        \"293\",\n        \"294\"\n      ],\n      \"skeleton\": []\n    }\n  ]\n}"
  },
  {
    "path": "tests/data/exlpose/test_exlpose.json",
    "content": "{\n    \"info\": {\n        \"description\": \"CGLab of POSTECH\",\n        \"year\": 2022,\n        \"date_created\": \"2022/02\"\n    },\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\",\n                \"head\",\n                \"neck\"\n            ],\n            \"skeleton\": [\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    0\n                ],\n                [\n                    13,\n                    1\n                ],\n                [\n                    0,\n                    2\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    13,\n                    7\n                ],\n                [\n                    13,\n                    6\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    8,\n                    10\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"file_name\": \"imgs_0212_hwangridan_vid000020_exp400_dark_000052__gain_3.40_exposure_1250.png\",\n            \"id\": 0,\n            \"height\": 1198,\n            \"width\": 1919,\n            \"crowdIndex\": 0\n        },\n        {\n            \"file_name\": \"imgs_0212_hwangridan_vid000020_exp1200_dark_000052__gain_3.40_exposure_417.png\",\n            \"id\": 1,\n            \"height\": 1198,\n            \"width\": 1919,\n            \"crowdIndex\": 0\n        }\n    ],\n    \"annotations\": [\n        {\n            \"num_keypoints\": 14,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                1399.73,\n                332.68,\n                2,\n                1240.1,\n                316.9,\n                2,\n                1438.03,\n                460.36,\n                2,\n                1195.44,\n                428.44,\n                2,\n                1438.0,\n                576.8,\n                2,\n                1169.9,\n                517.82,\n                2,\n                1329.5,\n                581.66,\n                2,\n                1233.74,\n                568.89,\n                2,\n                1297.58,\n                741.26,\n                2,\n                1240.13,\n                734.88,\n                2,\n                1303.97,\n                894.48,\n                2,\n                1272.05,\n                894.48,\n                2,\n                1318.7,\n                190.7,\n                2,\n                1323.12,\n                294.38,\n                2\n            ],\n            \"image_id\": 0,\n            \"bbox\": [\n                1141.75,\n                169.89,\n                329.81999999999994,\n                816.16\n            ],\n            \"category_id\": 1,\n            \"id\": 0\n        },\n        {\n            \"num_keypoints\": 14,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                1198.02,\n                352.83,\n                2,\n                1077.6,\n                352.83,\n                2,\n                1214.45,\n                456.83,\n                2,\n                1046.3,\n                434.0,\n                2,\n                1196.6,\n                535.0,\n                2,\n                1018.5,\n                463.0,\n                2,\n                1159.8,\n                567.3,\n                2,\n                1086.1,\n                560.3,\n                2,\n                1115.92,\n                703.14,\n                2,\n                1077.6,\n                697.67,\n                2,\n                1141.7,\n                832.6,\n                2,\n                1080.6,\n                859.9,\n                2,\n                1137.81,\n                232.41,\n                2,\n                1137.81,\n                325.46,\n                2\n            ],\n            \"image_id\": 0,\n            \"bbox\": [\n                1029.62,\n                218.73,\n                177.08000000000015,\n                699.62\n            ],\n            \"category_id\": 1,\n            \"id\": 1\n        },\n        {\n            \"num_keypoints\": 14,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                743.06,\n                351.98,\n                2,\n                790.68,\n                357.27,\n                2,\n                730.72,\n                383.72,\n                2,\n                794.21,\n                394.31,\n                2,\n                734.24,\n                415.47,\n                2,\n                787.16,\n                415.47,\n                2,\n                746.59,\n                419.0,\n                2,\n                778.34,\n                419.0,\n                2,\n                748.35,\n                463.09,\n                2,\n                772.4,\n                465.8,\n                2,\n                744.9,\n                504.3,\n                2,\n                761.3,\n                504.9,\n                2,\n                773.7,\n                312.0,\n                2,\n                771.28,\n                337.87,\n                2\n            ],\n            \"image_id\": 1,\n            \"bbox\": [\n                732.07,\n                307.0,\n                72.13,\n                224.76\n            ],\n            \"category_id\": 1,\n            \"id\": 2\n        },\n        {\n            \"num_keypoints\": 12,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                674.3,\n                336.65,\n                2,\n                715.1,\n                338.5,\n                2,\n                656.88,\n                362.79,\n                2,\n                733.1,\n                368.7,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                680.84,\n                419.42,\n                2,\n                702.62,\n                421.6,\n                2,\n                689.55,\n                476.06,\n                2,\n                702.62,\n                478.23,\n                2,\n                687.37,\n                530.51,\n                2,\n                693.91,\n                534.87,\n                2,\n                709.8,\n                297.9,\n                2,\n                700.44,\n                321.4,\n                2\n            ],\n            \"image_id\": 1,\n            \"bbox\": [\n                650.96,\n                276.75,\n                117.55999999999995,\n                277.80999999999995\n            ],\n            \"category_id\": 1,\n            \"id\": 3\n        },\n        {\n            \"num_keypoints\": 14,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                620.44,\n                336.27,\n                2,\n                641.2,\n                337.86,\n                2,\n                614.85,\n                350.64,\n                2,\n                646.79,\n                354.63,\n                2,\n                612.46,\n                361.82,\n                2,\n                646.79,\n                365.81,\n                2,\n                622.84,\n                364.21,\n                2,\n                638.01,\n                366.61,\n                2,\n                623.64,\n                380.98,\n                2,\n                636.45,\n                382.97,\n                2,\n                626.03,\n                400.93,\n                2,\n                638.2,\n                399.9,\n                2,\n                632.42,\n                314.71,\n                2,\n                631.62,\n                329.88,\n                2\n            ],\n            \"image_id\": 1,\n            \"bbox\": [\n                605.38,\n                311.92,\n                42.690000000000055,\n                101.19\n            ],\n            \"category_id\": 1,\n            \"id\": 4\n        },\n        {\n            \"num_keypoints\": 14,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                806.08,\n                340.99,\n                2,\n                856.65,\n                342.8,\n                2,\n                795.25,\n                382.53,\n                2,\n                867.49,\n                386.14,\n                2,\n                793.44,\n                411.42,\n                2,\n                869.29,\n                418.64,\n                2,\n                815.5,\n                417.8,\n                2,\n                847.62,\n                416.84,\n                2,\n                812.8,\n                471.1,\n                2,\n                840.9,\n                473.2,\n                2,\n                809.7,\n                512.55,\n                2,\n                831.9,\n                513.5,\n                2,\n                833.3,\n                306.9,\n                2,\n                831.37,\n                324.74,\n                2\n            ],\n            \"image_id\": 1,\n            \"bbox\": [\n                794.29,\n                302.16,\n                82.19000000000005,\n                230.16000000000003\n            ],\n            \"category_id\": 1,\n            \"id\": 5\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/fld/test_fld.json",
    "content": "{\n    \"info\": {\n        \"description\": \"Fashion Landmark Detection (FLD) test set for full-body clothes generated by MMPose Team.\",\n        \"url\": \"http://mmlab.ie.cuhk.edu.hk/projects/DeepFashion/LandmarkDetection.html\",\n        \"version\": \"1.0\",\n        \"year\": \"2021\",\n        \"date_created\": \"2021/01/02\"\n    },\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"fashion\",\n            \"keypoints\": [\n                \"left collar\",\n                \"right collar\",\n                \"left sleeve\",\n                \"right sleeve\",\n                \"left waistline\",\n                \"right waistline\",\n                \"left hem\",\n                \"right hem\"\n            ],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 128,\n            \"file_name\": \"img_00000128.jpg\",\n            \"height\": 250,\n            \"width\": 200\n        },\n        {\n            \"id\": 132,\n            \"file_name\": \"img_00000132.jpg\",\n            \"height\": 250,\n            \"width\": 200\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                108.0,\n                33.0,\n                1.0,\n                121.0,\n                36.0,\n                1.0,\n                95.0,\n                65.0,\n                2.0,\n                128.0,\n                68.0,\n                1.0,\n                118.0,\n                79.0,\n                2.0,\n                114.0,\n                75.0,\n                1.0,\n                115.0,\n                150.0,\n                2.0,\n                112.0,\n                143.0,\n                1.0\n            ],\n            \"num_keypoints\": 8,\n            \"bbox\": [\n                88,\n                21,\n                48,\n                142\n            ],\n            \"iscrowd\": 0,\n            \"area\": 6816,\n            \"category_id\": 1,\n            \"id\": 128,\n            \"image_id\": 128\n        },\n        {\n            \"keypoints\": [\n                71.0,\n                19.0,\n                2.0,\n                127.0,\n                15.0,\n                2.0,\n                37.0,\n                80.0,\n                2.0,\n                162.0,\n                71.0,\n                2.0,\n                60.0,\n                112.0,\n                2.0,\n                145.0,\n                109.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                172.0,\n                235.0,\n                2.0\n            ],\n            \"num_keypoints\": 7,\n            \"bbox\": [\n                1,\n                1,\n                199,\n                249\n            ],\n            \"iscrowd\": 0,\n            \"area\": 49551,\n            \"category_id\": 1,\n            \"id\": 132,\n            \"image_id\": 132\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/fly/test_fly.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"animal\",\n            \"id\": 1,\n            \"name\": \"fly\",\n            \"keypoints\": [\n                \"head\",\n                \"eyeL\",\n                \"eyeR\",\n                \"neck\",\n                \"thorax\",\n                \"abdomen\",\n                \"forelegR1\",\n                \"forelegR2\",\n                \"forelegR3\",\n                \"forelegR4\",\n                \"midlegR1\",\n                \"midlegR2\",\n                \"midlegR3\",\n                \"midlegR4\",\n                \"hindlegR1\",\n                \"hindlegR2\",\n                \"hindlegR3\",\n                \"hindlegR4\",\n                \"forelegL1\",\n                \"forelegL2\",\n                \"forelegL3\",\n                \"forelegL4\",\n                \"midlegL1\",\n                \"midlegL2\",\n                \"midlegL3\",\n                \"midlegL4\",\n                \"hindlegL1\",\n                \"hindlegL2\",\n                \"hindlegL3\",\n                \"hindlegL4\",\n                \"wingL\",\n                \"wingR\"\n            ],\n            \"skeleton\": [\n                [\n                    2,\n                    1\n                ],\n                [\n                    3,\n                    1\n                ],\n                [\n                    4,\n                    1\n                ],\n                [\n                    5,\n                    4\n                ],\n                [\n                    6,\n                    5\n                ],\n                [\n                    8,\n                    7\n                ],\n                [\n                    9,\n                    8\n                ],\n                [\n                    10,\n                    9\n                ],\n                [\n                    12,\n                    11\n                ],\n                [\n                    13,\n                    12\n                ],\n                [\n                    14,\n                    13\n                ],\n                [\n                    16,\n                    15\n                ],\n                [\n                    17,\n                    16\n                ],\n                [\n                    18,\n                    17\n                ],\n                [\n                    20,\n                    19\n                ],\n                [\n                    21,\n                    20\n                ],\n                [\n                    22,\n                    21\n                ],\n                [\n                    24,\n                    23\n                ],\n                [\n                    25,\n                    24\n                ],\n                [\n                    26,\n                    25\n                ],\n                [\n                    28,\n                    27\n                ],\n                [\n                    29,\n                    28\n                ],\n                [\n                    30,\n                    29\n                ],\n                [\n                    31,\n                    4\n                ],\n                [\n                    32,\n                    4\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 1400,\n            \"file_name\": \"1400.jpg\",\n            \"height\": 192,\n            \"width\": 192\n        },\n        {\n            \"id\": 1450,\n            \"file_name\": \"1450.jpg\",\n            \"height\": 192,\n            \"width\": 192\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                146.0,\n                95.0,\n                2.0,\n                134.0,\n                80.0,\n                2.0,\n                136.0,\n                112.0,\n                2.0,\n                129.0,\n                97.0,\n                2.0,\n                99.0,\n                97.0,\n                2.0,\n                52.0,\n                95.0,\n                2.0,\n                123.0,\n                107.0,\n                2.0,\n                140.0,\n                114.0,\n                2.0,\n                158.0,\n                109.0,\n                2.0,\n                173.0,\n                109.0,\n                2.0,\n                110.0,\n                106.0,\n                2.0,\n                115.0,\n                127.0,\n                2.0,\n                133.0,\n                127.0,\n                2.0,\n                146.0,\n                138.0,\n                2.0,\n                96.0,\n                106.0,\n                2.0,\n                64.18991088867188,\n                120.96142578125,\n                2.0,\n                46.0,\n                126.0,\n                2.0,\n                34.0,\n                137.0,\n                2.0,\n                121.0,\n                86.0,\n                2.0,\n                147.0,\n                78.0,\n                2.0,\n                169.0,\n                79.0,\n                2.0,\n                184.0,\n                75.0,\n                2.0,\n                108.0,\n                86.0,\n                2.0,\n                103.0,\n                70.0,\n                2.0,\n                109.0,\n                40.0,\n                2.0,\n                114.0,\n                18.0,\n                2.0,\n                93.0,\n                87.0,\n                2.0,\n                82.0,\n                64.0,\n                2.0,\n                74.0,\n                46.0,\n                2.0,\n                67.0,\n                22.0,\n                2.0,\n                19.0,\n                86.0,\n                2.0,\n                23.0,\n                137.0,\n                2.0\n            ],\n            \"image_id\": 1400,\n            \"id\": 1400,\n            \"num_keypoints\": 32,\n            \"bbox\": [\n                19.0,\n                18.0,\n                166.0,\n                121.0\n            ],\n            \"iscrowd\": 0,\n            \"area\": 20086.0,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                147.43026733398438,\n                96.94955444335938,\n                2.0,\n                137.32937622070312,\n                79.7210693359375,\n                2.0,\n                138.43026733398438,\n                110.86053466796875,\n                2.0,\n                128.0,\n                96.0,\n                2.0,\n                98.0,\n                96.0,\n                2.0,\n                49.329376220703125,\n                94.13946533203125,\n                2.0,\n                122.37982177734375,\n                108.81008911132812,\n                2.0,\n                129.43026733398438,\n                114.18991088867188,\n                2.0,\n                138.65875244140625,\n                114.62017822265625,\n                2.0,\n                144.480712890625,\n                118.7596435546875,\n                2.0,\n                112.18991088867188,\n                109.18991088867188,\n                2.0,\n                105.557861328125,\n                118.43026733398438,\n                2.0,\n                95.67062377929688,\n                121.91098022460938,\n                2.0,\n                91.13946533203125,\n                136.10089111328125,\n                2.0,\n                91.46884155273438,\n                104.2017822265625,\n                2.0,\n                73.2403564453125,\n                117.43026733398438,\n                2.0,\n                57.37833786010742,\n                107.22997283935547,\n                2.0,\n                44.87240219116211,\n                112.96142578125,\n                2.0,\n                119.65875244140625,\n                84.81008911132812,\n                2.0,\n                123.78634643554688,\n                77.94955444335938,\n                2.0,\n                132.36795043945312,\n                76.58160400390625,\n                2.0,\n                140.0,\n                64.0,\n                2.0,\n                113.2789306640625,\n                83.29080200195312,\n                2.0,\n                100.08901977539062,\n                74.98812866210938,\n                2.0,\n                98.519287109375,\n                67.13946533203125,\n                2.0,\n                93.62017822265625,\n                55.810089111328125,\n                2.0,\n                94.22848510742188,\n                85.08901977539062,\n                2.0,\n                78.36795043945312,\n                69.2403564453125,\n                2.0,\n                71.60830688476562,\n                74.58160400390625,\n                2.0,\n                60.848663330078125,\n                68.67062377929688,\n                2.0,\n                16.0,\n                66.0,\n                2.0,\n                16.0,\n                126.0,\n                2.0\n            ],\n            \"image_id\": 1450,\n            \"id\": 1450,\n            \"num_keypoints\": 32,\n            \"bbox\": [\n                16.0,\n                55.810089111328125,\n                132.43026733398438,\n                81.29080200195312\n            ],\n            \"iscrowd\": 0,\n            \"area\": 10765.362640912645,\n            \"category_id\": 1\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/freihand/test_freihand.json",
    "content": "{\n    \"info\": {\n        \"description\": \"FreiHand\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/09/08\"\n    },\n    \"licenses\": \"\",\n    \"images\": [\n        {\n            \"file_name\": \"00017620.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 17620\n        },\n        {\n            \"file_name\": \"00050180.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 50180\n        },\n        {\n            \"file_name\": \"00082740.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 82740\n        },\n        {\n            \"file_name\": \"00115300.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 115300\n        },\n        {\n            \"file_name\": \"00000355.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 355\n        },\n        {\n            \"file_name\": \"00032915.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 32915\n        },\n        {\n            \"file_name\": \"00065475.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 65475\n        },\n        {\n            \"file_name\": \"00098035.jpg\",\n            \"height\": 224,\n            \"width\": 224,\n            \"id\": 98035\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox\": [\n                62,\n                82,\n                104,\n                63\n            ],\n            \"keypoints\": [\n                75.09007144965095,\n                114.79035385093314,\n                1,\n                88.01978404720953,\n                109.72359615889864,\n                1,\n                98.79950536639522,\n                109.05442666062974,\n                1,\n                110.16327936938085,\n                114.72375114390456,\n                1,\n                121.75826373686846,\n                122.01572654269421,\n                1,\n                126.92528942089982,\n                93.65489136216958,\n                1,\n                144.49316505581498,\n                94.71206260545628,\n                1,\n                152.3510241000562,\n                102.03474955900822,\n                1,\n                159.94413202793353,\n                111.6105502403288,\n                1,\n                136.5822887073417,\n                102.58162787991249,\n                1,\n                153.71181890922904,\n                105.7627322321249,\n                1,\n                158.23785994857087,\n                113.05793071695886,\n                1,\n                159.1827624858022,\n                122.12860754004963,\n                1,\n                131.78312266215684,\n                118.12603871987666,\n                1,\n                144.37435502719956,\n                122.97613121869307,\n                1,\n                144.12850082414747,\n                130.24233623490562,\n                1,\n                138.0058328373116,\n                135.03475933083362,\n                1,\n                123.6128526185571,\n                130.55957078894423,\n                1,\n                126.52617237783046,\n                135.2764317635352,\n                1,\n                123.26857656908544,\n                138.5518599403549,\n                1,\n                118.92147700299864,\n                140.34319120176468,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 17620,\n            \"image_id\": 17620,\n            \"segmentation\": [\n                [\n                    62,\n                    82,\n                    62,\n                    113.0,\n                    62,\n                    144,\n                    113.5,\n                    144,\n                    165,\n                    144,\n                    165,\n                    113.0,\n                    165,\n                    82,\n                    113.5,\n                    82\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 6552\n        },\n        {\n            \"bbox\": [\n                62,\n                82,\n                104,\n                63\n            ],\n            \"keypoints\": [\n                75.09007144965095,\n                114.79035385093314,\n                1,\n                88.01978404720953,\n                109.72359615889864,\n                1,\n                98.79950536639522,\n                109.05442666062974,\n                1,\n                110.16327936938085,\n                114.72375114390456,\n                1,\n                121.75826373686846,\n                122.01572654269421,\n                1,\n                126.92528942089982,\n                93.65489136216958,\n                1,\n                144.49316505581498,\n                94.71206260545628,\n                1,\n                152.3510241000562,\n                102.03474955900822,\n                1,\n                159.94413202793353,\n                111.6105502403288,\n                1,\n                136.5822887073417,\n                102.58162787991249,\n                1,\n                153.71181890922904,\n                105.7627322321249,\n                1,\n                158.23785994857087,\n                113.05793071695886,\n                1,\n                159.1827624858022,\n                122.12860754004963,\n                1,\n                131.78312266215684,\n                118.12603871987666,\n                1,\n                144.37435502719956,\n                122.97613121869307,\n                1,\n                144.12850082414747,\n                130.24233623490562,\n                1,\n                138.0058328373116,\n                135.03475933083362,\n                1,\n                123.6128526185571,\n                130.55957078894423,\n                1,\n                126.52617237783046,\n                135.2764317635352,\n                1,\n                123.26857656908544,\n                138.5518599403549,\n                1,\n                118.92147700299864,\n                140.34319120176468,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 50180,\n            \"image_id\": 50180,\n            \"segmentation\": [\n                [\n                    62,\n                    82,\n                    62,\n                    113.0,\n                    62,\n                    144,\n                    113.5,\n                    144,\n                    165,\n                    144,\n                    165,\n                    113.0,\n                    165,\n                    82,\n                    113.5,\n                    82\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 6552\n        },\n        {\n            \"bbox\": [\n                62,\n                82,\n                104,\n                63\n            ],\n            \"keypoints\": [\n                75.09007144965095,\n                114.79035385093314,\n                1,\n                88.01978404720953,\n                109.72359615889864,\n                1,\n                98.79950536639522,\n                109.05442666062974,\n                1,\n                110.16327936938085,\n                114.72375114390456,\n                1,\n                121.75826373686846,\n                122.01572654269421,\n                1,\n                126.92528942089982,\n                93.65489136216958,\n                1,\n                144.49316505581498,\n                94.71206260545628,\n                1,\n                152.3510241000562,\n                102.03474955900822,\n                1,\n                159.94413202793353,\n                111.6105502403288,\n                1,\n                136.5822887073417,\n                102.58162787991249,\n                1,\n                153.71181890922904,\n                105.7627322321249,\n                1,\n                158.23785994857087,\n                113.05793071695886,\n                1,\n                159.1827624858022,\n                122.12860754004963,\n                1,\n                131.78312266215684,\n                118.12603871987666,\n                1,\n                144.37435502719956,\n                122.97613121869307,\n                1,\n                144.12850082414747,\n                130.24233623490562,\n                1,\n                138.0058328373116,\n                135.03475933083362,\n                1,\n                123.6128526185571,\n                130.55957078894423,\n                1,\n                126.52617237783046,\n                135.2764317635352,\n                1,\n                123.26857656908544,\n                138.5518599403549,\n                1,\n                118.92147700299864,\n                140.34319120176468,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 82740,\n            \"image_id\": 82740,\n            \"segmentation\": [\n                [\n                    62,\n                    82,\n                    62,\n                    113.0,\n                    62,\n                    144,\n                    113.5,\n                    144,\n                    165,\n                    144,\n                    165,\n                    113.0,\n                    165,\n                    82,\n                    113.5,\n                    82\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 6552\n        },\n        {\n            \"bbox\": [\n                62,\n                82,\n                104,\n                63\n            ],\n            \"keypoints\": [\n                75.09007144965095,\n                114.79035385093314,\n                1,\n                88.01978404720953,\n                109.72359615889864,\n                1,\n                98.79950536639522,\n                109.05442666062974,\n                1,\n                110.16327936938085,\n                114.72375114390456,\n                1,\n                121.75826373686846,\n                122.01572654269421,\n                1,\n                126.92528942089982,\n                93.65489136216958,\n                1,\n                144.49316505581498,\n                94.71206260545628,\n                1,\n                152.3510241000562,\n                102.03474955900822,\n                1,\n                159.94413202793353,\n                111.6105502403288,\n                1,\n                136.5822887073417,\n                102.58162787991249,\n                1,\n                153.71181890922904,\n                105.7627322321249,\n                1,\n                158.23785994857087,\n                113.05793071695886,\n                1,\n                159.1827624858022,\n                122.12860754004963,\n                1,\n                131.78312266215684,\n                118.12603871987666,\n                1,\n                144.37435502719956,\n                122.97613121869307,\n                1,\n                144.12850082414747,\n                130.24233623490562,\n                1,\n                138.0058328373116,\n                135.03475933083362,\n                1,\n                123.6128526185571,\n                130.55957078894423,\n                1,\n                126.52617237783046,\n                135.2764317635352,\n                1,\n                123.26857656908544,\n                138.5518599403549,\n                1,\n                118.92147700299864,\n                140.34319120176468,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 115300,\n            \"image_id\": 115300,\n            \"segmentation\": [\n                [\n                    62,\n                    82,\n                    62,\n                    113.0,\n                    62,\n                    144,\n                    113.5,\n                    144,\n                    165,\n                    144,\n                    165,\n                    113.0,\n                    165,\n                    82,\n                    113.5,\n                    82\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 6552\n        },\n        {\n            \"bbox\": [\n                48,\n                81,\n                111,\n                73\n            ],\n            \"keypoints\": [\n                72.3863777322552,\n                118.66396006693559,\n                1,\n                94.24833834345874,\n                103.27814170253427,\n                1,\n                110.88311700561579,\n                95.90395591649063,\n                1,\n                126.4579609506009,\n                94.84947407598384,\n                1,\n                150.22575721471514,\n                90.20807463489129,\n                1,\n                101.58391664034835,\n                95.2364549099302,\n                1,\n                123.22957111339275,\n                99.32947575213643,\n                1,\n                139.48821317513102,\n                106.07413659069489,\n                1,\n                157.4869130814403,\n                114.05678966958038,\n                1,\n                102.72641676686953,\n                113.8112215401411,\n                1,\n                124.77010074005784,\n                117.9386487787441,\n                1,\n                138.88096072705787,\n                120.6828207743196,\n                1,\n                153.55692830019055,\n                122.08891417018086,\n                1,\n                101.79667808841384,\n                132.8686913780324,\n                1,\n                122.47431735923229,\n                131.3244981984239,\n                1,\n                136.86479076428296,\n                129.51781183394235,\n                1,\n                147.14149503293044,\n                124.23211514642553,\n                1,\n                103.99186381010902,\n                143.91615273519855,\n                1,\n                119.95852588057097,\n                140.94459694337758,\n                1,\n                130.47757563177504,\n                137.0559475661833,\n                1,\n                140.32638831475907,\n                128.94416862968552,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 355,\n            \"image_id\": 355,\n            \"segmentation\": [\n                [\n                    48,\n                    81,\n                    48,\n                    117.0,\n                    48,\n                    153,\n                    103.0,\n                    153,\n                    158,\n                    153,\n                    158,\n                    117.0,\n                    158,\n                    81,\n                    103.0,\n                    81\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 8103\n        },\n        {\n            \"bbox\": [\n                48,\n                81,\n                111,\n                73\n            ],\n            \"keypoints\": [\n                72.3863777322552,\n                118.66396006693559,\n                1,\n                94.24833834345874,\n                103.27814170253427,\n                1,\n                110.88311700561579,\n                95.90395591649063,\n                1,\n                126.4579609506009,\n                94.84947407598384,\n                1,\n                150.22575721471514,\n                90.20807463489129,\n                1,\n                101.58391664034835,\n                95.2364549099302,\n                1,\n                123.22957111339275,\n                99.32947575213643,\n                1,\n                139.48821317513102,\n                106.07413659069489,\n                1,\n                157.4869130814403,\n                114.05678966958038,\n                1,\n                102.72641676686953,\n                113.8112215401411,\n                1,\n                124.77010074005784,\n                117.9386487787441,\n                1,\n                138.88096072705787,\n                120.6828207743196,\n                1,\n                153.55692830019055,\n                122.08891417018086,\n                1,\n                101.79667808841384,\n                132.8686913780324,\n                1,\n                122.47431735923229,\n                131.3244981984239,\n                1,\n                136.86479076428296,\n                129.51781183394235,\n                1,\n                147.14149503293044,\n                124.23211514642553,\n                1,\n                103.99186381010902,\n                143.91615273519855,\n                1,\n                119.95852588057097,\n                140.94459694337758,\n                1,\n                130.47757563177504,\n                137.0559475661833,\n                1,\n                140.32638831475907,\n                128.94416862968552,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 32915,\n            \"image_id\": 32915,\n            \"segmentation\": [\n                [\n                    48,\n                    81,\n                    48,\n                    117.0,\n                    48,\n                    153,\n                    103.0,\n                    153,\n                    158,\n                    153,\n                    158,\n                    117.0,\n                    158,\n                    81,\n                    103.0,\n                    81\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 8103\n        },\n        {\n            \"bbox\": [\n                48,\n                81,\n                111,\n                73\n            ],\n            \"keypoints\": [\n                72.3863777322552,\n                118.66396006693559,\n                1,\n                94.24833834345874,\n                103.27814170253427,\n                1,\n                110.88311700561579,\n                95.90395591649063,\n                1,\n                126.4579609506009,\n                94.84947407598384,\n                1,\n                150.22575721471514,\n                90.20807463489129,\n                1,\n                101.58391664034835,\n                95.2364549099302,\n                1,\n                123.22957111339275,\n                99.32947575213643,\n                1,\n                139.48821317513102,\n                106.07413659069489,\n                1,\n                157.4869130814403,\n                114.05678966958038,\n                1,\n                102.72641676686953,\n                113.8112215401411,\n                1,\n                124.77010074005784,\n                117.9386487787441,\n                1,\n                138.88096072705787,\n                120.6828207743196,\n                1,\n                153.55692830019055,\n                122.08891417018086,\n                1,\n                101.79667808841384,\n                132.8686913780324,\n                1,\n                122.47431735923229,\n                131.3244981984239,\n                1,\n                136.86479076428296,\n                129.51781183394235,\n                1,\n                147.14149503293044,\n                124.23211514642553,\n                1,\n                103.99186381010902,\n                143.91615273519855,\n                1,\n                119.95852588057097,\n                140.94459694337758,\n                1,\n                130.47757563177504,\n                137.0559475661833,\n                1,\n                140.32638831475907,\n                128.94416862968552,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 65475,\n            \"image_id\": 65475,\n            \"segmentation\": [\n                [\n                    48,\n                    81,\n                    48,\n                    117.0,\n                    48,\n                    153,\n                    103.0,\n                    153,\n                    158,\n                    153,\n                    158,\n                    117.0,\n                    158,\n                    81,\n                    103.0,\n                    81\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 8103\n        },\n        {\n            \"bbox\": [\n                48,\n                81,\n                111,\n                73\n            ],\n            \"keypoints\": [\n                72.3863777322552,\n                118.66396006693559,\n                1,\n                94.24833834345874,\n                103.27814170253427,\n                1,\n                110.88311700561579,\n                95.90395591649063,\n                1,\n                126.4579609506009,\n                94.84947407598384,\n                1,\n                150.22575721471514,\n                90.20807463489129,\n                1,\n                101.58391664034835,\n                95.2364549099302,\n                1,\n                123.22957111339275,\n                99.32947575213643,\n                1,\n                139.48821317513102,\n                106.07413659069489,\n                1,\n                157.4869130814403,\n                114.05678966958038,\n                1,\n                102.72641676686953,\n                113.8112215401411,\n                1,\n                124.77010074005784,\n                117.9386487787441,\n                1,\n                138.88096072705787,\n                120.6828207743196,\n                1,\n                153.55692830019055,\n                122.08891417018086,\n                1,\n                101.79667808841384,\n                132.8686913780324,\n                1,\n                122.47431735923229,\n                131.3244981984239,\n                1,\n                136.86479076428296,\n                129.51781183394235,\n                1,\n                147.14149503293044,\n                124.23211514642553,\n                1,\n                103.99186381010902,\n                143.91615273519855,\n                1,\n                119.95852588057097,\n                140.94459694337758,\n                1,\n                130.47757563177504,\n                137.0559475661833,\n                1,\n                140.32638831475907,\n                128.94416862968552,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 98035,\n            \"image_id\": 98035,\n            \"segmentation\": [\n                [\n                    48,\n                    81,\n                    48,\n                    117.0,\n                    48,\n                    153,\n                    103.0,\n                    153,\n                    158,\n                    153,\n                    158,\n                    117.0,\n                    158,\n                    81,\n                    103.0,\n                    81\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 8103\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"hand\",\n            \"id\": 1,\n            \"name\": \"hand\",\n            \"keypoints\": [\n                \"wrist\",\n                \"thumb1\",\n                \"thumb2\",\n                \"thumb3\",\n                \"thumb4\",\n                \"forefinger1\",\n                \"forefinger2\",\n                \"forefinger3\",\n                \"forefinger4\",\n                \"middle_finger1\",\n                \"middle_finger2\",\n                \"middle_finger3\",\n                \"middle_finger4\",\n                \"ring_finger1\",\n                \"ring_finger2\",\n                \"ring_finger3\",\n                \"ring_finger4\",\n                \"pinky_finger1\",\n                \"pinky_finger2\",\n                \"pinky_finger3\",\n                \"pinky_finger4\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    1,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    8,\n                    9\n                ],\n                [\n                    1,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    1,\n                    14\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ],\n                [\n                    1,\n                    18\n                ],\n                [\n                    18,\n                    19\n                ],\n                [\n                    19,\n                    20\n                ],\n                [\n                    20,\n                    21\n                ]\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/h36m/h36m_coco.json",
    "content": "{\"categories\": [{\"supercategory\": \"person\", \"id\": 1, \"name\": \"person\", \"keypoints\": [\"root (pelvis)\", \"left_hip\", \"left_knee\", \"left_foot\", \"right_hip\", \"right_knee\", \"right_foot\", \"spine\", \"thorax\", \"neck_base\", \"head\", \"left_shoulder\", \"left_elbow\", \"left_wrist\", \"right_shoulder\", \"right_elbow\", \"right_wrist\"], \"skeleton\": [[0, 1], [1, 2], [2, 3], [0, 4], [4, 5], [5, 6], [0, 7], [7, 8], [8, 9], [9, 10], [8, 11], [11, 12], [12, 13], [8, 14], [14, 15], [15, 16]]}], \"images\": [{\"file_name\": \"S1_Directions_1.54138969_000001.jpg\", \"height\": 1002, \"width\": 1000, \"id\": 1}, {\"file_name\": \"S5_SittingDown.54138969_002061.jpg\", \"height\": 1002, \"width\": 1000, \"id\": 2}, {\"file_name\": \"S7_Greeting.55011271_000396.jpg\", \"height\": 1002, \"width\": 1000, \"id\": 3}, {\"file_name\": \"S8_WalkDog_1.55011271_000026.jpg\", \"height\": 1000, \"width\": 1000, \"id\": 4}], \"annotations\": [{\"id\": 1, \"category_id\": 1, \"image_id\": 1, \"iscrowd\": 0, \"bbox\": [264.9376922607422, 263.9518524169922, 403.4372680664062, 403.4372680664062], \"area\": 162761.6292648853, \"num_keypoints\": 17, \"keypoints\": [473.6835632324219, 444.9424133300781, 1.0, 500.99609375, 448.0298767089844, 1.0, 479.8392639160156, 530.78564453125, 1.0, 506.2183837890625, 622.56884765625, 1.0, 445.90008544921875, 441.81585693359375, 1.0, 456.1890563964844, 537.1580810546875, 1.0, 467.3092346191406, 633.7693481445312, 1.0, 488.1867370605469, 397.4340515136719, 1.0, 481.0284729003906, 340.3969421386719, 1.0, 478.5175476074219, 318.8080139160156, 1.0, 485.7689514160156, 297.5716247558594, 1.0, 454.0160827636719, 359.7595520019531, 1.0, 430.05877685546875, 415.7348937988281, 1.0, 412.9972229003906, 452.88665771484375, 1.0, 508.1343688964844, 356.49151611328125, 1.0, 520.3154296875, 413.3182678222656, 1.0, 515.4714965820312, 456.4298400878906, 1.0], \"keypoints_3d\": [-0.09167896467684544, 0.15440384287163678, 0.9072610776685424, 1.0, -0.22323561595581554, 0.16380534684958903, 0.8905342751070698, 1.0, -0.18847025361683212, 0.014076936796798556, 0.47516886851117857, 1.0, -0.2618404912559873, 0.1865526993157367, 0.06143897298248735, 1.0, 0.039877919019916996, 0.1450023222842871, 0.923987909780832, 1.0, -0.011675957824905936, 0.16089903522172655, 0.48439154540870843, 1.0, -0.051550255421339175, 0.2201460834524429, 0.035834453020362034, 1.0, -0.1323477693191084, 0.2157300269714426, 1.128839650641341, 1.0, -0.09716736817976912, 0.20234419005974758, 1.3831467408152163, 1.0, -0.11297070886154925, 0.1279692883955672, 1.4774457457591577, 1.0, -0.12003286832485882, 0.19096459762702, 1.5734000571086066, 1.0, 0.025895481465340486, 0.1923593164851738, 1.2961572344669199, 1.0, 0.10710585363549718, 0.11605013463811531, 1.040506322546096, 1.0, 0.12983817437702339, -0.04802507206683693, 0.8509481470388911, 1.0, -0.23036952033496494, 0.20317906334818225, 1.31196399244637, 1.0, -0.3154053270492714, 0.1645526934522641, 1.0491747593377458, 1.0, -0.35077130389737743, 0.04344200135666121, 0.8313473515463179, 1.0]}, {\"id\": 2, \"category_id\": 1, \"image_id\": 2, \"iscrowd\": 0, \"bbox\": [332.0779327392578, 473.9801391601562, 290.84520263671874, 290.84520263671874], \"area\": 84590.93189679399, \"num_keypoints\": 17, \"keypoints\": [504.7028503417969, 669.4107666015625, 1.0, 522.782958984375, 662.7621459960938, 1.0, 480.4589538574219, 573.927490234375, 1.0, 423.3778991699219, 652.5033569335938, 1.0, 485.9207763671875, 676.2982788085938, 1.0, 421.36602783203125, 601.1521606445312, 1.0, 356.3150329589844, 537.103759765625, 1.0, 550.3255004882812, 662.92822265625, 1.0, 589.5880126953125, 619.5794067382812, 1.0, 571.8924560546875, 595.6388549804688, 1.0, 598.68603515625, 587.589599609375, 1.0, 568.692138671875, 634.8923950195312, 1.0, 566.2520751953125, 701.7017211914062, 1.0, 511.3590087890625, 693.0339965820312, 1.0, 590.8366088867188, 616.5315551757812, 1.0, 591.3470458984375, 677.7720947265625, 1.0, 537.99951171875, 670.0408325195312, 1.0], \"keypoints_3d\": [0.18313216685808942, 0.8231641950309152, 0.07380225812969665, 1.0, 0.07554131210634596, 0.7715923776310918, 0.07325729992245722, 1.0, 0.16299457213112878, 0.5166802880563885, 0.4061248320474351, 1.0, 0.37620554042837284, 0.3923511353809239, 0.03891887911670544, 1.0, 0.2907222583652278, 0.8747356465826233, 0.07434721247102738, 1.0, 0.4538780403958691, 0.569630972616368, 0.3267755094977387, 1.0, 0.6251452690485007, 0.22271823762053078, 0.5414286139004776, 1.0, 0.06532934302457871, 1.001159255205049, 0.14274932444804866, 1.0, -0.04454656018317582, 1.1125556363460358, 0.342905193075141, 1.0, 0.009223497357126575, 1.0593620630585874, 0.43232439773437603, 1.0, -0.06893729069462973, 1.1318276163177168, 0.4755019124242963, 1.0, 0.08050700263825616, 1.1749652405144606, 0.31219388344281884, 1.0, 0.09351924672160816, 1.1979948900004627, 0.04893463071448689, 1.0, 0.23106479380471234, 0.9914363940751381, 0.03387224672098732, 1.0, -0.11785994971756253, 0.9928514533779302, 0.3151021783048409, 1.0, -0.13147583042309652, 0.9930890169754685, 0.05086920141700024, 1.0, 0.01277369696599484, 0.7909373534094728, 0.039085449376500936, 1.0]}, {\"id\": 3, \"category_id\": 1, \"image_id\": 3, \"iscrowd\": 0, \"bbox\": [170.23768615722656, 237.9368133544922, 390.06866455078125, 390.06866455078125], \"area\": 152153.5630644299, \"num_keypoints\": 17, \"keypoints\": [368.17724609375, 411.8692626953125, 1.0, 343.07647705078125, 416.750244140625, 1.0, 353.4913635253906, 517.2151489257812, 1.0, 331.39996337890625, 595.499755859375, 1.0, 392.517578125, 407.1534729003906, 1.0, 398.1598815917969, 503.8897399902344, 1.0, 385.0705261230469, 588.869140625, 1.0, 362.5104675292969, 362.4866027832031, 1.0, 366.911376953125, 306.0451354980469, 1.0, 367.71380615234375, 290.8963623046875, 1.0, 363.420654296875, 270.4425354003906, 1.0, 386.78955078125, 316.49371337890625, 1.0, 399.1440734863281, 365.17083740234375, 1.0, 353.6079406738281, 381.5865478515625, 1.0, 342.8076477050781, 318.3569641113281, 1.0, 342.71282958984375, 364.5867614746094, 1.0, 366.3352355957031, 365.45220947265625, 1.0], \"keypoints_3d\": [-0.6301309252725336, -0.6344397044573773, 0.9206111026673937, 1.0, -0.6882790651010198, -0.7567714273847876, 0.9098024882822011, 1.0, -0.605197492011686, -0.8176252814087839, 0.47316837750582774, 1.0, -0.766804548823675, -0.755787085309862, 0.07078524813387999, 1.0, -0.5719828361729054, -0.5121080882530507, 0.9314197076230729, 1.0, -0.5345570064294822, -0.5306570068297987, 0.4847542734658332, 1.0, -0.6210461702486163, -0.5067827322307146, 0.056033899109727114, 1.0, -0.6429426515493781, -0.6598479640784474, 1.1450644187666705, 1.0, -0.6072065974986334, -0.6803959533246831, 1.3971234240234174, 1.0, -0.5632315191812003, -0.7496893544569412, 1.466008916363522, 1.0, -0.6158132161954746, -0.6947954939152909, 1.5523081521170095, 1.0, -0.5777025823723583, -0.5535770126047312, 1.3464529557428198, 1.0, -0.5941298810296396, -0.4062447056281533, 1.1141629855017834, 1.0, -0.7189789681120353, -0.6100210358087663, 1.0505663930038809, 1.0, -0.6584496220675611, -0.8004586993700178, 1.3473324561682447, 1.0, -0.5530156532845365, -0.9799554689731194, 1.1667654450548033, 1.0, -0.3551462593488601, -1.1271667875753684, 1.1850106181886038, 1.0]}, {\"id\": 4, \"category_id\": 1, \"image_id\": 4, \"iscrowd\": 0, \"bbox\": [426.30922546386716, 216.63374938964844, 331.06431884765624, 331.06431884765624], \"area\": 109603.5832140626, \"num_keypoints\": 17, \"keypoints\": [580.787841796875, 370.0909729003906, 1.0, 556.613037109375, 367.4950866699219, 1.0, 555.3511962890625, 443.8667907714844, 1.0, 555.9659423828125, 512.378173828125, 1.0, 605.2581176757812, 372.7404479980469, 1.0, 602.246826171875, 450.21441650390625, 1.0, 602.3458251953125, 520.109375, 1.0, 582.8226318359375, 324.77984619140625, 1.0, 583.9212036132812, 280.9236755371094, 1.0, 580.145751953125, 264.3388671875, 1.0, 578.8571166992188, 244.22244262695312, 1.0, 613.561279296875, 281.4887390136719, 1.0, 663.5371704101562, 290.7607727050781, 1.0, 703.6394653320312, 289.19964599609375, 1.0, 559.4656372070312, 283.4862365722656, 1.0, 518.9984741210938, 293.1536560058594, 1.0, 480.0433044433594, 294.3433837890625, 1.0], \"keypoints_3d\": [0.19220202254147178, 1.189309849497537, 0.9821400313764364, 1.0, 0.04600865836610568, 1.183930600453361, 0.9906196026753151, 1.0, 0.04461316569282081, 1.1926418282628157, 0.538558154313876, 1.0, 0.031201472570259625, 1.2700369233139401, 0.10701519045307029, 1.0, 0.33839414669826073, 1.1946890529146854, 0.9736605320016554, 1.0, 0.333404073845164, 1.193994506607667, 0.5215423147214628, 1.0, 0.3263552025015575, 1.2632366584322137, 0.08846607677389562, 1.0, 0.19539291023644667, 1.19850396285414, 1.243174997496277, 1.0, 0.1993584536744768, 1.1888196540778582, 1.493981021453426, 1.0, 0.19903504684644213, 1.1133379968098671, 1.5878569145306556, 1.0, 0.18327226834497345, 1.1310217923883403, 1.700390853655377, 1.0, 0.3645112266620312, 1.2261360502087753, 1.4942545468581971, 1.0, 0.6478297588674613, 1.2677031012472364, 1.4489805530636382, 1.0, 0.8872620514452785, 1.2228143555784783, 1.4657017622368516, 1.0, 0.03701256277219178, 1.2330351409283296, 1.475094968744001, 1.0, -0.23806504890556468, 1.2985863358997447, 1.4112075036634106, 1.0, -0.4812982456964936, 1.2808732588306402, 1.399103701708569, 1.0]}]}"
  },
  {
    "path": "tests/data/halpe/test_halpe.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"license\": 4,\n            \"file_name\": \"000000000785.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000000785.jpg\",\n            \"height\": 425,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 21:22:42\",\n            \"flickr_url\": \"http://farm8.staticflickr.com/7015/6795644157_f019453ae7_z.jpg\",\n            \"id\": 785\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000040083.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000040083.jpg\",\n            \"height\": 333,\n            \"width\": 500,\n            \"date_captured\": \"2013-11-18 03:30:24\",\n            \"flickr_url\": \"http://farm1.staticflickr.com/116/254881838_e21c6d17b8_z.jpg\",\n            \"id\": 40083\n        },\n        {\n            \"license\": 1,\n            \"file_name\": \"000000196141.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000196141.jpg\",\n            \"height\": 429,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-22 22:37:15\",\n            \"flickr_url\": \"http://farm4.staticflickr.com/3310/3611902235_57d4ae496d_z.jpg\",\n            \"id\": 196141\n        },\n        {\n            \"license\": 3,\n            \"file_name\": \"000000197388.jpg\",\n            \"coco_url\": \"http://images.cocodataset.org/val2017/000000197388.jpg\",\n            \"height\": 392,\n            \"width\": 640,\n            \"date_captured\": \"2013-11-19 20:10:37\",\n            \"flickr_url\": \"http://farm9.staticflickr.com/8375/8507321836_5b8b13188f_z.jpg\",\n            \"id\": 197388\n        }\n    ],\n    \"annotations\": [\n        {\n            \"num_keypoints\": 17,\n            \"area\": 27789.11055,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                367,\n                81,\n                2,\n                374,\n                73,\n                2,\n                360,\n                75,\n                2,\n                386,\n                78,\n                2,\n                356,\n                81,\n                2,\n                399,\n                108,\n                2,\n                358,\n                129,\n                2,\n                433,\n                142,\n                2,\n                341,\n                159,\n                2,\n                449,\n                165,\n                2,\n                309,\n                178,\n                2,\n                424,\n                203,\n                2,\n                393,\n                214,\n                2,\n                429,\n                294,\n                2,\n                367,\n                273,\n                2,\n                466,\n                362,\n                2,\n                396,\n                341,\n                2,\n                370,\n                52,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                431,\n                378,\n                2,\n                364,\n                366,\n                2,\n                437,\n                383,\n                2,\n                358,\n                361,\n                2,\n                488,\n                372,\n                2,\n                414,\n                353,\n                2,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                382.0,\n                88.0,\n                0.0,\n                384.0,\n                85.0,\n                0.0,\n                386.0,\n                80.0,\n                0.0,\n                386.0,\n                76.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                367.0,\n                76.0,\n                0.0,\n                367.0,\n                79.0,\n                0.0,\n                367.0,\n                81.0,\n                0.0,\n                364.0,\n                83.0,\n                0.0,\n                366.0,\n                83.0,\n                0.0,\n                367.0,\n                84.0,\n                0.0,\n                369.0,\n                83.0,\n                0.0,\n                371.0,\n                83.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                363.0,\n                88.0,\n                0.0,\n                364.0,\n                86.0,\n                0.0,\n                366.0,\n                86.0,\n                0.0,\n                368.0,\n                86.0,\n                0.0,\n                369.0,\n                86.0,\n                0.0,\n                372.0,\n                86.0,\n                0.0,\n                376.0,\n                86.0,\n                0.0,\n                373.0,\n                89.0,\n                0.0,\n                371.0,\n                90.0,\n                0.0,\n                368.0,\n                90.0,\n                0.0,\n                366.0,\n                90.0,\n                0.0,\n                364.0,\n                89.0,\n                0.0,\n                364.0,\n                88.0,\n                0.0,\n                366.0,\n                87.0,\n                0.0,\n                368.0,\n                87.0,\n                0.0,\n                370.0,\n                87.0,\n                0.0,\n                375.0,\n                87.0,\n                0.0,\n                370.0,\n                89.0,\n                0.0,\n                368.0,\n                89.0,\n                0.0,\n                367.0,\n                89.0,\n                0.0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                435,\n                172,\n                2,\n                441,\n                178,\n                2,\n                442,\n                160,\n                2,\n                444,\n                170,\n                2,\n                444,\n                173,\n                2,\n                444,\n                178,\n                2,\n                447,\n                161,\n                2,\n                448,\n                170,\n                2,\n                448,\n                174,\n                2,\n                448,\n                180,\n                2,\n                453,\n                161,\n                2,\n                453,\n                170,\n                2,\n                452,\n                176,\n                2,\n                453,\n                181,\n                2,\n                459,\n                163,\n                2,\n                459,\n                171,\n                2,\n                458,\n                176,\n                2,\n                456,\n                182,\n                2,\n                306,\n                188,\n                2,\n                302,\n                181,\n                2,\n                298,\n                179,\n                2,\n                293,\n                183,\n                2,\n                290,\n                188,\n                2,\n                291,\n                174,\n                2,\n                285,\n                180,\n                2,\n                285,\n                185,\n                2,\n                290,\n                189,\n                2,\n                283,\n                177,\n                2,\n                282,\n                185,\n                2,\n                285,\n                190,\n                2,\n                290,\n                194,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 785,\n            \"bbox\": [\n                280.79,\n                44.73,\n                218.7,\n                346.68\n            ],\n            \"category_id\": 1,\n            \"id\": 442619\n        },\n        {\n            \"num_keypoints\": 14,\n            \"area\": 11025.219,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                99,\n                144,\n                2,\n                104,\n                141,\n                2,\n                96,\n                137,\n                2,\n                0,\n                0,\n                0,\n                78,\n                133,\n                2,\n                56,\n                161,\n                2,\n                81,\n                162,\n                2,\n                0,\n                0,\n                0,\n                103,\n                208,\n                2,\n                116,\n                204,\n                2,\n                0,\n                0,\n                0,\n                57,\n                246,\n                1,\n                82,\n                259,\n                1,\n                137,\n                219,\n                2,\n                138,\n                247,\n                2,\n                177,\n                256,\n                2,\n                158,\n                296,\n                1,\n                106,\n                120,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                207,\n                256,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                184,\n                272,\n                2,\n                0,\n                0,\n                0,\n                82,\n                130,\n                2,\n                80,\n                134,\n                2,\n                80,\n                139,\n                2,\n                80,\n                143,\n                2,\n                81,\n                147,\n                2,\n                82,\n                151,\n                2,\n                85,\n                154,\n                2,\n                88,\n                156,\n                2,\n                92,\n                158,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                94,\n                131,\n                2,\n                97,\n                131,\n                2,\n                98,\n                131,\n                2,\n                100,\n                133,\n                2,\n                101,\n                134,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                101,\n                139,\n                2,\n                100,\n                142,\n                2,\n                99,\n                144,\n                2,\n                98,\n                146,\n                2,\n                96,\n                147,\n                2,\n                97,\n                147,\n                2,\n                98,\n                148,\n                2,\n                99,\n                148,\n                2,\n                99,\n                148,\n                2,\n                93,\n                137,\n                2,\n                95,\n                136,\n                2,\n                97,\n                136,\n                2,\n                97,\n                138,\n                2,\n                96,\n                138,\n                2,\n                95,\n                138,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                89,\n                149,\n                2,\n                92,\n                149,\n                2,\n                95,\n                150,\n                2,\n                96,\n                150,\n                2,\n                97,\n                151,\n                2,\n                97,\n                152,\n                2,\n                97,\n                153,\n                2,\n                96,\n                153,\n                2,\n                96,\n                153,\n                2,\n                94,\n                153,\n                2,\n                93,\n                153,\n                2,\n                91,\n                151,\n                2,\n                90,\n                149,\n                2,\n                95,\n                150,\n                2,\n                96,\n                151,\n                2,\n                97,\n                151,\n                2,\n                97,\n                153,\n                2,\n                96,\n                153,\n                2,\n                94,\n                153,\n                2,\n                94,\n                152,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                118,\n                198,\n                2,\n                113,\n                197,\n                2,\n                109,\n                197,\n                2,\n                0,\n                0,\n                0,\n                118,\n                202,\n                2,\n                111,\n                201,\n                2,\n                106,\n                201,\n                2,\n                0,\n                0,\n                0,\n                117,\n                206,\n                2,\n                111,\n                205,\n                2,\n                108,\n                205,\n                2,\n                104,\n                203,\n                2,\n                116,\n                209,\n                2,\n                110,\n                209,\n                2,\n                107,\n                208,\n                2,\n                104,\n                206,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                38.08,\n                110.95,\n                174.71,\n                174.71\n            ],\n            \"category_id\": 1,\n            \"id\": 198196\n        },\n        {\n            \"num_keypoints\": 15,\n            \"area\": 10171.9544,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                343,\n                164,\n                2,\n                348,\n                160,\n                2,\n                340,\n                160,\n                2,\n                359,\n                163,\n                2,\n                332,\n                164,\n                2,\n                370,\n                189,\n                2,\n                334,\n                190,\n                2,\n                358,\n                236,\n                2,\n                348,\n                234,\n                2,\n                339,\n                270,\n                2,\n                330,\n                262,\n                2,\n                378,\n                262,\n                2,\n                343,\n                254,\n                2,\n                338,\n                280,\n                2,\n                283,\n                272,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                343,\n                143,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                332.3577977797564,\n                162.3496914134306,\n                2.0,\n                332.8988608117197,\n                165.6187214570887,\n                2.0,\n                333.63467933804384,\n                168.74800139782477,\n                2.0,\n                334.44826124602673,\n                171.62306650199142,\n                2.0,\n                335.45694729674096,\n                174.28548183067173,\n                2.0,\n                336.96602223714194,\n                176.06009946336934,\n                2.0,\n                339.1693873087565,\n                177.1661381740196,\n                2.0,\n                342.3967300714231,\n                178.20855305989585,\n                2.0,\n                346.46408769196154,\n                178.59725353764554,\n                2.0,\n                349.8700014600567,\n                177.54131727031634,\n                2.0,\n                352.5932256960401,\n                176.49227677887563,\n                2.0,\n                354.83135782877605,\n                175.44453310499006,\n                2.0,\n                356.3679296755323,\n                173.84137070599724,\n                2.0,\n                357.0065454221239,\n                171.40940037147672,\n                2.0,\n                357.534409347235,\n                168.54578019684436,\n                2.0,\n                357.7505070106656,\n                165.60219732546338,\n                2.0,\n                357.9972831576478,\n                162.53520322313494,\n                2.0,\n                334.98978292427813,\n                157.50515154670268,\n                2.0,\n                336.268189015108,\n                155.9984682569317,\n                2.0,\n                338.20047804888554,\n                155.20954518037684,\n                2.0,\n                339.8509974460976,\n                155.23421301748238,\n                2.0,\n                341.352836967917,\n                155.51378012264476,\n                2.0,\n                347.8451109044692,\n                155.22197044222963,\n                2.0,\n                349.3337133669386,\n                154.8293061798694,\n                2.0,\n                351.12965129777496,\n                154.6547285491345,\n                2.0,\n                353.1635732613358,\n                155.35309825224036,\n                2.0,\n                354.5697377522786,\n                156.92000379375384,\n                2.0,\n                344.713427734375,\n                159.3260030409869,\n                2.0,\n                344.74998306573605,\n                161.3128111596201,\n                2.0,\n                344.9170358096852,\n                163.04858473235487,\n                2.0,\n                344.9786475088082,\n                164.92118542241116,\n                2.0,\n                342.8344047097599,\n                167.29107576258042,\n                2.0,\n                343.73243414186965,\n                167.34131457758886,\n                2.0,\n                345.013671875,\n                167.60332833084405,\n                2.0,\n                345.8795548981311,\n                167.26825794893153,\n                2.0,\n                346.9039867326325,\n                167.04604671702666,\n                2.0,\n                337.4534390917011,\n                160.08626361921722,\n                2.0,\n                338.55446807262945,\n                159.17182970233992,\n                2.0,\n                340.002108854406,\n                159.25801017611636,\n                2.0,\n                341.49895665785846,\n                160.03499301087624,\n                2.0,\n                340.23350459080115,\n                160.5913200228822,\n                2.0,\n                338.5602124083276,\n                160.56629581825405,\n                2.0,\n                347.86048488242955,\n                159.88770386938955,\n                2.0,\n                349.3879867254519,\n                159.04122164857154,\n                2.0,\n                350.88049507889093,\n                158.927533976237,\n                2.0,\n                352.11961969113815,\n                159.93540822945388,\n                2.0,\n                350.849705954159,\n                160.3235902374866,\n                2.0,\n                349.1870314654182,\n                160.32544540704464,\n                2.0,\n                340.80742998310166,\n                172.02484322342218,\n                2.0,\n                342.28591649672563,\n                170.90962129480698,\n                2.0,\n                344.0934833302217,\n                170.10430531221277,\n                2.0,\n                345.1530334472656,\n                170.32844890519684,\n                2.0,\n                345.8770950616575,\n                170.0848247453278,\n                2.0,\n                347.8689553653493,\n                170.66106716978783,\n                2.0,\n                349.58350770239736,\n                171.62832581763175,\n                2.0,\n                348.09330994849114,\n                172.68533762015548,\n                2.0,\n                346.88256608551626,\n                173.17178057502298,\n                2.0,\n                345.6372661515778,\n                173.27078642003676,\n                2.0,\n                343.9210619159773,\n                173.28780972349878,\n                2.0,\n                342.63790340049593,\n                172.8480547736673,\n                2.0,\n                341.26428671444165,\n                171.89147685929842,\n                2.0,\n                343.8292683320887,\n                171.36270207423792,\n                2.0,\n                345.2252255308862,\n                171.2339672013825,\n                2.0,\n                346.42121037501914,\n                171.26879086961932,\n                2.0,\n                349.3406477385876,\n                171.65391995299098,\n                2.0,\n                346.50171341241577,\n                171.7467015883502,\n                2.0,\n                345.33072832892924,\n                171.8389222986558,\n                2.0,\n                343.8844602697036,\n                171.8535089231005,\n                2.0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                257.76,\n                139.06,\n                140.05,\n                154.21\n            ],\n            \"category_id\": 1,\n            \"id\": 230195\n        },\n        {\n            \"num_keypoints\": 0,\n            \"area\": 491.2669,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 40083,\n            \"bbox\": [\n                275.17,\n                126.5,\n                10.69,\n                68.26\n            ],\n            \"category_id\": 1,\n            \"id\": 1202706\n        },\n        {\n            \"num_keypoints\": 15,\n            \"area\": 17123.92955,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                297,\n                111,\n                2,\n                299,\n                106,\n                2,\n                0,\n                0,\n                0,\n                314,\n                108,\n                2,\n                0,\n                0,\n                0,\n                329,\n                141,\n                2,\n                346,\n                125,\n                2,\n                295,\n                164,\n                2,\n                323,\n                130,\n                2,\n                266,\n                155,\n                2,\n                279,\n                143,\n                2,\n                329,\n                225,\n                2,\n                331,\n                221,\n                2,\n                327,\n                298,\n                2,\n                283,\n                269,\n                2,\n                398,\n                327,\n                2,\n                288,\n                349,\n                2,\n                309,\n                78,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                399,\n                363,\n                2,\n                261,\n                361,\n                2,\n                402,\n                360,\n                2,\n                254,\n                359,\n                2,\n                408,\n                327,\n                2,\n                296,\n                358,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                308,\n                121,\n                2,\n                310,\n                119,\n                2,\n                311,\n                117,\n                2,\n                312,\n                115,\n                2,\n                313,\n                112,\n                2,\n                313,\n                110,\n                2,\n                314,\n                108,\n                2,\n                313,\n                105,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                298,\n                101,\n                2,\n                300,\n                101,\n                2,\n                302,\n                101,\n                2,\n                303,\n                101,\n                2,\n                305,\n                103,\n                2,\n                297,\n                104,\n                2,\n                297,\n                106,\n                2,\n                296,\n                109,\n                2,\n                296,\n                111,\n                2,\n                299,\n                111,\n                2,\n                300,\n                111,\n                2,\n                298,\n                112,\n                2,\n                299,\n                112,\n                2,\n                300,\n                112,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                298,\n                104,\n                2,\n                300,\n                103,\n                2,\n                302,\n                104,\n                2,\n                304,\n                106,\n                2,\n                302,\n                106,\n                2,\n                300,\n                106,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                264,\n                156,\n                2,\n                263,\n                147,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                253,\n                149,\n                2,\n                248,\n                147,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                253,\n                154,\n                2,\n                245,\n                155,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                251,\n                157,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                252,\n                160,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                276,\n                146,\n                2,\n                270,\n                150,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                268,\n                139,\n                2,\n                262,\n                145,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                247.76,\n                74.23,\n                169.67,\n                300.78\n            ],\n            \"category_id\": 1,\n            \"id\": 460541\n        },\n        {\n            \"num_keypoints\": 15,\n            \"area\": 2789.0208,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                589,\n                113,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                595,\n                112,\n                1,\n                584,\n                110,\n                2,\n                598,\n                123,\n                2,\n                579,\n                119,\n                2,\n                594,\n                141,\n                2,\n                570,\n                137,\n                2,\n                576,\n                135,\n                2,\n                585,\n                139,\n                2,\n                590,\n                157,\n                2,\n                574,\n                156,\n                2,\n                589,\n                192,\n                2,\n                565,\n                189,\n                1,\n                587,\n                222,\n                1,\n                557,\n                219,\n                1,\n                589,\n                102,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                584,\n                111,\n                2,\n                584,\n                112,\n                2,\n                584,\n                113,\n                2,\n                584,\n                115,\n                2,\n                585,\n                116,\n                2,\n                586,\n                117,\n                2,\n                587,\n                118,\n                2,\n                588,\n                119,\n                2,\n                589,\n                119,\n                2,\n                591,\n                119,\n                2,\n                592,\n                118,\n                2,\n                593,\n                117,\n                2,\n                593,\n                116,\n                2,\n                594,\n                115,\n                2,\n                594,\n                113,\n                2,\n                594,\n                112,\n                2,\n                594,\n                110,\n                2,\n                584,\n                108,\n                2,\n                585,\n                108,\n                2,\n                587,\n                108,\n                2,\n                588,\n                108,\n                2,\n                589,\n                108,\n                2,\n                591,\n                109,\n                2,\n                592,\n                108,\n                2,\n                593,\n                108,\n                2,\n                593,\n                109,\n                2,\n                594,\n                109,\n                2,\n                589,\n                110,\n                2,\n                589,\n                111,\n                2,\n                589,\n                112,\n                2,\n                589,\n                112,\n                2,\n                588,\n                113,\n                2,\n                589,\n                113,\n                2,\n                589,\n                113,\n                2,\n                590,\n                113,\n                2,\n                590,\n                113,\n                2,\n                585,\n                110,\n                2,\n                586,\n                109,\n                2,\n                587,\n                109,\n                2,\n                588,\n                110,\n                2,\n                587,\n                110,\n                2,\n                586,\n                110,\n                2,\n                590,\n                110,\n                2,\n                591,\n                109,\n                2,\n                592,\n                109,\n                2,\n                594,\n                110,\n                2,\n                592,\n                110,\n                2,\n                591,\n                110,\n                2,\n                587,\n                115,\n                2,\n                588,\n                115,\n                2,\n                589,\n                114,\n                2,\n                589,\n                114,\n                2,\n                590,\n                114,\n                2,\n                591,\n                115,\n                2,\n                591,\n                115,\n                2,\n                591,\n                115,\n                2,\n                590,\n                116,\n                2,\n                589,\n                116,\n                2,\n                589,\n                116,\n                2,\n                588,\n                116,\n                2,\n                587,\n                115,\n                2,\n                589,\n                115,\n                2,\n                589,\n                115,\n                2,\n                590,\n                115,\n                2,\n                591,\n                115,\n                2,\n                590,\n                116,\n                2,\n                589,\n                116,\n                2,\n                589,\n                116,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                555.57,\n                99.84,\n                48.32,\n                113.05\n            ],\n            \"category_id\": 1,\n            \"id\": 488308\n        },\n        {\n            \"num_keypoints\": 0,\n            \"area\": 285.7906,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                440.85,\n                73.13,\n                16.79,\n                32.45\n            ],\n            \"category_id\": 1,\n            \"id\": 508900\n        },\n        {\n            \"num_keypoints\": 12,\n            \"area\": 21608.94075,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                552,\n                234,\n                2,\n                0,\n                0,\n                0,\n                531,\n                262,\n                2,\n                600,\n                283,\n                2,\n                480,\n                260,\n                2,\n                622,\n                336,\n                2,\n                466,\n                242,\n                2,\n                0,\n                0,\n                0,\n                546,\n                365,\n                2,\n                592,\n                371,\n                2,\n                470,\n                351,\n                2,\n                551,\n                330,\n                2,\n                519,\n                394,\n                2,\n                589,\n                391,\n                2,\n                575,\n                211,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                498,\n                408,\n                2,\n                0,\n                0,\n                0,\n                534,\n                395,\n                2,\n                587,\n                401,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                453.77,\n                206.81,\n                177.23,\n                210.87\n            ],\n            \"category_id\": 1,\n            \"id\": 1717641\n        },\n        {\n            \"num_keypoints\": 17,\n            \"area\": 1870.14015,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                48,\n                79,\n                2,\n                50,\n                77,\n                2,\n                46,\n                77,\n                2,\n                54,\n                78,\n                2,\n                45,\n                78,\n                2,\n                57,\n                90,\n                2,\n                42,\n                90,\n                2,\n                63,\n                103,\n                2,\n                42,\n                105,\n                2,\n                56,\n                113,\n                2,\n                49,\n                112,\n                2,\n                55,\n                117,\n                2,\n                44,\n                117,\n                2,\n                55,\n                140,\n                2,\n                47,\n                140,\n                2,\n                56,\n                160,\n                2,\n                49,\n                159,\n                2,\n                47,\n                71,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 196141,\n            \"bbox\": [\n                36.12,\n                67.59,\n                30.41,\n                96.08\n            ],\n            \"category_id\": 1,\n            \"id\": 1724673\n        },\n        {\n            \"num_keypoints\": 16,\n            \"area\": 14250.29385,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                334,\n                135,\n                2,\n                340,\n                129,\n                2,\n                331,\n                129,\n                2,\n                0,\n                0,\n                0,\n                319,\n                123,\n                2,\n                340,\n                146,\n                2,\n                292,\n                133,\n                2,\n                353,\n                164,\n                2,\n                246,\n                144,\n                2,\n                354,\n                197,\n                2,\n                250,\n                185,\n                2,\n                293,\n                197,\n                2,\n                265,\n                187,\n                2,\n                305,\n                252,\n                2,\n                231,\n                254,\n                2,\n                293,\n                321,\n                2,\n                193,\n                297,\n                2,\n                333,\n                109,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                299,\n                332,\n                2,\n                185,\n                309,\n                2,\n                310,\n                333,\n                2,\n                176,\n                303,\n                2,\n                287,\n                328,\n                2,\n                198,\n                303,\n                2,\n                321,\n                127,\n                2,\n                321,\n                130,\n                2,\n                321,\n                133,\n                2,\n                321,\n                136,\n                2,\n                322,\n                138,\n                2,\n                324,\n                140,\n                2,\n                326,\n                142,\n                2,\n                329,\n                143,\n                2,\n                332,\n                143,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                328,\n                125,\n                2,\n                330,\n                125,\n                2,\n                331,\n                126,\n                2,\n                333,\n                126,\n                2,\n                335,\n                127,\n                2,\n                339,\n                128,\n                2,\n                340,\n                127,\n                2,\n                342,\n                126,\n                2,\n                343,\n                126,\n                2,\n                345,\n                125,\n                2,\n                336,\n                130,\n                2,\n                336,\n                132,\n                2,\n                337,\n                134,\n                2,\n                338,\n                136,\n                2,\n                334,\n                138,\n                2,\n                335,\n                138,\n                2,\n                337,\n                138,\n                2,\n                338,\n                137,\n                2,\n                339,\n                138,\n                2,\n                329,\n                127,\n                2,\n                331,\n                127,\n                2,\n                333,\n                128,\n                2,\n                334,\n                129,\n                2,\n                332,\n                130,\n                2,\n                331,\n                129,\n                2,\n                339,\n                129,\n                2,\n                341,\n                127,\n                2,\n                342,\n                127,\n                2,\n                344,\n                127,\n                2,\n                342,\n                129,\n                2,\n                341,\n                129,\n                2,\n                329,\n                139,\n                2,\n                331,\n                139,\n                2,\n                333,\n                139,\n                2,\n                334,\n                139,\n                2,\n                334,\n                139,\n                2,\n                335,\n                139,\n                2,\n                336,\n                139,\n                2,\n                335,\n                140,\n                2,\n                334,\n                141,\n                2,\n                333,\n                141,\n                2,\n                333,\n                141,\n                2,\n                331,\n                141,\n                2,\n                330,\n                139,\n                2,\n                333,\n                139,\n                2,\n                334,\n                140,\n                2,\n                334,\n                139,\n                2,\n                336,\n                140,\n                2,\n                334,\n                140,\n                2,\n                334,\n                141,\n                2,\n                331,\n                141,\n                2,\n                0,\n                0,\n                0,\n                349,\n                202,\n                2,\n                345,\n                203,\n                2,\n                342,\n                207,\n                2,\n                338,\n                212,\n                2,\n                349,\n                214,\n                2,\n                341,\n                219,\n                2,\n                336,\n                219,\n                2,\n                333,\n                218,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                250,\n                187,\n                2,\n                255,\n                188,\n                2,\n                260,\n                189,\n                2,\n                264,\n                194,\n                2,\n                268,\n                201,\n                2,\n                254,\n                193,\n                2,\n                256,\n                201,\n                2,\n                260,\n                205,\n                2,\n                0,\n                0,\n                0,\n                252,\n                193,\n                2,\n                252,\n                201,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                247,\n                193,\n                2,\n                248,\n                200,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                139.41,\n                102.25,\n                222.39,\n                241.57\n            ],\n            \"category_id\": 1,\n            \"id\": 437295\n        },\n        {\n            \"num_keypoints\": 16,\n            \"area\": 3404.869,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                345,\n                92,\n                2,\n                350,\n                87,\n                2,\n                341,\n                87,\n                2,\n                0,\n                0,\n                0,\n                330,\n                83,\n                2,\n                357,\n                94,\n                2,\n                316,\n                92,\n                2,\n                357,\n                104,\n                2,\n                291,\n                123,\n                1,\n                351,\n                133,\n                2,\n                281,\n                136,\n                1,\n                326,\n                131,\n                1,\n                305,\n                128,\n                1,\n                336,\n                152,\n                1,\n                303,\n                171,\n                1,\n                318,\n                206,\n                2,\n                294,\n                211,\n                1,\n                344,\n                70,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                320,\n                214,\n                2,\n                0,\n                0,\n                0,\n                328,\n                213,\n                2,\n                0,\n                0,\n                0,\n                313,\n                210,\n                2,\n                0,\n                0,\n                0,\n                333,\n                85,\n                2,\n                333,\n                87,\n                2,\n                333,\n                89,\n                2,\n                334,\n                92,\n                2,\n                335,\n                95,\n                2,\n                337,\n                97,\n                2,\n                338,\n                98,\n                2,\n                341,\n                99,\n                2,\n                343,\n                100,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                337,\n                86,\n                2,\n                339,\n                85,\n                2,\n                341,\n                85,\n                2,\n                342,\n                86,\n                2,\n                344,\n                87,\n                2,\n                348,\n                87,\n                2,\n                349,\n                86,\n                2,\n                350,\n                85,\n                2,\n                351,\n                85,\n                2,\n                353,\n                84,\n                2,\n                345,\n                88,\n                2,\n                345,\n                90,\n                2,\n                345,\n                92,\n                2,\n                345,\n                94,\n                2,\n                342,\n                94,\n                2,\n                343,\n                94,\n                2,\n                345,\n                95,\n                2,\n                346,\n                94,\n                2,\n                347,\n                94,\n                2,\n                337,\n                87,\n                2,\n                339,\n                86,\n                2,\n                341,\n                86,\n                2,\n                343,\n                88,\n                2,\n                341,\n                88,\n                2,\n                340,\n                88,\n                2,\n                348,\n                88,\n                2,\n                349,\n                86,\n                2,\n                351,\n                86,\n                2,\n                353,\n                86,\n                2,\n                351,\n                87,\n                2,\n                350,\n                88,\n                2,\n                340,\n                97,\n                2,\n                341,\n                96,\n                2,\n                343,\n                96,\n                2,\n                344,\n                96,\n                2,\n                345,\n                96,\n                2,\n                346,\n                96,\n                2,\n                346,\n                97,\n                2,\n                346,\n                98,\n                2,\n                345,\n                98,\n                2,\n                344,\n                98,\n                2,\n                343,\n                98,\n                2,\n                341,\n                98,\n                2,\n                341,\n                97,\n                2,\n                343,\n                96,\n                2,\n                344,\n                96,\n                2,\n                345,\n                96,\n                2,\n                346,\n                97,\n                2,\n                345,\n                98,\n                2,\n                344,\n                98,\n                2,\n                343,\n                98,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                287.17,\n                61.52,\n                74.88,\n                165.61\n            ],\n            \"category_id\": 1,\n            \"id\": 467657\n        },\n        {\n            \"num_keypoints\": 15,\n            \"area\": 8913.98475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                591,\n                78,\n                2,\n                594,\n                74,\n                2,\n                586,\n                74,\n                2,\n                0,\n                0,\n                0,\n                573,\n                70,\n                2,\n                598,\n                86,\n                2,\n                566,\n                93,\n                2,\n                626,\n                105,\n                2,\n                546,\n                126,\n                2,\n                0,\n                0,\n                0,\n                561,\n                150,\n                2,\n                582,\n                150,\n                2,\n                557,\n                154,\n                2,\n                606,\n                194,\n                2,\n                558,\n                209,\n                1,\n                591,\n                252,\n                2,\n                539,\n                262,\n                1,\n                587,\n                57,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                600,\n                262,\n                2,\n                0,\n                0,\n                0,\n                604,\n                261,\n                2,\n                0,\n                0,\n                0,\n                586,\n                262,\n                2,\n                0,\n                0,\n                0,\n                576.0,\n                73.0,\n                2.0,\n                577.0,\n                76.0,\n                2.0,\n                577.0,\n                78.0,\n                2.0,\n                577.0,\n                81.0,\n                2.0,\n                579.0,\n                83.0,\n                2.0,\n                580.0,\n                85.0,\n                2.0,\n                583.0,\n                86.0,\n                2.0,\n                585.0,\n                87.0,\n                2.0,\n                588.0,\n                88.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                590.0,\n                76.0,\n                0.0,\n                590.0,\n                77.0,\n                0.0,\n                591.0,\n                79.0,\n                0.0,\n                591.0,\n                80.0,\n                0.0,\n                587.0,\n                81.0,\n                0.0,\n                589.0,\n                81.0,\n                0.0,\n                591.0,\n                81.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                586.8761575736252,\n                83.61172634947533,\n                2.0,\n                588.9412473790786,\n                83.41106519512101,\n                2.0,\n                590.7724136651731,\n                82.86258592792586,\n                2.0,\n                591.6996507831648,\n                82.73443932626762,\n                2.0,\n                592.2456105550131,\n                82.31442081227021,\n                2.0,\n                593.6493129356235,\n                81.90362788181679,\n                2.0,\n                594.2114473230698,\n                81.26071885052849,\n                2.0,\n                594.1276526357614,\n                83.53407437193627,\n                2.0,\n                593.6044897939645,\n                84.44948682598039,\n                2.0,\n                592.6541667265051,\n                84.92630393832337,\n                2.0,\n                590.9756801829618,\n                85.08662594065947,\n                2.0,\n                589.348352170458,\n                84.76877788468903,\n                2.0,\n                587.2321394378064,\n                83.56702886843215,\n                2.0,\n                590.3445832495596,\n                83.57368678672641,\n                2.0,\n                591.8126301484949,\n                83.20736933689491,\n                2.0,\n                592.7565172980813,\n                82.68511125153186,\n                2.0,\n                594.1612270579618,\n                81.3825154024012,\n                2.0,\n                593.0988272872626,\n                83.2510259291705,\n                2.0,\n                592.1117610557407,\n                83.63720194498697,\n                2.0,\n                590.626023236443,\n                84.00301465801164,\n                2.0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                559,\n                151,\n                2,\n                565,\n                151,\n                2,\n                569,\n                153,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                568,\n                156,\n                2,\n                570,\n                162,\n                2,\n                571,\n                166,\n                2,\n                571,\n                169,\n                2,\n                565,\n                157,\n                2,\n                565,\n                162,\n                2,\n                566,\n                164,\n                2,\n                566,\n                166,\n                2,\n                561,\n                158,\n                2,\n                562,\n                161,\n                2,\n                563,\n                163,\n                2,\n                563,\n                165,\n                2,\n                558,\n                159,\n                2,\n                559,\n                162,\n                2,\n                560,\n                163,\n                2,\n                560,\n                164,\n                2\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                540.04,\n                48.81,\n                99.96,\n                223.36\n            ],\n            \"category_id\": 1,\n            \"id\": 531914\n        },\n        {\n            \"num_keypoints\": 16,\n            \"area\": 14267.20475,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                580,\n                211,\n                2,\n                586,\n                206,\n                2,\n                574,\n                204,\n                2,\n                0,\n                0,\n                0,\n                562,\n                198,\n                2,\n                584,\n                220,\n                2,\n                529,\n                215,\n                2,\n                599,\n                242,\n                2,\n                512,\n                260,\n                2,\n                619,\n                274,\n                2,\n                538,\n                285,\n                2,\n                537,\n                288,\n                2,\n                506,\n                277,\n                2,\n                562,\n                332,\n                2,\n                452,\n                332,\n                2,\n                550,\n                387,\n                1,\n                402,\n                371,\n                2,\n                582,\n                184,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                387,\n                389,\n                2,\n                0,\n                0,\n                0,\n                374,\n                383,\n                2,\n                0,\n                0,\n                0,\n                390,\n                365,\n                2,\n                559,\n                197,\n                2,\n                559,\n                202,\n                2,\n                559,\n                205,\n                2,\n                560,\n                209,\n                2,\n                561,\n                213,\n                2,\n                564,\n                217,\n                2,\n                567,\n                220,\n                2,\n                570,\n                223,\n                2,\n                573,\n                225,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                573,\n                201,\n                2,\n                575,\n                202,\n                2,\n                577,\n                203,\n                2,\n                579,\n                204,\n                2,\n                580,\n                206,\n                2,\n                584,\n                207,\n                2,\n                585,\n                206,\n                2,\n                587,\n                205,\n                2,\n                589,\n                205,\n                2,\n                590,\n                205,\n                2,\n                582,\n                207,\n                2,\n                582,\n                209,\n                2,\n                581,\n                212,\n                2,\n                581,\n                215,\n                2,\n                577,\n                214,\n                2,\n                578,\n                214,\n                2,\n                580,\n                216,\n                2,\n                581,\n                216,\n                2,\n                582,\n                216,\n                2,\n                573,\n                204,\n                2,\n                576,\n                204,\n                2,\n                578,\n                205,\n                2,\n                580,\n                207,\n                2,\n                578,\n                207,\n                2,\n                575,\n                206,\n                2,\n                584,\n                208,\n                2,\n                586,\n                207,\n                2,\n                588,\n                206,\n                2,\n                590,\n                207,\n                2,\n                588,\n                208,\n                2,\n                586,\n                209,\n                2,\n                571,\n                217,\n                2,\n                574,\n                217,\n                2,\n                576,\n                217,\n                2,\n                577,\n                217,\n                2,\n                577,\n                217,\n                2,\n                578,\n                217,\n                2,\n                579,\n                218,\n                2,\n                578,\n                219,\n                2,\n                577,\n                219,\n                2,\n                576,\n                220,\n                2,\n                575,\n                219,\n                2,\n                573,\n                218,\n                2,\n                572,\n                217,\n                2,\n                576,\n                217,\n                2,\n                576,\n                218,\n                2,\n                577,\n                218,\n                2,\n                579,\n                218,\n                2,\n                577,\n                219,\n                2,\n                576,\n                219,\n                2,\n                575,\n                219,\n                2,\n                622,\n                274,\n                2,\n                620,\n                281,\n                2,\n                620,\n                287,\n                2,\n                623,\n                292,\n                2,\n                627,\n                297,\n                2,\n                628,\n                284,\n                2,\n                635,\n                290,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                628,\n                281,\n                2,\n                631,\n                285,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                628,\n                278,\n                2,\n                632,\n                283,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                628,\n                277,\n                2,\n                631,\n                279,\n                2,\n                633,\n                282,\n                2,\n                0,\n                0,\n                0,\n                542,\n                286,\n                2,\n                551,\n                285,\n                2,\n                557,\n                289,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                557,\n                293,\n                2,\n                559,\n                301,\n                2,\n                559,\n                306,\n                2,\n                558,\n                312,\n                2,\n                551,\n                293,\n                2,\n                552,\n                302,\n                2,\n                552,\n                307,\n                2,\n                0,\n                0,\n                0,\n                546,\n                296,\n                2,\n                548,\n                302,\n                2,\n                549,\n                307,\n                2,\n                0,\n                0,\n                0,\n                543,\n                298,\n                2,\n                544,\n                303,\n                2,\n                545,\n                307,\n                2,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                372.58,\n                170.84,\n                266.63,\n                217.19\n            ],\n            \"category_id\": 1,\n            \"id\": 533949\n        },\n        {\n            \"num_keypoints\": 13,\n            \"area\": 8260.75085,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                36,\n                79,\n                2,\n                40,\n                74,\n                2,\n                31,\n                75,\n                2,\n                0,\n                0,\n                0,\n                19,\n                69,\n                2,\n                45,\n                77,\n                2,\n                2,\n                89,\n                2,\n                74,\n                99,\n                2,\n                0,\n                0,\n                0,\n                78,\n                92,\n                2,\n                0,\n                0,\n                0,\n                33,\n                149,\n                2,\n                7,\n                153,\n                2,\n                44,\n                196,\n                2,\n                2,\n                205,\n                2,\n                35,\n                245,\n                2,\n                0,\n                0,\n                0,\n                33,\n                54,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                41,\n                255,\n                2,\n                0,\n                0,\n                0,\n                48,\n                255,\n                2,\n                0,\n                0,\n                0,\n                29,\n                253,\n                2,\n                0,\n                0,\n                0,\n                22,\n                70,\n                2,\n                22,\n                73,\n                2,\n                23,\n                76,\n                2,\n                24,\n                78,\n                2,\n                25,\n                80,\n                2,\n                27,\n                82,\n                2,\n                29,\n                84,\n                2,\n                31,\n                85,\n                2,\n                34,\n                85,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                27,\n                72,\n                2,\n                29,\n                72,\n                2,\n                31,\n                72,\n                2,\n                33,\n                72,\n                2,\n                34,\n                73,\n                2,\n                38,\n                73,\n                2,\n                40,\n                72,\n                2,\n                41,\n                71,\n                2,\n                42,\n                71,\n                2,\n                43,\n                70,\n                2,\n                37,\n                75,\n                2,\n                37,\n                77,\n                2,\n                37,\n                78,\n                2,\n                37,\n                80,\n                2,\n                35,\n                80,\n                2,\n                37,\n                80,\n                2,\n                37,\n                80,\n                2,\n                38,\n                80,\n                2,\n                39,\n                80,\n                2,\n                28,\n                74,\n                2,\n                31,\n                73,\n                2,\n                33,\n                74,\n                2,\n                34,\n                75,\n                2,\n                32,\n                76,\n                2,\n                31,\n                75,\n                2,\n                39,\n                75,\n                2,\n                40,\n                73,\n                2,\n                41,\n                73,\n                2,\n                43,\n                72,\n                2,\n                42,\n                74,\n                2,\n                40,\n                75,\n                2,\n                30,\n                83,\n                2,\n                33,\n                82,\n                2,\n                35,\n                82,\n                2,\n                36,\n                82,\n                2,\n                37,\n                82,\n                2,\n                37,\n                82,\n                2,\n                38,\n                82,\n                2,\n                37,\n                83,\n                2,\n                37,\n                84,\n                2,\n                36,\n                84,\n                2,\n                35,\n                84,\n                2,\n                33,\n                84,\n                2,\n                31,\n                83,\n                2,\n                35,\n                83,\n                2,\n                36,\n                83,\n                2,\n                37,\n                83,\n                2,\n                38,\n                82,\n                2,\n                37,\n                83,\n                2,\n                36,\n                84,\n                2,\n                35,\n                84,\n                2,\n                0,\n                0,\n                0,\n                76,\n                89,\n                2,\n                74,\n                86,\n                2,\n                75,\n                81,\n                2,\n                77,\n                76,\n                2,\n                86,\n                80,\n                2,\n                82,\n                84,\n                2,\n                78,\n                85,\n                2,\n                76,\n                86,\n                2,\n                86,\n                83,\n                2,\n                82,\n                86,\n                2,\n                79,\n                87,\n                2,\n                76,\n                87,\n                2,\n                87,\n                84,\n                2,\n                84,\n                88,\n                2,\n                80,\n                88,\n                2,\n                78,\n                89,\n                2,\n                88,\n                87,\n                2,\n                85,\n                89,\n                2,\n                82,\n                90,\n                2,\n                79,\n                91,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 197388,\n            \"bbox\": [\n                0.5,\n                43.74,\n                90.1,\n                220.09\n            ],\n            \"category_id\": 1,\n            \"id\": 543117\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/horse10/test_horse10.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"animal\",\n            \"id\": 1,\n            \"name\": \"horse\",\n            \"keypoints\": [\n                \"Nose\",\n                \"Eye\",\n                \"Nearknee\",\n                \"Nearfrontfetlock\",\n                \"Nearfrontfoot\",\n                \"Offknee\",\n                \"Offfrontfetlock\",\n                \"Offfrontfoot\",\n                \"Shoulder\",\n                \"Midshoulder\",\n                \"Elbow\",\n                \"Girth\",\n                \"Wither\",\n                \"Nearhindhock\",\n                \"Nearhindfetlock\",\n                \"Nearhindfoot\",\n                \"Hip\",\n                \"Stifle\",\n                \"Offhindhock\",\n                \"Offhindfetlock\",\n                \"Offhindfoot\",\n                \"Ischium\"\n            ],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 100,\n            \"file_name\": \"0244.png\",\n            \"height\": 162,\n            \"width\": 288\n        },\n        {\n            \"id\": 500,\n            \"file_name\": \"0292.png\",\n            \"height\": 162,\n            \"width\": 288\n        },\n        {\n            \"id\": 900,\n            \"file_name\": \"0465.png\",\n            \"height\": 162,\n            \"width\": 288\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                126.0,\n                71.1,\n                2.0,\n                117.3,\n                56.4,\n                2.0,\n                90.0,\n                98.7,\n                2.0,\n                92.1,\n                112.8,\n                2.0,\n                98.7,\n                117.3,\n                2.0,\n                71.39999999999999,\n                102.89999999999999,\n                2.0,\n                63.599999999999994,\n                114.0,\n                2.0,\n                56.699999999999996,\n                120.0,\n                2.0,\n                80.1,\n                73.5,\n                2.0,\n                78.3,\n                63.0,\n                2.0,\n                67.5,\n                82.2,\n                2.0,\n                65.39999999999999,\n                82.8,\n                2.0,\n                72.0,\n                52.199999999999996,\n                2.0,\n                29.4,\n                97.5,\n                2.0,\n                27.0,\n                113.39999999999999,\n                2.0,\n                31.5,\n                120.6,\n                2.0,\n                36.3,\n                56.1,\n                2.0,\n                37.5,\n                75.6,\n                2.0,\n                38.4,\n                97.8,\n                2.0,\n                46.8,\n                112.8,\n                2.0,\n                51.0,\n                120.3,\n                2.0,\n                23.099999999999998,\n                63.599999999999994,\n                2.0\n            ],\n            \"image_id\": 100,\n            \"id\": 100,\n            \"num_keypoints\": 22,\n            \"bbox\": [\n                2,\n                38,\n                145,\n                97\n            ],\n            \"iscrowd\": 0,\n            \"area\": 14065,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                267.9,\n                67.8,\n                2.0,\n                265.5,\n                51.6,\n                2.0,\n                200.7,\n                94.8,\n                2.0,\n                190.79999999999998,\n                106.2,\n                2.0,\n                190.2,\n                114.6,\n                2.0,\n                229.5,\n                97.8,\n                2.0,\n                234.0,\n                111.6,\n                2.0,\n                240.6,\n                118.19999999999999,\n                2.0,\n                233.7,\n                69.0,\n                2.0,\n                226.5,\n                57.599999999999994,\n                2.0,\n                219.6,\n                79.5,\n                2.0,\n                213.0,\n                81.6,\n                2.0,\n                216.29999999999998,\n                48.3,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                182.1,\n                47.699999999999996,\n                2.0,\n                176.1,\n                72.0,\n                2.0,\n                162.0,\n                92.1,\n                2.0,\n                162.9,\n                111.89999999999999,\n                2.0,\n                167.4,\n                117.6,\n                2.0,\n                161.4,\n                54.9,\n                2.0\n            ],\n            \"image_id\": 500,\n            \"id\": 500,\n            \"num_keypoints\": 19,\n            \"bbox\": [\n                140,\n                33,\n                148,\n                100\n            ],\n            \"iscrowd\": 0,\n            \"area\": 14800,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                286.2,\n                118.8,\n                2.0,\n                282.0,\n                123.89999999999999,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                252.0,\n                102.89999999999999,\n                2.0,\n                261.9,\n                119.39999999999999,\n                2.0,\n                268.8,\n                128.1,\n                2.0,\n                263.09999999999997,\n                60.3,\n                2.0,\n                253.5,\n                84.0,\n                2.0,\n                236.7,\n                103.2,\n                2.0,\n                230.7,\n                121.19999999999999,\n                2.0,\n                234.6,\n                129.0,\n                2.0,\n                240.29999999999998,\n                67.5,\n                2.0\n            ],\n            \"image_id\": 900,\n            \"id\": 900,\n            \"num_keypoints\": 11,\n            \"bbox\": [\n                219,\n                46,\n                69,\n                97\n            ],\n            \"iscrowd\": 0,\n            \"area\": 6693,\n            \"category_id\": 1\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/humanart/test_humanart.json",
    "content": "{\n    \"info\": {\n        \"description\": \"For testing Human-Art dataset only.\",\n        \"year\": 2023,\n        \"date_created\": \"2023/06/12\"\n    },\n    \"images\": [\n        {\n            \"file_name\": \"HumanArt/images/2D_virtual_human/digital_art/000000001648.jpg\",\n            \"height\": 1750,\n            \"width\": 1280,\n            \"id\": 2000000001648,\n            \"page_url\": \"https://www.deviantart.com/endemilk/art/Autumn-Mood-857953165\",\n            \"image_url\": \"https://images-wixmp-ed30a86b8c4ca887773594c2.wixmp.com/f/cef0f0b2-832e-4f53-95c6-32f822f796ac/de6swwd-8ae0bba7-f879-43db-9f34-33d067ea3683.png/v1/fill/w_1280,h_1750,q_80,strp/autumn_mood_by_endemilk_de6swwd-fullview.jpg?token=eyJ0eXAiOiJKV1QiLCJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1cm46YXBwOjdlMGQxODg5ODIyNjQzNzNhNWYwZDQxNWVhMGQyNmUwIiwiaXNzIjoidXJuOmFwcDo3ZTBkMTg4OTgyMjY0MzczYTVmMGQ0MTVlYTBkMjZlMCIsIm9iaiI6W1t7ImhlaWdodCI6Ijw9MTc1MCIsInBhdGgiOiJcL2ZcL2NlZjBmMGIyLTgzMmUtNGY1My05NWM2LTMyZjgyMmY3OTZhY1wvZGU2c3d3ZC04YWUwYmJhNy1mODc5LTQzZGItOWYzNC0zM2QwNjdlYTM2ODMucG5nIiwid2lkdGgiOiI8PTEyODAifV1dLCJhdWQiOlsidXJuOnNlcnZpY2U6aW1hZ2Uub3BlcmF0aW9ucyJdfQ.u2McWPeJ1MDJokGkVa3qnJlYJFoldamHt9B6rGtSf9Y\",\n            \"picture_name\": \"Autumn Mood\",\n            \"author\": \"Endemilk\",\n            \"description\": \"digital_art, a girl in a white dress standing under a tree with autumn leaves\",\n            \"category\": \"digital art\"\n        },\n        {\n            \"file_name\": \"HumanArt/images/3D_virtual_human/garage_kits/000000005603.jpg\",\n            \"height\": 600,\n            \"width\": 700,\n            \"id\": 12000000005603,\n            \"page_url\": \"https://www.goodsmile.info/ja/product/6010/%E3%81%AD%E3%82%93%E3%81%A9%E3%82%8D%E3%81%84%E3%81%A9+%E3%82%A8%E3%83%83%E3%82%AF%E3%82%B9+%E3%83%95%E3%83%AB%E3%82%A2%E3%83%BC%E3%83%9E%E3%83%BC.html\",\n            \"image_url\": \"https://images.goodsmile.info/cgm/images/product/20161014/6010/41809/large/7b2d02a6a8a8d89af3a34f70942fdcc7.jpg\",\n            \"picture_name\": \"Irregular hunter who wants peace\",\n            \"author\": \"None\",\n            \"description\": \"garage_kits, a figurine of a character holding a gun\",\n            \"category\": \"garage kits\"\n        },\n        {\n            \"file_name\": \"HumanArt/images/real_human/acrobatics/000000000590.jpg\",\n            \"height\": 612,\n            \"width\": 589,\n            \"id\": 15000000000590,\n            \"page_url\": \"https://www.istockphoto.com/hk/search/2/image?phrase=acrobatics&page=\",\n            \"image_url\": \"https://media.istockphoto.com/photos/women-couple-of-dancers-acrobats-picture-id494524123?k=20&m=494524123&s=612x612&w=0&h=Mt-1N5a2aCS3n6spX_Fw8JRmf3zAO2VnvB4T0mGCN4s=\",\n            \"picture_name\": \"None\",\n            \"author\": \"None\",\n            \"description\": \"acrobatics, two women in green and white performing acrobatics\",\n            \"category\": \"acrobatics\"\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                715.4305,\n                970.0197,\n                2,\n                698.8416,\n                942.6802,\n                2,\n                679.6984,\n                941.7231,\n                2,\n                644.7338,\n                948.259,\n                2,\n                611.9386,\n                946.367,\n                2,\n                518.0118,\n                1122.8295,\n                2,\n                656.3654,\n                1106.6009,\n                2,\n                529.2618,\n                1364.4753,\n                2,\n                589.2787,\n                1375.8299,\n                2,\n                687.9009,\n                1377.9864,\n                2,\n                744.6238,\n                1409.0027,\n                2,\n                557.0198,\n                1505.5454,\n                2,\n                680.6947,\n                1499.8197,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"keypoints_21\": [\n                715.4305,\n                970.0197,\n                2,\n                698.8416,\n                942.6802,\n                2,\n                679.6984,\n                941.7231,\n                2,\n                644.7338,\n                948.259,\n                2,\n                611.9386,\n                946.367,\n                2,\n                518.0118,\n                1122.8295,\n                2,\n                656.3654,\n                1106.6009,\n                2,\n                529.2618,\n                1364.4753,\n                2,\n                589.2787,\n                1375.8299,\n                2,\n                687.9009,\n                1377.9864,\n                2,\n                744.6238,\n                1409.0027,\n                2,\n                557.0198,\n                1505.5454,\n                2,\n                680.6947,\n                1499.8197,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                711.6695,\n                1391.3213,\n                2,\n                764.9766,\n                1420.8272,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"self_contact\": [],\n            \"num_keypoints\": 13,\n            \"num_keypoints_21\": 15,\n            \"iscrowd\": 0,\n            \"image_id\": 2000000001648,\n            \"area\": 288736.90076053096,\n            \"bbox\": [\n                468.61884,\n                828.9586400000001,\n                355.629312,\n                811.9041119999999\n            ],\n            \"category_id\": 1,\n            \"id\": 2000000006746,\n            \"annotator\": 67037\n        },\n        {\n            \"keypoints\": [\n                313.972,\n                252.666,\n                2,\n                333.8015,\n                228.7117,\n                2,\n                272.5658,\n                207.7711,\n                2,\n                342.3681,\n                227.4426,\n                2,\n                200.6833,\n                204.2117,\n                2,\n                0,\n                0,\n                0,\n                251.3643,\n                302.7895,\n                2,\n                0,\n                0,\n                0,\n                275.9871,\n                312.5822,\n                2,\n                0,\n                0,\n                0,\n                292.1347,\n                313.8643,\n                2,\n                304.7952,\n                403.3614,\n                2,\n                286.269,\n                402.473,\n                2,\n                330.7358,\n                441.4618,\n                2,\n                260.2096,\n                441.0565,\n                2,\n                321.9826,\n                495.339,\n                2,\n                222.4324,\n                493.9369,\n                2\n            ],\n            \"keypoints_21\": [\n                313.972,\n                252.666,\n                2,\n                333.8015,\n                228.7117,\n                2,\n                272.5658,\n                207.7711,\n                2,\n                342.3681,\n                227.4426,\n                2,\n                200.6833,\n                204.2117,\n                2,\n                0,\n                0,\n                0,\n                251.3643,\n                302.7895,\n                2,\n                0,\n                0,\n                0,\n                275.9871,\n                312.5822,\n                2,\n                0,\n                0,\n                0,\n                292.1347,\n                313.8643,\n                2,\n                304.7952,\n                403.3614,\n                2,\n                286.269,\n                402.473,\n                2,\n                330.7358,\n                441.4618,\n                2,\n                260.2096,\n                441.0565,\n                2,\n                321.9826,\n                495.339,\n                2,\n                222.4324,\n                493.9369,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                398.5162,\n                556.9002,\n                2,\n                212.5182,\n                563.4001,\n                2\n            ],\n            \"self_contact\": [],\n            \"num_keypoints\": 14,\n            \"num_keypoints_21\": 16,\n            \"iscrowd\": 0,\n            \"image_id\": 12000000005603,\n            \"area\": 132932.1180077885,\n            \"bbox\": [\n                161.11672,\n                132.37402000000003,\n                284.87937600000004,\n                466.62597999999997\n            ],\n            \"category_id\": 1,\n            \"id\": 12000000076660,\n            \"annotator\": 66991\n        },\n        {\n            \"keypoints\": [\n                319.2161,\n                546.3765,\n                2,\n                317.6563,\n                536.4973,\n                2,\n                315.5024,\n                536.8374,\n                2,\n                295.7777,\n                539.4827,\n                2,\n                290.2372,\n                538.9287,\n                2,\n                260.5583,\n                539.1473,\n                2,\n                252.989,\n                559.7042,\n                2,\n                222.0985,\n                494.5581,\n                2,\n                204.3461,\n                496.7641,\n                2,\n                229.7767,\n                555.3691,\n                2,\n                203.9402,\n                564.1676,\n                2,\n                254.6329,\n                440.3163,\n                2,\n                252.7878,\n                421.1483,\n                2,\n                351.9561,\n                400.9315,\n                2,\n                368.0247,\n                412.8534,\n                2,\n                347.6211,\n                500.3006,\n                2,\n                367.0544,\n                542.1705,\n                2\n            ],\n            \"keypoints_21\": [\n                319.2161,\n                546.3765,\n                2,\n                317.6563,\n                536.4973,\n                2,\n                315.5024,\n                536.8374,\n                2,\n                295.7777,\n                539.4827,\n                2,\n                290.2372,\n                538.9287,\n                2,\n                260.5583,\n                539.1473,\n                2,\n                252.989,\n                559.7042,\n                2,\n                222.0985,\n                494.5581,\n                2,\n                204.3461,\n                496.7641,\n                2,\n                229.7767,\n                555.3691,\n                2,\n                203.9402,\n                564.1676,\n                2,\n                254.6329,\n                440.3163,\n                2,\n                252.7878,\n                421.1483,\n                2,\n                351.9561,\n                400.9315,\n                2,\n                368.0247,\n                412.8534,\n                2,\n                347.6211,\n                500.3006,\n                2,\n                367.0544,\n                542.1705,\n                2,\n                248.5114,\n                559.976,\n                2,\n                253.5939,\n                575.1541,\n                2,\n                357.1097,\n                548.0375,\n                2,\n                379.7624,\n                573.8666,\n                2\n            ],\n            \"self_contact\": [\n                [\n                    245.1376,\n                    570.4875\n                ]\n            ],\n            \"num_keypoints\": 17,\n            \"num_keypoints_21\": 21,\n            \"iscrowd\": 0,\n            \"image_id\": 15000000000590,\n            \"area\": 62008.05021846336,\n            \"bbox\": [\n                168.77576,\n                366.08698000000004,\n                253.18396800000005,\n                244.91301999999996\n            ],\n            \"category_id\": 1,\n            \"id\": 15000000092347,\n            \"annotator\": 66705\n        },\n        {\n            \"keypoints\": [\n                233.1389,\n                406.6037,\n                2,\n                243.5176,\n                397.9166,\n                2,\n                243.0948,\n                396.1787,\n                2,\n                235.8086,\n                380.0257,\n                2,\n                233.4394,\n                371.1951,\n                2,\n                200.7799,\n                367.2566,\n                2,\n                222.3385,\n                339.9251,\n                2,\n                218.5684,\n                431.6162,\n                2,\n                216.3631,\n                433.129,\n                2,\n                238.3363,\n                495.4999,\n                2,\n                240.2118,\n                500.6888,\n                2,\n                253.2291,\n                222.9011,\n                2,\n                270.424,\n                250.1,\n                2,\n                192.7242,\n                138.9058,\n                2,\n                372.9364,\n                324.4092,\n                2,\n                148.4319,\n                79.9982,\n                2,\n                444.6949,\n                407.9868,\n                2\n            ],\n            \"keypoints_21\": [\n                233.1389,\n                406.6037,\n                2,\n                243.5176,\n                397.9166,\n                2,\n                243.0948,\n                396.1787,\n                2,\n                235.8086,\n                380.0257,\n                2,\n                233.4394,\n                371.1951,\n                2,\n                200.7799,\n                367.2566,\n                2,\n                222.3385,\n                339.9251,\n                2,\n                218.5684,\n                431.6162,\n                2,\n                216.3631,\n                433.129,\n                2,\n                238.3363,\n                495.4999,\n                2,\n                240.2118,\n                500.6888,\n                2,\n                253.2291,\n                222.9011,\n                2,\n                270.424,\n                250.1,\n                2,\n                192.7242,\n                138.9058,\n                2,\n                372.9364,\n                324.4092,\n                2,\n                148.4319,\n                79.9982,\n                2,\n                444.6949,\n                407.9868,\n                2,\n                245.196,\n                517.5082,\n                2,\n                238.3205,\n                541.3807,\n                2,\n                113.9739,\n                40.4267,\n                2,\n                501.7295,\n                448.3217,\n                2\n            ],\n            \"self_contact\": [],\n            \"num_keypoints\": 17,\n            \"num_keypoints_21\": 21,\n            \"iscrowd\": 0,\n            \"image_id\": 15000000000590,\n            \"area\": 337013.68142,\n            \"bbox\": [\n                36.42278,\n                0,\n                551.57722,\n                611\n            ],\n            \"category_id\": 1,\n            \"id\": 15000000092348,\n            \"annotator\": 66705\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"left_eye\",\n                \"right_eye\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\",\n                \"left_finger\",\n                \"right_finger\",\n                \"left_toe\",\n                \"right_toe\"\n            ],\n            \"skeleton\": [\n                [\n                    20,\n                    16\n                ],\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    21,\n                    17\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    10,\n                    18\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    11,\n                    19\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/humanart/test_humanart_det_AP_H_56.json",
    "content": "[\n    {\n        \"bbox\": [\n            411.55450439453125,\n            773.5175170898438,\n            925.8963623046875,\n            1736.38623046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 2000000001648,\n        \"score\": 0.9018925428390503\n    },\n    {\n        \"bbox\": [\n            23.97265625,\n            19.622175216674805,\n            1121.828369140625,\n            1269.2109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 2000000001648,\n        \"score\": 0.4558742344379425\n    },\n    {\n        \"bbox\": [\n            82.678466796875,\n            475.8934020996094,\n            1093.4742431640625,\n            1717.331298828125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 2000000001648,\n        \"score\": 0.37606894969940186\n    },\n    {\n        \"bbox\": [\n            393.59222412109375,\n            125.75264739990234,\n            895.0135498046875,\n            1201.154296875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 2000000001648,\n        \"score\": 0.08204865455627441\n    },\n    {\n        \"bbox\": [\n            75.03559875488281,\n            52.54023742675781,\n            759.2489624023438,\n            974.7556762695312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 2000000001648,\n        \"score\": 0.07333727180957794\n    },\n    {\n        \"bbox\": [\n            197.08047485351562,\n            139.95877075195312,\n            402.2601318359375,\n            591.4268188476562\n        ],\n        \"category_id\": 1,\n        \"image_id\": 12000000005603,\n        \"score\": 0.9604519009590149\n    },\n    {\n        \"bbox\": [\n            67.07928466796875,\n            132.88070678710938,\n            535.9130249023438,\n            600.0\n        ],\n        \"category_id\": 1,\n        \"image_id\": 12000000005603,\n        \"score\": 0.10827567428350449\n    },\n    {\n        \"bbox\": [\n            21.64974594116211,\n            0.0,\n            564.9321899414062,\n            592.8584594726562\n        ],\n        \"category_id\": 1,\n        \"image_id\": 15000000000590,\n        \"score\": 0.9986042380332947\n    },\n    {\n        \"bbox\": [\n            158.69786071777344,\n            249.30482482910156,\n            410.9751281738281,\n            608.938720703125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 15000000000590,\n        \"score\": 0.7594972252845764\n    },\n    {\n        \"bbox\": [\n            184.25045776367188,\n            370.5571594238281,\n            361.1768493652344,\n            601.1585083007812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 15000000000590,\n        \"score\": 0.26641231775283813\n    },\n    {\n        \"bbox\": [\n            129.24253845214844,\n            251.26560974121094,\n            552.2449951171875,\n            517.3319702148438\n        ],\n        \"category_id\": 1,\n        \"image_id\": 15000000000590,\n        \"score\": 0.05408962443470955\n    },\n    {\n        \"bbox\": [\n            168.77576,\n            366.08698000000004,\n            421.95972800000004,\n            611.0\n        ],\n        \"category_id\": 1,\n        \"image_id\": 15000000000590,\n        \"score\": 0.6465661513194214\n    },\n    {\n        \"bbox\": [\n            36.42278,\n            0.0,\n            588.0,\n            611.0\n        ],\n        \"category_id\": 1,\n        \"image_id\": 15000000000590,\n        \"score\": 0.844070429325392\n    }\n]"
  },
  {
    "path": "tests/data/interhand2.6m/test_interhand2.6m_camera.json",
    "content": "{\n    \"3\": {\n        \"campos\": {\n            \"400026\": [\n                -415.1940002441406,\n                132.24954223632812,\n                59.5650749206543\n            ]\n        },\n        \"camrot\": {\n            \"400026\": [\n                [\n                    0.9201921224594116,\n                    -0.012140202336013317,\n                    -0.39127883315086365\n                ],\n                [\n                    0.06150508299469948,\n                    0.9915890097618103,\n                    0.11387889832258224\n                ],\n                [\n                    0.38660526275634766,\n                    -0.1288560926914215,\n                    0.9131990671157837\n                ]\n            ]\n        },\n        \"focal\": {\n            \"400026\": [\n                1261.5291748046875,\n                1261.6845703125\n            ]\n        },\n        \"princpt\": {\n            \"400026\": [\n                155.8163604736328,\n                258.8305969238281\n            ]\n        }\n    },\n    \"2\": {\n        \"campos\": {\n            \"400012\": [\n                606.0524291992188,\n                -174.7548828125,\n                163.86656188964844\n            ]\n        },\n        \"camrot\": {\n            \"400012\": [\n                [\n                    0.82091224193573,\n                    0.05194839835166931,\n                    0.5686866044998169\n                ],\n                [\n                    0.05824033170938492,\n                    0.9830448031425476,\n                    -0.17387045919895172\n                ],\n                [\n                    -0.5680767297744751,\n                    0.17585287988185883,\n                    0.8039680123329163\n                ]\n            ]\n        },\n        \"focal\": {\n            \"400012\": [\n                1270.7069091796875,\n                1270.5194091796875\n            ]\n        },\n        \"princpt\": {\n            \"400012\": [\n                196.347412109375,\n                240.42515563964844\n            ]\n        }\n    },\n    \"7\": {\n        \"campos\": {\n            \"410053\": [\n                973.9876098632812,\n                -151.85047912597656,\n                576.7235107421875\n            ]\n        },\n        \"camrot\": {\n            \"410053\": [\n                [\n                    0.42785099148750305,\n                    0.07326933741569519,\n                    0.900874674320221\n                ],\n                [\n                    0.10334496945142746,\n                    0.9862067103385925,\n                    -0.12929096817970276\n                ],\n                [\n                    -0.8979216814041138,\n                    0.148418128490448,\n                    0.41437748074531555\n                ]\n            ]\n        },\n        \"focal\": {\n            \"410053\": [\n                1272.947021484375,\n                1272.957275390625\n            ]\n        },\n        \"princpt\": {\n            \"410053\": [\n                187.24343872070312,\n                243.6494903564453\n            ]\n        }\n    },\n    \"4\": {\n        \"campos\": {\n            \"410028\": [\n                224.87350463867188,\n                144.3102569580078,\n                -8.186153411865234\n            ]\n        },\n        \"camrot\": {\n            \"410028\": [\n                [\n                    0.9784372448921204,\n                    0.024140462279319763,\n                    0.2051287442445755\n                ],\n                [\n                    -0.048440802842378616,\n                    0.9922666549682617,\n                    0.11428194493055344\n                ],\n                [\n                    -0.2007835954427719,\n                    -0.12175431102514267,\n                    0.972040057182312\n                ]\n            ]\n        },\n        \"focal\": {\n            \"410028\": [\n                1274.1224365234375,\n                1274.2861328125\n            ]\n        },\n        \"princpt\": {\n            \"410028\": [\n                270.805419921875,\n                175.498046875\n            ]\n        }\n    }\n}\n"
  },
  {
    "path": "tests/data/interhand2.6m/test_interhand2.6m_data.json",
    "content": "{\n    \"images\": [\n        {\n            \"id\": 326750,\n            \"file_name\": \"image69148.jpg\",\n            \"width\": 334,\n            \"height\": 512,\n            \"capture\": 3,\n            \"subject\": 3,\n            \"seq_name\": \"0390_dh_touchROM\",\n            \"camera\": \"400026\",\n            \"frame_idx\": 69148\n        },\n        {\n            \"id\": 286291,\n            \"file_name\": \"image44669.jpg\",\n            \"width\": 334,\n            \"height\": 512,\n            \"capture\": 2,\n            \"subject\": 2,\n            \"seq_name\": \"0266_dh_pray\",\n            \"camera\": \"400012\",\n            \"frame_idx\": 44669\n        },\n        {\n            \"id\": 680801,\n            \"file_name\": \"image29590.jpg\",\n            \"width\": 334,\n            \"height\": 512,\n            \"capture\": 7,\n            \"subject\": 6,\n            \"seq_name\": \"0115_rocker_backside\",\n            \"camera\": \"410053\",\n            \"frame_idx\": 29590\n        },\n        {\n            \"id\": 471953,\n            \"file_name\": \"image2017.jpg\",\n            \"width\": 512,\n            \"height\": 334,\n            \"capture\": 4,\n            \"subject\": 0,\n            \"seq_name\": \"0007_thumbup_normal\",\n            \"camera\": \"410028\",\n            \"frame_idx\": 2017\n        }\n    ],\n    \"annotations\": [\n        {\n            \"id\": 326750,\n            \"image_id\": 326750,\n            \"bbox\": [\n                33.56839370727539,\n                164.92373657226562,\n                185.057861328125,\n                142.7256622314453\n            ],\n            \"joint_valid\": [\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ]\n            ],\n            \"hand_type\": \"interacting\",\n            \"hand_type_valid\": 1\n        },\n        {\n            \"id\": 286291,\n            \"image_id\": 286291,\n            \"bbox\": [\n                116.43374633789062,\n                79.66770935058594,\n                163.1707763671875,\n                175.00582885742188\n            ],\n            \"joint_valid\": [\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ]\n            ],\n            \"hand_type\": \"interacting\",\n            \"hand_type_valid\": 1\n        },\n        {\n            \"id\": 680801,\n            \"image_id\": 680801,\n            \"bbox\": [\n                32.624629974365234,\n                116.9090805053711,\n                182.95919799804688,\n                117.79376983642578\n            ],\n            \"joint_valid\": [\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ]\n            ],\n            \"hand_type\": \"left\",\n            \"hand_type_valid\": 1\n        },\n        {\n            \"id\": 471953,\n            \"image_id\": 471953,\n            \"bbox\": [\n                154.45904541015625,\n                27.944841384887695,\n                90.6390380859375,\n                184.53550720214844\n            ],\n            \"joint_valid\": [\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    1\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ],\n                [\n                    0\n                ]\n            ],\n            \"hand_type\": \"right\",\n            \"hand_type_valid\": 1\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/interhand2.6m/test_interhand2.6m_joint_3d.json",
    "content": "{\n    \"3\": {\n        \"69148\": {\n            \"world_coord\": [\n                [\n                    43.03519821166992,\n                    -82.2948989868164,\n                    1090.739990234375\n                ],\n                [\n                    15.719200134277344,\n                    -80.0010986328125,\n                    1093.1600341796875\n                ],\n                [\n                    -14.644499778747559,\n                    -69.28589630126953,\n                    1099.43994140625\n                ],\n                [\n                    -49.500701904296875,\n                    -48.752601623535156,\n                    1105.739990234375\n                ],\n                [\n                    54.10329818725586,\n                    -52.207000732421875,\n                    1071.3699951171875\n                ],\n                [\n                    44.71070098876953,\n                    -60.90570068359375,\n                    1053.8299560546875\n                ],\n                [\n                    23.355300903320312,\n                    -66.95800018310547,\n                    1042.2099609375\n                ],\n                [\n                    -16.109899520874023,\n                    -59.50210189819336,\n                    1054.7900390625\n                ],\n                [\n                    46.1421012878418,\n                    -27.448999404907227,\n                    1044.06005859375\n                ],\n                [\n                    37.125099182128906,\n                    -28.523000717163086,\n                    1025.0699462890625\n                ],\n                [\n                    11.805299758911133,\n                    -33.19449996948242,\n                    1015.8599853515625\n                ],\n                [\n                    -16.28969955444336,\n                    -35.808101654052734,\n                    1042.489990234375\n                ],\n                [\n                    38.874000549316406,\n                    -5.6127800941467285,\n                    1047.969970703125\n                ],\n                [\n                    29.25860023498535,\n                    1.5931299924850464,\n                    1033.010009765625\n                ],\n                [\n                    5.099699974060059,\n                    0.5625370144844055,\n                    1025.989990234375\n                ],\n                [\n                    -19.3031005859375,\n                    -10.963600158691406,\n                    1047.75\n                ],\n                [\n                    32.95539855957031,\n                    15.77239990234375,\n                    1067.75\n                ],\n                [\n                    20.76289939880371,\n                    22.153799057006836,\n                    1056.8699951171875\n                ],\n                [\n                    1.3557000160217285,\n                    20.561199188232422,\n                    1053.72998046875\n                ],\n                [\n                    -22.658199310302734,\n                    9.142279624938965,\n                    1060.719970703125\n                ],\n                [\n                    -73.1697006225586,\n                    -24.75469970703125,\n                    1109.239990234375\n                ],\n                [\n                    -25.849300384521484,\n                    -76.86360168457031,\n                    1051.6700439453125\n                ],\n                [\n                    -3.0323801040649414,\n                    -76.0531997680664,\n                    1065.52001953125\n                ],\n                [\n                    23.313899993896484,\n                    -64.78929901123047,\n                    1083.3800048828125\n                ],\n                [\n                    52.25170135498047,\n                    -44.1338005065918,\n                    1104.050048828125\n                ],\n                [\n                    -33.858699798583984,\n                    -56.21229934692383,\n                    1052.5\n                ],\n                [\n                    -22.00670051574707,\n                    -54.78179931640625,\n                    1034.52001953125\n                ],\n                [\n                    -1.2521899938583374,\n                    -52.484100341796875,\n                    1021.3099975585938\n                ],\n                [\n                    34.637001037597656,\n                    -44.75859832763672,\n                    1045.5\n                ],\n                [\n                    -38.37810134887695,\n                    -28.615999221801758,\n                    1048.77001953125\n                ],\n                [\n                    -27.590499877929688,\n                    -21.247900009155273,\n                    1031.81005859375\n                ],\n                [\n                    -2.5142500400543213,\n                    -15.51039981842041,\n                    1018.5399780273438\n                ],\n                [\n                    27.976900100708008,\n                    -17.880300521850586,\n                    1042.260009765625\n                ],\n                [\n                    -42.81999969482422,\n                    -7.296229839324951,\n                    1054.06005859375\n                ],\n                [\n                    -29.135400772094727,\n                    4.149099826812744,\n                    1043.780029296875\n                ],\n                [\n                    -3.725130081176758,\n                    12.038700103759766,\n                    1038.300048828125\n                ],\n                [\n                    22.907699584960938,\n                    3.807229995727539,\n                    1054.469970703125\n                ],\n                [\n                    -37.29899978637695,\n                    14.395500183105469,\n                    1082.6500244140625\n                ],\n                [\n                    -24.36440086364746,\n                    21.874000549316406,\n                    1073.199951171875\n                ],\n                [\n                    -4.3188300132751465,\n                    23.260000228881836,\n                    1067.699951171875\n                ],\n                [\n                    19.15329933166504,\n                    15.103500366210938,\n                    1070.9300537109375\n                ],\n                [\n                    68.70819854736328,\n                    -17.395599365234375,\n                    1113.5\n                ]\n            ],\n            \"joint_valid\": [\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ]\n            ],\n            \"hand_type\": \"interacting\",\n            \"hand_type_valid\": true\n        }\n    },\n    \"2\": {\n        \"44669\": {\n            \"world_coord\": [\n                [\n                    5.577770233154297,\n                    -108.26300048828125,\n                    1036.1800537109375\n                ],\n                [\n                    -1.7330399751663208,\n                    -83.05719757080078,\n                    1046.1300048828125\n                ],\n                [\n                    -9.004420280456543,\n                    -57.55229949951172,\n                    1056.969970703125\n                ],\n                [\n                    -15.412199974060059,\n                    -23.791000366210938,\n                    1063.6199951171875\n                ],\n                [\n                    14.21619987487793,\n                    -101.65699768066406,\n                    939.3079833984375\n                ],\n                [\n                    8.966190338134766,\n                    -89.8812026977539,\n                    958.7620239257812\n                ],\n                [\n                    2.066649913787842,\n                    -76.95020294189453,\n                    978.1170043945312\n                ],\n                [\n                    -10.0802001953125,\n                    -54.769500732421875,\n                    1008.3200073242188\n                ],\n                [\n                    15.2121000289917,\n                    -91.22869873046875,\n                    921.1090087890625\n                ],\n                [\n                    9.925020217895508,\n                    -78.84239959716797,\n                    940.4929809570312\n                ],\n                [\n                    0.7208520174026489,\n                    -62.57080078125,\n                    963.5479736328125\n                ],\n                [\n                    -12.486300468444824,\n                    -35.79169845581055,\n                    996.291015625\n                ],\n                [\n                    15.342300415039062,\n                    -71.01309967041016,\n                    920.666015625\n                ],\n                [\n                    10.613200187683105,\n                    -56.69279861450195,\n                    938.3099975585938\n                ],\n                [\n                    3.1483700275421143,\n                    -40.60240173339844,\n                    958.9559936523438\n                ],\n                [\n                    -7.7616801261901855,\n                    -16.659000396728516,\n                    990.3289794921875\n                ],\n                [\n                    9.923910140991211,\n                    -27.469100952148438,\n                    926.0250244140625\n                ],\n                [\n                    7.101960182189941,\n                    -17.535900115966797,\n                    944.4459838867188\n                ],\n                [\n                    3.706239938735962,\n                    -9.478739738464355,\n                    961.2869873046875\n                ],\n                [\n                    -3.7822699546813965,\n                    4.785309791564941,\n                    988.9990234375\n                ],\n                [\n                    -38.23350143432617,\n                    10.85420036315918,\n                    1060.1099853515625\n                ],\n                [\n                    16.591100692749023,\n                    -104.06300354003906,\n                    1032.6300048828125\n                ],\n                [\n                    17.85449981689453,\n                    -79.44409942626953,\n                    1044.3399658203125\n                ],\n                [\n                    20.3125,\n                    -54.15850067138672,\n                    1059.300048828125\n                ],\n                [\n                    23.35300064086914,\n                    -20.347400665283203,\n                    1065.97998046875\n                ],\n                [\n                    28.29199981689453,\n                    -103.08699798583984,\n                    941.9169921875\n                ],\n                [\n                    25.710399627685547,\n                    -89.40409851074219,\n                    960.614013671875\n                ],\n                [\n                    24.782400131225586,\n                    -75.04440307617188,\n                    980.3049926757812\n                ],\n                [\n                    28.035999298095703,\n                    -51.11090087890625,\n                    1011.47998046875\n                ],\n                [\n                    28.736099243164062,\n                    -94.62069702148438,\n                    921.4580078125\n                ],\n                [\n                    26.57539939880371,\n                    -79.62640380859375,\n                    940.0040283203125\n                ],\n                [\n                    27.174400329589844,\n                    -61.3489990234375,\n                    963.3049926757812\n                ],\n                [\n                    30.206899642944336,\n                    -34.29090118408203,\n                    998.177001953125\n                ],\n                [\n                    27.319000244140625,\n                    -72.35669708251953,\n                    919.8040161132812\n                ],\n                [\n                    24.843399047851562,\n                    -56.612098693847656,\n                    937.927001953125\n                ],\n                [\n                    24.483699798583984,\n                    -40.11029815673828,\n                    958.5869750976562\n                ],\n                [\n                    26.43560028076172,\n                    -15.020400047302246,\n                    993.2479858398438\n                ],\n                [\n                    21.380199432373047,\n                    -28.9552001953125,\n                    928.9580078125\n                ],\n                [\n                    19.721099853515625,\n                    -17.84980010986328,\n                    945.948974609375\n                ],\n                [\n                    19.108400344848633,\n                    -9.263039588928223,\n                    961.9609985351562\n                ],\n                [\n                    21.694400787353516,\n                    6.166550159454346,\n                    992.6019897460938\n                ],\n                [\n                    41.08219909667969,\n                    14.29419994354248,\n                    1066.219970703125\n                ]\n            ],\n            \"joint_valid\": [\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ]\n            ],\n            \"hand_type\": \"interacting\",\n            \"hand_type_valid\": true\n        }\n    },\n    \"7\": {\n        \"29590\": {\n            \"world_coord\": [\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    -40.71049880981445,\n                    -95.89289855957031,\n                    957.885986328125\n                ],\n                [\n                    -26.640199661254883,\n                    -90.76909637451172,\n                    980.64697265625\n                ],\n                [\n                    -13.102499961853027,\n                    -84.02850341796875,\n                    1006.030029296875\n                ],\n                [\n                    -6.498330116271973,\n                    -56.183799743652344,\n                    1019.77001953125\n                ],\n                [\n                    -41.832698822021484,\n                    -92.818603515625,\n                    924.9089965820312\n                ],\n                [\n                    -22.394100189208984,\n                    -89.95939636230469,\n                    928.322998046875\n                ],\n                [\n                    -1.334820032119751,\n                    -85.85769653320312,\n                    937.4730224609375\n                ],\n                [\n                    16.722900390625,\n                    -76.81639862060547,\n                    969.6079711914062\n                ],\n                [\n                    -50.71979904174805,\n                    -79.05770111083984,\n                    930.426025390625\n                ],\n                [\n                    -30.792600631713867,\n                    -72.3136978149414,\n                    923.927978515625\n                ],\n                [\n                    -3.884079933166504,\n                    -64.59410095214844,\n                    926.760986328125\n                ],\n                [\n                    17.58009910583496,\n                    -55.07429885864258,\n                    961.2780151367188\n                ],\n                [\n                    -49.63779830932617,\n                    -60.04690170288086,\n                    929.5150146484375\n                ],\n                [\n                    -30.802799224853516,\n                    -51.40850067138672,\n                    926.1209716796875\n                ],\n                [\n                    -7.165579795837402,\n                    -42.4640998840332,\n                    930.6539916992188\n                ],\n                [\n                    11.347599983215332,\n                    -35.320701599121094,\n                    960.9920043945312\n                ],\n                [\n                    -39.11000061035156,\n                    -22.250900268554688,\n                    922.677978515625\n                ],\n                [\n                    -25.091400146484375,\n                    -18.327800750732422,\n                    932.7310180664062\n                ],\n                [\n                    -11.675299644470215,\n                    -16.21780014038086,\n                    943.9849853515625\n                ],\n                [\n                    -1.8433400392532349,\n                    -18.33609962463379,\n                    966.3060302734375\n                ],\n                [\n                    12.858099937438965,\n                    -27.72319984436035,\n                    1035.3299560546875\n                ]\n            ],\n            \"joint_valid\": [\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ]\n            ],\n            \"hand_type\": \"left\",\n            \"hand_type_valid\": true\n        }\n    },\n    \"4\": {\n        \"2017\": {\n            \"world_coord\": [\n                [\n                    -43.12799835205078,\n                    -103.62300109863281,\n                    1034.6500244140625\n                ],\n                [\n                    -46.652801513671875,\n                    -77.29830169677734,\n                    1047.8599853515625\n                ],\n                [\n                    -61.026798248291016,\n                    -60.12670135498047,\n                    1071.8699951171875\n                ],\n                [\n                    -65.07230377197266,\n                    -23.870800018310547,\n                    1084.949951171875\n                ],\n                [\n                    -21.526500701904297,\n                    -36.08110046386719,\n                    1048.530029296875\n                ],\n                [\n                    -23.342899322509766,\n                    -42.05630111694336,\n                    1027.739990234375\n                ],\n                [\n                    -40.31650161743164,\n                    -48.307098388671875,\n                    1008.1400146484375\n                ],\n                [\n                    -80.72380065917969,\n                    -43.20439910888672,\n                    1025.510009765625\n                ],\n                [\n                    -28.87649917602539,\n                    -21.68560028076172,\n                    1051.6800537109375\n                ],\n                [\n                    -20.812700271606445,\n                    -22.777000427246094,\n                    1031.489990234375\n                ],\n                [\n                    -34.154598236083984,\n                    -25.006399154663086,\n                    1004.1900024414062\n                ],\n                [\n                    -80.04650115966797,\n                    -17.935100555419922,\n                    1016.8699951171875\n                ],\n                [\n                    -29.98819923400879,\n                    -4.726659774780273,\n                    1053.030029296875\n                ],\n                [\n                    -20.322599411010742,\n                    -2.968640089035034,\n                    1034.4000244140625\n                ],\n                [\n                    -30.557600021362305,\n                    -0.6155570149421692,\n                    1006.489990234375\n                ],\n                [\n                    -75.96330261230469,\n                    6.1682000160217285,\n                    1017.4600219726562\n                ],\n                [\n                    -36.91109848022461,\n                    10.100500106811523,\n                    1045.4200439453125\n                ],\n                [\n                    -28.660600662231445,\n                    15.840399742126465,\n                    1029.7099609375\n                ],\n                [\n                    -37.89339828491211,\n                    24.52589988708496,\n                    1012.3099975585938\n                ],\n                [\n                    -72.37090301513672,\n                    29.537099838256836,\n                    1021.8099975585938\n                ],\n                [\n                    -93.10230255126953,\n                    5.9222798347473145,\n                    1101.989990234375\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    -60.13209915161133,\n                    -4.4926300048828125,\n                    1036.8599853515625\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ],\n                [\n                    1.0,\n                    1.0,\n                    1.0\n                ]\n            ],\n            \"joint_valid\": [\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    true\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ],\n                [\n                    false\n                ]\n            ],\n            \"hand_type\": \"right\",\n            \"hand_type_valid\": true\n        }\n    }\n}\n"
  },
  {
    "path": "tests/data/jhmdb/test_jhmdb_sub1.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"neck\",\n                \"belly\",\n                \"head\",\n                \"right_shoulder\",\n                \"left_shoulder\",\n                \"right_hip\",\n                \"left_hip\",\n                \"right_elbow\",\n                \"left_elbow\",\n                \"right_knee\",\n                \"left_knee\",\n                \"right_wrist\",\n                \"left_wrist\",\n                \"right_ankle\",\n                \"left_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    3\n                ],\n                [\n                    1,\n                    4\n                ],\n                [\n                    1,\n                    5\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    4,\n                    8\n                ],\n                [\n                    8,\n                    12\n                ],\n                [\n                    5,\n                    9\n                ],\n                [\n                    9,\n                    13\n                ],\n                [\n                    2,\n                    6\n                ],\n                [\n                    2,\n                    7\n                ],\n                [\n                    6,\n                    10\n                ],\n                [\n                    10,\n                    14\n                ],\n                [\n                    7,\n                    11\n                ],\n                [\n                    11,\n                    15\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"is_labeled\": true,\n            \"file_name\": \"Frisbee_catch_f_cm_np1_ri_med_0/00001.png\",\n            \"nframes\": 37,\n            \"frame_id\": 2280001,\n            \"vid_id\": \"00228\",\n            \"id\": 2280001,\n            \"width\": 320,\n            \"height\": 240\n        },\n        {\n            \"is_labeled\": true,\n            \"file_name\": \"Frisbee_catch_f_cm_np1_ri_med_1/00001.png\",\n            \"nframes\": 40,\n            \"frame_id\": 2290001,\n            \"vid_id\": \"00229\",\n            \"id\": 2290001,\n            \"width\": 320,\n            \"height\": 240\n        },\n        {\n            \"is_labeled\": true,\n            \"file_name\": \"Goalkeeper_Training_Day_@_7_catch_f_cm_np1_ri_med_0/00001.png\",\n            \"nframes\": 30,\n            \"frame_id\": 2300001,\n            \"vid_id\": \"00230\",\n            \"id\": 2300001,\n            \"width\": 320,\n            \"height\": 240\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                98.851746,\n                92.59851,\n                2.0,\n                101.382222,\n                133.488694,\n                2.0,\n                100.914365,\n                79.770933,\n                2.0,\n                86.888258,\n                101.976452,\n                2.0,\n                107.314272,\n                103.37138,\n                2.0,\n                96.914279,\n                145.028519,\n                2.0,\n                106.514281,\n                141.828552,\n                2.0,\n                91.779302,\n                90.131713,\n                2.0,\n                111.71446,\n                119.029127,\n                2.0,\n                101.371546,\n                177.429379,\n                2.0,\n                113.428535,\n                169.257124,\n                2.0,\n                90.261035,\n                71.796419,\n                2.0,\n                125.372119,\n                117.142762,\n                2.0,\n                96.68488,\n                206.18226,\n                2.0,\n                87.838304,\n                191.933582,\n                2.0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 2280001,\n            \"bbox\": [\n                79.0,\n                62.0,\n                54.0,\n                159.0\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1000002280001\n        },\n        {\n            \"keypoints\": [\n                126.293586,\n                86.516958,\n                2.0,\n                125.127052,\n                119.880592,\n                2.0,\n                128.800121,\n                77.713852,\n                2.0,\n                123.142858,\n                93.771388,\n                2.0,\n                127.599998,\n                93.314242,\n                2.0,\n                125.314285,\n                126.685723,\n                2.0,\n                125.257142,\n                128.685637,\n                2.0,\n                122.857184,\n                111.302686,\n                2.0,\n                128.40003,\n                107.885918,\n                2.0,\n                122.228575,\n                148.91426,\n                2.0,\n                125.600109,\n                150.403006,\n                2.0,\n                141.391708,\n                106.511998,\n                2.0,\n                141.254766,\n                105.486158,\n                2.0,\n                119.657303,\n                169.255877,\n                2.0,\n                127.656398,\n                173.757251,\n                2.0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 2290001,\n            \"bbox\": [\n                114.0,\n                68.0,\n                38.0,\n                115.0\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1000002290001\n        },\n        {\n            \"keypoints\": [\n                104.590181,\n                138.44876,\n                2.0,\n                105.733877,\n                165.843418,\n                2.0,\n                104.400092,\n                130.809558,\n                2.0,\n                113.714288,\n                142.914297,\n                2.0,\n                97.999996,\n                146.228585,\n                2.0,\n                110.914299,\n                173.028594,\n                2.0,\n                102.628562,\n                171.028599,\n                2.0,\n                116.687889,\n                156.478492,\n                2.0,\n                94.455572,\n                157.210571,\n                2.0,\n                121.257055,\n                190.342707,\n                2.0,\n                95.200265,\n                191.484992,\n                2.0,\n                120.571144,\n                170.45612,\n                2.0,\n                93.885656,\n                169.029784,\n                2.0,\n                128.177332,\n                206.720448,\n                2.0,\n                90.000104,\n                209.256786,\n                2.0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 2300001,\n            \"bbox\": [\n                84.0,\n                123.0,\n                51.0,\n                94.0\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1000002300001\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/lapa/test_lapa.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"face\",\n            \"keypoints\": [],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\"id\": 40, \"file_name\": \"10773046825_0.jpg\", \"height\": 1494, \"width\": 1424},\n        {\"id\": 41, \"file_name\": \"13609937564_5.jpg\", \"height\": 496, \"width\": 486}\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                406.0, 644.0, 2.0, 402.0, 682.0, 2.0, 397.0, 719.0, 2.0, 391.0, 757.0, 2.0, 388.0, 795.0, 2.0, 389.0, 834.0, 2.0, 394.0, 874.0, 2.0, 402.0, 913.0, 2.0, 413.0, 952.0, 2.0, 426.0, 989.0, 2.0, 443.0, 1025.0, 2.0, 461.0, 1059.0, 2.0, 481.0, 1092.0, 2.0, 502.0, 1126.0, 2.0, 527.0, 1156.0, 2.0, 559.0, 1180.0, 2.0, 603.0, 1193.0, 2.0, 658.0, 1195.0, 2.0, 713.0, 1187.0, 2.0, 766.0, 1172.0, 2.0, 816.0, 1151.0, 2.0, 863.0, 1128.0, 2.0, 907.0, 1101.0, 2.0, 945.0, 1067.0, 2.0, 978.0, 1029.0, 2.0, 1003.0, 986.0, 2.0, 1019.0, 938.0, 2.0, 1030.0, 888.0, 2.0, 1037.0, 838.0, 2.0, 1040.0, 788.0, 2.0, 1040.0, 739.0, 2.0, 1037.0, 689.0, 2.0, 1033.0, 640.0, 2.0, 417.0, 595.0, 2.0, 445.0, 559.0, 2.0, 488.0, 548.0, 2.0, 535.0, 558.0, 2.0, 569.0, 579.0, 2.0, 562.0, 604.0, 2.0, 526.0, 588.0, 2.0, 487.0, 579.0, 2.0, 451.0, 581.0, 2.0, 662.0, 566.0, 2.0, 713.0, 545.0, 2.0, 777.0, 541.0, 2.0, 839.0, 558.0, 2.0, 887.0, 600.0, 2.0, 832.0, 581.0, 2.0, 777.0, 572.0, 2.0, 721.0, 578.0, 2.0, 669.0, 593.0, 2.0, 614.0, 654.0, 2.0, 602.0, 704.0, 2.0, 590.0, 755.0, 2.0, 577.0, 807.0, 2.0, 573.0, 678.0, 2.0, 540.0, 778.0, 2.0, 518.0, 826.0, 2.0, 538.0, 846.0, 2.0, 562.0, 855.0, 2.0, 592.0, 866.0, 2.0, 632.0, 856.0, 2.0, 668.0, 848.0, 2.0, 703.0, 827.0, 2.0, 681.0, 778.0, 2.0, 667.0, 676.0, 2.0, 447.0, 672.0, 2.0, 472.0, 662.0, 2.0, 499.0, 658.0, 2.0, 526.0, 662.0, 2.0, 550.0, 675.0, 2.0, 524.0, 674.0, 2.0, 498.0, 673.0, 2.0, 472.0, 673.0, 2.0, 501.0, 666.0, 2.0, 701.0, 673.0, 2.0, 729.0, 658.0, 2.0, 760.0, 654.0, 2.0, 792.0, 659.0, 2.0, 822.0, 671.0, 2.0, 791.0, 672.0, 2.0, 761.0, 672.0, 2.0, 731.0, 672.0, 2.0, 762.0, 663.0, 2.0, 503.0, 940.0, 2.0, 532.0, 923.0, 2.0, 575.0, 921.0, 2.0, 602.0, 927.0, 2.0, 631.0, 922.0, 2.0, 704.0, 930.0, 2.0, 775.0, 951.0, 2.0, 735.0, 1001.0, 2.0, 680.0, 1032.0, 2.0, 608.0, 1040.0, 2.0, 553.0, 1023.0, 2.0, 522.0, 987.0, 2.0, 519.0, 945.0, 2.0, 549.0, 937.0, 2.0, 604.0, 944.0, 2.0, 687.0, 942.0, 2.0, 751.0, 955.0, 2.0, 700.0, 996.0, 2.0, 609.0, 1007.0, 2.0, 546.0, 987.0, 2.0, 501.0, 666.0, 2.0, 762.0, 663.0, 2.0],\n            \"image_id\": 40,\n            \"id\": 40,\n            \"num_keypoints\": 106,\n            \"bbox\": [388.0, 541.0, 652.0, 654.0],\n            \"iscrowd\": 0,\n            \"area\": 426408,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                179.0, 213.0, 2.0, 176.0, 225.0, 2.0, 173.0, 237.0, 2.0, 170.0, 249.0, 2.0, 167.0, 261.0, 2.0, 166.0, 273.0, 2.0, 165.0, 286.0, 2.0, 166.0, 299.0, 2.0, 170.0, 311.0, 2.0, 176.0, 322.0, 2.0, 184.0, 331.0, 2.0, 194.0, 340.0, 2.0, 206.0, 347.0, 2.0, 218.0, 353.0, 2.0, 231.0, 358.0, 2.0, 244.0, 362.0, 2.0, 258.0, 365.0, 2.0, 269.0, 364.0, 2.0, 278.0, 361.0, 2.0, 286.0, 355.0, 2.0, 293.0, 349.0, 2.0, 300.0, 342.0, 2.0, 306.0, 334.0, 2.0, 311.0, 326.0, 2.0, 315.0, 317.0, 2.0, 318.0, 307.0, 2.0, 321.0, 298.0, 2.0, 323.0, 288.0, 2.0, 323.0, 279.0, 2.0, 323.0, 269.0, 2.0, 322.0, 260.0, 2.0, 321.0, 251.0, 2.0, 322.0, 242.0, 2.0, 207.0, 214.0, 2.0, 220.0, 206.0, 2.0, 236.0, 204.0, 2.0, 253.0, 208.0, 2.0, 266.0, 214.0, 2.0, 263.0, 221.0, 2.0, 250.0, 216.0, 2.0, 235.0, 212.0, 2.0, 221.0, 212.0, 2.0, 293.0, 223.0, 2.0, 302.0, 221.0, 2.0, 313.0, 221.0, 2.0, 321.0, 225.0, 2.0, 325.0, 233.0, 2.0, 318.0, 230.0, 2.0, 311.0, 228.0, 2.0, 302.0, 227.0, 2.0, 293.0, 228.0, 2.0, 277.0, 234.0, 2.0, 280.0, 244.0, 2.0, 283.0, 254.0, 2.0, 285.0, 265.0, 2.0, 261.0, 238.0, 2.0, 256.0, 257.0, 2.0, 248.0, 269.0, 2.0, 256.0, 275.0, 2.0, 266.0, 278.0, 2.0, 275.0, 282.0, 2.0, 282.0, 281.0, 2.0, 288.0, 281.0, 2.0, 293.0, 277.0, 2.0, 291.0, 263.0, 2.0, 285.0, 243.0, 2.0, 220.0, 228.0, 2.0, 228.0, 224.0, 2.0, 237.0, 224.0, 2.0, 245.0, 228.0, 2.0, 251.0, 235.0, 2.0, 243.0, 234.0, 2.0, 234.0, 234.0, 2.0, 226.0, 231.0, 2.0, 232.0, 228.0, 2.0, 287.0, 242.0, 2.0, 293.0, 238.0, 2.0, 301.0, 237.0, 2.0, 307.0, 241.0, 2.0, 311.0, 246.0, 2.0, 306.0, 247.0, 2.0, 299.0, 246.0, 2.0, 293.0, 245.0, 2.0, 297.0, 241.0, 2.0, 222.0, 299.0, 2.0, 242.0, 293.0, 2.0, 263.0, 292.0, 2.0, 271.0, 295.0, 2.0, 279.0, 295.0, 2.0, 288.0, 302.0, 2.0, 292.0, 310.0, 2.0, 286.0, 318.0, 2.0, 277.0, 324.0, 2.0, 263.0, 325.0, 2.0, 246.0, 320.0, 2.0, 233.0, 310.0, 2.0, 229.0, 300.0, 2.0, 246.0, 298.0, 2.0, 269.0, 302.0, 2.0, 282.0, 305.0, 2.0, 289.0, 310.0, 2.0, 280.0, 313.0, 2.0, 265.0, 313.0, 2.0, 243.0, 307.0, 2.0, 232.0, 228.0, 2.0, 297.0, 241.0, 2.0],\n            \"image_id\": 41,\n            \"id\": 41,\n            \"num_keypoints\": 106,\n            \"bbox\": [165.0, 204.0, 160.0, 161.0],\n            \"iscrowd\": 0,\n            \"area\": 25760,\n            \"category_id\": 1\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/locust/test_locust.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"animal\",\n            \"id\": 1,\n            \"name\": \"locust\",\n            \"keypoints\": [\n                \"head\",\n                \"neck\",\n                \"thorax\",\n                \"abdomen1\",\n                \"abdomen2\",\n                \"anttipL\",\n                \"antbaseL\",\n                \"eyeL\",\n                \"forelegL1\",\n                \"forelegL2\",\n                \"forelegL3\",\n                \"forelegL4\",\n                \"midlegL1\",\n                \"midlegL2\",\n                \"midlegL3\",\n                \"midlegL4\",\n                \"hindlegL1\",\n                \"hindlegL2\",\n                \"hindlegL3\",\n                \"hindlegL4\",\n                \"anttipR\",\n                \"antbaseR\",\n                \"eyeR\",\n                \"forelegR1\",\n                \"forelegR2\",\n                \"forelegR3\",\n                \"forelegR4\",\n                \"midlegR1\",\n                \"midlegR2\",\n                \"midlegR3\",\n                \"midlegR4\",\n                \"hindlegR1\",\n                \"hindlegR2\",\n                \"hindlegR3\",\n                \"hindlegR4\"\n            ],\n            \"skeleton\": [\n                [\n                    2,\n                    1\n                ],\n                [\n                    3,\n                    2\n                ],\n                [\n                    4,\n                    3\n                ],\n                [\n                    5,\n                    4\n                ],\n                [\n                    7,\n                    6\n                ],\n                [\n                    8,\n                    7\n                ],\n                [\n                    10,\n                    9\n                ],\n                [\n                    11,\n                    10\n                ],\n                [\n                    12,\n                    11\n                ],\n                [\n                    14,\n                    13\n                ],\n                [\n                    15,\n                    14\n                ],\n                [\n                    16,\n                    15\n                ],\n                [\n                    18,\n                    17\n                ],\n                [\n                    19,\n                    18\n                ],\n                [\n                    20,\n                    19\n                ],\n                [\n                    22,\n                    21\n                ],\n                [\n                    23,\n                    22\n                ],\n                [\n                    25,\n                    24\n                ],\n                [\n                    26,\n                    25\n                ],\n                [\n                    27,\n                    26\n                ],\n                [\n                    29,\n                    28\n                ],\n                [\n                    30,\n                    29\n                ],\n                [\n                    31,\n                    30\n                ],\n                [\n                    33,\n                    32\n                ],\n                [\n                    34,\n                    33\n                ],\n                [\n                    35,\n                    34\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 630,\n            \"file_name\": \"630.jpg\",\n            \"height\": 160,\n            \"width\": 160\n        },\n        {\n            \"id\": 650,\n            \"file_name\": \"650.jpg\",\n            \"height\": 160,\n            \"width\": 160\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                96.50167788139936,\n                79.08306303388312,\n                2.0,\n                88.16894217433088,\n                80.0,\n                2.0,\n                71.83105782566912,\n                80.0,\n                2.0,\n                43.076199694670166,\n                81.43588116352915,\n                2.0,\n                25.32887764003749,\n                82.27820200265606,\n                2.0,\n                110.83265850033396,\n                64.38260807811851,\n                2.0,\n                96.89436603268481,\n                77.79724180953298,\n                2.0,\n                92.64247009206748,\n                75.90977635533528,\n                2.0,\n                83.39926607647823,\n                72.82433076402732,\n                2.0,\n                82.67339213429909,\n                64.27184461240981,\n                2.0,\n                77.6884112016259,\n                61.04563086937941,\n                2.0,\n                77.45675634815713,\n                53.70793132675738,\n                2.0,\n                76.53903805777047,\n                72.5751936338004,\n                2.0,\n                71.96661261225319,\n                65.52855444465679,\n                2.0,\n                71.75442535243388,\n                57.456652943107045,\n                2.0,\n                71.32325166700342,\n                50.50892818053555,\n                2.0,\n                68.30277076791707,\n                73.75801488839979,\n                2.0,\n                53.231016278533986,\n                76.08684171200879,\n                2.0,\n                43.82802063202446,\n                71.2340227958044,\n                2.0,\n                35.106594786098235,\n                71.66012724670512,\n                2.0,\n                106.38084243468204,\n                93.57855909773465,\n                2.0,\n                96.92326999269929,\n                80.82566265131587,\n                2.0,\n                94.00509910253301,\n                82.81711130561807,\n                2.0,\n                86.23508453811776,\n                87.44135484984199,\n                2.0,\n                89.53039251130028,\n                95.03156856963247,\n                2.0,\n                93.56705070950602,\n                96.78650579864731,\n                2.0,\n                95.92358648030009,\n                102.7013970756846,\n                2.0,\n                76.38469744035021,\n                88.48766220561612,\n                2.0,\n                68.9346295215593,\n                95.07191551878313,\n                2.0,\n                61.51609313834261,\n                101.49429058760627,\n                2.0,\n                58.801694058956855,\n                107.68266252152361,\n                2.0,\n                68.60028938490109,\n                86.4375531155976,\n                2.0,\n                49.508565619095066,\n                85.14994772406058,\n                2.0,\n                46.69889605871468,\n                93.99222310236672,\n                2.0,\n                38.16941690562348,\n                96.27433127807184,\n                2.0\n            ],\n            \"image_id\": 630,\n            \"id\": 630,\n            \"num_keypoints\": 35,\n            \"bbox\": [\n                25.32887764003749,\n                50.50892818053555,\n                86.50378086029647,\n                58.17373434098806\n            ],\n            \"iscrowd\": 0,\n            \"area\": 5032.247967257935,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                97.23191700267623,\n                80.39325063190708,\n                2.0,\n                88.51415643927471,\n                80.0,\n                2.0,\n                71.48584356072527,\n                80.0,\n                2.0,\n                36.905138572570486,\n                78.04476695194448,\n                2.0,\n                16.961673753971056,\n                75.93092988166644,\n                2.0,\n                113.49247835569392,\n                67.25231199016146,\n                2.0,\n                97.64673560186061,\n                78.62374942355183,\n                2.0,\n                94.59207701254518,\n                76.42905623590133,\n                2.0,\n                86.61299882845682,\n                72.98025939672249,\n                2.0,\n                92.79065379033919,\n                63.557810609540184,\n                2.0,\n                98.53306658179334,\n                60.560826412407806,\n                2.0,\n                103.15691560103025,\n                54.704957013528016,\n                2.0,\n                78.15050140841085,\n                72.0525607684763,\n                2.0,\n                67.19679320947252,\n                63.129491930981956,\n                2.0,\n                66.81613570544552,\n                56.68704758248447,\n                2.0,\n                65.81511750771388,\n                50.30081842401707,\n                2.0,\n                68.60029149309025,\n                71.73022380161136,\n                2.0,\n                46.45069339825895,\n                75.19901789908113,\n                2.0,\n                52.58790600614371,\n                64.54029671009006,\n                2.0,\n                43.39186120464909,\n                61.90008440661086,\n                2.0,\n                114.31225140311544,\n                94.14582220648037,\n                2.0,\n                97.0916788683189,\n                82.39643083701381,\n                2.0,\n                93.88962787007102,\n                84.03290507899544,\n                2.0,\n                85.2589207759562,\n                87.7242665022609,\n                2.0,\n                86.20699274387225,\n                96.23021381618412,\n                2.0,\n                85.92496886773941,\n                99.18054227199636,\n                2.0,\n                87.80771669496954,\n                103.97613146233982,\n                2.0,\n                77.42016997828726,\n                87.49638798189035,\n                2.0,\n                70.98251459751503,\n                98.88127929151817,\n                2.0,\n                77.88427189277336,\n                101.23547565641657,\n                2.0,\n                78.23906551163462,\n                108.63777750516068,\n                2.0,\n                68.33776490317005,\n                85.89688698861642,\n                2.0,\n                42.71215070869465,\n                90.66846983209739,\n                2.0,\n                33.419979116798764,\n                90.66772059057342,\n                2.0,\n                23.04868990312741,\n                92.48441448580822,\n                2.0\n            ],\n            \"image_id\": 650,\n            \"id\": 650,\n            \"num_keypoints\": 35,\n            \"bbox\": [\n                16.961673753971056,\n                50.30081842401707,\n                98.35057764914438,\n                59.33695908114361\n            ],\n            \"iscrowd\": 0,\n            \"area\": 5835.824201574118,\n            \"category_id\": 1\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/macaque/test_macaque.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"animal\",\n            \"id\": 1,\n            \"name\": \"macaque\",\n            \"keypoints\": [\n                \"nose\",\n                \"left_eye\",\n                \"right_eye\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 12900,\n            \"file_name\": \"d47f1b1ee9d3217e.jpg\",\n            \"height\": 710,\n            \"width\": 1024\n        },\n        {\n            \"id\": 12950,\n            \"file_name\": \"PRI_1473.jpg\",\n            \"height\": 1424,\n            \"width\": 1728\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                641.06,\n                308.89,\n                2.0,\n                644.23,\n                269.75,\n                2.0,\n                612.5,\n                275.04,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                545.85,\n                216.86,\n                2.0,\n                580.0,\n                225.0,\n                2.0,\n                464.0,\n                258.0,\n                2.0,\n                582.0,\n                366.0,\n                2.0,\n                377.65,\n                360.73,\n                2.0,\n                697.12,\n                358.61,\n                2.0,\n                590.28,\n                394.58,\n                2.0,\n                508.0,\n                424.0,\n                2.0,\n                385.0,\n                475.0,\n                2.0,\n                618.0,\n                369.0,\n                2.0,\n                445.0,\n                386.0,\n                2.0,\n                695.0,\n                468.0,\n                2.0,\n                522.58,\n                550.08,\n                2.0\n            ],\n            \"image_id\": 12900,\n            \"id\": 16169,\n            \"num_keypoints\": 16,\n            \"bbox\": [\n                143.87,\n                147.04,\n                623.01,\n                535.22\n            ],\n            \"iscrowd\": 0,\n            \"area\": 138067.96479999926,\n            \"category_id\": 1,\n            \"segmentation\": [\n                [\n                    408.33,\n                    534.21,\n                    465.45,\n                    547.97,\n                    502.48,\n                    587.11,\n                    573.36,\n                    593.45,\n                    652.69,\n                    608.26,\n                    687.6,\n                    578.64,\n                    656.93,\n                    544.79,\n                    616.73,\n                    537.39,\n                    588.17,\n                    501.42,\n                    532.1,\n                    483.44,\n                    518.35,\n                    455.93,\n                    536.33,\n                    426.31,\n                    567.01,\n                    417.85,\n                    629.42,\n                    430.55,\n                    696.07,\n                    437.95,\n                    670.68,\n                    403.04,\n                    705.59,\n                    395.64,\n                    737.32,\n                    413.62,\n                    738.38,\n                    431.6,\n                    765.88,\n                    431.6,\n                    759.54,\n                    379.77,\n                    722.51,\n                    341.69,\n                    654.81,\n                    322.64,\n                    652.69,\n                    271.87,\n                    675.97,\n                    230.61,\n                    651.64,\n                    168.2,\n                    567.01,\n                    147.04,\n                    492.96,\n                    157.62,\n                    423.14,\n                    186.18,\n                    372.36,\n                    243.31,\n                    317.36,\n                    325.82,\n                    307.83,\n                    404.1,\n                    334.28,\n                    469.69,\n                    353.32,\n                    488.73,\n                    290.91,\n                    521.52,\n                    231.67,\n                    563.83,\n                    174.55,\n                    628.36,\n                    143.87,\n                    675.97,\n                    200.99,\n                    681.26,\n                    245.42,\n                    622.02,\n                    307.83,\n                    574.41,\n                    407.27,\n                    536.33\n                ]\n            ]\n        },\n        {\n            \"keypoints\": [\n                783.0,\n                890.0,\n                2.0,\n                775.14,\n                848.5,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                834.0,\n                796.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                987.0,\n                815.0,\n                2.0,\n                833.0,\n                819.0,\n                2.0,\n                1132.15,\n                789.82,\n                2.0,\n                887.0,\n                919.0,\n                2.0,\n                1191.0,\n                852.0,\n                2.0,\n                869.0,\n                1040.0,\n                2.0,\n                1177.0,\n                527.0,\n                2.0,\n                1082.0,\n                513.0,\n                2.0,\n                1173.72,\n                721.35,\n                2.0,\n                1086.0,\n                737.0,\n                2.0,\n                1307.0,\n                678.0,\n                2.0,\n                1218.0,\n                783.0,\n                2.0\n            ],\n            \"image_id\": 12950,\n            \"id\": 16227,\n            \"num_keypoints\": 15,\n            \"bbox\": [\n                722.61,\n                393.97,\n                642.3100000000001,\n                754.1700000000001\n            ],\n            \"iscrowd\": 0,\n            \"area\": 242621.70749999955,\n            \"category_id\": 1,\n            \"segmentation\": [\n                [\n                    1248.37,\n                    529.25,\n                    1212.77,\n                    474.67,\n                    1179.55,\n                    420.08,\n                    1134.45,\n                    398.72,\n                    1084.61,\n                    393.97,\n                    1053.76,\n                    429.57,\n                    1043.26,\n                    467.44,\n                    996.8,\n                    531.63,\n                    930.35,\n                    607.57,\n                    842.53,\n                    659.79,\n                    806.93,\n                    704.88,\n                    768.96,\n                    728.61,\n                    722.61,\n                    767.77,\n                    727.12,\n                    831.0,\n                    740.67,\n                    878.42,\n                    783.58,\n                    937.13,\n                    812.93,\n                    957.45,\n                    812.93,\n                    1027.46,\n                    799.38,\n                    1072.62,\n                    765.51,\n                    1113.27,\n                    758.74,\n                    1142.62,\n                    803.9,\n                    1147.14,\n                    862.61,\n                    1138.11,\n                    923.58,\n                    1068.1,\n                    950.68,\n                    1000.36,\n                    948.42,\n                    905.52,\n                    1007.13,\n                    891.97,\n                    1083.91,\n                    873.9,\n                    1151.65,\n                    919.07,\n                    1187.78,\n                    957.45,\n                    1223.91,\n                    982.29,\n                    1262.3,\n                    950.68,\n                    1272.11,\n                    901.87,\n                    1264.56,\n                    844.55,\n                    1302.95,\n                    821.96,\n                    1341.34,\n                    779.06,\n                    1363.92,\n                    704.54,\n                    1352.8,\n                    633.68,\n                    1274.48,\n                    598.08\n                ]\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/mhp/test_mhp.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"Right-ankle\",\n                \"Right-knee\",\n                \"Right-hip\",\n                \"Left-hip\",\n                \"Left-knee\",\n                \"Left-ankle\",\n                \"Pelvis\",\n                \"Thorax\",\n                \"Upper-neck\",\n                \"Head-top\",\n                \"Right-wrist\",\n                \"Right-elbow\",\n                \"Right-shoulder\",\n                \"Left-shoulder\",\n                \"Left-elbow\",\n                \"Left-wrist\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    7\n                ],\n                [\n                    7,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    5,\n                    6\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    8,\n                    9\n                ],\n                [\n                    9,\n                    10\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    13,\n                    9\n                ],\n                [\n                    9,\n                    14\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"license\": 0,\n            \"file_name\": \"10084.jpg\",\n            \"height\": 299,\n            \"width\": 298,\n            \"id\": 2889\n        },\n        {\n            \"license\": 0,\n            \"file_name\": \"10112.jpg\",\n            \"height\": 180,\n            \"width\": 215,\n            \"id\": 3928\n        }\n    ],\n    \"annotations\": [\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 13,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                151.74249267578125,\n                251.90750122070312,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                156.2274932861328,\n                136.0449981689453,\n                2.0,\n                94.18499755859375,\n                203.32000732421875,\n                2.0,\n                128.57000732421875,\n                246.6750030517578,\n                2.0,\n                119.5999984741211,\n                143.52000427246094,\n                2.0,\n                116.61000061035156,\n                85.9625015258789,\n                2.0,\n                109.13500213623047,\n                41.86000061035156,\n                2.0,\n                108.38749694824219,\n                7.474999904632568,\n                2.0,\n                44.849998474121094,\n                105.39749908447266,\n                2.0,\n                80.7300033569336,\n                112.125,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                122.58999633789062,\n                47.84000015258789,\n                2.0,\n                87.4574966430664,\n                83.72000122070312,\n                2.0,\n                35.880001068115234,\n                97.17500305175781,\n                2.0\n            ],\n            \"image_id\": 2889,\n            \"bbox\": [\n                3.737499952316284,\n                5.232500076293945,\n                169.68249821662903,\n                282.5550060272217\n            ],\n            \"category_id\": 1,\n            \"id\": 7646,\n            \"face_box\": [\n                96.42749786376953,\n                12.707500457763672,\n                35.13249969482422,\n                29.15250015258789\n            ],\n            \"area\": 47944.63930631365\n        },\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 14,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0.0,\n                0.0,\n                0.0,\n                254.14999389648438,\n                219.76499938964844,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                292.2724914550781,\n                147.25750732421875,\n                2.0,\n                223.50250244140625,\n                195.09750366210938,\n                2.0,\n                242.19000244140625,\n                276.57501220703125,\n                2.0,\n                264.614990234375,\n                150.9949951171875,\n                2.0,\n                233.22000122070312,\n                81.47750091552734,\n                2.0,\n                236.95750427246094,\n                59.0525016784668,\n                2.0,\n                230.9774932861328,\n                16.44499969482422,\n                2.0,\n                142.02499389648438,\n                66.52749633789062,\n                2.0,\n                180.89500427246094,\n                65.77999877929688,\n                2.0,\n                221.25999450683594,\n                63.537498474121094,\n                2.0,\n                260.87750244140625,\n                59.79999923706055,\n                2.0,\n                296.010009765625,\n                92.69000244140625,\n                2.0,\n                281.05999755859375,\n                146.50999450683594,\n                2.0\n            ],\n            \"image_id\": 2889,\n            \"bbox\": [\n                117.35749816894531,\n                11.212499618530273,\n                181.6425018310547,\n                285.5450077056885\n            ],\n            \"category_id\": 1,\n            \"id\": 7647,\n            \"face_box\": [\n                210.04750061035156,\n                19.434999465942383,\n                31.395004272460938,\n                38.12249946594238\n            ],\n            \"area\": 51867.109585029044\n        },\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 7,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                38.70000076293945,\n                117.44999694824219,\n                2.0,\n                48.599998474121094,\n                71.0999984741211,\n                2.0,\n                66.5999984741211,\n                17.549999237060547,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                3.1500000953674316,\n                158.39999389648438,\n                2.0,\n                3.5999999046325684,\n                74.69999694824219,\n                2.0,\n                97.19999694824219,\n                76.94999694824219,\n                2.0,\n                102.1500015258789,\n                145.35000610351562,\n                2.0,\n                0.0,\n                0.0,\n                0.0\n            ],\n            \"image_id\": 3928,\n            \"bbox\": [\n                2.25,\n                10.350000381469727,\n                114.30000305175781,\n                169.2000026702881\n            ],\n            \"category_id\": 1,\n            \"id\": 10379,\n            \"face_box\": [\n                30.600000381469727,\n                26.100000381469727,\n                47.24999809265137,\n                45.89999961853027\n            ],\n            \"area\": 19339.56082157136\n        },\n        {\n            \"segmentation\": [],\n            \"num_keypoints\": 7,\n            \"iscrowd\": 0,\n            \"keypoints\": [\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                147.60000610351562,\n                126.9000015258789,\n                2.0,\n                155.6999969482422,\n                81.9000015258789,\n                2.0,\n                152.5500030517578,\n                25.200000762939453,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                127.3499984741211,\n                93.1500015258789,\n                2.0,\n                198.4499969482422,\n                89.0999984741211,\n                2.0,\n                198.89999389648438,\n                163.35000610351562,\n                2.0,\n                148.5,\n                151.64999389648438,\n                2.0\n            ],\n            \"image_id\": 3928,\n            \"bbox\": [\n                112.05000305175781,\n                18.450000762939453,\n                96.30000305175781,\n                161.10000228881836\n            ],\n            \"category_id\": 1,\n            \"id\": 10380,\n            \"face_box\": [\n                132.3000030517578,\n                39.150001525878906,\n                44.55000305175781,\n                40.04999542236328\n            ],\n            \"area\": 15513.930712051399\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/mpii/test_mpii.json",
    "content": "[\n    {\n        \"joints_vis\": [\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1\n        ],\n        \"joints\": [\n            [\n                804.0,\n                711.0\n            ],\n            [\n                816.0,\n                510.0\n            ],\n            [\n                908.0,\n                438.0\n            ],\n            [\n                1040.0,\n                454.0\n            ],\n            [\n                906.0,\n                528.0\n            ],\n            [\n                883.0,\n                707.0\n            ],\n            [\n                974.0,\n                446.0\n            ],\n            [\n                985.0,\n                253.0\n            ],\n            [\n                982.7591,\n                235.9694\n            ],\n            [\n                962.2409,\n                80.0306\n            ],\n            [\n                869.0,\n                214.0\n            ],\n            [\n                798.0,\n                340.0\n            ],\n            [\n                902.0,\n                253.0\n            ],\n            [\n                1067.0,\n                253.0\n            ],\n            [\n                1167.0,\n                353.0\n            ],\n            [\n                1142.0,\n                478.0\n            ]\n        ],\n        \"image\": \"005808361.jpg\",\n        \"scale\": 4.718488,\n        \"center\": [\n            966.0,\n            340.0\n        ]\n    },\n    {\n        \"joints_vis\": [\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1\n        ],\n        \"joints\": [\n            [\n                317.0,\n                412.0\n            ],\n            [\n                318.0,\n                299.0\n            ],\n            [\n                290.0,\n                274.0\n            ],\n            [\n                353.0,\n                275.0\n            ],\n            [\n                403.0,\n                299.0\n            ],\n            [\n                394.0,\n                409.0\n            ],\n            [\n                322.0,\n                275.0\n            ],\n            [\n                327.0,\n                172.0\n            ],\n            [\n                329.9945,\n                162.1051\n            ],\n            [\n                347.0055,\n                105.8949\n            ],\n            [\n                296.0,\n                135.0\n            ],\n            [\n                281.0,\n                208.0\n            ],\n            [\n                296.0,\n                167.0\n            ],\n            [\n                358.0,\n                177.0\n            ],\n            [\n                387.0,\n                236.0\n            ],\n            [\n                392.0,\n                167.0\n            ]\n        ],\n        \"image\": \"052475643.jpg\",\n        \"scale\": 1.761835,\n        \"center\": [\n            316.0,\n            220.0\n        ]\n    },\n    {\n        \"joints_vis\": [\n            0,\n            1,\n            1,\n            1,\n            1,\n            0,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1\n        ],\n        \"joints\": [\n            [\n                -1.0,\n                -1.0\n            ],\n            [\n                1033.0,\n                649.0\n            ],\n            [\n                1072.0,\n                474.0\n            ],\n            [\n                973.0,\n                496.0\n            ],\n            [\n                961.0,\n                650.0\n            ],\n            [\n                -1.0,\n                -1.0\n            ],\n            [\n                1023.0,\n                485.0\n            ],\n            [\n                1031.0,\n                295.0\n            ],\n            [\n                1026.998,\n                281.6248\n            ],\n            [\n                997.002,\n                181.3752\n            ],\n            [\n                988.0,\n                294.0\n            ],\n            [\n                1018.0,\n                317.0\n            ],\n            [\n                1070.0,\n                290.0\n            ],\n            [\n                991.0,\n                300.0\n            ],\n            [\n                912.0,\n                345.0\n            ],\n            [\n                842.0,\n                330.0\n            ]\n        ],\n        \"image\": \"051423444.jpg\",\n        \"scale\": 3.139233,\n        \"center\": [\n            1030.0,\n            396.0\n        ]\n    },\n    {\n        \"joints_vis\": [\n            0,\n            1,\n            1,\n            1,\n            1,\n            0,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1\n        ],\n        \"joints\": [\n            [\n                -1.0,\n                -1.0\n            ],\n            [\n                804.0,\n                659.0\n            ],\n            [\n                786.0,\n                498.0\n            ],\n            [\n                868.0,\n                509.0\n            ],\n            [\n                860.0,\n                693.0\n            ],\n            [\n                -1.0,\n                -1.0\n            ],\n            [\n                827.0,\n                504.0\n            ],\n            [\n                840.0,\n                314.0\n            ],\n            [\n                838.9079,\n                308.9326\n            ],\n            [\n                816.0921,\n                203.0674\n            ],\n            [\n                698.0,\n                264.0\n            ],\n            [\n                740.0,\n                297.0\n            ],\n            [\n                790.0,\n                300.0\n            ],\n            [\n                889.0,\n                328.0\n            ],\n            [\n                915.0,\n                452.0\n            ],\n            [\n                906.0,\n                553.0\n            ]\n        ],\n        \"image\": \"004645041.jpg\",\n        \"scale\": 3.248877,\n        \"center\": [\n            809.0,\n            403.0\n        ]\n    },\n    {\n        \"joints_vis\": [\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1,\n            1\n        ],\n        \"joints\": [\n            [\n                694.0,\n                684.0\n            ],\n            [\n                685.0,\n                579.0\n            ],\n            [\n                670.0,\n                437.0\n            ],\n            [\n                747.0,\n                421.0\n            ],\n            [\n                751.0,\n                574.0\n            ],\n            [\n                768.0,\n                717.0\n            ],\n            [\n                709.0,\n                429.0\n            ],\n            [\n                649.0,\n                230.0\n            ],\n            [\n                642.6337,\n                217.5659\n            ],\n            [\n                591.3663,\n                117.4341\n            ],\n            [\n                488.0,\n                351.0\n            ],\n            [\n                551.0,\n                307.0\n            ],\n            [\n                600.0,\n                242.0\n            ],\n            [\n                698.0,\n                217.0\n            ],\n            [\n                767.0,\n                310.0\n            ],\n            [\n                790.0,\n                405.0\n            ]\n        ],\n        \"image\": \"060754485.jpg\",\n        \"scale\": 3.374796,\n        \"center\": [\n            698.0,\n            404.0\n        ]\n    }\n]\n"
  },
  {
    "path": "tests/data/mpii/test_mpii_trb.json",
    "content": "{\n    \"info\": {\n        \"description\": \"For TRBMPI testing.\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/06/20\"\n    },\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\",\n                \"head\",\n                \"neck\",\n                \"right_neck\",\n                \"left_neck\",\n                \"medial_right_shoulder\",\n                \"lateral_right_shoulder\",\n                \"medial_right_bow\",\n                \"lateral_right_bow\",\n                \"medial_right_wrist\",\n                \"lateral_right_wrist\",\n                \"medial_left_shoulder\",\n                \"lateral_left_shoulder\",\n                \"medial_left_bow\",\n                \"lateral_left_bow\",\n                \"medial_left_wrist\",\n                \"lateral_left_wrist\",\n                \"medial_right_hip\",\n                \"lateral_right_hip\",\n                \"medial_right_knee\",\n                \"lateral_right_knee\",\n                \"medial_right_ankle\",\n                \"lateral_right_ankle\",\n                \"medial_left_hip\",\n                \"lateral_left_hip\",\n                \"medial_left_knee\",\n                \"lateral_left_knee\",\n                \"medial_left_ankle\",\n                \"lateral_left_ankle\"\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"file_name\": \"004645041.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 4645041\n        },\n        {\n            \"file_name\": \"005808361.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 5808361\n        },\n        {\n            \"file_name\": \"051423444.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 51423444\n        },\n        {\n            \"file_name\": \"052475643.jpg\",\n            \"height\": 480,\n            \"width\": 854,\n            \"id\": 52475643\n        },\n        {\n            \"file_name\": \"060754485.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 60754485\n        }\n    ],\n    \"annotations\": [\n        {\n            \"num_joints\": 38,\n            \"keypoints\": [\n                1067.0,\n                253.0,\n                2.0,\n                902.0,\n                253.0,\n                2.0,\n                1167.0,\n                353.0,\n                2.0,\n                798.0,\n                340.0,\n                2.0,\n                1142.0,\n                478.0,\n                2.0,\n                869.0,\n                214.0,\n                2.0,\n                1040.0,\n                454.0,\n                2.0,\n                908.0,\n                438.0,\n                2.0,\n                906.0,\n                528.0,\n                2.0,\n                816.0,\n                510.0,\n                2.0,\n                883.0,\n                707.0,\n                2.0,\n                804.0,\n                711.0,\n                2.0,\n                962.2409,\n                80.0306,\n                2.0,\n                982.7591,\n                235.9694,\n                2.0,\n                895.418,\n                241.258,\n                2,\n                1043.704,\n                160.177,\n                2,\n                901.513,\n                343.02,\n                2,\n                863.72,\n                263.644,\n                2,\n                837.5939,\n                349.993,\n                2,\n                862.766,\n                257.015,\n                2,\n                801.5946,\n                274.022,\n                2,\n                879.233,\n                196.169,\n                2,\n                1110.547,\n                339.254,\n                2,\n                1036.455,\n                221.547,\n                2,\n                1133.252,\n                424.742,\n                2,\n                1157.976,\n                298.364,\n                2,\n                1128.938,\n                496.521,\n                2,\n                1178.462,\n                418.695,\n                2,\n                906.36,\n                495.814,\n                2,\n                886.084,\n                430.921,\n                2,\n                921.047,\n                497.919,\n                2,\n                798.3963,\n                620.615,\n                2,\n                883.956,\n                622.444,\n                2,\n                0,\n                0,\n                0,\n                906.36,\n                495.814,\n                2,\n                1063.55,\n                427.43,\n                2,\n                858.607,\n                625.533,\n                2,\n                998.667,\n                532.689,\n                2,\n                0,\n                0,\n                0,\n                930.346,\n                637.297,\n                2\n            ],\n            \"image_id\": 5808361,\n            \"center\": [\n                966.0,\n                340.0\n            ],\n            \"scale\": 0.1756068552,\n            \"category_id\": 1,\n            \"id\": 2736,\n            \"iscrowd\": 0\n        },\n        {\n            \"num_joints\": 40,\n            \"keypoints\": [\n                358.0,\n                177.0,\n                2.0,\n                296.0,\n                167.0,\n                2.0,\n                387.0,\n                236.0,\n                2.0,\n                281.0,\n                208.0,\n                2.0,\n                392.0,\n                167.0,\n                2.0,\n                296.0,\n                135.0,\n                2.0,\n                353.0,\n                275.0,\n                2.0,\n                290.0,\n                274.0,\n                2.0,\n                403.0,\n                299.0,\n                2.0,\n                318.0,\n                299.0,\n                2.0,\n                394.0,\n                409.0,\n                2.0,\n                317.0,\n                412.0,\n                2.0,\n                347.0055,\n                105.8949,\n                2.0,\n                329.9945,\n                162.1051,\n                2.0,\n                288.387,\n                168.411,\n                2,\n                352.646,\n                153.542,\n                2,\n                278.645,\n                195.766,\n                2,\n                272.16,\n                185.5,\n                2,\n                295.672,\n                202.247,\n                2,\n                275.016,\n                171.472,\n                2,\n                297.774,\n                179.573,\n                2,\n                314.8,\n                136.217,\n                2,\n                362.128,\n                228.378,\n                2,\n                343.02,\n                176.81,\n                2,\n                402.3,\n                211.171,\n                2,\n                373.628,\n                192.749,\n                2,\n                389.14,\n                148.105,\n                2,\n                382.448,\n                186.517,\n                2,\n                340.876,\n                312.739,\n                2,\n                271.97,\n                273.448,\n                2,\n                323.194,\n                285.55,\n                2,\n                300.533,\n                368.868,\n                2,\n                328.476,\n                360.12,\n                2,\n                309.13,\n                434.758,\n                2,\n                340.876,\n                312.739,\n                2,\n                362.155,\n                232.654,\n                2,\n                381.581,\n                365.148,\n                2,\n                388.754,\n                284.757,\n                2,\n                396.32,\n                448.91,\n                2,\n                409.878,\n                357.015,\n                2\n            ],\n            \"image_id\": 52475643,\n            \"center\": [\n                316.0,\n                220.0\n            ],\n            \"scale\": 0.47030507400000005,\n            \"category_id\": 1,\n            \"id\": 28438,\n            \"iscrowd\": 0\n        },\n        {\n            \"num_joints\": 32,\n            \"keypoints\": [\n                991.0,\n                300.0,\n                2.0,\n                1070.0,\n                290.0,\n                2.0,\n                912.0,\n                345.0,\n                2.0,\n                1018.0,\n                317.0,\n                1.0,\n                842.0,\n                330.0,\n                2.0,\n                988.0,\n                294.0,\n                1.0,\n                973.0,\n                496.0,\n                2.0,\n                1072.0,\n                474.0,\n                2.0,\n                961.0,\n                650.0,\n                2.0,\n                1033.0,\n                649.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                997.002,\n                181.3752,\n                2.0,\n                1026.998,\n                281.6248,\n                2.0,\n                1071.131,\n                283.036,\n                2,\n                969.6,\n                247.337,\n                2,\n                1087.017,\n                347.51,\n                2,\n                1058.52,\n                305.636,\n                2,\n                1026.458,\n                332.152,\n                2,\n                1014.72,\n                288.149,\n                2,\n                995.817,\n                309.098,\n                2,\n                980.493,\n                294.738,\n                2,\n                937.925,\n                366.241,\n                2,\n                987.08,\n                282.067,\n                2,\n                869.4918,\n                356.925,\n                2,\n                931.259,\n                311.619,\n                2,\n                844.2,\n                326.671,\n                2,\n                873.5471,\n                326.164,\n                2,\n                1004.56,\n                610.365,\n                2,\n                1075.26,\n                526.816,\n                2,\n                1005.788,\n                610.747,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                1004.56,\n                610.365,\n                2,\n                935.105,\n                446.09,\n                2,\n                0,\n                0,\n                0,\n                937.158,\n                604.939,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 51423444,\n            \"center\": [\n                1030.0,\n                396.0\n            ],\n            \"scale\": 0.2639497014,\n            \"category_id\": 1,\n            \"id\": 27407,\n            \"iscrowd\": 0\n        },\n        {\n            \"num_joints\": 32,\n            \"keypoints\": [\n                889.0,\n                328.0,\n                2.0,\n                790.0,\n                300.0,\n                2.0,\n                915.0,\n                452.0,\n                2.0,\n                740.0,\n                297.0,\n                2.0,\n                906.0,\n                553.0,\n                2.0,\n                698.0,\n                264.0,\n                2.0,\n                868.0,\n                509.0,\n                2.0,\n                786.0,\n                498.0,\n                2.0,\n                860.0,\n                693.0,\n                2.0,\n                804.0,\n                659.0,\n                2.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                0.0,\n                816.0921,\n                203.0674,\n                2.0,\n                838.9079,\n                308.9326,\n                2.0,\n                790.983,\n                286.144,\n                2,\n                864.959,\n                243.71,\n                2,\n                769.273,\n                388.686,\n                2,\n                780.19,\n                289.158,\n                2,\n                742.1957,\n                339.679,\n                2,\n                729.0975,\n                277.63,\n                2,\n                710.4349,\n                292.928,\n                2,\n                690.765,\n                253.113,\n                2,\n                871.88,\n                429.244,\n                2,\n                861.04,\n                275.182,\n                2,\n                894.319,\n                509.588,\n                2,\n                929.981,\n                418.01,\n                2,\n                901.22,\n                581.445,\n                2,\n                924.708,\n                508.795,\n                2,\n                823.63,\n                647.69,\n                2,\n                769.341,\n                541.653,\n                2,\n                850.322,\n                625.912,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                823.63,\n                647.69,\n                2,\n                905.804,\n                486.059,\n                2,\n                0,\n                0,\n                0,\n                907.2,\n                647.636,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"image_id\": 4645041,\n            \"center\": [\n                809.0,\n                403.0\n            ],\n            \"scale\": 0.2550422514,\n            \"category_id\": 1,\n            \"id\": 26901,\n            \"iscrowd\": 0\n        },\n        {\n            \"num_joints\": 39,\n            \"keypoints\": [\n                698.0,\n                217.0,\n                2.0,\n                600.0,\n                242.0,\n                2.0,\n                767.0,\n                310.0,\n                2.0,\n                551.0,\n                307.0,\n                2.0,\n                790.0,\n                405.0,\n                2.0,\n                488.0,\n                351.0,\n                2.0,\n                747.0,\n                421.0,\n                2.0,\n                670.0,\n                437.0,\n                2.0,\n                751.0,\n                574.0,\n                2.0,\n                685.0,\n                579.0,\n                2.0,\n                768.0,\n                717.0,\n                2.0,\n                694.0,\n                684.0,\n                2.0,\n                591.3663,\n                117.4341,\n                2.0,\n                642.6337,\n                217.5659,\n                2.0,\n                584.59,\n                231.591,\n                2,\n                649.816,\n                141.342,\n                2,\n                605.668,\n                337.961,\n                2,\n                566.695,\n                256.226,\n                2,\n                581.685,\n                330.685,\n                2,\n                510.6881,\n                317.872,\n                2,\n                530.2038,\n                341.493,\n                2,\n                481.6367,\n                358.297,\n                2,\n                725.537,\n                311.805,\n                2,\n                651.465,\n                169.726,\n                2,\n                766.905,\n                363.613,\n                2,\n                774.747,\n                267.874,\n                2,\n                784.675,\n                432.399,\n                2,\n                796.495,\n                356.847,\n                2,\n                726.118,\n                528.068,\n                2,\n                649.638,\n                446.552,\n                2,\n                737.496,\n                516.31,\n                2,\n                667.32,\n                620.422,\n                2,\n                736.118,\n                628.657,\n                2,\n                663.697,\n                699.859,\n                2,\n                726.118,\n                528.068,\n                2,\n                799.279,\n                341.113,\n                2,\n                727.888,\n                644.205,\n                2,\n                798.633,\n                526.499,\n                2,\n                0,\n                0,\n                0,\n                799.314,\n                644.016,\n                2\n            ],\n            \"image_id\": 60754485,\n            \"center\": [\n                698.0,\n                404.0\n            ],\n            \"scale\": 0.24552578040000003,\n            \"category_id\": 1,\n            \"id\": 26834,\n            \"iscrowd\": 0\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/ochuman/test_ochuman.json",
    "content": "{\n    \"categories\": [\n        {\n            \"keypoints\": [\n                \"nose\",\n                \"left_eye\",\n                \"right_eye\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ],\n            \"id\": 1,\n            \"supercategory\": \"person\",\n            \"name\": \"person\"\n        }\n    ],\n    \"images\": [\n        {\n            \"file_name\": \"003799.jpg\",\n            \"width\": 900,\n            \"height\": 864,\n            \"id\": 1\n        },\n        {\n            \"file_name\": \"000817.jpg\",\n            \"width\": 665,\n            \"height\": 1000,\n            \"id\": 2\n        },\n        {\n            \"file_name\": \"003896.jpg\",\n            \"width\": 602,\n            \"height\": 900,\n            \"id\": 3\n        }\n    ],\n    \"annotations\": [\n        {\n            \"area\": 356725,\n            \"image_id\": 1,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"bbox\": [\n                250,\n                112,\n                475,\n                751\n            ],\n            \"segmentation\": {\n                \"counts\": \"Zei62gj08I7N2N2N2N1O1O001O1O1O001O1O4L3M3M2N2N1N3N1c_OdNU7]1jHhNQ7Y1nHlNm6V1PIPOk6Q1TITOh6l0fFcNnKf0W=h0kFjNeKc0[=d0oFQO]Ka0`=>SGQO\\\\Kg0[=9YGQOZKk0X=5^GPOYKS1g9mNoFWOnMk1R6oNYK]1\\\\9WO\\\\FnNkNa1T6mNWKd1W9EdEdNIX1U6lNUKe1V9f0`EjNU6kNUKf1S9f0cEjNT6kNUKh1Q9c0fEkNT6kNSKi1_4oMRNc2XLkNT6jNRKk1Z4bNfMo1jLkNT6iNRKm1S4SO]M]1ZMkNS6iNRKn1n3]OYMS1dMjNS6iNPKo1l33dL>]NhNS6nNjJk1l37dL;cNfNS6mNiJn1`3?nL2fNeNR6mNiJP2l2P1_MAiNcNS6lNhJT2[2Z1oMUOkNbNS6jNiJW2U2X1UNVOjNbNS6iNhJZ2Q2T1[NYOiNaNR6iNhJ\\\\2m1U1]NVOlN`NS6iNgJ^2h1X1[NUOSO]NS6hNfJa2d1Z1gMFLhMS6gNeJd2a1V6gM_HS6hNdJf2^1T6kM_Ho5`MRJW1f0h2Z1S6oM]HP6bMQJU1f0l2V1Q6SN\\\\HP6dMPJS1f0P3S1n5VNZHR6fMnIS1g0Q3o0m5ZNYHR6gMnIR1f0T3j0m5`NVHR6QOcJP3e0k5fNTHR6QOdJR3?k5kNRHR6QOdJa3N^5\\\\OPH^5EXKQ>ZOZBZ5I\\\\Km=ZOZBo44hKa=YO\\\\Bm44jK`=YO\\\\Bl45kK_=YO`Ah5Q1PK^=XO_Ai5U1nJn>R5TAmJl>R5VAnJj>Q5VAoJj>Q5WAnJj>R5VAnJi>R5XAmJi>S5WAlJi>U5WAkJi>T5WAlJi>U5WAgJm>X5TAdJX=F_Ag5ja0YJV^Og5ia0ZJU^Oi5ia0XJV^Oj5ia0VJW^Oj5ha0WJX^Oj5ea0RJa^On5l`0dJU_O]5\\\\`0oJf_OR5m?YKS@h4k?YKV@h4g?XK[@h4c?YK]@i4`?WKa@k4[?WKe@j4Y?WKf@l4X?TKh@n4U?RKm@o4P?RKQAo4l>RKUAP5g>QKZAP5b>RK_Ao4^>QKdAQ5W>PKkAQ5R>oJPBR5n=mJTBU5h=lJYBU5d=kJ^BV5_=jJcBX5Z=iJfBX5W=iJjBX5S=jJmBX5o<jJQCW5l<kJUCU5e<oJ\\\\CS5^<QKbCQ5Z<QKfCP5W<QKkCP5P<SKPDn4m;TKSDn4k;RKUDP5m;lJTDT5o;gJRD[5P<aJPDa5S<ZJmCg5X<SJhCo5]<jIcCW6b<cI^C_6j<WIVCk6m<PIRCR7n<mHRCV7l<hHUCZ7j<cHXC`7f<]H\\\\Cf7d<UH^Cn7f<jG[CY8d?2N3M3i_O^Gk=e8PB_Gn=]9TAgFi>_9o@fFU7HBg9RIeFY7O[Oa9UIcF^75UO^:h0eEUO]:j0fESO[:k0hERO[:k0iEROX:m0jEPOX:o0jEoNX:n0kEoNW:P1kEnNV:Q1lEmNV:P1lEnNV:Q1lEmNU:R1mElNU::eFD\\\\96kFHV94nFJT92QGLP93QGLQ91QGMQ91QGNP90RGNP91QGOo8OTGOn8MUG2l8LVG4j8JXG5i8IYG5i8JXG4k8JUG4n8JTG4n8KSG1Q9MQGOT9OmFOU9NnFOU9OmFOU9NmF1U9MjF1\\\\9CcFd0b9[O\\\\Ff0f9YOXFh0j9XOTFg0o9XOPFh0R:TOSEnKlMm4S=ROPEVLjMh4X=QOlD\\\\LeMf4a=mNhDaLdMc4e=kNeDfLbM`4k=iNbDkL_MY4T>^NiD\\\\MPMP4_>cN`D`MmLm3g>aNZDh1YMXK_>P3VDf1d<YNZCf1j<YNTCf1P=ZNmBe1W=ZNgBh1Z=XNcBj1^=VN_Bl1b=TN\\\\BVMRNh3c?RO[BmL_Nl3W?WOaCd0`<\\\\OdCPMWLU3W`0KnCNV<SOe_OdNY4R2V<XOd_OdNZ4o1T<\\\\Od_OcN\\\\4m1Q<^Og_OaN]4l1n;]Ol_OdNX4m1n;^Ol_ObNY4f0eKBW`0V1VESOWKVOe?g1UEoNZ<P1fCPOZ<P1gCnNZ<R1fCmN[<S1fCUNaJ4ia0g1i6O10001O001O001O0O101N1O2O001O000O2O001O001N100O2O0O2O001N2O0O2O1N101O1O0O2O001O1N101O1O001N101O0O2O00000O2O000O101O0O10001O0O10000O2O000O1O2N1N2N2ORhl1OPXSN1O001O1O100O001O1O1O1O001O1O1O1O001O1O1O1O001O1O1O1O001O1O1O001O0O2O00000000000O1000000O2O0000000O100000000O010000000O01000000000O010001O00001O0000002N1O2N2N1O0O100O1O1O1O100000001O2N1N2N3M3N3MShf4\",\n                \"size\": [\n                    864,\n                    900\n                ]\n            },\n            \"num_keypoints\": 17,\n            \"id\": 1,\n            \"keypoints\": [\n                371.5701271305881,\n                188.86769422623237,\n                2,\n                380.9752835872622,\n                174.5554996182501,\n                2,\n                353.4413472938106,\n                177.5542451551607,\n                2,\n                397.6046906555844,\n                184.91480238212299,\n                2,\n                328.49723669132726,\n                196.90978452976526,\n                2,\n                478,\n                258,\n                2,\n                302,\n                285,\n                2,\n                577,\n                287,\n                1,\n                343,\n                390,\n                2,\n                661,\n                282,\n                2,\n                431,\n                363,\n                2,\n                430,\n                486,\n                1,\n                352,\n                477,\n                2,\n                416,\n                662,\n                2,\n                335,\n                643,\n                2,\n                329,\n                785,\n                2,\n                307,\n                810,\n                2\n            ]\n        },\n        {\n            \"area\": 154660,\n            \"image_id\": 2,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"bbox\": [\n                147,\n                172,\n                220,\n                703\n            ],\n            \"segmentation\": {\n                \"counts\": \"ffn4=bn0=^Ob0]Ob0gNX1I7I7J5J7mNdLRVO`3ki0Q1M3L4G8G:K5K4L5K5K4L5J5L5J5K31Q1oN2M3N2N2N2M3N2N1O1N2O1O2N1O100O2O000O10001N1FhFdZOX9Ze0kFdZOV9Ye0nFfZOS9We0QGgZOj8\\\\e0g0I8G8I8H8H=B>m\\\\OaEd`0m:k^OgEd`0f<F;F:F9H9G6K3L5XCX@h9l?lE^@k9n?gE^@R:k?aE`@X:o?WEY@d:Xb0L4M3M3L4M4L3O1N2O1O1O1O1N2O1O10000OYMPFf]O0\\\\2P:d?WFZ^OIk1P:b?]Fi^OAd1R:V?gF[_OWO]1R:l<WF]BQ1@eNU1S:j<QIVBlLn0S:h<SI^BjLh0S:h:mFWDY2;hLd0Q:k:TKcDkJa0Q:l:RKgDlJ<R:m:QKiDnJ8Q:o:PKkDoJ5Q:P;oJnDPK0Q:R;nJQEPKLR:S;lJgFU5Y9hJjFX5V9lHiCWNg1kNUOS:[;fHgD_Mo0IlNR:];aHkG^M`LR:e;[HSHiMoKl9Y<kGPHT9V9`ERG^:n>N1O2N2N2N010O010O010O0100O0YM_Eh@a:S?iEh@V:T?QFi@P:R?WFl@k9n>[Fo@h9j>^FTAe9e>bFWAb9b>eF[A^9^>iF_AZ9Z>mFbAX9V>nFhAV9P>PGnAS9k=SGRBQ9g=UGWBm8c=YG[Bj8J\\\\DV<P3mCk8A_DZ<l2SDR9QO\\\\Dc<h2YDR:b;VFZDk9a;]FXDg9c;`FWDc9c;gFUD^9c;X5H8G8I7I7I7I7I7I7]FgZOP9`e0mFdZOo8_e0nFdZOR9\\\\e0kFhZOT9fe0M4F:F9@a0L4K5kMnXOnKWg0o3RYOcKVg0Z4QYOZKWg0f4YYOSK^f0o4UYOaKff0`4SYOeKnf0h4bXO[K`g0e4ZXO\\\\Klg0k56K6J6I8I8H8hKSWOh1Ti0nMYWOi1lh0PNbWOc1bh0XNiWO`1Yh0[NQXO_1Ph0[N[XO_1gg0[NcXO]1`g0]NkXO[1ij0H6J7I8I7J2M3I7JmYZ9\",\n                \"size\": [\n                    1000,\n                    665\n                ]\n            },\n            \"num_keypoints\": 16,\n            \"id\": 2,\n            \"keypoints\": [\n                274.6507065128343,\n                246.39765980455803,\n                2,\n                285.42040464043833,\n                233.5265571642508,\n                2,\n                260.99157718026333,\n                231.16247708745965,\n                2,\n                0,\n                0,\n                0,\n                239.45218092505533,\n                241.40682408688787,\n                2,\n                317,\n                320,\n                2,\n                205,\n                323,\n                2,\n                328,\n                415,\n                2,\n                183,\n                423,\n                2,\n                345,\n                506,\n                2,\n                173,\n                504,\n                2,\n                300,\n                495,\n                2,\n                230,\n                496,\n                2,\n                291,\n                661,\n                2,\n                240,\n                665,\n                2,\n                276,\n                763,\n                2,\n                245,\n                800,\n                2\n            ]\n        },\n        {\n            \"area\": 94308,\n            \"image_id\": 2,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"bbox\": [\n                143,\n                235,\n                174,\n                542\n            ],\n            \"segmentation\": {\n                \"counts\": \"Sme48on09G8H8H8H8H7I1O2N1^Ob0POP1J6]NeLTWOa3fh0kLmVO[3nh0QMfVOT3Ui0b1K5L3L5L3N3M2N3M4L4L3M4L4K5M2N3M3Mm0SO3N2M3M3M2N3O000O2O0O101O0O100O2O000O2O0O101O0O100O2O000@b0I9H8G9I7g^OWEh=Q;TAQFg>U:V@nFc?a<J5J7J5J7J5J7I7I6J7H7[Ca_OX:f`0ZEh_O_:_`0SEP@T:Pc0J6J4M1N2O0O2N2O1N2O1N2O01000O100000TMjEf@V:n>TFSAl9b>^F`Ab9o;ZFgB>\\\\1X9_;PGaB2R2n8o:fG[BFh2c8`:RJoChK0V:c;_J_D^KJS:[;iJoDVKAR:`;fJSEZKYOP:c;eJWE^KROl9h;dJZEbKjNj9l;bJ^EfKbNh9P<aJ`EjK\\\\Ne9T<_JdEnKTNb9X<PI[CUN]2YOmMc9[<[HWD]Nf1GeMa9^<VHdDTNa16ZM`9a<SHoDiM^1d0PMa9n<dGPHmNoJ_9c=oFbGl9P9_ETGa:i>0100O00100O00100O10O01O10O0`MZE_@f:Z?eEb@Z:X?PFe@o9U?\\\\Ff@f9R?dFk@^9k>lFSAW9e>PGXAS9a>TG\\\\Ao8]>XG_Al8Z>ZGcAj8V>]GfAg8S>`GiAd8P>cGlAa8m=eGPB_8j=gGSB]8f=iGVB\\\\8;mCQ<m3`C[86YDk;Qb0J4L3M3L4M3D<E;E;E;E;G;M4K5K4M2M3H7H9F:G900O100YMcYOaL^f0a3aYO^L_f0d3aYOYL`f0i3PYO^J8f1hf0o3mXO_J:`1if0Y4YYOeKhf0[4UYOhKkf0W4SYOkKof0S4oXOPLWg0l3dXOWLcg0d56J4kJVXOb2og0oLaXOl2dg0jLfXOQ3^g0gLkXOT3Yg0dLPYOV3Vg0aLXYOT3mf0eLbYOn2cf0jLnYOi2^i0J1O001gMiSO`1Vm0oNaROKbm0ObRO0am0JcRO5`m0FdRO9^m0AfRO>]m0\\\\OhROb0Pn0O101N2N3M3K5Kd^R9\",\n                \"size\": [\n                    1000,\n                    665\n                ]\n            },\n            \"num_keypoints\": 13,\n            \"id\": 3,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                217.01654468945043,\n                302.1730492658786,\n                2,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                285,\n                328,\n                2,\n                187,\n                339,\n                2,\n                293,\n                412,\n                2,\n                176,\n                414,\n                2,\n                308,\n                490,\n                2,\n                174,\n                495,\n                2,\n                270,\n                491,\n                2,\n                224,\n                493,\n                2,\n                271,\n                614,\n                1,\n                227,\n                614,\n                2,\n                225,\n                704,\n                2,\n                215,\n                716,\n                2\n            ]\n        },\n        {\n            \"area\": 517461,\n            \"image_id\": 3,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"bbox\": [\n                0,\n                39,\n                601,\n                861\n            ],\n            \"segmentation\": {\n                \"counts\": \"Xj0Y1jj02N101N10001N10000O0100O010O10O0100O02O00001N101O001N2O001O0O2O1O0O2O0UAUN]3l1aLZNY3h1fLXNZ3h1eLYN[3h1dLXN[3j1cLWN]3i1cLWN[EL[=o1XMVNZEN]=m1YMUNWE1_=l1XMSNXE4^=j1XMRNZE6]=i1XMQNZE8]=h1XMPNZE:j<^O_CZ2[:nM\\\\E<_<JeCm1_:mM]Ea0LXOT<f0nCe1d:mM\\\\Ei0`;l2RO[L^Ek0];l2TOZL^Ek0\\\\;m2UOZL]Ej0\\\\;n2TO[L^Ej0[;m2UOfM;k2CUM<n2CRM;P3EPM9S3GkLdEXN^:o4NhLcE\\\\N[:P52aLdEbNV:o46\\\\LdEjNo9BPF\\\\5]:iLDW3<jLEU3;jLFV39jLIT37lLKS35lLLT33lLOR32mLOS30nL1n22PM0n20QM4k2NSM6g2NVM6d2OYM6c2L[M8a2I_M:\\\\2IbM;Q20nM3k12TN1j1NVN4h1MXN5f1KZN7d1H]N:a1F_N<^1EcN<Y1FhN<S1FoN;l0HTO:g0H[OYMWNlIZ2l8AcD[Nm7NcJS2n8;\\\\LfMfJj1P9a0XLjMfJb1S9f0TLkMiJ\\\\1U9i0PLnMlJU1U9n0mKoMoJo0V9T1gKQNSKh0W9X1bKUNXK?X9\\\\1]KYN[K8Y9P1dKQOSKK[9S1aKVOUKC\\\\9U1^K\\\\OVK\\\\O]9W1]KAUKUO_9Y1[KFWKmN_9\\\\1ZKKVKfNb9S1_K=oJ]Nc9S1\\\\Kg0QKTNc9R1^Km0oJoMd9o0`KU1lJjMd9i0gK_1fJfMc9i0gKe1fJ_Me9i0fKk1fJYMd9l0eKn1gJTMd9n0dKQ2hJoLd9P1cKT2^7lM`HW2^7iM`HZ2_7fM`H]2^7dM`H_2^7aMaHb2]7^MaHe2^7\\\\M`Hg2^7ZM_Hj2_7VMTHPOkHm3P?TMSHTOhHk3S?RMnGa3P8_LoGd3n7^LQHc3n7^LPHe3n7[LRHg3l7ZLRHi3l7XLRHk3l7ULPHQ4n7PLmGU4R8lKjGY4U8fKjG]4T8dKkG]4U8bKjGa4T8`KjGb4U8_KiGc4W8\\\\KiGe4V8\\\\KhGn3WJPKP>S1gGn3^JjJl=W1eGP4cJeJh=\\\\1dGo3U9PLjFQ4W9oKgFR4Z9nKeFR4\\\\9mKdFS4\\\\9nKbFS4_9mK`FS4a9lK_FT4b9lK]FT4d9kK[FV4e9kKZFT4h9kKXFU4i9kKVFU4k9jKUFV4l9iKTFW4l9jKTFU4m9jKTFU4m9jKSFV4n9jKRFU4n9kKSFU4m9kKRFU4o9jKRFU4o9jKRFU4n9lKQFT4o9lKRFS4o9lKQFT4o9mKQFR4o9nKRFQ4o9nKQFR4o9nKRFQ4n9PLQFP4P:oKQFo3P:QLQFn3o9RLQFn3P:RLPFm3P:SLQFl3o9TLRFk3o9SLSFl3m9SLUFk3l9ULUFj3l9VLTFi3l9XLRFi3n9XLoEj3R:VLlEk3U:ULhEm3X:SLgEn3Z:RLdEo3]:QL`EQ4`:PL^EQ4c:oK[ER4e:oKYER4h:nKWER4j:nKTES4l:nKRET4n:lKPEU4P;lKnDU4S;jKmDV4S;kKkDV4U;kKjDU4W;kKgDV4Y;jKfDW4[;iKdDW4\\\\;jKbDW4^;iKaDX4`;hK_DX4a;iK]DX4c;hK\\\\DY4e;gKYDZ4g;gKWD[4i;dKVD]4j;dKUD\\\\4l;dKRD^4m;bKSD^4n;bKPD_4Q<aKmCa4R<`KlCa4U<_KiCb4X<^KgCc4X<^KfCc4[<]K\\\\Ck4d<VKYCm4g<SKXCm4i<SKUCn4k<SKSCn4n<QKRCo4n<RKnBP5T=PKiBR5W=oJeBS5]=lJaBV5_=kJ`BU5a=kJ^BT5c=lJ\\\\BU5e=kJZBT5g=mJWBU5i=jJVBW5j=jJTBX5l=hJRBY5n=gJQB[5o=eJcAh5]>XJbAj5^>VJ`Ak5a>UJ]Am5c>SJ[An5f>QJYAQ6g>oIWAR6i>oIUAS6k>mIRAU6o>jIPAW6Q?iIm@X6T?hIj@Y6V?hIg@Z6Z?fIc@]6\\\\?dIa@^6`?cI\\\\@_6d?cIY@^6h?cI`_OZN2U8_`0bIZ_ObN0m7f`0cIV_OU7k`0Q2001O1O001O0O2O010O0010O01O10O01O100O1O1000000001O000000001O0000001O0oLUEiDk:W;WEgDi:Y;YEeDh:Z;YEeDg:[;ZEdDf:\\\\;[EcDf:[;\\\\EdDd:\\\\;]EcDc:\\\\;_EcDa:];_EdDa:Z;aEeD_:[;cEcD^:[;dEdD]:[;dEdD^:Y;dEfD]:Y;dEfD^:W;eEgD[:Y;fEgDZ:h:XFVEh9i:\\\\FTEe9j:_FSEa9l:dFPE\\\\9o:kFkDU9U;PGeDP9\\\\;TG`Dk8a;ZGYDg8g;]GUDb8l;bGoC^8R<eG`Cf8`<]GYCf8b<_DSCQ31d8l<\\\\310O1O10O01O1;E1O1O00000O2O00M3M3O02O1O01O00001O01ON3Lb0_O5A?L4M4K4L4L4L8H5L1N2N3N100O2O0O100O100O10WL_EnE`:P:dEoE\\\\:n9gERFX:l9kETFU:i9nEWFR:f9RFYFm9f9VFXFl9oLbEP;0ZEe0f2k9hLeEV;1VEc0k2i9cLgEY;5RE>R3U:k7fEjD7[3Z9`L\\\\FX;^1YHT8cLZF\\\\:FkEo1W3o7jLTFm98mEh1\\\\3k7]7cFSEd1a3h7Y7XIhHf6W7\\\\IiHc6U7aIkH]6T7eImHY6R7jInHT6Q7nIPIQ6n6RJQIm5n6UJSIi5k6[JUIc5j6_JVI`5g6eJYIZ5a6lJ_IS5X6WKiIg4S6^KmIb4o5bKQJ]4l5gKUJW4h5mKYJQ4f5QLZJo3c5UL]Ji3b5YL^Jf3W1jFTOd5Ec3T1oFoNb5KS4a0]FAc5NS4=\\\\FAe50P4=^F_Oe54m3<_F]Oh55k3<^F\\\\Oj58h3;_F[Ok59d3>bFXOk5<\\\\3`0jFROl5c0R3=SGnNm5j0h29\\\\GlNn5o0`26cGjNn5T1Y23jGgNo5V1U24mGdNS6T1n1:oGaNZ6P1e1`0RH_N`6k0]1g0SH\\\\Ng6h0mHbLc7Z4jH[Nh6j0fHdLh7`0oGm2k0SOk6m0]HfLn7;PHP3j0ROm6\\\\18aLQHR3k0oNo6]14aLRHT3l0mNP7\\\\12aLTHV3k0lNQ7\\\\1O`LVHY3j0jNT7\\\\1LVL_He3a0iNV7[1<DaGeLm0[2X7\\\\18CdGfLl0[2Z7Z16DeGgLk0[2]7W12SOfGdM1Fj0]2`7R1OTOkGbMOKh0\\\\2c7P1IXOPH\\\\MOOe0]2i7j0C^ORHWM13b0]2n7e0]ODcHZM2]2T8`0UOJfHXM2]2V8>ROMgHWM1^2Y8;nN1iHVM0]2[8:mN1iHWM1]2[8:kN1jHWM1]2]88iNfMnGf1S2=W75hNdMRHa1D]N^2X2V74gNbMTHe1DXN^2\\\\2V73WOYOiId0Q71VO[OjIc0S7OSO]OlIc0S7NQO_OlId0U7KmNBoIb0W7IjNEPJa0W7IhNGRJ`0W7GgNIRJ`0X7GdNJUJ>Y7FbNLVJ>X7EaNNWJ=Y7D_N0YJ<Y7B^NH]GbNl2T2[7_O_NE`GfNg2V2[7]OcN^O`GnNc2V2\\\\7[OeN[OdJZ1i6YOcN[OgJ\\\\1g6WOcNYOiJ`1f6TObNZOkJb1d6RObNYOlJe1e6nN`NZOoJh1b6lN`NVOSKn1`6iNU3V1lLgNW3W1kLgNW3X1jLeNY3Y1hLfNZ3Y1gLdNZ3\\\\1gLbN[3^1fL_N[3a1gL[N\\\\3e1gLVN[3i1jLQNW3P2_;O100O1N2M3M3M3M201O1O001O1O00100O1O1O1O1O00010O00001O000010O01O100O1O010O010O0100O2O0O100O2N1O00001O0000000O101O0O1O1O1BiNnUOX1Qj0>N10100000000001OO01000000O1O100O1N2N3M2N3M2N3M2K5OO1O20O0000100O1O1O1O1O2N1N3QOnTOh0Xk0N3M2H8M3N3M2NTW3\",\n                \"size\": [\n                    900,\n                    602\n                ]\n            },\n            \"num_keypoints\": 12,\n            \"id\": 4,\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                446,\n                292,\n                2,\n                263,\n                225,\n                2,\n                540,\n                346,\n                2,\n                161,\n                269,\n                2,\n                560,\n                327,\n                2,\n                103,\n                312,\n                2,\n                308,\n                495,\n                2,\n                236,\n                491,\n                2,\n                352,\n                499,\n                2,\n                124,\n                652,\n                2,\n                442,\n                677,\n                2,\n                67,\n                827,\n                2\n            ]\n        },\n        {\n            \"area\": 404028,\n            \"image_id\": 3,\n            \"iscrowd\": 0,\n            \"category_id\": 1,\n            \"bbox\": [\n                84,\n                45,\n                516,\n                783\n            ],\n            \"segmentation\": {\n                \"counts\": \"ln`2?ck04M2M3N2M3N2M3N2M3N2M3M4L3M3N3L5K4L5K5L2M3M2O2O0O2N2O0O2N101N2N2N2O1N2N2O1N2N4M4K4L2O1N2O1O000O10000000O1001N101O001O001O001O001O0010O01O1O001O1O3M;E1O2O0O2N1O2N2N1O2N1O3N2M3M3M3N2R@PKc8o4\\\\GQKe8o4YGSKh8l4VGUKl8f4e@fJ]6f0o8b4g@fJY6i0P9a4SG`Ko8_4PGaKR9]4mFcKV9\\\\4iFdKY9[4fFdK\\\\9[4cFfK_9Y4dARKX3d0W;Y4aATKW3a0[;Z4]AXKU3=`;Z4\\\\AZKR3;e;Z4YA]KP36k;\\\\4TAbKm21R<[4RAgKXO1U2Jf=]4m@kKiN>`2TOP>c4g@VMX1XNS>`4e@YMU1ZNY>Z4b@\\\\MS1[N_>U4_@`Mo0]Ng>o3Y@dMo0^Nl>j3V@hMk0_NT?f3Q@kMi0_N[?b3m_OoMe0`Na?`3i_OQNc0`Ng?]3g_OSN`0`Nk?]3e_OSN=`NR`0[3a_OVN;_NW`0Z3^_OWN7bN\\\\`0V3^_OXN1eNd`0R3[_OYNMgNj`0o2Z_OZNHjNPa0k2X_O[NDkN[;QO[Ig3gK]N_OlNa;SOWId3jK\\\\NZOnNh;TOSI`3lK^NUOPOn;UOnH]3oK^NQOROS<VOlHX3QL`NgNXO_<ROhHT3SL9W;eLdHQ3VL8W;iLcHm2WL6Z;mL_Hl2WL3^;SM[Hh2XL2`;VMXHg2XL1c;XMVHe2XL0d;]MSHb2ZL0d;^MSH`2YL2d;_MSH_2YL1e;`MSH]2XL3f;aMQH\\\\2YL1g;dMQHZ2WL2i;dMPHY2XL2h;fMQHW2WL2i;fMQHX2UL1k;hMQHV2TL0l;jMRHT2RL0o;lMoGT2RLNP<nMPHS2PLMR<PNnGS2oKKU<RNnGQ2nKKV<TNlGQ2mKHZ<WNkGP2kKE^<[NgGP2kKAa<_NeGo1jKAc<`NcGo1jK^Oe<cNaGP2jK[Og<eN_GP2iKYOj<gN^Go1iKjNX=WOPGo1hKhNY=ZOoFn1gKgN[=[OoFm1gKeN\\\\=_OlFm1hKbN]=AlFm1fKaN_=CkFk1RLTNT=2kFj1]L\\\\Mk<S1hF`1l;aNUD_1i;cNVD]1i;dNXD\\\\1f;fNZDZ1d;gN]DX1b;jN]DW1b;iN_DV1a;kN_DU1_;lNaDT1_;mNaDS1^;mNbDT1];mNcDR1\\\\;oNdDR1[;oNeDQ1Y;POhDo0X;ROgDo0W;ROjDn0U;SOjDn0U;ROlDn0S;ROnDn0j6]MQGe1T2o0l4gMZFi0c1a0X3o0k4jMVFR1\\\\15c3o0l4lMPF^1T1GQ4o0k4nMlEk1j0YO^4o0l4PNgEY2`0gNn4P1k4RNcEa2;^NW5o0k4UN_Ec2:ZN\\\\5n0k4WNVEm2>mMa5P1l4b2]E_Lg5o0l4o4UKQKk4o4TKRKl4n4TKRKl4m4UKSKl4l4TKTKl4k4TKVKl4j4TKWKk4h4VKXKk4g4UKYKk4g4TKZKm4d4TK]Kl4b4TK^Kl4a4UK_Kl4`4SKbKl4]4UKcKl4\\\\4TKeKk4[4UKeKl4Y4TKiKl4V4TKjKl4U4UKkKl4T4TKmKk4R4VKnKj4R4WKnKh4R4XKSIcI^2U;^4ZKQIeI_2Q;`4ZKPIiI^2l:a4]KoHjI]2j:d4\\\\KnHmI\\\\2g:f4]KkHPJ\\\\2d:h4ULTKl3l4VLRKi3n4ZLoJg3Q5[LlJe3T5_LXJR4h5PLkI[4U6gK`Ia4`6cKWIc4i6_KoHg4P7V810O01000O010UKS[O^2md0dMS[O[2md0fMS[OX2md0jMT[OT2ld0nMS[OQ2ld0QNT[Om1md0TNS[Ok1ld0WNT[Og1md0[NS[O\\\\Nn0S1nc0c0U[OjMc1[1Wc0l0g]OlNZb0T1m]OdNTb0]1S^OZNna0f1W^OTNla0j1X^OQNja0n1Y^OnMia0R2Z^OiMha0V2[^OfMga0Y2]^ObMea0]2_^O^Mca0b2P4O1O2N3N1N2N3M2O2M3_NoUOi0Uj0POoUOP1Sj0hNRVOY1\\\\j0010O010000O10000O1000]LhNY\\\\OW1ec0mN[\\\\OR1bc0RO]\\\\Om0ac0VO`\\\\Oi0]c0[Oc\\\\Od0Zc0_Og\\\\O`0Ub0nNX[Of0b2<na0WO\\\\[O`0g28ea0V1\\\\^OiN_a0\\\\1a^OdN\\\\a0^1f^OaNVa0c1k^O]Na`0WOP\\\\O_2`3ZN^`0W2c_OhM[`0Y2f_OgMX`0[2i_OcMV`0^2k_ObMS`0`2m_O`MQ`0c2n_O\\\\MQ`0h2m_OXMP`0m2o_OQMP`0S3n_OmLP`0V3o_OjLn?Z3Q@eLn?^3R@aLk?b3V@]Lh?e3Y@YLf?i3[@VL]:[ORGb4bNQLZ:BPG_4gNnKW:FnF_4lNjKS:JoF^4oNfKQ:NlF`4SObKn91hFd4YO[Ko92bFi4_OUKP:1[FP5EoJQ:0UFV5JiJR:1oE\\\\5NcJS:0mE`50`JS:0jEc53]JS:0hEe55ZJT:0eEh58XJS:0bEj5<VJR:0_El5?TJT:O[Eo5l>PJRAQ6P?oIn@Q6T?oIi@R6Y?nIe@R6]?mIc@S6^?mI`@S6b?mI]@R6e?nIZ@P6i?PJV@j5Q`0VJm_Oh5W`0WJi_Og5Z`0YJe_Od5_`0\\\\J__Oc5d`0]J\\\\_O`5g`0_JY_O_5j`0`JV_O]5o`0aJQ_OR5]a0mJc^Oo4ba0QK^^Ok4fa0TKZ^Oh4ka0WKU^Og4S1WKR=1kAf4V1\\\\Kk<NoAc4Z1cKc<JSB`4]1jK\\\\<FVB_4`1oKV<AZB^4c1ULn;^O^B[4g1ZLh;ZOaB[4i1^Lc;WOdBX4l1cL^;UOeBV4P2gLf8ROZE10U4Q2iLc8SO\\\\EOOS4U2lL\\\\8TOaEMMQ4Y2nLW8VOcEJNo3[2RMP8WOhEHLm3_2UMj7XOkEFKk3c2WMd7ZO]H]32ZM^7[O_HY36\\\\MX7]OcHT38`MR7^OeHP3<bMl6@hHm2=fMg6_OkHi2a0iMa6_OoHe2c0nMY6@SI`2g0QNS6@VI^2i0SNm5BZIX2l0XNf5A^IU2o0[N_5CaIQ2R1^NY5BfIm1T1aNS5EhIh1X1cNn4FkId1Z1gNg4HnI`1]1hNc4JPJ[1`1kN^4LQJW1e1mNY4LRJT1h1POV4LQJR1l1ROR4MQJo0P2UOn3LRJl0T2XOh3LTJk0V2ZOe3KUJh0Y2^O`3KVJf0]2_O\\\\3KVJe0`2AX3KXJb0b2DU3JVJc0g2EQ3HVJc0k2Fm2HVJb0n2Hk2FUJ`0T3Ke2EUJ?Y3Na2CUJ<]31^2DTJ8b33[2DSJ7d34[2EoI5j35W2GnI2m37V2FmI0Q49R2HlIMT4;Q2GlIKU4>P2GkIHX4`0n1HSJ\\\\OQ4l0m1Gf38[LHd38]LHc37^LHb38_LHa37`LH`38aLH_37bLI^36cLI]37dLI\\\\36eLI\\\\36eLJZ36fLKZ33hLLY33hLMW33jLLW33jLMU32lLOT30mLOS31nLOR30oLOQ31PMOP3ORM0n20RM1n2NSM2l2MVM2k2MVM3i2LYM3h2KYM6f2J[M6d2I^M6c2I^M7a2HaM7_2IaM8^2GdM9\\\\2FeM:Z2EhM;W2EjM;V2ClM=T2BmM>R2APN?P2@PNa0P2]ORNc0m1]OTNc0l1[OVNe0j1ZOWNf0h1YOZNg0f1XO[Nh0e1VO]Nj0b1UO`Nl0_1ROcNo0\\\\1oNeNR1[1lNgNW1V1gNlN]1_CaNY=OZOl1c0SN^Oo1`0oMBS2W=1O1N0`VOlMQi0S2dVOXN]i0W21O1O1O1O010O1O1N2L4L4M2F;L3M4L3M4M2N3L3N3M2N3O0O2O0O2O0O2O0O2O002M5L3M4L_d0\",\n                \"size\": [\n                    900,\n                    602\n                ]\n            },\n            \"num_keypoints\": 15,\n            \"id\": 5,\n            \"keypoints\": [\n                138.28123044948043,\n                178.42673457794075,\n                2,\n                133.4071828533262,\n                152.16976849543238,\n                2,\n                0,\n                0,\n                0,\n                168.78333476089736,\n                123.08271026031831,\n                2,\n                0,\n                0,\n                0,\n                201,\n                192,\n                2,\n                322,\n                124,\n                1,\n                249,\n                344,\n                1,\n                488,\n                172,\n                2,\n                219,\n                433,\n                1,\n                572,\n                238,\n                2,\n                436,\n                381,\n                2,\n                439,\n                380,\n                2,\n                354,\n                608,\n                2,\n                307,\n                523,\n                1,\n                494,\n                683,\n                2,\n                313,\n                753,\n                2\n            ]\n        }\n    ],\n    \"info\": {\n        \"description\": \"MMPose example ochuman dataset\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/08/31\"\n    }\n}\n"
  },
  {
    "path": "tests/data/onehand10k/test_onehand10k.json",
    "content": "{\n    \"info\": {\n        \"description\": \"OneHand10K\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/08/03\"\n    },\n    \"licenses\": \"\",\n    \"images\": [\n        {\n            \"file_name\": \"9.jpg\",\n            \"height\": 358,\n            \"width\": 238,\n            \"id\": 9\n        },\n        {\n            \"file_name\": \"33.jpg\",\n            \"height\": 346,\n            \"width\": 226,\n            \"id\": 33\n        },\n        {\n            \"file_name\": \"784.jpg\",\n            \"height\": 960,\n            \"width\": 540,\n            \"id\": 784\n        },\n        {\n            \"file_name\": \"1402.jpg\",\n            \"height\": 339,\n            \"width\": 226,\n            \"id\": 1402\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox\": [\n                63,\n                92,\n                99,\n                194\n            ],\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                81,\n                251,\n                1,\n                71,\n                229,\n                1,\n                72,\n                192,\n                1,\n                76,\n                169,\n                1,\n                95,\n                196,\n                1,\n                91,\n                144,\n                1,\n                93,\n                122,\n                1,\n                91,\n                98,\n                1,\n                116,\n                199,\n                1,\n                111,\n                148,\n                1,\n                108,\n                120,\n                1,\n                107,\n                101,\n                1,\n                139,\n                203,\n                1,\n                130,\n                153,\n                1,\n                128,\n                124,\n                1,\n                122,\n                107,\n                1,\n                154,\n                205,\n                1,\n                150,\n                177,\n                1,\n                147,\n                159,\n                1,\n                142,\n                132,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 9,\n            \"image_id\": 9,\n            \"segmentation\": [\n                [\n                    63,\n                    92,\n                    63,\n                    188.5,\n                    63,\n                    285,\n                    112.0,\n                    285,\n                    161,\n                    285,\n                    161,\n                    188.5,\n                    161,\n                    92,\n                    112.0,\n                    92\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 19206\n        },\n        {\n            \"bbox\": [\n                61,\n                154,\n                34,\n                68\n            ],\n            \"keypoints\": [\n                86,\n                221,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                92,\n                176,\n                1,\n                90,\n                168,\n                1,\n                90,\n                160,\n                1,\n                92,\n                189,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                87,\n                191,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                79,\n                194,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"category_id\": 1,\n            \"id\": 33,\n            \"image_id\": 33,\n            \"segmentation\": [\n                [\n                    61,\n                    154,\n                    61,\n                    187.5,\n                    61,\n                    221,\n                    77.5,\n                    221,\n                    94,\n                    221,\n                    94,\n                    187.5,\n                    94,\n                    154,\n                    77.5,\n                    154\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 2312\n        },\n        {\n            \"bbox\": [\n                51,\n                312,\n                376,\n                372\n            ],\n            \"keypoints\": [\n                153,\n                652,\n                1,\n                198,\n                486,\n                1,\n                258,\n                438,\n                1,\n                333,\n                384,\n                1,\n                393,\n                352,\n                1,\n                160,\n                369,\n                1,\n                274,\n                334,\n                1,\n                325,\n                337,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                412,\n                418,\n                1,\n                0,\n                0,\n                0,\n                334,\n                454,\n                1,\n                303,\n                492,\n                1,\n                270,\n                540,\n                1,\n                0,\n                0,\n                0,\n                325,\n                508,\n                1,\n                295,\n                544,\n                1,\n                258,\n                562,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 784,\n            \"image_id\": 784,\n            \"segmentation\": [\n                [\n                    51,\n                    312,\n                    51,\n                    497.5,\n                    51,\n                    683,\n                    238.5,\n                    683,\n                    426,\n                    683,\n                    426,\n                    497.5,\n                    426,\n                    312,\n                    238.5,\n                    312\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 139872\n        },\n        {\n            \"bbox\": [\n                32,\n                68,\n                150,\n                210\n            ],\n            \"keypoints\": [\n                92,\n                264,\n                1,\n                150,\n                213,\n                1,\n                167,\n                202,\n                1,\n                172,\n                187,\n                1,\n                174,\n                172,\n                1,\n                126,\n                164,\n                1,\n                142,\n                147,\n                1,\n                157,\n                151,\n                1,\n                163,\n                168,\n                1,\n                105,\n                151,\n                1,\n                108,\n                120,\n                1,\n                112,\n                98,\n                1,\n                109,\n                70,\n                1,\n                85,\n                157,\n                1,\n                77,\n                132,\n                1,\n                78,\n                108,\n                1,\n                72,\n                89,\n                1,\n                74,\n                174,\n                1,\n                63,\n                157,\n                1,\n                47,\n                137,\n                1,\n                37,\n                119,\n                1\n            ],\n            \"category_id\": 1,\n            \"id\": 1402,\n            \"image_id\": 1402,\n            \"segmentation\": [\n                [\n                    32,\n                    68,\n                    32,\n                    172.5,\n                    32,\n                    277,\n                    106.5,\n                    277,\n                    181,\n                    277,\n                    181,\n                    172.5,\n                    181,\n                    68,\n                    106.5,\n                    68\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 31500\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"hand\",\n            \"id\": 1,\n            \"name\": \"hand\",\n            \"keypoints\": [\n                \"wrist\",\n                \"thumb1\",\n                \"thumb2\",\n                \"thumb3\",\n                \"thumb4\",\n                \"forefinger1\",\n                \"forefinger2\",\n                \"forefinger3\",\n                \"forefinger4\",\n                \"middle_finger1\",\n                \"middle_finger2\",\n                \"middle_finger3\",\n                \"middle_finger4\",\n                \"ring_finger1\",\n                \"ring_finger2\",\n                \"ring_finger3\",\n                \"ring_finger4\",\n                \"pinky_finger1\",\n                \"pinky_finger2\",\n                \"pinky_finger3\",\n                \"pinky_finger4\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    1,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    8,\n                    9\n                ],\n                [\n                    1,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    1,\n                    14\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ],\n                [\n                    1,\n                    18\n                ],\n                [\n                    18,\n                    19\n                ],\n                [\n                    19,\n                    20\n                ],\n                [\n                    20,\n                    21\n                ]\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/panoptic/test_panoptic.json",
    "content": "{\n    \"info\": {\n        \"description\": \"panoptic\",\n        \"version\": \"1.0\",\n        \"year\": \"2020\",\n        \"date_created\": \"2020/09/21\"\n    },\n    \"licenses\": \"\",\n    \"images\": [\n        {\n            \"file_name\": \"005880453_01_l.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 100586\n        },\n        {\n            \"file_name\": \"005880453_01_r.jpg\",\n            \"height\": 720,\n            \"width\": 1280,\n            \"id\": 100587\n        },\n        {\n            \"file_name\": \"ex2_2.flv_000040_l.jpg\",\n            \"height\": 300,\n            \"width\": 400,\n            \"id\": 100520\n        },\n        {\n            \"file_name\": \"ex2_2.flv_000040_r.jpg\",\n            \"height\": 300,\n            \"width\": 400,\n            \"id\": 100521\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox\": [\n                720.32470703125,\n                188.09907531738278,\n                55.445434570312614,\n                36.900924682617216\n            ],\n            \"head_size\": 140.0,\n            \"center\": [\n                747.5474243164062,\n                206.0495376586914\n            ],\n            \"keypoints\": [\n                721.0,\n                224.0,\n                1.0,\n                720.32470703125,\n                216.51248168945315,\n                1.0,\n                727.2195434570314,\n                200.88510131835943,\n                1.0,\n                739.107177734375,\n                194.2553100585938,\n                1.0,\n                752.6591186523438,\n                191.17718505859378,\n                1.0,\n                740.0582275390625,\n                188.09907531738278,\n                1.0,\n                757.6519165039061,\n                189.75651550292972,\n                1.0,\n                760.98046875,\n                196.62309265136716,\n                1.0,\n                760.98046875,\n                202.77932739257812,\n                1.0,\n                742.9112548828123,\n                196.14953613281247,\n                1.0,\n                753.3723754882812,\n                189.75651550292972,\n                1.0,\n                765.0222778320311,\n                199.93798828125,\n                1.0,\n                767.6375122070312,\n                207.04133605957034,\n                1.0,\n                747.6663208007811,\n                202.5425567626953,\n                1.0,\n                757.1763916015626,\n                197.80697631835943,\n                1.0,\n                769.3018188476562,\n                203.72644042968753,\n                1.0,\n                772.3925781249999,\n                209.40911865234378,\n                1.0,\n                753.610107421875,\n                209.17234802246097,\n                1.0,\n                761.6937255859375,\n                205.85745239257815,\n                1.0,\n                769.7772827148438,\n                208.93556213378903,\n                1.0,\n                774.7701416015626,\n                213.43435668945315,\n                1.0\n            ],\n            \"category_id\": 1,\n            \"id\": 100586,\n            \"image_id\": 100586,\n            \"segmentation\": [\n                [\n                    720.32470703125,\n                    188.09907531738278,\n                    720.32470703125,\n                    206.0495376586914,\n                    720.32470703125,\n                    224.0,\n                    747.5474243164062,\n                    224.0,\n                    774.7701416015626,\n                    224.0,\n                    774.7701416015626,\n                    206.0495376586914,\n                    774.7701416015626,\n                    188.09907531738278,\n                    747.5474243164062,\n                    188.09907531738278\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 2045.9878050740865,\n            \"dataset\": \"mpii\"\n        },\n        {\n            \"bbox\": [\n                746.0122680664061,\n                313.11645507812494,\n                50.4322509765625,\n                77.21240234375\n            ],\n            \"head_size\": 140.0,\n            \"center\": [\n                770.7283935546874,\n                351.22265624999994\n            ],\n            \"keypoints\": [\n                746.0122680664061,\n                363.82229614257807,\n                1.0,\n                750.3375854492186,\n                347.22766113281256,\n                1.0,\n                766.0941162109375,\n                330.6329956054688,\n                1.0,\n                778.1432495117188,\n                324.1795349121093,\n                1.0,\n                785.2490844726564,\n                313.11645507812494,\n                1.0,\n                787.720703125,\n                349.3788146972656,\n                1.0,\n                795.4445190429686,\n                349.3788146972656,\n                1.0,\n                790.5012817382812,\n                348.7641906738282,\n                1.0,\n                785.5580444335938,\n                347.5349426269532,\n                1.0,\n                787.720703125,\n                362.90036010742193,\n                1.0,\n                793.8997802734376,\n                360.74920654296875,\n                1.0,\n                785.5580444335938,\n                359.51998901367193,\n                1.0,\n                780.9237670898438,\n                359.2126770019531,\n                1.0,\n                783.7043457031251,\n                374.2707824707031,\n                1.0,\n                791.4281616210938,\n                374.57806396484375,\n                1.0,\n                784.3222656249998,\n                371.5050048828125,\n                1.0,\n                778.7611083984374,\n                370.2757568359375,\n                1.0,\n                777.8342895507812,\n                384.71923828124994,\n                1.0,\n                782.1596069335938,\n                389.32885742187494,\n                1.0,\n                774.435791015625,\n                385.3338623046875,\n                1.0,\n                771.9641723632812,\n                382.87539672851557,\n                1.0\n            ],\n            \"category_id\": 1,\n            \"id\": 100587,\n            \"image_id\": 100587,\n            \"segmentation\": [\n                [\n                    746.0122680664061,\n                    313.11645507812494,\n                    746.0122680664061,\n                    351.22265624999994,\n                    746.0122680664061,\n                    389.32885742187494,\n                    770.7283935546874,\n                    389.32885742187494,\n                    795.4445190429686,\n                    389.32885742187494,\n                    795.4445190429686,\n                    351.22265624999994,\n                    795.4445190429686,\n                    313.11645507812494,\n                    770.7283935546874,\n                    313.11645507812494\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 3893.9952535033226,\n            \"dataset\": \"mpii\"\n        },\n        {\n            \"bbox\": [\n                179.84646606445315,\n                260.29730224609364,\n                42.822525024414034,\n                30.21246337890642\n            ],\n            \"head_size\": 72.5531,\n            \"center\": [\n                200.75772857666016,\n                274.9035339355469\n            ],\n            \"keypoints\": [\n                221.6689910888672,\n                260.29730224609364,\n                1.0,\n                211.34570312499997,\n                260.29730224609364,\n                1.0,\n                192.55204772949222,\n                265.0344543457031,\n                1.0,\n                188.31684875488278,\n                271.0874938964844,\n                1.0,\n                180.90525817871094,\n                275.82464599609375,\n                1.0,\n                192.02264404296878,\n                265.2976379394531,\n                1.0,\n                179.84646606445315,\n                278.7195739746093,\n                1.0,\n                186.4639587402344,\n                279.7722778320313,\n                1.0,\n                190.43444824218753,\n                275.82464599609375,\n                1.0,\n                194.4049377441406,\n                271.6138305664063,\n                1.0,\n                187.52275085449222,\n                284.7726135253906,\n                1.0,\n                192.8167419433594,\n                282.14086914062506,\n                1.0,\n                195.72843933105474,\n                278.4563903808594,\n                1.0,\n                201.28712463378906,\n                277.93005371093744,\n                1.0,\n                194.14024353027344,\n                288.1938781738282,\n                1.0,\n                199.6989288330078,\n                285.0357971191406,\n                1.0,\n                202.34593200683594,\n                282.14086914062506,\n                1.0,\n                207.1105194091797,\n                281.35131835937494,\n                1.0,\n                201.28712463378906,\n                289.50976562500006,\n                1.0,\n                204.72822570800778,\n                286.3516540527344,\n                1.0,\n                207.1105194091797,\n                284.7726135253906,\n                1.0\n            ],\n            \"category_id\": 1,\n            \"id\": 100520,\n            \"image_id\": 100520,\n            \"segmentation\": [\n                [\n                    179.84646606445315,\n                    260.29730224609364,\n                    179.84646606445315,\n                    274.9035339355469,\n                    179.84646606445315,\n                    289.50976562500006,\n                    200.75772857666016,\n                    289.50976562500006,\n                    221.6689910888672,\n                    289.50976562500006,\n                    221.6689910888672,\n                    274.9035339355469,\n                    221.6689910888672,\n                    260.29730224609364,\n                    200.75772857666016,\n                    260.29730224609364\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 1293.7739690924127,\n            \"dataset\": \"nzsl\"\n        },\n        {\n            \"bbox\": [\n                186.37617492675776,\n                196.84266662597656,\n                46.34579467773443,\n                44.16563415527344\n            ],\n            \"head_size\": 72.5531,\n            \"center\": [\n                209.04907226562497,\n                218.42548370361328\n            ],\n            \"keypoints\": [\n                186.37617492675776,\n                232.66671752929688,\n                1.0,\n                190.1365051269531,\n                223.60145568847656,\n                1.0,\n                200.65892028808597,\n                212.39300537109378,\n                1.0,\n                212.89080810546878,\n                203.87417602539062,\n                1.0,\n                219.56018066406247,\n                196.84266662597656,\n                1.0,\n                205.30081176757812,\n                208.3026885986328,\n                1.0,\n                217.7982025146484,\n                207.76916503906244,\n                1.0,\n                227.2103424072266,\n                213.4448394775391,\n                1.0,\n                231.7219696044922,\n                220.28102111816406,\n                1.0,\n                198.5165100097656,\n                212.5708312988281,\n                1.0,\n                219.04794311523443,\n                217.55035400390625,\n                1.0,\n                223.4833374023438,\n                223.01550292968747,\n                1.0,\n                226.81802368164062,\n                230.0469970703125,\n                1.0,\n                196.21739196777344,\n                218.71846008300778,\n                1.0,\n                215.47726440429688,\n                225.73097229003903,\n                1.0,\n                219.04794311523443,\n                232.31103515625,\n                1.0,\n                213.47929382324216,\n                232.78147888183597,\n                1.0,\n                200.53286743164062,\n                233.95339965820318,\n                1.0,\n                211.71386718749997,\n                236.68786621093753,\n                1.0,\n                216.81396484374997,\n                240.00830078125,\n                1.0,\n                210.92922973632812,\n                239.6176605224609,\n                1.0\n            ],\n            \"category_id\": 1,\n            \"id\": 100521,\n            \"image_id\": 100521,\n            \"segmentation\": [\n                [\n                    186.37617492675776,\n                    196.84266662597656,\n                    186.37617492675776,\n                    218.42548370361328,\n                    186.37617492675776,\n                    240.00830078125,\n                    209.04907226562497,\n                    240.00830078125,\n                    231.7219696044922,\n                    240.00830078125,\n                    231.7219696044922,\n                    218.42548370361328,\n                    231.7219696044922,\n                    196.84266662597656,\n                    209.04907226562497,\n                    196.84266662597656\n                ]\n            ],\n            \"iscrowd\": 0,\n            \"area\": 2046.8914123722377,\n            \"dataset\": \"nzsl\"\n        }\n    ],\n    \"categories\": [\n        {\n            \"supercategory\": \"hand\",\n            \"id\": 1,\n            \"name\": \"hand\",\n            \"keypoints\": [\n                \"wrist\",\n                \"thumb1\",\n                \"thumb2\",\n                \"thumb3\",\n                \"thumb4\",\n                \"forefinger1\",\n                \"forefinger2\",\n                \"forefinger3\",\n                \"forefinger4\",\n                \"middle_finger1\",\n                \"middle_finger2\",\n                \"middle_finger3\",\n                \"middle_finger4\",\n                \"ring_finger1\",\n                \"ring_finger2\",\n                \"ring_finger3\",\n                \"ring_finger4\",\n                \"pinky_finger1\",\n                \"pinky_finger2\",\n                \"pinky_finger3\",\n                \"pinky_finger4\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    1,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    8,\n                    9\n                ],\n                [\n                    1,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    1,\n                    14\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ],\n                [\n                    1,\n                    18\n                ],\n                [\n                    18,\n                    19\n                ],\n                [\n                    19,\n                    20\n                ],\n                [\n                    20,\n                    21\n                ]\n            ]\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/panoptic_body3d/160906_band1/calibration_160906_band1.json",
    "content": "{\n\t\"calibDataSource\": \"160906_calib_norm\",\n\t\"cameras\": [\n\t\t{\n\t\t\t\"name\": \"01_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.698,0,375.512],\n\t\t\t\t[0,745.89,226.023],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324009,0.0732398,-0.000601245,0.000808154,0.0311011],\n\t\t\t\"R\": [\n\t\t\t\t[0.9609979695,0.02878724306,-0.2750530807],\n\t\t\t\t[-0.05024448072,0.9961896773,-0.07128547526],\n\t\t\t\t[0.2719529274,0.08232509619,0.9587826572]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-51.56945892],\n\t\t\t\t[143.9587601],\n\t\t\t\t[282.5664691]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[745.462,0,369.225],\n\t\t\t\t[0,745.627,226.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336594,0.141798,-0.000612176,0.000160485,-0.0646767],\n\t\t\t\"R\": [\n\t\t\t\t[0.9715220842,-0.01574832828,-0.2364251047],\n\t\t\t\t[0.005323209906,0.998987679,-0.04466856407],\n\t\t\t\t[0.2368892218,0.042137956,0.9706224236]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-66.22242206],\n\t\t\t\t[142.1317177],\n\t\t\t\t[278.6626087]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.261,0,378.952],\n\t\t\t\t[0,746.496,239.595],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322069,0.0440329,-0.000951664,0.000892653,0.103376],\n\t\t\t\"R\": [\n\t\t\t\t[0.9665011873,0.05534363601,-0.2506242943],\n\t\t\t\t[-0.07024277085,0.996230894,-0.05089164033],\n\t\t\t\t[0.2468631364,0.06679137568,0.9667458322]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-54.75524211],\n\t\t\t\t[118.3584455],\n\t\t\t\t[281.78809]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.661,0,366.929],\n\t\t\t\t[0,747.759,234.022],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32333,0.0462607,-0.000972333,-0.000898261,0.102804],\n\t\t\t\"R\": [\n\t\t\t\t[0.9662588837,0.08601234823,-0.2427872436],\n\t\t\t\t[-0.1112831564,0.9894890375,-0.09234448444],\n\t\t\t\t[0.23229255,0.1162468093,0.9656742984]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.08626445],\n\t\t\t\t[96.75744843],\n\t\t\t\t[287.7183779]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[742.413,0,353.224],\n\t\t\t\t[0,742.622,209.478],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.297729,-0.0985766,-0.000505185,-0.000773418,0.328727],\n\t\t\t\"R\": [\n\t\t\t\t[0.9718071292,0.05098345905,-0.2301990238],\n\t\t\t\t[-0.07271497659,0.9935575811,-0.0869244798],\n\t\t\t\t[0.2242842746,0.1012127458,0.9692536016]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-26.91018729],\n\t\t\t\t[77.97642882],\n\t\t\t\t[285.7140393]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[743.487,0,372.277],\n\t\t\t\t[0,743.725,241.821],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317534,0.0281748,0.00130284,-0.000186889,0.119129],\n\t\t\t\"R\": [\n\t\t\t\t[0.9681278444,0.07458666466,-0.2390926732],\n\t\t\t\t[-0.09383510211,0.9931135585,-0.07014580141],\n\t\t\t\t[0.2322142341,0.09034538891,0.968459736]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.038020326],\n\t\t\t\t[73.51221006],\n\t\t\t\t[284.7303027]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[748.393,0,380.919],\n\t\t\t\t[0,748.388,229.353],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.344193,0.174813,-0.00034307,0.00107023,-0.0968505],\n\t\t\t\"R\": [\n\t\t\t\t[0.9670535143,-0.02995409712,-0.2528047715],\n\t\t\t\t[0.01712365053,0.9984582116,-0.0528013286],\n\t\t\t\t[0.2539966162,0.04673276982,0.9660754459]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.52170598],\n\t\t\t\t[98.55800179],\n\t\t\t\t[280.6705064]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.37,0,362.362],\n\t\t\t\t[0,745.56,217.483],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326014,0.0789588,-0.000462463,-0.00138061,0.0222432],\n\t\t\t\"R\": [\n\t\t\t\t[0.9652282485,0.06485174985,-0.2532364089],\n\t\t\t\t[-0.07898708824,0.9958116468,-0.0460456736],\n\t\t\t\t[0.2491896228,0.06444699145,0.9663079826]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.28384049],\n\t\t\t\t[86.2200762],\n\t\t\t\t[282.8912643]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.037,0,338.236],\n\t\t\t\t[0,746.053,236.859],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314486,0.0395532,0.000625849,-0.000232478,0.0599275],\n\t\t\t\"R\": [\n\t\t\t\t[0.9656569777,0.07278005487,-0.2494186543],\n\t\t\t\t[-0.09030273149,0.9941334749,-0.05953193019],\n\t\t\t\t[0.2436226964,0.08001060955,0.9665641645]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.35508632],\n\t\t\t\t[94.7965848],\n\t\t\t\t[284.0947744]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.938,0,379.271],\n\t\t\t\t[0,748.269,227.432],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3484,0.205218,-0.00110069,0.000562921,-0.151344],\n\t\t\t\"R\": [\n\t\t\t\t[0.9662738854,-0.001312373382,-0.2575132151],\n\t\t\t\t[-0.009587322107,0.9991104143,-0.04106657164],\n\t\t\t\t[0.2573380297,0.04215041788,0.9654017199]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.05861189],\n\t\t\t\t[130.0028668],\n\t\t\t\t[279.9552314]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[746.12,0,364.693],\n\t\t\t\t[0,745.844,223.621],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335335,0.119703,0.000192218,0.00118296,-0.00812072],\n\t\t\t\"R\": [\n\t\t\t\t[0.9869891455,-0.01212212734,-0.1603292883],\n\t\t\t\t[0.00355647539,0.9985558958,-0.05360479805],\n\t\t\t\t[0.1607475603,0.05233714665,0.9856069424]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[71.07099717],\n\t\t\t\t[142.6182462],\n\t\t\t\t[275.3539702]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.407,0,358.691],\n\t\t\t\t[0,745.503,226.329],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325389,0.0923962,-0.00061832,-0.00189678,-0.0159561],\n\t\t\t\"R\": [\n\t\t\t\t[0.9589650047,0.08538224277,-0.2703627054],\n\t\t\t\t[-0.09708669181,0.9948178626,-0.03019262438],\n\t\t\t\t[0.2663837347,0.05520229083,0.9622849957]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[54.63033668],\n\t\t\t\t[157.9150468],\n\t\t\t\t[281.9236261]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.389,0,339.442],\n\t\t\t\t[0,744.512,216.258],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320138,0.0543285,-0.000196977,-0.00116274,0.0473598],\n\t\t\t\"R\": [\n\t\t\t\t[0.9724830194,-0.06319437739,-0.2242392645],\n\t\t\t\t[0.03959405574,0.9933373951,-0.1082272161],\n\t\t\t\t[0.2295845984,0.09637058799,0.9685058709]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[19.90234626],\n\t\t\t\t[154.6647449],\n\t\t\t\t[286.7518211]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[746.213,0,363.165],\n\t\t\t\t[0,746.641,235.418],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.33414,0.127633,-0.000792357,0.000136075,-0.0405619],\n\t\t\t\"R\": [\n\t\t\t\t[0.9643490552,0.006836134333,-0.2645452079],\n\t\t\t\t[-0.02440508255,0.9977035557,-0.06318233054],\n\t\t\t\t[0.2635057717,0.0673860684,0.9623013177]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[19.24633902],\n\t\t\t\t[182.0747755],\n\t\t\t\t[282.9928946]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.225,0,366.568],\n\t\t\t\t[0,745.569,216.05],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319743,0.046174,-0.00158438,-0.000953331,0.0743504],\n\t\t\t\"R\": [\n\t\t\t\t[0.9602661069,0.03565913048,-0.2767985376],\n\t\t\t\t[-0.06162250151,0.9944158624,-0.08567239854],\n\t\t\t\t[0.2721978533,0.09932531892,0.9571012536]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[0.9330302863],\n\t\t\t\t[174.5612072],\n\t\t\t\t[288.1067574]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.633,0,371.752],\n\t\t\t\t[0,747.88,230.613],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.347758,0.198029,0.00072103,0.00029865,-0.136932],\n\t\t\t\"R\": [\n\t\t\t\t[0.9682573711,0.05614690975,-0.2435676248],\n\t\t\t\t[-0.07153002565,0.9959334273,-0.05477283913],\n\t\t\t\t[0.2395018137,0.07045660367,0.968336072]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.74774],\n\t\t\t\t[172.5737662],\n\t\t\t\t[282.7618788]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[748.152,0,373.9],\n\t\t\t\t[0,748.508,234.452],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.345127,0.177692,-0.00116897,0.00210199,-0.0818461],\n\t\t\t\"R\": [\n\t\t\t\t[0.9639501783,0.02458774974,-0.264944327],\n\t\t\t\t[-0.04477053879,0.9965129817,-0.07040934697],\n\t\t\t\t[0.2622892538,0.07973280283,0.9616896732]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-36.08309916],\n\t\t\t\t[173.4726636],\n\t\t\t\t[283.4522322]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[743.791,0,363.617],\n\t\t\t\t[0,744.126,236.963],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312734,0.0122172,-0.00120247,-0.000963953,0.133944],\n\t\t\t\"R\": [\n\t\t\t\t[0.9523198878,0.06045552763,-0.2990517689],\n\t\t\t\t[-0.07234112338,0.9969633514,-0.02882425707],\n\t\t\t\t[0.2964010681,0.04908365416,0.9538014478]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.80984395],\n\t\t\t\t[175.8598769],\n\t\t\t\t[275.2458542]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.162,0,364.748],\n\t\t\t\t[0,743.331,220.785],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311505,0.00290054,-0.000860754,-0.000437091,0.146397],\n\t\t\t\"R\": [\n\t\t\t\t[0.9677776267,0.05243241618,-0.246287042],\n\t\t\t\t[-0.06515666231,0.9969134625,-0.04379677618],\n\t\t\t\t[0.243230497,0.05843278173,0.968206866]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.88792012],\n\t\t\t\t[144.796335],\n\t\t\t\t[280.8929426]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.661,0,343.237],\n\t\t\t\t[0,744.907,246.044],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326994,0.0904776,0.000984855,-0.00107766,-0.0214165],\n\t\t\t\"R\": [\n\t\t\t\t[0.9717064093,0.03462931454,-0.2336396043],\n\t\t\t\t[-0.0436324388,0.998486683,-0.03347468014],\n\t\t\t\t[0.2321268283,0.04272182698,0.9717468709]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.15244103],\n\t\t\t\t[127.7778149],\n\t\t\t\t[279.5122056]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[742.462,0,365.246],\n\t\t\t\t[0,742.468,221.387],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311193,-0.0017069,-0.0010044,-5.33063e-05,0.168374],\n\t\t\t\"R\": [\n\t\t\t\t[0.9650420793,0.04068979072,-0.2589172188],\n\t\t\t\t[-0.04945049005,0.9984003719,-0.02741069744],\n\t\t\t\t[0.257387712,0.03925605981,0.965510501]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.672862451],\n\t\t\t\t[122.1992626],\n\t\t\t\t[279.1232554]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.021,0,363.587],\n\t\t\t\t[0,744.301,226.764],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330855,0.115198,-0.00111581,-0.000578883,-0.0257811],\n\t\t\t\"R\": [\n\t\t\t\t[0.9624230562,-0.007741542698,-0.2714441553],\n\t\t\t\t[-0.003557050749,0.9991484058,-0.04110730506],\n\t\t\t\t[0.271531229,0.0405281588,0.9615759252]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.289641778],\n\t\t\t\t[135.1743597],\n\t\t\t\t[279.2863723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[745.029,0,358.645],\n\t\t\t\t[0,745.162,224.101],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31925,0.0412999,-0.000788365,0.000625647,0.108146],\n\t\t\t\"R\": [\n\t\t\t\t[0.9553340738,0.01211961015,-0.2952793973],\n\t\t\t\t[-0.03701510886,0.9961975848,-0.07886858543],\n\t\t\t\t[0.293200766,0.08627564605,0.9521501057]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-2.968489269],\n\t\t\t\t[143.230855],\n\t\t\t\t[285.3382881]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.501,0,369.38],\n\t\t\t\t[0,744.575,244.409],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317214,0.0306635,-5.65201e-05,-0.000305408,0.106933],\n\t\t\t\"R\": [\n\t\t\t\t[0.9627375442,0.05351140442,-0.2650904574],\n\t\t\t\t[-0.07422624073,0.9948691584,-0.06874462026],\n\t\t\t\t[0.2600516991,0.08585969499,0.9617698408]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.333655278],\n\t\t\t\t[148.0612654],\n\t\t\t\t[284.8699573]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[746.79,0,376.022],\n\t\t\t\t[0,747.048,234.17],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317408,0.0301922,-0.000108969,-0.00027109,0.105931],\n\t\t\t\"R\": [\n\t\t\t\t[0.977473966,0.04697618088,0.2057617172],\n\t\t\t\t[0.001487552662,0.9733575223,-0.2292878562],\n\t\t\t\t[-0.211050783,0.2244289915,0.9513617581]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.729507611],\n\t\t\t\t[175.3460492],\n\t\t\t\t[304.9109171]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.689,0,367.065],\n\t\t\t\t[0,747.811,212.158],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333664,0.117162,0.000577725,-0.000310896,-0.0327554],\n\t\t\t\"R\": [\n\t\t\t\t[0.9812751339,-0.05714257326,0.183939767],\n\t\t\t\t[0.09271495859,0.9771941455,-0.1910380552],\n\t\t\t\t[-0.1688284573,0.2045148611,0.9641942873]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-50.62568249],\n\t\t\t\t[190.9654762],\n\t\t\t\t[299.6250374]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[745.627,0,353.486],\n\t\t\t\t[0,745.817,252.683],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321416,0.0392112,-0.00107045,-0.00134198,0.0908854],\n\t\t\t\"R\": [\n\t\t\t\t[0.9757098845,0.1270834984,0.1784376802],\n\t\t\t\t[-0.07601456941,0.9603325594,-0.2682967771],\n\t\t\t\t[-0.2054556071,0.248215954,0.946666168]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.13649132],\n\t\t\t\t[169.3490841],\n\t\t\t\t[309.2380875]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[746.11,0,381.584],\n\t\t\t\t[0,746.321,224.917],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323963,0.0585021,-0.000871966,0.000552522,0.0715102],\n\t\t\t\"R\": [\n\t\t\t\t[0.979331342,0.07410153523,0.1881995881],\n\t\t\t\t[-0.02608477747,0.9689731658,-0.2457856551],\n\t\t\t\t[-0.2005734451,0.2357964511,0.950878713]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.63906075],\n\t\t\t\t[150.8763932],\n\t\t\t\t[306.9317958]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.11,0,378.377],\n\t\t\t\t[0,744.035,244.823],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323078,0.0494134,-0.000238923,-0.000981516,0.0727453],\n\t\t\t\"R\": [\n\t\t\t\t[0.9857440106,0.05652749171,0.1584720428],\n\t\t\t\t[-0.01525193411,0.9680163878,-0.250422945],\n\t\t\t\t[-0.1675593154,0.244435913,0.95507851]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.3494258],\n\t\t\t\t[135.8190029],\n\t\t\t\t[306.0165552]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[743.928,0,352.844],\n\t\t\t\t[0,744.181,228.627],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303908,-0.0528673,-0.000528541,8.08764e-05,0.267531],\n\t\t\t\"R\": [\n\t\t\t\t[0.9814194485,0.06212733968,0.1815380393],\n\t\t\t\t[-0.0101664424,0.9616367605,-0.2741375282],\n\t\t\t\t[-0.1916050874,0.2671983057,0.9444006332]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.86742917],\n\t\t\t\t[106.6702196],\n\t\t\t\t[310.2214119]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.501,0,376.178],\n\t\t\t\t[0,746.591,217.394],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323449,0.0621904,-0.000592526,0.000355354,0.0689781],\n\t\t\t\"R\": [\n\t\t\t\t[0.9775323693,0.09704954661,0.1871145437],\n\t\t\t\t[-0.05094527723,0.9701636443,-0.2370381445],\n\t\t\t\t[-0.2045361721,0.2221798567,0.9533105819]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.21830655],\n\t\t\t\t[111.2122483],\n\t\t\t\t[305.8578091]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[747.056,0,346.722],\n\t\t\t\t[0,747.425,231.954],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331626,0.0978711,0.000923123,-0.00170198,0.0128988],\n\t\t\t\"R\": [\n\t\t\t\t[0.9738310577,0.04398424166,0.222976361],\n\t\t\t\t[0.006459505741,0.9753414162,-0.2206068824],\n\t\t\t\t[-0.2271813062,0.2162741507,0.9495336465]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.1615402],\n\t\t\t\t[89.62617671],\n\t\t\t\t[306.715437]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.084,0,344.827],\n\t\t\t\t[0,746.456,222.936],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31385,0.00765504,0.000335804,0.000338293,0.157318],\n\t\t\t\"R\": [\n\t\t\t\t[0.9708044988,0.02558390192,0.2385038556],\n\t\t\t\t[0.01777728087,0.9838878899,-0.1779005014],\n\t\t\t\t[-0.2392124442,0.1769465571,0.9547079776]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.622489705],\n\t\t\t\t[92.86686988],\n\t\t\t\t[302.6276511]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.875,0,345.16],\n\t\t\t\t[0,744.131,231.932],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309364,-0.0158069,0.000435688,-0.000318284,0.167974],\n\t\t\t\"R\": [\n\t\t\t\t[0.9837217555,0.04774800386,0.1732386674],\n\t\t\t\t[-0.008457215477,0.9752859506,-0.220784488],\n\t\t\t\t[-0.179499257,0.2157253874,0.9598138226]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[0.6070589451],\n\t\t\t\t[94.58504844],\n\t\t\t\t[305.3954199]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[748.642,0,372.727],\n\t\t\t\t[0,749.029,221.349],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329743,0.0894243,0.000705225,0.000452301,0.0255748],\n\t\t\t\"R\": [\n\t\t\t\t[0.9762818677,-0.03993432779,0.2127885436],\n\t\t\t\t[0.08495434643,0.9746762651,-0.20685487],\n\t\t\t\t[-0.1991393328,0.2200259705,0.9549513592]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.17502224],\n\t\t\t\t[86.30258496],\n\t\t\t\t[305.899008]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.297,0,386.393],\n\t\t\t\t[0,746.341,223.432],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329805,0.088881,-0.000101498,-0.000342857,0.0238941],\n\t\t\t\"R\": [\n\t\t\t\t[0.9769251111,-0.05225372472,0.2070914666],\n\t\t\t\t[0.09392861168,0.9759243238,-0.1968479875],\n\t\t\t\t[-0.1918195589,0.211757556,0.9583130982]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.97904484],\n\t\t\t\t[101.8192368],\n\t\t\t\t[305.2554798]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[746.887,0,386.903],\n\t\t\t\t[0,746.77,241.912],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330222,0.0894843,0.000608161,-0.000202457,0.0188277],\n\t\t\t\"R\": [\n\t\t\t\t[0.9805035597,0.07291108666,0.1824739514],\n\t\t\t\t[-0.03359954242,0.9771464723,-0.2098948364],\n\t\t\t\t[-0.1936074385,0.199671593,0.9605453736]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.8755561],\n\t\t\t\t[121.0360498],\n\t\t\t\t[302.8306622]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.399,0,359.381],\n\t\t\t\t[0,745.103,221.453],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32351,0.0564367,0.000553752,0.000358328,0.0789504],\n\t\t\t\"R\": [\n\t\t\t\t[0.9639890244,-0.01369700088,0.2655890681],\n\t\t\t\t[0.06651808592,0.9793475216,-0.1909287203],\n\t\t\t\t[-0.2574888447,0.2017196672,0.9449913601]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[64.66924198],\n\t\t\t\t[136.2834945],\n\t\t\t\t[299.1868513]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.343,0,376.035],\n\t\t\t\t[0,746.136,233.449],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332319,0.10939,0.000552685,0.00121175,-0.00685584],\n\t\t\t\"R\": [\n\t\t\t\t[0.9739293667,-0.02993852249,0.2248672353],\n\t\t\t\t[0.07982373372,0.9730868608,-0.2161715356],\n\t\t\t\t[-0.2123434957,0.2284855491,0.9501076748]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.67937397],\n\t\t\t\t[146.9667487],\n\t\t\t\t[305.3208703]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.983,0,369.069],\n\t\t\t\t[0,747.865,212.357],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333814,0.119177,-0.00123283,0.000206724,-0.0313224],\n\t\t\t\"R\": [\n\t\t\t\t[0.9828420813,0.01261378295,0.1840172159],\n\t\t\t\t[0.03080156014,0.9724259604,-0.2311688027],\n\t\t\t\t[-0.181859031,0.2328704445,0.9553526307]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.33056427],\n\t\t\t\t[154.6384713],\n\t\t\t\t[307.0242051]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[743.255,0,372.405],\n\t\t\t\t[0,743.629,259.514],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.301911,-0.0577323,-0.000292445,-0.000537705,0.240913],\n\t\t\t\"R\": [\n\t\t\t\t[0.9702237144,0.05425789408,0.2360551311],\n\t\t\t\t[-0.004184220731,0.978195713,-0.2076430576],\n\t\t\t\t[-0.2421743923,0.2004725119,0.9492957051]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.95715372],\n\t\t\t\t[182.9757461],\n\t\t\t\t[299.4720725]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[746.171,0,380.016],\n\t\t\t\t[0,746.628,215.7],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310416,0.0111871,-0.00156578,-0.000885002,0.110566],\n\t\t\t\"R\": [\n\t\t\t\t[0.9751942313,0.01121985931,0.2210663386],\n\t\t\t\t[0.02134458651,0.9892938663,-0.1443677759],\n\t\t\t\t[-0.220319359,0.1455051918,0.9645141882]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.159436194],\n\t\t\t\t[213.6293599],\n\t\t\t\t[288.3403437]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.09,0,380.114],\n\t\t\t\t[0,745.176,232.983],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31746,0.043353,-0.000108725,0.000220738,0.0862213],\n\t\t\t\"R\": [\n\t\t\t\t[0.9809185988,0.05584586521,0.1862255137],\n\t\t\t\t[-0.01423917048,0.975920974,-0.2176591338],\n\t\t\t\t[-0.1938967473,0.2108541957,0.9580942331]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.989355998],\n\t\t\t\t[159.4183424],\n\t\t\t\t[303.0216832]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[746.359,0,393.165],\n\t\t\t\t[0,746.438,228.007],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32236,0.0673245,-0.000115957,0.00130444,0.0588071],\n\t\t\t\"R\": [\n\t\t\t\t[0.9826018096,0.03015545669,0.1832602856],\n\t\t\t\t[0.01576123022,0.9696317731,-0.2440610748],\n\t\t\t\t[-0.1850547688,0.2427032613,0.9522866477]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-25.36954265],\n\t\t\t\t[136.7143691],\n\t\t\t\t[307.7149997]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[747.137,0,358.509],\n\t\t\t\t[0,747.202,238.678],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327929,0.0852816,0.000460613,0.000357406,0.0365027],\n\t\t\t\"R\": [\n\t\t\t\t[0.9780966382,0.08951991601,0.1879179366],\n\t\t\t\t[-0.04045439222,0.9673344336,-0.2502549415],\n\t\t\t\t[-0.2041822921,0.2371714111,0.9497680314]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.00427836],\n\t\t\t\t[118.005594],\n\t\t\t\t[307.3165834]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.847,0,374.568],\n\t\t\t\t[0,746.074,247.807],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32052,0.063252,0.000743322,-0.000945252,0.0534877],\n\t\t\t\"R\": [\n\t\t\t\t[0.9839840132,0.07804627455,0.160263036],\n\t\t\t\t[-0.03749054936,0.9695570383,-0.2419785283],\n\t\t\t\t[-0.1742696772,0.2320946541,0.9569546233]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.458572059],\n\t\t\t\t[110.2636917],\n\t\t\t\t[306.6072245]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.851,0,375.128],\n\t\t\t\t[0,744.899,236.672],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328747,0.0731957,0.000409854,0.000115616,0.0573405],\n\t\t\t\"R\": [\n\t\t\t\t[0.9798731388,0.006836815724,0.1995041098],\n\t\t\t\t[0.04188111895,0.9701291749,-0.2389463451],\n\t\t\t\t[-0.1951783896,0.2424925605,0.9503171862]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.92766978],\n\t\t\t\t[118.8861106],\n\t\t\t\t[308.0337581]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[748.108,0,365.63],\n\t\t\t\t[0,748.409,236.546],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337502,0.145226,-9.99404e-05,-0.000712599,-0.0768278],\n\t\t\t\"R\": [\n\t\t\t\t[0.9858983234,-0.01937546959,0.166219996],\n\t\t\t\t[0.057736328,0.9716683618,-0.2291879382],\n\t\t\t\t[-0.1570700873,0.2355529362,0.9590848773]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.69779309],\n\t\t\t\t[141.0775615],\n\t\t\t\t[307.1963385]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.205,0,364.445],\n\t\t\t\t[0,745.671,223.278],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321278,0.0550501,-0.000663141,0.000431329,0.0680735],\n\t\t\t\"R\": [\n\t\t\t\t[0.789168654,0.1464091436,-0.5964706181],\n\t\t\t\t[-0.3274382264,0.921936374,-0.2069239719],\n\t\t\t\t[0.5196123973,0.3586051937,0.7755032377]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.48720347],\n\t\t\t\t[106.8731646],\n\t\t\t\t[321.197831]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.402,0,367.989],\n\t\t\t\t[0,746.656,218.884],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319108,0.0415571,-0.000289565,0.00121415,0.0978966],\n\t\t\t\"R\": [\n\t\t\t\t[0.7844411333,0.123213727,-0.6078408392],\n\t\t\t\t[-0.3461950886,0.9001611021,-0.2643084389],\n\t\t\t\t[0.5145882519,0.4177659246,0.7487793823]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-25.69855827],\n\t\t\t\t[65.19717944],\n\t\t\t\t[326.035328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[747.999,0,350.415],\n\t\t\t\t[0,748.222,213.374],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322361,0.0444301,-0.000132478,-4.14576e-05,0.110213],\n\t\t\t\"R\": [\n\t\t\t\t[0.8075592295,0.0617799019,-0.5865418439],\n\t\t\t\t[-0.2672496857,0.9248714179,-0.2705373648],\n\t\t\t\t[0.525762015,0.3752280693,0.763399109]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.799326732],\n\t\t\t\t[72.40249706],\n\t\t\t\t[323.1224723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.819,0,376.394],\n\t\t\t\t[0,744.912,212.894],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335892,0.121706,-0.00015411,0.0017688,-0.0013985],\n\t\t\t\"R\": [\n\t\t\t\t[0.8410364559,-0.03582960221,-0.5397906256],\n\t\t\t\t[-0.192384631,0.9127679401,-0.3603371217],\n\t\t\t\t[0.5056143132,0.4069040761,0.7607780486]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.728898504],\n\t\t\t\t[75.32503712],\n\t\t\t\t[325.8417248]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[746.446,0,376.523],\n\t\t\t\t[0,746.682,251.012],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330943,0.0996499,0.00144142,-0.000113946,0.0131394],\n\t\t\t\"R\": [\n\t\t\t\t[0.8610606531,-0.05437396314,-0.5055868113],\n\t\t\t\t[-0.176556083,0.9004429458,-0.3975304402],\n\t\t\t\t[0.4768673833,0.4315622475,0.7657359371]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.93527518],\n\t\t\t\t[62.43528973],\n\t\t\t\t[326.764058]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.998,0,378.484],\n\t\t\t\t[0,744.973,240.788],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31652,0.0338012,-0.0010118,-0.000122735,0.0959735],\n\t\t\t\"R\": [\n\t\t\t\t[0.8769583834,-0.06555368648,-0.4760742674],\n\t\t\t\t[-0.1128149484,0.9348860407,-0.3365425358],\n\t\t\t\t[0.4671367907,0.348842092,0.8124607151]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[52.69213606],\n\t\t\t\t[109.2131316],\n\t\t\t\t[317.2562433]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.942,0,394.454],\n\t\t\t\t[0,745.513,230.902],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322593,0.0669124,0.000685625,0.000650135,0.0435827],\n\t\t\t\"R\": [\n\t\t\t\t[0.8511772215,-0.03734239681,-0.5235483579],\n\t\t\t\t[-0.1521244983,0.9371023984,-0.3141611561],\n\t\t\t\t[0.5023499524,0.3470513512,0.7919595223]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.57000229],\n\t\t\t\t[127.8421428],\n\t\t\t\t[318.5564893]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.592,0,375.596],\n\t\t\t\t[0,744.695,234.586],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314208,0.0115966,-0.0002404,-0.00129875,0.131833],\n\t\t\t\"R\": [\n\t\t\t\t[0.863242284,-0.08735605341,-0.4971736911],\n\t\t\t\t[-0.1241310572,0.9179337282,-0.3768144785],\n\t\t\t\t[0.4892895255,0.386996887,0.7815556088]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.3076273],\n\t\t\t\t[133.8669044],\n\t\t\t\t[323.1008342]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.083,0,388.49],\n\t\t\t\t[0,746.196,219.485],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327776,0.0952708,0.000477894,0.00116098,0.0130168],\n\t\t\t\"R\": [\n\t\t\t\t[0.8627791791,-0.162720556,-0.478679547],\n\t\t\t\t[-0.06768333431,0.9010943873,-0.4283081501],\n\t\t\t\t[0.5010299935,0.401933982,0.766432006]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.91664651],\n\t\t\t\t[150.3571005],\n\t\t\t\t[326.7446808]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.984,0,374.291],\n\t\t\t\t[0,745.244,231.69],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317288,0.0201616,0.000340337,0.000302133,0.135473],\n\t\t\t\"R\": [\n\t\t\t\t[0.8433461687,-0.104156761,-0.5271798639],\n\t\t\t\t[-0.1611508321,0.8868626272,-0.433018579],\n\t\t\t\t[0.5126379318,0.4501400333,0.7311472501]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.809004706],\n\t\t\t\t[133.1751931],\n\t\t\t\t[335.4888131]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[746.325,0,369.755],\n\t\t\t\t[0,746.606,238.315],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330117,0.107892,0.000853042,-0.00148033,-0.0192727],\n\t\t\t\"R\": [\n\t\t\t\t[0.8487877999,-0.06352852013,-0.5249032272],\n\t\t\t\t[-0.1660312052,0.9105147821,-0.3786772643],\n\t\t\t\t[0.5019889537,0.4085669574,0.7622861219]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[10.90299391],\n\t\t\t\t[168.9126588],\n\t\t\t\t[328.8547345]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.397,0,373.191],\n\t\t\t\t[0,745.394,241.989],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315431,0.0239438,0.00152043,8.78247e-05,0.132462],\n\t\t\t\"R\": [\n\t\t\t\t[0.7899500519,0.01447673769,-0.613000277],\n\t\t\t\t[-0.2772192125,0.9001468868,-0.3359837649],\n\t\t\t\t[0.5469263421,0.4353458466,0.7150843098]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.01289772],\n\t\t\t\t[165.4412244],\n\t\t\t\t[333.9391633]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[746.289,0,356.696],\n\t\t\t\t[0,746.559,221.83],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307674,-0.0320128,-0.000713248,-0.000212304,0.187939],\n\t\t\t\"R\": [\n\t\t\t\t[0.7812025858,0.003231301473,-0.6242692358],\n\t\t\t\t[-0.256925784,0.9130359895,-0.316787663],\n\t\t\t\t[0.5689566429,0.4078662043,0.7140962805]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.04397497],\n\t\t\t\t[158.6113997],\n\t\t\t\t[327.0561852]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.216,0,367.374],\n\t\t\t\t[0,744.503,234.384],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313106,0.0107213,0.00051099,0.000391129,0.137335],\n\t\t\t\"R\": [\n\t\t\t\t[0.7647493291,0.08765142393,-0.6383382266],\n\t\t\t\t[-0.3090501184,0.9192036391,-0.2440342068],\n\t\t\t\t[0.5653728752,0.3839035005,0.7300490493]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.23656889],\n\t\t\t\t[178.7825502],\n\t\t\t\t[321.7207122]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.827,0,380.852],\n\t\t\t\t[0,747.806,237.021],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329904,0.102056,0.000500868,0.000776535,0.0163276],\n\t\t\t\"R\": [\n\t\t\t\t[0.8420936086,0.09442452017,-0.5310012847],\n\t\t\t\t[-0.2692856411,0.9266613257,-0.2622670985],\n\t\t\t\t[0.4672939095,0.3638444688,0.8057627471]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.683781844],\n\t\t\t\t[164.2881649],\n\t\t\t\t[322.7392687]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.289,0,371.652],\n\t\t\t\t[0,745.447,216.538],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317152,0.0301694,-0.000847782,0.000226416,0.100881],\n\t\t\t\"R\": [\n\t\t\t\t[0.7751085928,0.08020770062,-0.6267163586],\n\t\t\t\t[-0.2817854267,0.9316829094,-0.2292682483],\n\t\t\t\t[0.5655118413,0.3543073259,0.74475679]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.18053512],\n\t\t\t\t[150.9579844],\n\t\t\t\t[316.9204289]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.591,0,386.471],\n\t\t\t\t[0,744.601,243.766],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308716,-0.020066,-0.000742984,7.36231e-05,0.18193],\n\t\t\t\"R\": [\n\t\t\t\t[0.8000888793,0.13985822,-0.5833502066],\n\t\t\t\t[-0.3086873752,0.9298003917,-0.2004578159],\n\t\t\t\t[0.5143635773,0.3404569133,0.7870954202]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.24407076],\n\t\t\t\t[139.76037],\n\t\t\t\t[318.5389184]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[747.091,0,388.41],\n\t\t\t\t[0,747.213,245.147],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331947,0.109947,-0.00018029,-0.000335458,-0.0100282],\n\t\t\t\"R\": [\n\t\t\t\t[0.7812031275,0.143907843,-0.6074637489],\n\t\t\t\t[-0.3493109676,0.9072427652,-0.2342912992],\n\t\t\t\t[0.5174007358,0.3952228456,0.7590094735]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-39.38157975],\n\t\t\t\t[101.9329028],\n\t\t\t\t[324.6812046]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.815,0,380.782],\n\t\t\t\t[0,743.921,233.579],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31618,0.0384848,0.000240219,0.000426998,0.0977231],\n\t\t\t\"R\": [\n\t\t\t\t[0.8097086682,0.09665101941,-0.578818152],\n\t\t\t\t[-0.2718115959,0.9359285209,-0.2239559336],\n\t\t\t\t[0.5200868476,0.3386685464,0.784100304]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.817362892],\n\t\t\t\t[126.1763792],\n\t\t\t\t[318.2990602]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[746.163,0,356.033],\n\t\t\t\t[0,746.281,215.327],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323416,0.0556958,5.62358e-06,-0.000684023,0.0815018],\n\t\t\t\"R\": [\n\t\t\t\t[0.8690981447,0.003405692177,-0.4946279574],\n\t\t\t\t[-0.1831744592,0.9310985933,-0.3154402114],\n\t\t\t\t[0.4594731031,0.3647517111,0.8098398958]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.15812523],\n\t\t\t\t[111.197586],\n\t\t\t\t[320.9871724]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.277,0,370.698],\n\t\t\t\t[0,745.633,251.594],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309423,-0.0154759,-0.000871178,-0.000110471,0.185828],\n\t\t\t\"R\": [\n\t\t\t\t[0.8519925598,-0.01534543221,-0.5233289556],\n\t\t\t\t[-0.157671027,0.9456449668,-0.2844212441],\n\t\t\t\t[0.4992479597,0.3248385977,0.8032629458]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.66925749],\n\t\t\t\t[140.0971121],\n\t\t\t\t[315.3107012]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[749.812,0,361.025],\n\t\t\t\t[0,750.052,224.033],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333335,0.0892582,3.32371e-05,-0.00136116,0.0353235],\n\t\t\t\"R\": [\n\t\t\t\t[0.8242021998,-0.0118106517,-0.5661724493],\n\t\t\t\t[-0.2609232338,0.8794144434,-0.3981824994],\n\t\t\t\t[0.5026030242,0.4759104383,0.7217336453]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.739100305],\n\t\t\t\t[105.8858326],\n\t\t\t\t[336.9710973]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.781,0,365.976],\n\t\t\t\t[0,744.836,235.682],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319452,0.032528,0.000754874,-0.000913445,0.102166],\n\t\t\t\"R\": [\n\t\t\t\t[0.8233335342,0.02583843362,-0.5669693703],\n\t\t\t\t[-0.2570181529,0.9076367155,-0.3318693443],\n\t\t\t\t[0.506027233,0.4189605805,0.7539286912]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.103462359],\n\t\t\t\t[133.5127669],\n\t\t\t\t[329.5726238]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[746.135,0,373.553],\n\t\t\t\t[0,746.515,225.298],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323756,0.0623909,2.70614e-05,0.000962707,0.0761173],\n\t\t\t\"R\": [\n\t\t\t\t[0.8557458945,0.0294251088,-0.5165589289],\n\t\t\t\t[-0.2234217673,0.921515875,-0.3176337608],\n\t\t\t\t[0.4666708454,0.3872242956,0.7951576366]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.49693002],\n\t\t\t\t[128.5290469],\n\t\t\t\t[325.1203285]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.756,0,368.953],\n\t\t\t\t[0,745.945,245.188],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3245,0.0724334,-0.000312337,0.000678015,0.0415529],\n\t\t\t\"R\": [\n\t\t\t\t[0.04501388353,-0.06073969189,-0.9971381249],\n\t\t\t\t[-0.08162898106,0.9945884367,-0.06426936354],\n\t\t\t\t[0.9956457501,0.08428838276,0.03981216889]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-59.71104012],\n\t\t\t\t[137.3658878],\n\t\t\t\t[280.4259077]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[745.144,0,382.474],\n\t\t\t\t[0,745.286,222.525],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322843,0.0690658,-0.000684608,-0.000275864,0.0370253],\n\t\t\t\"R\": [\n\t\t\t\t[0.1096717734,-0.01795980665,-0.9938055884],\n\t\t\t\t[-0.007042199406,0.9997976117,-0.01884523745],\n\t\t\t\t[0.9939429106,0.009065367736,0.1095231006]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.83503278],\n\t\t\t\t[149.6185443],\n\t\t\t\t[272.7820927]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[742.832,0,377.499],\n\t\t\t\t[0,742.665,258.984],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312355,-0.00257413,0.000454129,0.00111055,0.151137],\n\t\t\t\"R\": [\n\t\t\t\t[0.07040546321,0.04162572676,-0.9966495721],\n\t\t\t\t[-0.08610880414,0.9956530214,0.03550119457],\n\t\t\t\t[0.9937949208,0.08332082476,0.07368375372]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-50.21742462],\n\t\t\t\t[111.4103034],\n\t\t\t\t[280.5940976]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[743.339,0,393.561],\n\t\t\t\t[0,743.571,223.626],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307228,-0.0295629,-0.000661125,6.4492e-05,0.183577],\n\t\t\t\"R\": [\n\t\t\t\t[0.09450112049,0.05679880598,-0.993903131],\n\t\t\t\t[-0.03670643306,0.9978910099,0.05353662459],\n\t\t\t\t[0.9948478155,0.03142336774,0.09638670013]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.9069],\n\t\t\t\t[118.1273376],\n\t\t\t\t[275.8163164]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[746.019,0,364.58],\n\t\t\t\t[0,746.273,258.887],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327759,0.0738839,0.000801649,0.000211169,0.0604088],\n\t\t\t\"R\": [\n\t\t\t\t[0.135847977,0.01131634816,-0.9906650632],\n\t\t\t\t[-0.049797809,0.9987488181,0.004580011864],\n\t\t\t\t[0.98947739,0.04871076425,0.1362415358]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.12624478],\n\t\t\t\t[90.71810202],\n\t\t\t\t[278.5550143]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.588,0,362.328],\n\t\t\t\t[0,745.695,224.495],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317313,0.0342325,-0.00011624,0.00140051,0.0955503],\n\t\t\t\"R\": [\n\t\t\t\t[0.09768474559,0.09486669264,-0.9906856217],\n\t\t\t\t[-0.08671696061,0.9924717325,0.0864871607],\n\t\t\t\t[0.9914322262,0.07746076975,0.1051758999]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.120914551],\n\t\t\t\t[75.66522558],\n\t\t\t\t[280.1538331]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.949,0,374.902],\n\t\t\t\t[0,744.948,218.152],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307279,-0.0368619,-0.000928182,-0.000206153,0.214368],\n\t\t\t\"R\": [\n\t\t\t\t[0.08413477249,-0.05845821559,-0.994738145],\n\t\t\t\t[-0.03729096802,0.9973936317,-0.06176833509],\n\t\t\t\t[0.9957563576,0.04229161317,0.08173552284]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.352563309],\n\t\t\t\t[99.7043349],\n\t\t\t\t[277.3248716]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.851,0,365.832],\n\t\t\t\t[0,744.82,236.655],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313642,0.00106915,0.000461187,-0.00049658,0.163492],\n\t\t\t\"R\": [\n\t\t\t\t[0.1068294918,-0.02053293437,-0.9940653189],\n\t\t\t\t[-0.04471775106,0.998675844,-0.02543386204],\n\t\t\t\t[0.9932712532,0.04716945203,0.1057698462]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.88142403],\n\t\t\t\t[92.93282517],\n\t\t\t\t[277.1804593]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.947,0,354.92],\n\t\t\t\t[0,745.962,217.292],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332252,0.114802,-0.000779302,-0.000175195,-0.0220414],\n\t\t\t\"R\": [\n\t\t\t\t[0.0951039165,0.01286389124,-0.99538423],\n\t\t\t\t[-0.04378002227,0.9990030715,0.008727700331],\n\t\t\t\t[0.9945041753,0.04274790527,0.09557228614]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.3876018],\n\t\t\t\t[107.4685168],\n\t\t\t\t[276.8925649]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.419,0,373.623],\n\t\t\t\t[0,743.493,209.714],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312784,-0.00205334,-0.00151839,-4.48796e-05,0.146707],\n\t\t\t\"R\": [\n\t\t\t\t[0.07554192003,-0.02015366607,-0.996938939],\n\t\t\t\t[-0.05402378201,0.9982445697,-0.02427365106],\n\t\t\t\t[0.9956780852,0.05569209012,0.07432053419]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[36.95032578],\n\t\t\t\t[126.4783785],\n\t\t\t\t[278.9862968]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.168,0,378.723],\n\t\t\t\t[0,743.196,231.359],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312654,0.00616666,0.000125459,-0.000163635,0.137741],\n\t\t\t\"R\": [\n\t\t\t\t[0.104627794,-0.01026277171,-0.994458496],\n\t\t\t\t[-0.05855646041,0.9981483637,-0.01646162423],\n\t\t\t\t[0.9927860624,0.05995431298,0.1038331098]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.78762978],\n\t\t\t\t[139.882294],\n\t\t\t\t[278.0088471]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.755,0,377.564],\n\t\t\t\t[0,747.014,231.526],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.342661,0.169314,0.000669193,0.000564241,-0.092518],\n\t\t\t\"R\": [\n\t\t\t\t[0.09069981891,0.03748374052,-0.9951726041],\n\t\t\t\t[-0.02832816732,0.9989841486,0.03504548138],\n\t\t\t\t[0.9954752924,0.02501279723,0.09166952704]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[63.18640006],\n\t\t\t\t[168.1511303],\n\t\t\t\t[272.7093484]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[745.766,0,371.377],\n\t\t\t\t[0,745.897,229.211],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323265,0.06437,0.000357726,0.000480753,0.061899],\n\t\t\t\"R\": [\n\t\t\t\t[0.03414536791,0.03842962758,-0.9986777546],\n\t\t\t\t[-0.02717943982,0.9989265658,0.03750992125],\n\t\t\t\t[0.9990472321,0.02586271187,0.03515321085]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.04698548],\n\t\t\t\t[171.5967975],\n\t\t\t\t[274.5649723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.965,0,366.266],\n\t\t\t\t[0,745.319,235.632],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317134,0.0349168,5.85303e-05,0.000379707,0.110605],\n\t\t\t\"R\": [\n\t\t\t\t[0.05221731101,0.04748668842,-0.9975060736],\n\t\t\t\t[0.03426805086,0.9981953182,0.04931335942],\n\t\t\t\t[0.9980476207,-0.03675759989,0.05049579913]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.93275734],\n\t\t\t\t[208.7852536],\n\t\t\t\t[260.7309393]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[744.586,0,371.051],\n\t\t\t\t[0,745.106,212.085],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332822,0.11382,-0.000911903,0.000640183,-0.00904196],\n\t\t\t\"R\": [\n\t\t\t\t[0.0693166226,0.04834029473,-0.9964228127],\n\t\t\t\t[-0.01396942206,0.9987743784,0.04748258878],\n\t\t\t\t[0.9974968978,0.01062811814,0.06990695264]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.12425569],\n\t\t\t\t[198.357827],\n\t\t\t\t[269.7404532]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[742.58,0,362.432],\n\t\t\t\t[0,742.717,222.722],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316061,0.0181932,0.000637155,-0.000119442,0.122715],\n\t\t\t\"R\": [\n\t\t\t\t[0.07545496093,-0.0349426896,-0.9965367817],\n\t\t\t\t[-0.03652359913,0.9986183515,-0.03778114217],\n\t\t\t\t[0.9964800929,0.03924788454,0.07407447592]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.86676392],\n\t\t\t\t[179.6369531],\n\t\t\t\t[275.0674259]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.044,0,350.241],\n\t\t\t\t[0,745.211,214.104],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330556,0.0995367,-0.000406045,-3.83783e-05,-0.00374247],\n\t\t\t\"R\": [\n\t\t\t\t[0.0837025501,0.02221656332,-0.9962430965],\n\t\t\t\t[-0.04478154079,0.9988252756,0.01851168242],\n\t\t\t\t[0.9954840515,0.04306382584,0.08459911461]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.0620205],\n\t\t\t\t[182.4550181],\n\t\t\t\t[276.0013748]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[747.543,0,399.307],\n\t\t\t\t[0,747.43,229.515],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337874,0.152604,0.000377489,0.002871,-0.0603327],\n\t\t\t\"R\": [\n\t\t\t\t[0.03967719066,0.06607189882,-0.9970256891],\n\t\t\t\t[-0.02383145062,0.9975901546,0.06516091958],\n\t\t\t\t[0.998928317,0.02117516625,0.04115616396]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.47747339],\n\t\t\t\t[181.8911988],\n\t\t\t\t[269.8403328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.963,0,369.391],\n\t\t\t\t[0,744.08,218.072],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320196,0.0539371,0.000417857,0.00192962,0.0700112],\n\t\t\t\"R\": [\n\t\t\t\t[0.0434323362,0.03783761887,-0.9983395949],\n\t\t\t\t[-0.08481170801,0.9958149524,0.03405223652],\n\t\t\t\t[0.9954499517,0.08319191804,0.04645964289]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.42650241],\n\t\t\t\t[136.5925943],\n\t\t\t\t[281.0885176]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.858,0,356.253],\n\t\t\t\t[0,746.045,207.418],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328012,0.0801152,-7.74627e-05,-0.000454429,0.0269942],\n\t\t\t\"R\": [\n\t\t\t\t[0.0976780849,0.06705669278,-0.9929563896],\n\t\t\t\t[-0.1171365339,0.9915671608,0.05544004021],\n\t\t\t\t[0.9883005738,0.1108961929,0.1047091699]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.775430866],\n\t\t\t\t[107.2147587],\n\t\t\t\t[285.054156]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.156,0,369.678],\n\t\t\t\t[0,746.129,226.325],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331296,0.10434,-0.000526263,0.0017798,0.0107539],\n\t\t\t\"R\": [\n\t\t\t\t[0.06864954522,0.009029787974,-0.9975999714],\n\t\t\t\t[-0.09824772164,0.9951594531,0.00224680986],\n\t\t\t\t[0.9927913301,0.09785768182,0.06920439997]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.330018678],\n\t\t\t\t[104.6606406],\n\t\t\t\t[283.2576255]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[746.305,0,363.016],\n\t\t\t\t[0,746.511,222.294],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313633,0.00103632,0.000318828,-0.000294887,0.154057],\n\t\t\t\"R\": [\n\t\t\t\t[0.08441946195,-0.0784287402,-0.9933389588],\n\t\t\t\t[-0.07957536672,0.9931828981,-0.08517917513],\n\t\t\t\t[0.9932477614,0.08623609206,0.07760297012]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.995164317],\n\t\t\t\t[122.6888691],\n\t\t\t\t[282.4272415]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[745.178,0,358.539],\n\t\t\t\t[0,745.299,233.674],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315081,0.0210219,-6.99317e-06,-0.000330658,0.115227],\n\t\t\t\"R\": [\n\t\t\t\t[0.1162513982,0.03935918122,-0.9924396542],\n\t\t\t\t[-0.02556811677,0.999001962,0.03662446354],\n\t\t\t\t[0.9928906706,0.02111716788,0.117141715]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.91845612],\n\t\t\t\t[159.7823772],\n\t\t\t\t[272.1694603]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[746.014,0,365.199],\n\t\t\t\t[0,746.411,216.584],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320661,0.0432533,-0.00136099,-0.000113861,0.0956118],\n\t\t\t\"R\": [\n\t\t\t\t[0.1001711426,-0.0639180002,-0.9929150172],\n\t\t\t\t[-0.0054812292,0.9978838124,-0.06479084071],\n\t\t\t\t[0.9949551238,0.01193256733,0.09960881242]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.066812064],\n\t\t\t\t[167.2144724],\n\t\t\t\t[271.0944115]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.506,0,379.212],\n\t\t\t\t[0,745.093,221.816],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322425,0.0503962,-0.00139268,-0.000488272,0.0792831],\n\t\t\t\"R\": [\n\t\t\t\t[0.4832137358,-0.07031409603,-0.8726742883],\n\t\t\t\t[-0.1214142278,0.9817563233,-0.14633218],\n\t\t\t\t[0.8670427157,0.1766647942,0.465861009]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-31.81590772],\n\t\t\t\t[187.5269902],\n\t\t\t\t[291.8752718]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.146,0,379.909],\n\t\t\t\t[0,746.274,243.237],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327102,0.0750235,0.00051439,0.000830868,0.0552106],\n\t\t\t\"R\": [\n\t\t\t\t[0.559561068,-0.04316954181,-0.8276640634],\n\t\t\t\t[-0.1711397799,0.9711012062,-0.1663539088],\n\t\t\t\t[0.8109269924,0.2347314165,0.5360024022]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.47998338],\n\t\t\t\t[182.028679],\n\t\t\t\t[304.5116426]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.598,0,366.137],\n\t\t\t\t[0,746.916,245.497],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.34673,0.191883,-0.000717065,0.000142378,-0.151818],\n\t\t\t\"R\": [\n\t\t\t\t[0.4493443217,0.06721032382,-0.8908268367],\n\t\t\t\t[-0.2833621033,0.9563979118,-0.07077395533],\n\t\t\t\t[0.8472281859,0.2842284411,0.4487968296]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.79170468],\n\t\t\t\t[156.78227],\n\t\t\t\t[309.5144468]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.97,0,361.533],\n\t\t\t\t[0,745.268,216.194],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320215,0.0355127,-0.000935438,6.82351e-05,0.107335],\n\t\t\t\"R\": [\n\t\t\t\t[0.5139859054,0.07264601249,-0.8547169391],\n\t\t\t\t[-0.2477501277,0.96651576,-0.06683681477],\n\t\t\t\t[0.8212419639,0.2461094116,0.5147735369]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.66847624],\n\t\t\t\t[145.8563675],\n\t\t\t\t[305.5618637]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[743.904,0,367.466],\n\t\t\t\t[0,744.108,216.808],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328736,0.086922,-0.000934339,0.000214876,0.0243362],\n\t\t\t\"R\": [\n\t\t\t\t[0.4889793362,0.07185582001,-0.8693307483],\n\t\t\t\t[-0.2209595119,0.9743010874,-0.0437525441],\n\t\t\t\t[0.8438460185,0.2134809878,0.4922903259]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-47.80972546],\n\t\t\t\t[144.3254019],\n\t\t\t\t[299.7644507]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.323,0,383.952],\n\t\t\t\t[0,745.526,234.808],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334223,0.133657,-0.000107051,0.00148947,-0.0461754],\n\t\t\t\"R\": [\n\t\t\t\t[0.4969854565,0.0559027949,-0.8659563116],\n\t\t\t\t[-0.2018212488,0.978003949,-0.05269211703],\n\t\t\t\t[0.8439630558,0.2009556001,0.4973361109]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.56558119],\n\t\t\t\t[125.7186081],\n\t\t\t\t[298.6423415]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.158,0,356.674],\n\t\t\t\t[0,746.317,240.893],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334568,0.11153,0.000321304,-0.000871385,-0.0157856],\n\t\t\t\"R\": [\n\t\t\t\t[0.5541201274,0.02610072644,-0.8320274253],\n\t\t\t\t[-0.1769665492,0.9803549196,-0.08710380092],\n\t\t\t\t[0.8134087072,0.1955069916,0.5478533484]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.70019562],\n\t\t\t\t[115.5481293],\n\t\t\t\t[299.4445791]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.96,0,386.044],\n\t\t\t\t[0,745.46,258.776],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325919,0.068823,-0.000458274,0.000477805,0.0465958],\n\t\t\t\"R\": [\n\t\t\t\t[0.4763065258,-0.004539644313,-0.8792675845],\n\t\t\t\t[-0.1710253429,0.980409884,-0.09770768372],\n\t\t\t\t[0.8624861886,0.1969158475,0.4661992314]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-40.46029545],\n\t\t\t\t[93.91456762],\n\t\t\t\t[297.4902987]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.188,0,367.116],\n\t\t\t\t[0,745.437,236.843],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328194,0.058828,0.000388874,-0.00143808,0.0829656],\n\t\t\t\"R\": [\n\t\t\t\t[0.5065601345,-0.04543027129,-0.8610069225],\n\t\t\t\t[-0.1705921502,0.9735884993,-0.1517357977],\n\t\t\t\t[0.845159836,0.2237443283,0.4854310735]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.55300824],\n\t\t\t\t[76.93410209],\n\t\t\t\t[300.8962768]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.452,0,374.886],\n\t\t\t\t[0,747.648,257.28],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337728,0.123608,0.00138141,5.97732e-05,-0.0225942],\n\t\t\t\"R\": [\n\t\t\t\t[0.4549222289,-0.02855444123,-0.8900732608],\n\t\t\t\t[-0.1699899924,0.9783230281,-0.1182685721],\n\t\t\t\t[0.8741562607,0.2051065493,0.4402069233]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-13.61854908],\n\t\t\t\t[96.6157071],\n\t\t\t\t[299.0141417]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[746.39,0,405.604],\n\t\t\t\t[0,746.458,241.87],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333064,0.100943,0.000870611,0.00103156,0.0180409],\n\t\t\t\"R\": [\n\t\t\t\t[0.5002384593,-0.05591048228,-0.8640807264],\n\t\t\t\t[-0.1916757277,0.9660062257,-0.1734715752],\n\t\t\t\t[0.8444062406,0.2524004556,0.4725167836]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.55277765],\n\t\t\t\t[75.44647006],\n\t\t\t\t[303.7304898]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.943,0,392.757],\n\t\t\t\t[0,746.143,272.1],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323245,0.0770562,0.00168738,0.000666505,0.0382015],\n\t\t\t\"R\": [\n\t\t\t\t[0.5344619138,-0.0483612619,-0.8438078283],\n\t\t\t\t[-0.2099054746,0.9594877737,-0.1879438847],\n\t\t\t\t[0.818712498,0.277568731,0.5026583782]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.5535171],\n\t\t\t\t[81.37072912],\n\t\t\t\t[304.8427161]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[748.463,0,383.471],\n\t\t\t\t[0,748.465,243.614],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.34071,0.149034,0.000455623,0.000254671,-0.0668973],\n\t\t\t\"R\": [\n\t\t\t\t[0.550270912,-0.09726860505,-0.8293013577],\n\t\t\t\t[-0.1127468592,0.975440235,-0.1892207537],\n\t\t\t\t[0.82733915,0.1976238001,0.525789658]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.15956958],\n\t\t\t\t[127.9842494],\n\t\t\t\t[295.9545727]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.467,0,372.192],\n\t\t\t\t[0,744.287,242.67],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321164,0.0557106,-0.000170048,0.000249902,0.0584864],\n\t\t\t\"R\": [\n\t\t\t\t[0.5607110475,-0.1151130063,-0.8199708025],\n\t\t\t\t[-0.101866971,0.9731761842,-0.2062795062],\n\t\t\t\t[0.8217215109,0.1991911399,0.5339444244]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.41224037],\n\t\t\t\t[142.3474205],\n\t\t\t\t[294.74195]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.542,0,352.38],\n\t\t\t\t[0,746.666,240.759],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327959,0.100036,-0.000636984,-0.00122606,-0.0366604],\n\t\t\t\"R\": [\n\t\t\t\t[0.5029624145,-0.05772144518,-0.8623787128],\n\t\t\t\t[-0.198700467,0.9633205664,-0.180365215],\n\t\t\t\t[0.8411580909,0.262071977,0.4730447599]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.04469815],\n\t\t\t\t[136.31759],\n\t\t\t\t[307.4406203]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.042,0,371.719],\n\t\t\t\t[0,747.231,244.896],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323957,0.0675271,-0.000219383,0.00030566,0.0452733],\n\t\t\t\"R\": [\n\t\t\t\t[0.5145114331,-0.105655334,-0.8509494319],\n\t\t\t\t[-0.1209004538,0.9735279663,-0.1939752023],\n\t\t\t\t[0.8489175846,0.2026826318,0.4881174913]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.341169646],\n\t\t\t\t[165.8735131],\n\t\t\t\t[297.8569993]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.814,0,386.675],\n\t\t\t\t[0,746.085,252.153],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320652,0.0597547,0.000647483,5.56623e-05,0.0523558],\n\t\t\t\"R\": [\n\t\t\t\t[0.5123119379,-0.06682282728,-0.856195765],\n\t\t\t\t[-0.1341513719,0.9785027468,-0.1566390244],\n\t\t\t\t[0.8482569703,0.1951078787,0.4923342645]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.076647729],\n\t\t\t\t[186.6487394],\n\t\t\t\t[296.0424945]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[744.362,0,367.747],\n\t\t\t\t[0,744.705,261.961],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317525,0.0240072,0.000331,-0.000409781,0.122239],\n\t\t\t\"R\": [\n\t\t\t\t[0.5214772573,-0.05602259067,-0.8514240656],\n\t\t\t\t[-0.1526209796,0.9756261952,-0.1576716965],\n\t\t\t\t[0.8395047985,0.2121673788,0.5002166498]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-2.829687906],\n\t\t\t\t[192.8140289],\n\t\t\t\t[298.6606918]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[744.259,0,353.379],\n\t\t\t\t[0,744.524,245.823],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320328,0.0298824,0.00026675,-0.00161079,0.123162],\n\t\t\t\"R\": [\n\t\t\t\t[0.5556726344,-0.05485450779,-0.8295896012],\n\t\t\t\t[-0.2099711545,0.9562161648,-0.2038694692],\n\t\t\t\t[0.8044501462,0.2874745713,0.519825291]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.476630227],\n\t\t\t\t[134.2745178],\n\t\t\t\t[310.4571486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[743.679,0,405.845],\n\t\t\t\t[0,743.856,234.88],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326644,0.0646831,0.000108119,5.73367e-05,0.058946],\n\t\t\t\"R\": [\n\t\t\t\t[0.447769915,-0.01338423954,-0.894048637],\n\t\t\t\t[-0.18660487,0.9764723016,-0.1080762074],\n\t\t\t\t[0.8744602482,0.2152271039,0.4347373552]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.39083575],\n\t\t\t\t[143.2049031],\n\t\t\t\t[297.8732354]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.956,0,354.763],\n\t\t\t\t[0,747.081,232.068],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333648,0.0797639,-0.000768992,-0.00091097,0.0508097],\n\t\t\t\"R\": [\n\t\t\t\t[0.5053420531,-0.009379958189,-0.8628681393],\n\t\t\t\t[-0.2526298673,0.9545207072,-0.1583299394],\n\t\t\t\t[0.8251106347,0.2979970402,0.4799897963]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.66925616],\n\t\t\t\t[96.29580053],\n\t\t\t\t[309.4868577]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[748.369,0,375.575],\n\t\t\t\t[0,748.642,247.648],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.339087,0.143465,-0.000470446,0.00132222,-0.0624301],\n\t\t\t\"R\": [\n\t\t\t\t[0.54260376,-0.05746408722,-0.8380209057],\n\t\t\t\t[-0.1470082191,0.975763273,-0.1620944744],\n\t\t\t\t[0.8270246327,0.2111490322,0.5210051277]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.173863757],\n\t\t\t\t[116.0988382],\n\t\t\t\t[299.4207466]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.544,0,368.615],\n\t\t\t\t[0,744.426,281.181],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322575,0.0664483,0.00114224,0.000391788,0.0483369],\n\t\t\t\"R\": [\n\t\t\t\t[0.5347472888,-0.05715349527,-0.8430769924],\n\t\t\t\t[-0.1466458645,0.9762943366,-0.1591991164],\n\t\t\t\t[0.832190079,0.2087650503,0.5136894259]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.7223507],\n\t\t\t\t[130.5590862],\n\t\t\t\t[298.5444367]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[743.308,0,356.74],\n\t\t\t\t[0,743.243,228.93],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321093,0.0447792,0.000127467,-8.40104e-05,0.095825],\n\t\t\t\"R\": [\n\t\t\t\t[0.5706235669,-0.133891243,-0.8102233519],\n\t\t\t\t[-0.1678811389,0.9467635938,-0.2746900447],\n\t\t\t\t[0.8038685639,0.2927658322,0.5177678046]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.742844805],\n\t\t\t\t[124.9131408],\n\t\t\t\t[309.8640068]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.518,0,344.042],\n\t\t\t\t[0,744.512,240.289],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313532,-0.0139368,0.00116047,-0.000125352,0.195046],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3305715804,0.1011846603,-0.9383411399],\n\t\t\t\t[-0.314462461,0.9256148845,0.2105954561],\n\t\t\t\t[0.8898515555,0.3646899369,-0.2741631979]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.56718534],\n\t\t\t\t[104.1648487],\n\t\t\t\t[320.754952]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[748.956,0,345.566],\n\t\t\t\t[0,748.875,227.82],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335662,0.0955564,-6.0167e-05,-0.0012999,0.0278092],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2903396332,0.1603112194,-0.9433998147],\n\t\t\t\t[-0.341086429,0.9037763758,0.2585504022],\n\t\t\t\t[0.8940709957,0.3968483028,-0.2077221201]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-2.499901432],\n\t\t\t\t[69.14355517],\n\t\t\t\t[325.2941984]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[743.901,0,369.68],\n\t\t\t\t[0,743.816,251.042],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320568,0.044977,0.000366128,-0.00033077,0.103335],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3123459653,0.110763308,-0.943488997],\n\t\t\t\t[-0.3278062139,0.9196080197,0.216481353],\n\t\t\t\t[0.891618239,0.3768986331,-0.250926954]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.578346941],\n\t\t\t\t[71.05917793],\n\t\t\t\t[323.4074447]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.814,0,378.476],\n\t\t\t\t[0,745.908,222.393],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316287,0.0251632,0.000357033,0.00145486,0.13215],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2756543214,0.09031338143,-0.9570048005],\n\t\t\t\t[-0.3333214643,0.9248259371,0.1832860813],\n\t\t\t\t[0.9016160472,0.3695138418,-0.2248288776]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.15902854],\n\t\t\t\t[86.10496093],\n\t\t\t\t[322.4382284]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[750.419,0,363.736],\n\t\t\t\t[0,750.614,222.964],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.344753,0.14329,-0.000836382,-0.000451111,-0.060951],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2930259634,0.06094491301,-0.9541601031],\n\t\t\t\t[-0.3875087878,0.9047544541,0.1767945619],\n\t\t\t\t[0.8740553324,0.4215508218,-0.2414998562]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[36.26889278],\n\t\t\t\t[61.41890121],\n\t\t\t\t[327.3260635]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[747.394,0,354.724],\n\t\t\t\t[0,747.506,211.184],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329009,0.0921746,-0.00050966,0.000333806,0.021085],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2297156979,0.02557529828,-0.9729216835],\n\t\t\t\t[-0.3964529538,0.9104994627,0.1175405629],\n\t\t\t\t[0.888850805,0.4127185877,-0.199016617]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[62.78312093],\n\t\t\t\t[81.38139883],\n\t\t\t\t[324.7093469]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.623,0,374.989],\n\t\t\t\t[0,746.758,209.923],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319339,0.0433323,-0.00139256,0.000754597,0.0938733],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2846142448,0.03267216609,-0.9580852056],\n\t\t\t\t[-0.3313740809,0.934457856,0.1303063082],\n\t\t\t\t[0.8995476364,0.3545716359,-0.255133308]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.81195811],\n\t\t\t\t[121.7115234],\n\t\t\t\t[320.8009986]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.971,0,357.954],\n\t\t\t\t[0,746.024,209.947],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314348,0.0246684,-0.0014997,0.000635776,0.111152],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3038162213,-0.0261928812,-0.9523705354],\n\t\t\t\t[-0.3441704234,0.9351353343,0.08407512184],\n\t\t\t\t[0.8883931693,0.3533211563,-0.2931240987]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.47715732],\n\t\t\t\t[140.438376],\n\t\t\t\t[322.3540865]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[742.648,0,362.103],\n\t\t\t\t[0,742.703,220.817],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.304218,-0.0643312,-0.000139411,-0.000234647,0.289172],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2807259034,-0.0411671215,-0.958904706],\n\t\t\t\t[-0.3740921558,0.9247597922,0.06981680165],\n\t\t\t\t[0.8838823599,0.3783181134,-0.2750043253]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.64720227],\n\t\t\t\t[153.3424109],\n\t\t\t\t[325.0305142]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.72,0,366.165],\n\t\t\t\t[0,747.851,213.209],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324647,0.0523798,-0.00077308,-0.000271098,0.0916616],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2880158499,0.02777358159,-0.957222805],\n\t\t\t\t[-0.3788720768,0.9147158267,0.1405379157],\n\t\t\t\t[0.8794900907,0.4031421393,-0.2529300217]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[33.16578395],\n\t\t\t\t[147.9736193],\n\t\t\t\t[327.8869733]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.331,0,369.444],\n\t\t\t\t[0,745.587,207.732],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317455,0.0357855,-0.00041249,0.000556817,0.0920153],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3142048567,0.04518634316,-0.9482792323],\n\t\t\t\t[-0.3166241188,0.9366885696,0.1495449465],\n\t\t\t\t[0.8949997069,0.3472358248,-0.2800050117]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.61359186],\n\t\t\t\t[187.9055539],\n\t\t\t\t[317.8889871]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[747.25,0,346.366],\n\t\t\t\t[0,747.394,225.779],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328454,0.0750084,3.92686e-05,0.00130952,0.0669429],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2993781475,0.05639323365,-0.9524665495],\n\t\t\t\t[-0.3171785116,0.9355987261,0.1550897014],\n\t\t\t\t[0.8998725002,0.3485323901,-0.2622110915]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.58039626],\n\t\t\t\t[195.4066632],\n\t\t\t\t[317.2443523]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[743.861,0,344.414],\n\t\t\t\t[0,743.872,231.421],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307564,-0.0231037,-0.000140407,-0.000635225,0.208058],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2583036736,0.07116007646,-0.9634393887],\n\t\t\t\t[-0.3357690773,0.9284960528,0.1586007776],\n\t\t\t\t[0.905835713,0.3644603181,-0.2159405881]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[14.66480509],\n\t\t\t\t[172.1699927],\n\t\t\t\t[320.6722019]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.949,0,378.98],\n\t\t\t\t[0,744.921,225.408],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321047,0.0567081,-0.000162218,0.000699701,0.0634367],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3208579847,0.07871363947,-0.9438507915],\n\t\t\t\t[-0.3472646452,0.9173632389,0.1945557869],\n\t\t\t\t[0.8811682132,0.3901907879,-0.267008856]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.70363788],\n\t\t\t\t[100.2282059],\n\t\t\t\t[322.9364507]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.712,0,360.895],\n\t\t\t\t[0,745.741,234.163],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31006,-0.0103454,0.000398478,0.000813845,0.181221],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3227895896,0.1367774117,-0.9365355415],\n\t\t\t\t[-0.3406635237,0.9063958148,0.2497898928],\n\t\t\t\t[0.8830375102,0.3996730746,-0.245980058]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.93002532],\n\t\t\t\t[154.0180569],\n\t\t\t\t[326.396188]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.931,0,372.193],\n\t\t\t\t[0,746.03,212.813],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325757,0.0830346,-0.000419051,0.00216162,0.0290765],\n\t\t\t\"R\": [\n\t\t\t\t[-0.311559769,0.02363818266,-0.9499324958],\n\t\t\t\t[-0.312276077,0.9416182622,0.1258518973],\n\t\t\t\t[0.8974486961,0.3358515813,-0.2859887293]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.03283731],\n\t\t\t\t[153.3338286],\n\t\t\t\t[314.9665339]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.756,0,368.403],\n\t\t\t\t[0,744.752,202.816],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313223,0.00720848,-0.00119606,0.000542174,0.130737],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3236003046,0.09291211415,-0.9416210394],\n\t\t\t\t[-0.3175516679,0.9267842511,0.2005788875],\n\t\t\t\t[0.8913157584,0.3639207207,-0.2704032691]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.098271],\n\t\t\t\t[130.5289196],\n\t\t\t\t[319.7107876]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[744.889,0,373.989],\n\t\t\t\t[0,745.092,230.989],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319065,0.0283013,-0.000935078,-0.000739787,0.111424],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3391260928,0.0773602665,-0.9375547357],\n\t\t\t\t[-0.3008220503,0.9353680392,0.1859911968],\n\t\t\t\t[0.8913470633,0.3451116057,-0.2939360344]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.38901828],\n\t\t\t\t[189.8595323],\n\t\t\t\t[315.0907711]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.21,0,358.424],\n\t\t\t\t[0,743.138,251.445],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316603,0.00648778,0.000375455,-0.000277526,0.16085],\n\t\t\t\"R\": [\n\t\t\t\t[-0.34774011,0.09728469559,-0.9325301624],\n\t\t\t\t[-0.3453355468,0.9113903597,0.2238548019],\n\t\t\t\t[0.8716766465,0.399879107,-0.2833311204]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-13.32995299],\n\t\t\t\t[105.9918293],\n\t\t\t\t[324.8353482]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.315,0,375.798],\n\t\t\t\t[0,745.342,214.671],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317661,0.021421,-0.000865931,0.000266434,0.124612],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2889220833,0.06736289331,-0.9549797225],\n\t\t\t\t[-0.355115135,0.918816287,0.172249446],\n\t\t\t\t[0.8890541438,0.3888944219,-0.2415447329]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.18922492],\n\t\t\t\t[101.394333],\n\t\t\t\t[324.5371374]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[743.803,0,341.335],\n\t\t\t\t[0,743.805,238.935],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305727,-0.0577903,-0.000702133,-0.00085287,0.249773],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2867564999,0.0564691645,-0.9563377767],\n\t\t\t\t[-0.3641939053,0.9168870998,0.1633427245],\n\t\t\t\t[0.8860775977,0.3951319776,-0.24235761]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[29.77890794],\n\t\t\t\t[113.785435],\n\t\t\t\t[325.4988706]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.285,0,373.625],\n\t\t\t\t[0,745.232,235.431],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319503,0.0483306,-0.000362012,0.00120612,0.080115],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3458253526,0.08893014684,-0.9340750797],\n\t\t\t\t[-0.3902640321,0.8916714915,0.2293816395],\n\t\t\t\t[0.8532870623,0.4438618933,-0.2736563703]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.96316513],\n\t\t\t\t[116.1979138],\n\t\t\t\t[333.2100324]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.536,0,366.592],\n\t\t\t\t[0,744.501,224.531],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312705,-0.014521,0.000375544,8.36622e-05,0.188212],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3181142509,0.09038767844,-0.94373375],\n\t\t\t\t[-0.4081954831,0.8853909401,0.2223945386],\n\t\t\t\t[0.8556750382,0.455974726,-0.2447596336]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.972278595],\n\t\t\t\t[119.3141773],\n\t\t\t\t[334.5341124]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.6,0,358.514],\n\t\t\t\t[0,744.655,220.515],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30152,-0.0573254,-0.000856409,-0.000288003,0.227002],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3545583501,0.05661769889,-0.9333181732],\n\t\t\t\t[-0.3227337004,0.929412527,0.1789841147],\n\t\t\t\t[0.8775712706,0.3646735401,-0.3112585327]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-25.22428756],\n\t\t\t\t[139.0090865],\n\t\t\t\t[319.514146]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.635,0,384.154],\n\t\t\t\t[0,745.75,223.733],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328279,0.104082,-0.000872931,0.00144148,0.00404207],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9078071857,0.03344162453,-0.4180523547],\n\t\t\t\t[0.00958043905,0.9982092569,0.05904654639],\n\t\t\t\t[0.4192783428,0.049597754,-0.9065019217]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.31434773],\n\t\t\t\t[152.0493649],\n\t\t\t\t[282.3431498]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.944,0,375.746],\n\t\t\t\t[0,747.112,207.581],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321827,0.078307,-0.00112183,4.35862e-05,0.0396046],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9306435439,0.005427673037,-0.3658867782],\n\t\t\t\t[-0.02457764723,0.9967049447,0.07729936951],\n\t\t\t\t[0.3651007167,0.08093079535,-0.9274436225]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.01828104],\n\t\t\t\t[131.8151818],\n\t\t\t\t[284.3018088]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[743.881,0,383.122],\n\t\t\t\t[0,743.965,237.105],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311008,0.000325185,-0.000782967,0.00055371,0.154469],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9217631286,0.06528892794,-0.3822173342],\n\t\t\t\t[0.03992506463,0.996464058,0.07392814261],\n\t\t\t\t[0.3856925251,0.05288418425,-0.9211104924]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.22640533],\n\t\t\t\t[121.5976731],\n\t\t\t\t[282.3432951]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[743.69,0,370.307],\n\t\t\t\t[0,743.828,227.79],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303025,-0.0263668,-0.000445815,0.00071591,0.180166],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9409979296,0.06863452498,-0.3313792366],\n\t\t\t\t[0.04529042225,0.9959498431,0.07767037874],\n\t\t\t\t[0.3353679682,0.05807936004,-0.9402952269]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-38.37277115],\n\t\t\t\t[113.0266013],\n\t\t\t\t[281.4230584]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[743.998,0,375.484],\n\t\t\t\t[0,744.299,220.79],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310908,0.00595719,-5.69241e-05,0.000519591,0.131448],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9269484075,0.08594630429,-0.3652121064],\n\t\t\t\t[0.04467826469,0.9917683984,0.1199970688],\n\t\t\t\t[0.3725191305,0.09491404865,-0.9231580692]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.36597135],\n\t\t\t\t[80.23534001],\n\t\t\t\t[286.4206576]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.602,0,379.444],\n\t\t\t\t[0,745.67,224.268],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303286,-0.0402497,-0.00132196,0.00012981,0.210105],\n\t\t\t\"R\": [\n\t\t\t\t[-0.923694641,0.09319000989,-0.3716232396],\n\t\t\t\t[0.04673933936,0.9901316615,0.1321163393],\n\t\t\t\t[0.3802678586,0.1046657299,-0.9189349491]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.9450645075],\n\t\t\t\t[68.69008136],\n\t\t\t\t[287.3198917]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.731,0,365.823],\n\t\t\t\t[0,745.481,229.263],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308219,-0.0231519,0.000110727,0.000180113,0.209056],\n\t\t\t\"R\": [\n\t\t\t\t[-0.917494877,0.04967698427,-0.3946331815],\n\t\t\t\t[0.001316203411,0.9925436367,0.1218827179],\n\t\t\t\t[0.3977454189,0.1113073518,-0.9107190869]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.92434207],\n\t\t\t\t[79.05208738],\n\t\t\t\t[288.1952445]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.611,0,393.911],\n\t\t\t\t[0,745.863,244.069],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318705,0.0460564,0.000184451,0.000507881,0.0745222],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9083609307,0.09070031,-0.4082326216],\n\t\t\t\t[0.05268537174,0.9932388068,0.1034452715],\n\t\t\t\t[0.4148550001,0.07245775567,-0.9069979066]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.31394514],\n\t\t\t\t[81.42535523],\n\t\t\t\t[283.8217571]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.77,0,370.33],\n\t\t\t\t[0,746.047,217.48],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321786,0.069205,4.67533e-05,5.58471e-05,0.0372207],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9211612824,0.007939579541,-0.3891000576],\n\t\t\t\t[-0.02433705705,0.996659961,0.07795274024],\n\t\t\t\t[0.3884193603,0.08127659646,-0.9178913418]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[49.65486911],\n\t\t\t\t[97.0413663],\n\t\t\t\t[285.6851525]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.504,0,363.969],\n\t\t\t\t[0,744.833,247.068],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335916,0.144192,-0.000823922,-0.000462503,-0.076361],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9225918644,-0.01579725191,-0.3854538864],\n\t\t\t\t[-0.05416624958,0.9945677902,0.08888716518],\n\t\t\t\t[0.381955847,0.1028851669,-0.9184358297]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.86826856],\n\t\t\t\t[113.0714764],\n\t\t\t\t[288.4804376]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.999,0,387.199],\n\t\t\t\t[0,745.384,239.21],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313806,0.0330336,-7.01628e-05,0.00132279,0.0985619],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9109471902,-0.006922747781,-0.4124648981],\n\t\t\t\t[-0.04540685091,0.9954664163,0.08357530662],\n\t\t\t\t[0.4100163832,0.09486142287,-0.9071316751]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[65.64483344],\n\t\t\t\t[130.0336458],\n\t\t\t\t[285.8729547]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.664,0,350.646],\n\t\t\t\t[0,743.861,222.503],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.300623,-0.0667329,-0.000394627,-0.00107967,0.272621],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9268683851,0.02536908581,-0.3745282449],\n\t\t\t\t[0.006256924582,0.9986192343,0.0521581796],\n\t\t\t\t[0.3753343145,0.04600037271,-0.9257473295]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.10937388],\n\t\t\t\t[163.0891099],\n\t\t\t\t[280.8513179]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.176,0,390.977],\n\t\t\t\t[0,744.332,246.666],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327257,0.10216,-0.000582688,0.00201022,0.0126373],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9290120658,-0.01909429991,-0.3695564765],\n\t\t\t\t[-0.04453762663,0.9971777882,0.06043888335],\n\t\t\t\t[0.3673594716,0.07260762025,-0.9272406117]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.5211548],\n\t\t\t\t[160.1280328],\n\t\t\t\t[285.2494721]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.044,0,360.721],\n\t\t\t\t[0,744.333,226.474],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311296,-0.00746755,-0.00165304,-0.000168766,0.17966],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9305033137,0.06302128148,-0.3608211486],\n\t\t\t\t[0.03165130136,0.9952368859,0.09220485899],\n\t\t\t\t[0.3649133847,0.07437646791,-0.9280659258]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.8814582],\n\t\t\t\t[178.0304645],\n\t\t\t\t[285.6034633]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[744.03,0,362.147],\n\t\t\t\t[0,744.447,229.329],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314413,0.0379836,-0.000745365,2.01034e-05,0.0898919],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9265853662,0.03975182478,-0.373977742],\n\t\t\t\t[0.01411888978,0.9973739765,0.07103385017],\n\t\t\t\t[0.3758193929,0.06053877555,-0.9247133829]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.14446289],\n\t\t\t\t[185.021862],\n\t\t\t\t[282.5666312]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[743.673,0,368.897],\n\t\t\t\t[0,743.962,238.378],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314216,0.0200058,-0.0002257,-0.000345788,0.11969],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9350006114,0.024774913,-0.3537796777],\n\t\t\t\t[-0.006073372197,0.9962920776,0.08582080369],\n\t\t\t\t[0.354594093,0.08239113958,-0.9313832344]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.51100446],\n\t\t\t\t[168.6528502],\n\t\t\t\t[285.9762696]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.686,0,385.346],\n\t\t\t\t[0,745.049,227.767],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317176,0.0455424,-0.000136917,0.000534438,0.0739505],\n\t\t\t\"R\": [\n\t\t\t\t[-0.908638426,0.05327873405,-0.4141709639],\n\t\t\t\t[0.04010861029,0.9983767379,0.04043746577],\n\t\t\t\t[0.4156531128,0.02013121347,-0.9093004036]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.322164421],\n\t\t\t\t[189.4505625],\n\t\t\t\t[275.8940033]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[746.282,0,378.432],\n\t\t\t\t[0,746.624,237.775],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320382,0.058651,0.000451819,0.000534403,0.062414],\n\t\t\t\"R\": [\n\t\t\t\t[-0.916555331,0.01769811564,-0.3995160846],\n\t\t\t\t[-0.01470055472,0.9968539618,0.07788499561],\n\t\t\t\t[0.3996376094,0.077259016,-0.9134116408]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-37.37478029],\n\t\t\t\t[164.0712496],\n\t\t\t\t[285.8486829]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.687,0,374.362],\n\t\t\t\t[0,743.883,225.048],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322503,0.0715253,7.77555e-05,0.000517375,0.0539586],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9239544056,0.01616424802,-0.3821609261],\n\t\t\t\t[-0.020576852,0.9955594902,0.09185801365],\n\t\t\t\t[0.3819487525,0.09273628522,-0.9195189677]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-17.14443298],\n\t\t\t\t[133.4982453],\n\t\t\t\t[287.2304165]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.801,0,368.555],\n\t\t\t\t[0,746.033,233.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317685,0.0475287,-3.52395e-05,0.000512076,0.0805211],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9241543321,-0.01069440692,-0.3818696113],\n\t\t\t\t[-0.04324692472,0.9961108974,0.076764468],\n\t\t\t\t[0.3795635307,0.08745690199,-0.9210227014]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.56758847],\n\t\t\t\t[113.8864258],\n\t\t\t\t[286.5218078]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.1,0,390.405],\n\t\t\t\t[0,744.284,237.593],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322514,0.0588182,0.000321804,0.00147162,0.0689104],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9369369296,0.006948104691,-0.3494294118],\n\t\t\t\t[-0.02026391849,0.9970404822,0.07415962808],\n\t\t\t\t[0.3489105381,0.07656370335,-0.9340232522]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.618393153],\n\t\t\t\t[111.1940513],\n\t\t\t\t[285.5030449]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[747.001,0,381.032],\n\t\t\t\t[0,747.132,234.437],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324882,0.0577225,-0.00134011,-0.00135265,0.0819201],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9282296861,0.06047570579,-0.3670590401],\n\t\t\t\t[0.02337036389,0.9942284933,0.1047068731],\n\t\t\t\t[0.3712727784,0.08861372459,-0.9242857414]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[25.6408869],\n\t\t\t\t[119.8980517],\n\t\t\t\t[286.9452799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[743.981,0,363.51],\n\t\t\t\t[0,744.339,258.582],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313768,0.0101513,0.00111395,-0.00104272,0.1345],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9138255678,-0.001018785166,-0.4061056435],\n\t\t\t\t[-0.03060482875,0.9973259054,0.06636552484],\n\t\t\t\t[0.4049520663,0.0730753071,-0.9114130916]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.3580015],\n\t\t\t\t[146.5427691],\n\t\t\t\t[284.2261849]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.847,0,398.685],\n\t\t\t\t[0,745.01,270.264],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328511,0.106892,0.000179407,0.00152869,-0.00291861],\n\t\t\t\"R\": [\n\t\t\t\t[-0.915939158,0.01937877811,-0.4008490012],\n\t\t\t\t[-0.01852012751,0.9957282098,0.09045627137],\n\t\t\t\t[0.4008895904,0.09027621565,-0.9116675607]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.147743662],\n\t\t\t\t[145.7157982],\n\t\t\t\t[287.1579534]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[743.703,0,360.221],\n\t\t\t\t[0,744.108,227.682],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309411,-0.0239561,-0.001159,0.000249551,0.191643],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6256262875,-0.004424555618,-0.7801103586],\n\t\t\t\t[-0.1745259617,0.9754325172,0.134432485],\n\t\t\t\t[0.7603502068,0.2202540071,-0.6110284243]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.656398722],\n\t\t\t\t[175.9817187],\n\t\t\t\t[302.7764948]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.203,0,376.344],\n\t\t\t\t[0,747.435,209.923],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331616,0.11313,4.7739e-05,0.00134479,-0.0154118],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6724252099,0.1092176997,-0.7320627235],\n\t\t\t\t[-0.09964199407,0.9666926758,0.2357472025],\n\t\t\t\t[0.7334274403,0.2314665517,-0.6391458561]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.9742570867],\n\t\t\t\t[185.4525058],\n\t\t\t\t[305.0714088]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[747.234,0,368.091],\n\t\t\t\t[0,747.404,224.293],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329137,0.0905459,-0.000565165,-0.000329878,0.0231933],\n\t\t\t\"R\": [\n\t\t\t\t[-0.656899377,0.0205246652,-0.7536988435],\n\t\t\t\t[-0.2005757989,0.9588523348,0.2009267253],\n\t\t\t\t[0.7268098496,0.2831623883,-0.6257527502]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.7353206],\n\t\t\t\t[153.4285774],\n\t\t\t\t[313.8994992]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.386,0,362.788],\n\t\t\t\t[0,747.713,235.953],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.341304,0.154379,-0.000777774,-0.000654564,-0.0867958],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6631685233,0.06657565756,-0.7455033143],\n\t\t\t\t[-0.1433461882,0.9663011288,0.2138083224],\n\t\t\t\t[0.7346151238,0.2486560079,-0.6312771259]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.98714967],\n\t\t\t\t[144.6795235],\n\t\t\t\t[307.788251]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.746,0,376.748],\n\t\t\t\t[0,745.752,233.642],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32088,0.0642866,0.000720856,0.00118823,0.0489989],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6568191598,0.04935682433,-0.7524310568],\n\t\t\t\t[-0.1452125328,0.970898021,0.19044777],\n\t\t\t\t[0.7399337211,0.2343521638,-0.6305371929]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.15667108],\n\t\t\t\t[135.9397275],\n\t\t\t\t[306.138018]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[743.581,0,359.642],\n\t\t\t\t[0,743.625,223.766],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309434,-0.0145066,-0.000137344,-0.000208072,0.169515],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6714433509,-0.01781555577,-0.7408417054],\n\t\t\t\t[-0.2359597182,0.9528188479,0.1909430659],\n\t\t\t\t[0.7024861834,0.3030162521,-0.6439676336]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.25895983],\n\t\t\t\t[89.79547495],\n\t\t\t\t[311.6502108]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.148,0,371.237],\n\t\t\t\t[0,745.103,220.621],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318768,0.034703,-0.000217256,0.000447556,0.0954449],\n\t\t\t\"R\": [\n\t\t\t\t[-0.7012843801,0.01049644172,-0.7128043511],\n\t\t\t\t[-0.1276034542,0.9818947595,0.1400001421],\n\t\t\t\t[0.7013683602,0.1891362102,-0.6872480755]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.70728874],\n\t\t\t\t[118.2041714],\n\t\t\t\t[298.0588141]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[743.06,0,391.891],\n\t\t\t\t[0,743.237,230.861],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322908,0.0553375,0.000339696,0.00130059,0.0777268],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6299217379,0.07604043096,-0.7729272003],\n\t\t\t\t[-0.1362742651,0.9689348188,0.2063846932],\n\t\t\t\t[0.7646096578,0.2353362908,-0.5999907511]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.915515028],\n\t\t\t\t[82.19520224],\n\t\t\t\t[306.2551203]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.456,0,356.955],\n\t\t\t\t[0,746.592,233.352],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320498,0.0507213,0.000550471,0.000126643,0.0741224],\n\t\t\t\"R\": [\n\t\t\t\t[-0.684872543,0.06612723284,-0.7256561093],\n\t\t\t\t[-0.09767122593,0.9785553778,0.1813551881],\n\t\t\t\t[0.7220872049,0.1950809107,-0.6637269822]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.194765679],\n\t\t\t\t[87.40737989],\n\t\t\t\t[301.7039487]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.33,0,361.528],\n\t\t\t\t[0,747.71,220.883],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322455,0.0389243,0.00118705,0.000768992,0.12227],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6055801648,0.01225702185,-0.7956899079],\n\t\t\t\t[-0.1760343759,0.973047512,0.1489645524],\n\t\t\t\t[0.7760699469,0.2302787546,-0.5871006154]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.64204154],\n\t\t\t\t[89.24589085],\n\t\t\t\t[303.2777117]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[747.774,0,350.264],\n\t\t\t\t[0,747.981,233.163],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312094,-0.0263709,0.00148203,-0.000526901,0.233175],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6738094891,0.06987822761,-0.7355935058],\n\t\t\t\t[-0.1142917175,0.9736808734,0.1971876265],\n\t\t\t\t[0.730012449,0.216939139,-0.6480889092]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.79986479],\n\t\t\t\t[83.7107121],\n\t\t\t\t[303.8218457]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.899,0,366.47],\n\t\t\t\t[0,744.848,222.726],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30396,-0.0418844,-0.00058576,-0.000160605,0.231689],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6160341517,-0.01803679921,-0.7875129191],\n\t\t\t\t[-0.1884772348,0.9740736778,0.1251271436],\n\t\t\t\t[0.7648387123,0.2255108512,-0.6034621779]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.57356311],\n\t\t\t\t[97.36793025],\n\t\t\t\t[301.4047959]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[746.859,0,368.586],\n\t\t\t\t[0,747.139,224.684],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318047,0.0428323,-0.000551709,0.000692584,0.0895927],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6485099772,-0.04236983322,-0.7600260566],\n\t\t\t\t[-0.2235198928,0.9650338886,0.1369249841],\n\t\t\t\t[0.7276494121,0.258678161,-0.6353046057]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[38.13208236],\n\t\t\t\t[106.9572182],\n\t\t\t\t[307.8393222]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.505,0,357.32],\n\t\t\t\t[0,744.53,228.165],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303025,-0.0702212,0.000533599,-0.000753966,0.269146],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6825611814,-0.04644305139,-0.729351271],\n\t\t\t\t[-0.1871280484,0.9758162042,0.1129859684],\n\t\t\t\t[0.7064653757,0.213601916,-0.6747450588]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.82592662],\n\t\t\t\t[132.5834032],\n\t\t\t\t[304.3020009]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.837,0,357.73],\n\t\t\t\t[0,745.88,221.629],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3197,0.0439542,-0.00136466,0.00170195,0.109142],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6069626381,-0.02117938565,-0.7944481037],\n\t\t\t\t[-0.2107505505,0.968144583,0.1352045554],\n\t\t\t\t[0.7662770787,0.2494944888,-0.5920911574]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[64.87618524],\n\t\t\t\t[141.1933336],\n\t\t\t\t[303.6799609]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.767,0,345.102],\n\t\t\t\t[0,744.781,229.581],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307131,-0.033453,0.0002274,-0.000565369,0.224073],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6350262321,-0.03398669713,-0.7717425665],\n\t\t\t\t[-0.2527580664,0.9531820242,0.1660041824],\n\t\t\t\t[0.7299692079,0.3004811693,-0.6138860012]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.611726],\n\t\t\t\t[134.434862],\n\t\t\t\t[314.3473002]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[743.543,0,370.548],\n\t\t\t\t[0,743.847,224.118],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308645,-0.0111516,9.80345e-05,-0.000744439,0.160705],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6124225565,-0.05791042639,-0.7884066177],\n\t\t\t\t[-0.1936876385,0.977907652,0.07862393367],\n\t\t\t\t[0.7664357188,0.2008556864,-0.610109238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[28.62018644],\n\t\t\t\t[186.6213498],\n\t\t\t\t[297.6164741]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[743.39,0,376.249],\n\t\t\t\t[0,743.751,216.723],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319375,0.0602092,-1.05699e-05,0.00110696,0.0487054],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6887185447,0.08181736584,-0.720397588],\n\t\t\t\t[-0.1043667464,0.9720764384,0.2101784484],\n\t\t\t\t[0.7174777686,0.2199393475,-0.6609480577]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.48604056],\n\t\t\t\t[189.7333893],\n\t\t\t\t[302.8177068]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[747.038,0,360.923],\n\t\t\t\t[0,747.259,204.023],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32724,0.0825647,-0.000697091,0.000733699,0.0397455],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6726100217,0.03848005322,-0.7389959704],\n\t\t\t\t[-0.1487286588,0.9712392562,0.1859411014],\n\t\t\t\t[0.7248969201,0.2349757278,-0.6475421705]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.177324598],\n\t\t\t\t[151.0352965],\n\t\t\t\t[305.3818706]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[747.914,0,388.693],\n\t\t\t\t[0,747.835,242.83],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.338429,0.134609,0.00136964,0.000561914,-0.0365273],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6685313457,0.02780025068,-0.7431641715],\n\t\t\t\t[-0.1765857142,0.9647874561,0.194942684],\n\t\t\t\t[0.722414926,0.2615574708,-0.6400815293]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.15175066],\n\t\t\t\t[129.456494],\n\t\t\t\t[308.9585645]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.296,0,369.274],\n\t\t\t\t[0,746.424,219.198],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312598,-0.010091,-0.000298989,-0.000771876,0.160922],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6341455554,-0.01222382885,-0.7731170626],\n\t\t\t\t[-0.1896201401,0.9718007188,0.1401697733],\n\t\t\t\t[0.7496023059,0.2354866044,-0.6185809907]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.414673774],\n\t\t\t\t[116.5175191],\n\t\t\t\t[305.5663378]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[743.609,0,361.562],\n\t\t\t\t[0,743.794,221.87],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314273,0.00142644,4.14402e-05,0.000150079,0.159707],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6552794634,-0.0176584532,-0.7551801135],\n\t\t\t\t[-0.2007508014,0.9678470127,0.1515627784],\n\t\t\t\t[0.7282224527,0.2509189891,-0.6377552198]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.541098798],\n\t\t\t\t[103.6271831],\n\t\t\t\t[307.0310837]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[748.435,0,354.117],\n\t\t\t\t[0,748.457,219.552],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324308,0.0627041,-0.000215295,-0.000444561,0.0758056],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6485698923,-0.03356212054,-0.7604148071],\n\t\t\t\t[-0.2015811272,0.9709293787,0.1290782349],\n\t\t\t\t[0.733976937,0.2370015309,-0.6364810526]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.56445448],\n\t\t\t\t[121.4098798],\n\t\t\t\t[305.3725739]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.572,0,350.678],\n\t\t\t\t[0,745.729,218.826],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313081,0.00890587,-0.000465969,-0.00023462,0.141032],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6716141,0.00283216084,-0.7408957278],\n\t\t\t\t[-0.1390702972,0.9817365211,0.1298185488],\n\t\t\t\t[0.7277320613,0.1902245569,-0.6589542206]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.95231346],\n\t\t\t\t[154.9907046],\n\t\t\t\t[298.6967118]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.377,0,383.314],\n\t\t\t\t[0,745.581,229.65],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311824,0.0113225,-0.000890232,0.000288511,0.13186],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9888207636,0.1490770148,-0.003088867539],\n\t\t\t\t[0.1339941062,0.8974831076,0.420201917],\n\t\t\t\t[0.06541465384,0.4150904904,-0.9074253732]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.5065201],\n\t\t\t\t[83.70733211],\n\t\t\t\t[330.6651976]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[745.133,0,380.598],\n\t\t\t\t[0,746.347,248.499],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.340543,0.0603048,-0.00219925,-0.00194065,0.128165],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9728033822,0.2090533065,0.09975116351],\n\t\t\t\t[0.2316107347,0.8720009628,0.4312433055],\n\t\t\t\t[0.003169728315,0.4426183864,-0.8967044758]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.76195567],\n\t\t\t\t[58.26386366],\n\t\t\t\t[329.69794]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[745.787,0,382.41],\n\t\t\t\t[0,745.973,216.203],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309439,0.00115788,-0.000439278,0.00154239,0.140783],\n\t\t\t\"R\": [\n\t\t\t\t[-0.995096801,0.09728424012,-0.01783629191],\n\t\t\t\t[0.08253738581,0.9161639792,0.3922131349],\n\t\t\t\t[0.05449712496,0.3888178749,-0.9197014317]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.72584843],\n\t\t\t\t[65.39953055],\n\t\t\t\t[327.4514754]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.782,0,384.335],\n\t\t\t\t[0,745.051,230.833],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319171,0.0452003,0.000841339,0.00114337,0.0902557],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9962766095,0.08536470964,0.01207409478],\n\t\t\t\t[0.0830687393,0.9129812009,0.3994557689],\n\t\t\t\t[0.02307600417,0.3989714189,-0.9166729542]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.91980994],\n\t\t\t\t[75.72355875],\n\t\t\t\t[328.4117918]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.938,0,386.124],\n\t\t\t\t[0,746.151,234.663],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322825,0.0563734,0.000659785,0.00216478,0.0846192],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9996885429,0.02460566921,0.004168718214],\n\t\t\t\t[0.02372582958,0.8852416043,0.464525981],\n\t\t\t\t[0.007739649829,0.4644802074,-0.8855496794]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.79490616],\n\t\t\t\t[45.57973364],\n\t\t\t\t[333.4360246]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.533,0,376.456],\n\t\t\t\t[0,745.938,237.583],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324418,0.0645728,-2.52302e-05,0.000695669,0.0784542],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9996292032,0.0242501169,-0.01238498622],\n\t\t\t\t[0.01720849374,0.9151046106,0.4028491273],\n\t\t\t\t[0.02110269642,0.4024866252,-0.9151826008]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[44.50201086],\n\t\t\t\t[83.15135806],\n\t\t\t\t[329.4460526]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.538,0,357.165],\n\t\t\t\t[0,745.859,222.198],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30448,-0.0356601,-0.000261684,-0.000249049,0.226264],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9994703128,-0.005373675551,-0.03209699996],\n\t\t\t\t[-0.01769948118,0.9174086112,0.3975527241],\n\t\t\t\t[0.02730974481,0.3979102457,-0.9170177829]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.28939518],\n\t\t\t\t[107.3778293],\n\t\t\t\t[329.1138759]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[746.393,0,361.584],\n\t\t\t\t[0,746.73,220.937],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31726,0.0513551,0.000643529,-0.000795525,0.0635312],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9973050313,-0.005865573042,-0.0731318648],\n\t\t\t\t[-0.03181904441,0.9327538711,0.3591068981],\n\t\t\t\t[0.06610766226,0.3604661023,-0.9304267656]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[64.05594666],\n\t\t\t\t[137.6750859],\n\t\t\t\t[322.0323762]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[750.271,0,344.156],\n\t\t\t\t[0,750.817,228.346],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.379154,0.391779,0.000225814,-0.000528714,-0.53339],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9991212371,-0.002089946585,-0.04186150665],\n\t\t\t\t[-0.01685937738,0.9344344151,0.355735977],\n\t\t\t\t[0.03837336329,0.3561291283,-0.933648504]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.49527243],\n\t\t\t\t[159.1149955],\n\t\t\t\t[322.66132]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.897,0,366.998],\n\t\t\t\t[0,745.389,227.752],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317307,0.0499201,-0.000255849,-0.000414203,0.0689696],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9956077306,0.03830608065,-0.08542769468],\n\t\t\t\t[0.005132094192,0.9334237661,0.3587390896],\n\t\t\t\t[0.093482129,0.3567249879,-0.9295205079]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.9897871],\n\t\t\t\t[163.3127669],\n\t\t\t\t[320.2676037]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.812,0,365.568],\n\t\t\t\t[0,746.463,243.927],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334591,0.135033,-0.000586766,0.000648781,-0.0516408],\n\t\t\t\"R\": [\n\t\t\t\t[-0.998272905,0.02856351314,-0.05133549401],\n\t\t\t\t[0.007150624435,0.926422355,0.3764179707],\n\t\t\t\t[0.05831016891,0.3754007803,-0.9250265825]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.7749059],\n\t\t\t\t[177.7642897],\n\t\t\t\t[325.0135255]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.195,0,380.908],\n\t\t\t\t[0,743.577,227.789],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308886,-0.0148964,-0.00146189,1.64512e-05,0.167268],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9994731762,0.02727182579,0.01759595347],\n\t\t\t\t[0.03184982914,0.9284235071,0.3701558858],\n\t\t\t\t[-0.006241669996,0.370521307,-0.9288029945]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.9618436208],\n\t\t\t\t[187.4005014],\n\t\t\t\t[324.424529]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[745.52,0,396.637],\n\t\t\t\t[0,745.641,231.295],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327971,0.0908214,-0.00010844,0.00165709,0.0286999],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9916965419,0.1263943494,0.02371575794],\n\t\t\t\t[0.1244737261,0.8970729317,0.4239887342],\n\t\t\t\t[0.03231501572,0.4234201503,-0.9053568998]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.62306638],\n\t\t\t\t[150.537484],\n\t\t\t\t[333.7640249]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.91,0,372.463],\n\t\t\t\t[0,744.965,226.423],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308854,-0.0214085,8.99951e-05,0.000256405,0.180188],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9924146786,0.1180105859,0.03444716585],\n\t\t\t\t[0.1215225705,0.8993517426,0.4199984619],\n\t\t\t\t[0.01858414592,0.4209987468,-0.9068708203]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.68067405],\n\t\t\t\t[162.2988485],\n\t\t\t\t[333.0026074]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.246,0,368.718],\n\t\t\t\t[0,747.604,232.745],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3413,0.139342,-0.00187439,-0.000934376,-0.0485015],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9858543141,0.1593536378,0.05193928607],\n\t\t\t\t[0.1663907088,0.8933064559,0.4175137217],\n\t\t\t\t[0.02013463084,0.4202499184,-0.9071849882]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.61956214],\n\t\t\t\t[147.1949584],\n\t\t\t\t[331.9981158]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[743.705,0,367.288],\n\t\t\t\t[0,743.835,246.124],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316616,0.0215265,-3.02132e-05,0.000242548,0.131229],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9974602961,0.07055123587,0.009771425173],\n\t\t\t\t[0.06902048446,0.9235857212,0.3771280794],\n\t\t\t\t[0.01758210332,0.3768447143,-0.9261095675]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.73982653],\n\t\t\t\t[139.9628037],\n\t\t\t\t[324.9351286]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[742.776,0,376.251],\n\t\t\t\t[0,742.956,242.934],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317736,0.0249159,0.000195501,0.000659428,0.110976],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9810894361,0.1806813104,0.06941024814],\n\t\t\t\t[0.1934432758,0.9031273242,0.3833284952],\n\t\t\t\t[0.006574003146,0.389506483,-0.9210002618]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.91453507],\n\t\t\t\t[125.2651482],\n\t\t\t\t[325.9500645]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[744.563,0,383.579],\n\t\t\t\t[0,744.554,245.613],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324188,0.0688729,0.000784842,0.000316148,0.0548859],\n\t\t\t\"R\": [\n\t\t\t\t[-0.970594512,0.2257141743,0.08366244524],\n\t\t\t\t[0.2406675117,0.9026066179,0.3569039677],\n\t\t\t\t[0.005044007626,0.3665438649,-0.9303870985]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.64851648],\n\t\t\t\t[114.5848432],\n\t\t\t\t[323.1694161]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.897,0,369.27],\n\t\t\t\t[0,746.007,226.27],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314378,0.0131268,-0.000749673,-0.000436078,0.140449],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9929061616,0.1118291068,0.04039313118],\n\t\t\t\t[0.1187797946,0.9175946163,0.3793566667],\n\t\t\t\t[0.005358597494,0.3814634596,-0.9243683867]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.348770156],\n\t\t\t\t[111.4514571],\n\t\t\t\t[325.9373984]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[743.647,0,378.532],\n\t\t\t\t[0,743.859,221.629],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312883,-0.00145442,-0.000725648,-1.91192e-05,0.160115],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9995005243,0.01416777706,-0.02824846864],\n\t\t\t\t[0.002450265794,0.9259270935,0.3776943389],\n\t\t\t\t[0.03150711165,0.3774364735,-0.9254993303]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.861259295],\n\t\t\t\t[105.360829],\n\t\t\t\t[326.1962043]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.35,0,364.423],\n\t\t\t\t[0,745.51,242.824],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317615,0.0309367,1.60295e-05,-0.00084218,0.138729],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9983267687,0.03243769532,-0.0478691851],\n\t\t\t\t[0.01510269673,0.9453721551,0.3256430514],\n\t\t\t\t[0.05581730476,0.3243752215,-0.9442802255]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.85545331],\n\t\t\t\t[138.1219419],\n\t\t\t\t[318.1793043]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.248,0,356.027],\n\t\t\t\t[0,744.436,238.226],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308137,-0.0481761,0.000357682,-8.3696e-05,0.245728],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9955839097,0.09158830299,-0.0205976113],\n\t\t\t\t[0.07579544873,0.9137019347,0.3992540852],\n\t\t\t\t[0.05538708142,0.3959297379,-0.9166089209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.25988756],\n\t\t\t\t[131.4528362],\n\t\t\t\t[328.3382973]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.535,0,363.359],\n\t\t\t\t[0,744.632,254.668],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311847,-0.00198079,0.000462082,-0.000460419,0.174118],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9946906764,0.1028474748,0.003585412436],\n\t\t\t\t[0.09771594436,0.9329851386,0.346396197],\n\t\t\t\t[0.03228083764,0.3449074195,-0.9380814567]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.3985171],\n\t\t\t\t[157.8437238],\n\t\t\t\t[320.5381764]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[743.311,0,385.98],\n\t\t\t\t[0,743.511,229.743],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319602,0.0480118,-0.000790169,0.000699953,0.0704098],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9986396845,0.04700092247,-0.02257640097],\n\t\t\t\t[0.03617494752,0.9363507866,0.3491970469],\n\t\t\t\t[0.03755201414,0.3479053287,-0.93677731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.936415104],\n\t\t\t\t[142.1371611],\n\t\t\t\t[321.4431282]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.128,0,369.511],\n\t\t\t\t[0,744.056,233.67],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31156,0.00550691,-0.000430053,0.000410016,0.149166],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6229970612,0.0209936641,0.781942407],\n\t\t\t\t[0.05250109858,0.9985078863,0.01502117145],\n\t\t\t\t[-0.7804603106,0.05041098106,-0.6231696692]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.84686717],\n\t\t\t\t[150.7389104],\n\t\t\t\t[280.0083694]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.282,0,357.827],\n\t\t\t\t[0,743.347,211.632],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30948,-0.00718458,0.000285593,0.000547399,0.164062],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6512046155,0.0977241901,0.7525839032],\n\t\t\t\t[0.103617117,0.9938368806,-0.03939223155],\n\t\t\t\t[-0.7517952126,0.05232817138,-0.6573170626]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.32005533],\n\t\t\t\t[143.0774393],\n\t\t\t\t[282.200902]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.012,0,361.17],\n\t\t\t\t[0,744.101,225.217],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303567,-0.0563565,0.000757602,-0.000519388,0.263551],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6320598226,0.04182219841,0.773790207],\n\t\t\t\t[0.06737176964,0.9977273282,0.001106034268],\n\t\t\t\t[-0.771985379,0.05283069539,-0.6334409935]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-54.02554254],\n\t\t\t\t[119.7786683],\n\t\t\t\t[280.9354705]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.209,0,380.966],\n\t\t\t\t[0,744.256,205.476],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315194,0.0249601,-0.000765583,0.001001,0.10286],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6566261636,0.06356030055,0.7515332125],\n\t\t\t\t[0.0713368826,0.9972094103,-0.02201002698],\n\t\t\t\t[-0.7508349555,0.03915967697,-0.6593279831]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.38173011],\n\t\t\t\t[115.5645607],\n\t\t\t\t[280.9145253]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.499,0,353.834],\n\t\t\t\t[0,744.652,215.524],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317042,0.0236932,-0.00147688,-0.000206715,0.11602],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6480155592,0.1057846486,0.754244949],\n\t\t\t\t[0.1559047408,0.9877614348,-0.004589090624],\n\t\t\t\t[-0.7454995284,0.1146165612,-0.6565771067]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-17.37690425],\n\t\t\t\t[72.84298088],\n\t\t\t\t[287.4167752]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[746.493,0,367.328],\n\t\t\t\t[0,746.754,207.575],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323089,0.0587326,-0.000981175,-0.000221417,0.0550321],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6607542091,0.07289791872,0.74705406],\n\t\t\t\t[0.1340507848,0.9907326878,0.02188900409],\n\t\t\t\t[-0.738535214,0.1146064347,-0.6644028167]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.021864726],\n\t\t\t\t[64.04371811],\n\t\t\t\t[286.9062935]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.949,0,365.308],\n\t\t\t\t[0,744.944,217.014],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320697,0.0459897,0.000335318,2.89241e-06,0.0947246],\n\t\t\t\"R\": [\n\t\t\t\t[-0.643287111,0.03528116955,0.764811697],\n\t\t\t\t[0.0902182212,0.9954712387,0.02996140018],\n\t\t\t\t[-0.7602909742,0.08827373343,-0.6435568215]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.776307982],\n\t\t\t\t[84.51813798],\n\t\t\t\t[285.3816638]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[748.112,0,395.78],\n\t\t\t\t[0,748.17,229.575],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325424,0.0774932,-0.000546,0.000524276,0.0351183],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6241633069,0.05185263499,0.7795713377],\n\t\t\t\t[0.04102617023,0.9985938587,-0.03357318505],\n\t\t\t\t[-0.7802160084,0.0110276762,-0.6254129601]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.24758235],\n\t\t\t\t[183.5392889],\n\t\t\t\t[272.6641799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.122,0,370.333],\n\t\t\t\t[0,746.261,210.753],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323285,0.0813962,-0.00031195,0.00117949,0.0118242],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6717702835,0.002860846795,0.7407540089],\n\t\t\t\t[0.1085475528,0.9895782107,0.09461708989],\n\t\t\t\t[-0.7327633417,0.1439679842,-0.6650797731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[53.6134591],\n\t\t\t\t[78.01841366],\n\t\t\t\t[288.9552018]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.498,0,355.775],\n\t\t\t\t[0,746.616,218.183],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320479,0.0482256,-0.000295345,0.000515541,0.088746],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6274497943,0.01735785812,0.7784635254],\n\t\t\t\t[0.05740772193,0.9980618939,0.02401685623],\n\t\t\t\t[-0.7765378993,0.0597591891,-0.6272302051]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.32452291],\n\t\t\t\t[122.8912729],\n\t\t\t\t[283.9520693]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.209,0,387.948],\n\t\t\t\t[0,745.058,237.868],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312054,0.0106095,2.04654e-05,-0.000407432,0.122509],\n\t\t\t\"R\": [\n\t\t\t\t[-0.663538187,0.0558857692,0.74605218],\n\t\t\t\t[0.09086672278,0.9958436408,0.006219474654],\n\t\t\t\t[-0.742603739,0.07191817555,-0.6658584406]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[70.41193089],\n\t\t\t\t[130.903078],\n\t\t\t\t[283.3216663]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.923,0,359.191],\n\t\t\t\t[0,746.955,219.728],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.34193,0.180291,-0.0011698,0.000387434,-0.142263],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6573529902,0.02662022179,0.7531124817],\n\t\t\t\t[0.0203979596,0.9996382488,-0.01752982786],\n\t\t\t\t[-0.7533066902,0.003838673213,-0.6576581901]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.18715226],\n\t\t\t\t[173.543055],\n\t\t\t\t[273.2477614]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[747.063,0,362.554],\n\t\t\t\t[0,747.091,228.588],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334743,0.115617,-0.000133435,0.000763825,-0.0142674],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6314178936,0.07344004486,0.771957255],\n\t\t\t\t[0.07624079511,0.9965613541,-0.03244701456],\n\t\t\t\t[-0.7716856775,0.03836700932,-0.6348457984]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.63694261],\n\t\t\t\t[165.7689372],\n\t\t\t\t[279.8275089]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.722,0,380.721],\n\t\t\t\t[0,745.932,237.231],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319645,0.0532601,-0.00105825,0.00148804,0.0812854],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6464741699,0.0407242176,0.7618482039],\n\t\t\t\t[0.05782238306,0.998317631,-0.004298792509],\n\t\t\t\t[-0.7607415591,0.04127282036,-0.6477413331]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.16059778],\n\t\t\t\t[187.0284564],\n\t\t\t\t[279.5510011]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.212,0,345.945],\n\t\t\t\t[0,745.407,234.052],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.345973,0.208044,0.00063894,-0.000591324,-0.26389],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6892736753,0.06991501806,0.7211197479],\n\t\t\t\t[0.04097555303,0.9975016565,-0.0575451947],\n\t\t\t\t[-0.7233414164,-0.01011610737,-0.6904164394]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[38.38229011],\n\t\t\t\t[201.7157692],\n\t\t\t\t[268.6124541]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[746.402,0,351.743],\n\t\t\t\t[0,746.432,235.34],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332074,0.123634,0.000553061,0.000200886,-0.050504],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6626903808,0.1069713565,0.7412142659],\n\t\t\t\t[0.1159650419,0.9924654921,-0.03955194002],\n\t\t\t\t[-0.7398605059,0.05974425322,-0.6701022728]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.24762504],\n\t\t\t\t[172.5928493],\n\t\t\t\t[282.9657885]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.425,0,381.954],\n\t\t\t\t[0,745.576,234.397],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316953,0.0361047,-0.000329948,0.00146685,0.0995591],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6439914485,0.08005681888,0.7608323863],\n\t\t\t\t[0.04150323442,0.9967010496,-0.06974596286],\n\t\t\t\t[-0.7639060779,-0.01333879876,-0.6451895695]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.39474973],\n\t\t\t\t[198.5707312],\n\t\t\t\t[268.934139]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[742.866,0,374.357],\n\t\t\t\t[0,743.163,216.484],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313801,-0.00472223,0.00105562,-0.000883374,0.146196],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6735625977,0.03695414336,0.7382058102],\n\t\t\t\t[0.08136680684,0.9963864104,0.02436316713],\n\t\t\t\t[-0.7346379174,0.07647556771,-0.6741354596]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.81793908],\n\t\t\t\t[81.57199105],\n\t\t\t\t[283.0241236]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[747.195,0,374.317],\n\t\t\t\t[0,747.324,252.705],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325848,0.0754879,0.000850799,-0.000494425,0.0423325],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6398121174,0.03550225829,0.7677109118],\n\t\t\t\t[0.06489671873,0.9978603994,0.00793971962],\n\t\t\t\t[-0.7657864391,0.05490184793,-0.6407471551]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-18.67539454],\n\t\t\t\t[143.739157],\n\t\t\t\t[281.6554752]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.074,0,359.595],\n\t\t\t\t[0,744.232,222.54],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312038,-0.00652471,0.000517579,-0.000473896,0.154037],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6341018605,0.07503908623,0.769599874],\n\t\t\t\t[0.1134623387,0.9935365213,-0.003387984729],\n\t\t\t\t[-0.7648798129,0.08517227417,-0.6385174669]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.64771601],\n\t\t\t\t[114.6784971],\n\t\t\t\t[285.5473806]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.669,0,353.595],\n\t\t\t\t[0,745.986,221.41],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331248,0.0956435,-0.00124938,0.0010706,0.0394747],\n\t\t\t\"R\": [\n\t\t\t\t[-0.618235149,0.02815342604,0.7854888192],\n\t\t\t\t[0.09838720035,0.994269895,0.04180113162],\n\t\t\t\t[-0.7798110408,0.1031249747,-0.6174625335]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.462045404],\n\t\t\t\t[102.4105128],\n\t\t\t\t[287.5712577]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.836,0,367.536],\n\t\t\t\t[0,745.883,217.602],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306908,-0.0326669,-0.000283909,0.000278093,0.200484],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6189078213,0.03804187807,0.7845418563],\n\t\t\t\t[0.07413417155,0.9971968305,0.01012945108],\n\t\t\t\t[-0.7819573092,0.06443055706,-0.6199931209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[14.73270812],\n\t\t\t\t[126.5060302],\n\t\t\t\t[283.9045417]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[742.749,0,379.273],\n\t\t\t\t[0,742.868,231.204],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310394,-0.00460726,-0.000822068,-0.000336616,0.147608],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6037549899,0.1086195044,0.7897352186],\n\t\t\t\t[0.1215591915,0.9916324658,-0.04345590495],\n\t\t\t\t[-0.787847241,0.0697628552,-0.6119067485]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[19.26192194],\n\t\t\t\t[145.0128457],\n\t\t\t\t[284.7838402]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.597,0,368.627],\n\t\t\t\t[0,745.598,227.731],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309585,-0.00749389,-0.000770097,-0.000330202,0.147896],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6450785239,0.075478584,0.760379301],\n\t\t\t\t[0.07622559694,0.9965021766,-0.03425011393],\n\t\t\t\t[-0.7603047786,0.03586635318,-0.6485755533]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[7.856697427],\n\t\t\t\t[160.1393432],\n\t\t\t\t[279.1413867]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[742.855,0,374.596],\n\t\t\t\t[0,743.116,213.495],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312561,0.00631745,-0.000399255,9.31566e-05,0.13435],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9229364354,0.00164792287,0.3849488544],\n\t\t\t\t[0.08421827064,0.9766305816,0.1977371741],\n\t\t\t\t[-0.3756269679,0.2149185694,-0.9015067329]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.777017447],\n\t\t\t\t[176.3500352],\n\t\t\t\t[303.9155303]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.543,0,362.467],\n\t\t\t\t[0,743.612,228.587],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311508,-0.0063044,0.000209199,0.000389142,0.157517],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9382305089,-0.009495783218,0.3458805319],\n\t\t\t\t[0.07354737957,0.9713073762,0.226169768],\n\t\t\t\t[-0.338103971,0.2376379833,-0.9106118238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.88478771],\n\t\t\t\t[180.6527832],\n\t\t\t\t[308.9268929]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[749.382,0,384.698],\n\t\t\t\t[0,749.44,241.756],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334994,0.135003,0.000819921,0.00199466,-0.05032],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9215516186,0.03410543981,0.3867550042],\n\t\t\t\t[0.1287847641,0.966589567,0.2216282778],\n\t\t\t\t[-0.3662746221,0.2540500501,-0.895154441]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-28.84627719],\n\t\t\t\t[162.2565593],\n\t\t\t\t[311.7587167]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.478,0,355.1],\n\t\t\t\t[0,747.786,237.425],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332665,0.125805,0.000559145,-0.000285828,-0.0488142],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9186497576,-0.03493542623,0.3935252708],\n\t\t\t\t[0.05923251482,0.9726444983,0.2246200995],\n\t\t\t\t[-0.3906073886,0.2296566914,-0.8914503195]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.73591523],\n\t\t\t\t[146.455357],\n\t\t\t\t[306.7233507]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.546,0,358.346],\n\t\t\t\t[0,744.606,240.06],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319412,0.0357687,0.00118284,-0.000939418,0.105494],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9252091585,0.02778676908,0.3784387777],\n\t\t\t\t[0.1130706466,0.9721977994,0.2050523536],\n\t\t\t\t[-0.3622196044,0.2325066328,-0.9026281759]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.43063623],\n\t\t\t\t[134.4377466],\n\t\t\t\t[308.7383564]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.682,0,386.644],\n\t\t\t\t[0,744.47,247.576],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310524,-0.0156223,-0.000288596,-3.26402e-05,0.156674],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9144551399,0.0484228537,0.4017798207],\n\t\t\t\t[0.1449564791,0.9661327489,0.2134833264],\n\t\t\t\t[-0.3778351707,0.2534615133,-0.8905042645]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-44.21957265],\n\t\t\t\t[107.5274508],\n\t\t\t\t[309.8949628]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.436,0,349.001],\n\t\t\t\t[0,746.553,211.863],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330393,0.0902383,-0.000783974,-0.000712996,0.00481592],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9105637485,0.003264968682,0.4133557789],\n\t\t\t\t[0.1001837456,0.9718993559,0.2130137535],\n\t\t\t\t[-0.401044732,0.2353741321,-0.8853034174]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-36.21090107],\n\t\t\t\t[102.2867759],\n\t\t\t\t[306.6852556]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.743,0,370.625],\n\t\t\t\t[0,745.85,233.671],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3257,0.0614375,0.00126654,-0.000627381,0.0722474],\n\t\t\t\"R\": [\n\t\t\t\t[-0.8981193216,-0.01090147501,0.4396166989],\n\t\t\t\t[0.09488580103,0.9713398361,0.2179348702],\n\t\t\t\t[-0.4293930238,0.2374449004,-0.8713446794]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.17364239],\n\t\t\t\t[80.07059019],\n\t\t\t\t[305.3107943]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[743.294,0,376.993],\n\t\t\t\t[0,743.306,225.516],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315184,-0.00458353,0.00085295,-0.000315923,0.19344],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9287334953,0.02657190893,0.369794576],\n\t\t\t\t[0.1072763174,0.9740215576,0.1994336907],\n\t\t\t\t[-0.354888555,0.2248909489,-0.9074569822]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.627896612],\n\t\t\t\t[76.0139061],\n\t\t\t\t[305.925361]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.981,0,373.015],\n\t\t\t\t[0,746.916,231.087],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31553,-0.0133214,-7.49701e-05,-0.000474937,0.183355],\n\t\t\t\"R\": [\n\t\t\t\t[-0.897589008,-0.01428097087,0.4406018914],\n\t\t\t\t[0.092180686,0.9712994893,0.219271574],\n\t\t\t\t[-0.431087803,0.2374307391,-0.8705113154]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.834972436],\n\t\t\t\t[85.69962032],\n\t\t\t\t[306.7617687]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.956,0,385.014],\n\t\t\t\t[0,743.968,233.944],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321873,0.0619652,-0.000204505,0.000631491,0.0680901],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9171447001,-0.01735780695,0.3981762243],\n\t\t\t\t[0.08629809142,0.9667012777,0.2409175774],\n\t\t\t\t[-0.3890992656,0.2553181275,-0.8851070078]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.82061991],\n\t\t\t\t[73.01187567],\n\t\t\t\t[307.7528197]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[749.192,0,349.167],\n\t\t\t\t[0,749.113,221.266],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334032,0.094759,-0.000689735,0.000727903,0.0409048],\n\t\t\t\"R\": [\n\t\t\t\t[-0.937850977,-0.03419002209,0.345349949],\n\t\t\t\t[0.06230645433,0.9623765935,0.2644791068],\n\t\t\t\t[-0.341399254,0.2695595196,-0.9004355695]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.17130279],\n\t\t\t\t[82.80130245],\n\t\t\t\t[306.825197]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.715,0,367.122],\n\t\t\t\t[0,744.786,220.538],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315954,0.0180051,3.91318e-05,0.000697083,0.145396],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9312656673,-0.01667316508,0.3639591494],\n\t\t\t\t[0.07039560041,0.9718946087,0.2246448954],\n\t\t\t\t[-0.3574754765,0.2348252013,-0.9039183639]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[46.96203938],\n\t\t\t\t[112.2947483],\n\t\t\t\t[304.8878272]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[746.505,0,367.697],\n\t\t\t\t[0,746.62,222.237],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323622,0.0629014,0.000917096,0.00064017,0.0716359],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9260527677,-0.07925799212,0.3689775632],\n\t\t\t\t[0.02937617957,0.9595934278,0.279852628],\n\t\t\t\t[-0.3762490021,0.2699974518,-0.8863058527]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.81898209],\n\t\t\t\t[116.0290364],\n\t\t\t\t[310.1255555]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.042,0,355.995],\n\t\t\t\t[0,745.821,261.077],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321065,0.0443736,0.000927074,0.000280863,0.106789],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9208600933,-0.04678508348,0.387076019],\n\t\t\t\t[0.03581020852,0.9784294414,0.2034538209],\n\t\t\t\t[-0.3882451771,0.2012137775,-0.8993212431]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[43.08113165],\n\t\t\t\t[154.6066575],\n\t\t\t\t[301.5640854]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[741.668,0,363.735],\n\t\t\t\t[0,741.796,217.06],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309875,-0.0179015,-1.19394e-05,-0.000437783,0.188022],\n\t\t\t\"R\": [\n\t\t\t\t[-0.8991061052,-0.0185684781,0.437336739],\n\t\t\t\t[0.0842559957,0.9730755765,0.214534029],\n\t\t\t\t[-0.4295452698,0.2297370977,-0.873333686]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.70791642],\n\t\t\t\t[154.14567],\n\t\t\t\t[307.2679797]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[747.822,0,361.761],\n\t\t\t\t[0,747.76,222.34],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334628,0.097635,0.00152491,-0.000486737,0.0213673],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9162397179,0.01033450945,0.4004971626],\n\t\t\t\t[0.1187416248,0.9617552428,0.2468345183],\n\t\t\t\t[-0.3826293322,0.2737152732,-0.8824254888]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.8785048],\n\t\t\t\t[159.3368695],\n\t\t\t\t[313.9971646]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.448,0,360.818],\n\t\t\t\t[0,745.84,214.85],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329534,0.0903331,0.00014069,0.000717079,0.0211508],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9101418911,0.04432675398,0.411918532],\n\t\t\t\t[0.1391589893,0.9692024732,0.2031781034],\n\t\t\t\t[-0.3902262342,0.2422430698,-0.888280238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.35209076],\n\t\t\t\t[181.679224],\n\t\t\t\t[308.9632727]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.167,0,363.996],\n\t\t\t\t[0,746.229,234.387],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310901,-0.0147285,-0.000729007,-0.000655789,0.178193],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9157731435,-0.03755396433,0.3999365568],\n\t\t\t\t[0.06406747528,0.9692207168,0.2377110865],\n\t\t\t\t[-0.3965537899,0.2433123544,-0.8851803149]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.79527777],\n\t\t\t\t[146.8696803],\n\t\t\t\t[308.5271108]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.588,0,384.664],\n\t\t\t\t[0,744.662,240.853],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307863,-0.0295446,-0.000517465,0.000242427,0.189333],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9170523574,0.0431160901,0.396429031],\n\t\t\t\t[0.124694228,0.9752892469,0.1823793695],\n\t\t\t\t[-0.3787694858,0.2166838427,-0.8997676305]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.200936127],\n\t\t\t\t[142.5227957],\n\t\t\t\t[304.9039442]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.832,0,378.426],\n\t\t\t\t[0,745.825,230.649],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317765,0.041948,0.000140897,0.000331931,0.0876249],\n\t\t\t\"R\": [\n\t\t\t\t[-0.903416406,0.009580467792,0.4286572198],\n\t\t\t\t[0.1299134284,0.9588705554,0.2523683006],\n\t\t\t\t[-0.4086089801,0.2836819921,-0.8675040223]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.38884391],\n\t\t\t\t[100.2357286],\n\t\t\t\t[311.942278]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.759,0,381.189],\n\t\t\t\t[0,746.033,229.615],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307738,-0.0303832,0.000694314,-0.000395606,0.211723],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9121889441,-0.007451044875,0.4097021017],\n\t\t\t\t[0.1102495844,0.9585035751,0.2628990789],\n\t\t\t\t[-0.394659802,0.2849831196,-0.8735148895]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.4671669308],\n\t\t\t\t[91.25062129],\n\t\t\t\t[311.8622342]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[748.678,0,358.839],\n\t\t\t\t[0,748.651,239.635],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328983,0.0919887,-1.22475e-05,-0.000911096,0.0194744],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9251940915,-0.06790089301,0.3733702744],\n\t\t\t\t[0.01633387562,0.9758259889,0.2179377065],\n\t\t\t\t[-0.3791425821,0.207733262,-0.9017193545]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[15.23843998],\n\t\t\t\t[129.776393],\n\t\t\t\t[302.9631654]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[747.741,0,374.843],\n\t\t\t\t[0,747.8,238.972],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320184,0.0453956,8.07771e-05,-0.000586724,0.0799959],\n\t\t\t\"R\": [\n\t\t\t\t[-0.901120423,0.005145678853,0.4335383549],\n\t\t\t\t[0.1030532182,0.9738156258,0.2026404726],\n\t\t\t\t[-0.4211437016,0.2272809911,-0.8780554275]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.522845915],\n\t\t\t\t[142.0951003],\n\t\t\t\t[306.255293]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.397,0,350.188],\n\t\t\t\t[0,745.422,244.528],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318784,0.0421446,0.000567418,-0.000208,0.092208],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2717431751,0.1656287556,0.9480098956],\n\t\t\t\t[0.4128654434,0.9098857043,-0.04062180222],\n\t\t\t\t[-0.86930879,0.3803618284,-0.3156376199]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-13.70303847],\n\t\t\t\t[97.1923903],\n\t\t\t\t[326.2673629]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.727,0,370.501],\n\t\t\t\t[0,747.788,234.298],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.349811,0.202844,-0.00194754,-0.000389321,-0.178679],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3883456032,0.1438043201,0.9102241537],\n\t\t\t\t[0.3131714459,0.9495549238,-0.01640403197],\n\t\t\t\t[-0.8666667975,0.2786857806,-0.4137908865]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.37192963],\n\t\t\t\t[105.5473845],\n\t\t\t\t[318.08591]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.831,0,387.09],\n\t\t\t\t[0,746.752,242.092],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.338844,0.109538,-0.000689346,-0.00140957,-0.0011227],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2489409576,0.07810816372,0.9653639285],\n\t\t\t\t[0.3865744043,0.9219167609,0.0250941395],\n\t\t\t\t[-0.8880251289,0.3794319447,-0.2596974581]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.03334166],\n\t\t\t\t[70.50216381],\n\t\t\t\t[325.3775618]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[746.601,0,360.45],\n\t\t\t\t[0,746.776,222.063],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336822,0.124774,0.000206697,-0.000417774,-0.0398672],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3081671276,0.03567998316,0.9506629057],\n\t\t\t\t[0.4212102042,0.9011275261,0.1027187694],\n\t\t\t\t[-0.8530035084,0.4320834647,-0.2927266543]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.764737811],\n\t\t\t\t[63.41476985],\n\t\t\t\t[331.1517594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[748.2,0,362.212],\n\t\t\t\t[0,748.363,218.877],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337789,0.133894,-0.000945522,-0.000498923,-0.0570031],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2841336654,-0.004801876737,0.9587726541],\n\t\t\t\t[0.3831436474,0.9161034097,0.118133349],\n\t\t\t\t[-0.8789021593,0.4009133132,-0.2584560111]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[10.92507323],\n\t\t\t\t[68.32263664],\n\t\t\t\t[329.7866549]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[747.371,0,350.388],\n\t\t\t\t[0,747.497,231.124],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.351189,0.233364,-0.000450075,-0.00118874,-0.265042],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3878504716,-0.01635524947,0.9215771902],\n\t\t\t\t[0.3346075558,0.9291346168,0.1573106717],\n\t\t\t\t[-0.8588421248,0.3693797093,-0.3548927092]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[53.76493542],\n\t\t\t\t[97.09757883],\n\t\t\t\t[324.1315487]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[747.196,0,383.602],\n\t\t\t\t[0,747.258,260.076],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.340453,0.149462,7.57635e-05,-0.00150211,-0.0810731],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3567494973,0.01375486298,0.934098817],\n\t\t\t\t[0.3428523716,0.9320474424,0.1172169629],\n\t\t\t\t[-0.8690121101,0.3620750873,-0.3372233439]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[46.87962376],\n\t\t\t\t[118.8343508],\n\t\t\t\t[324.070693]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[748.388,0,360.952],\n\t\t\t\t[0,748.584,220.934],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.353387,0.236369,0.000317101,-0.000350889,-0.25062],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3882650784,-0.0538394581,0.9199736636],\n\t\t\t\t[0.3529834406,0.9134681838,0.2024316376],\n\t\t\t\t[-0.8512654812,0.4033326047,-0.3356633588]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[53.63586961],\n\t\t\t\t[124.5990463],\n\t\t\t\t[329.2926486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.023,0,373.202],\n\t\t\t\t[0,745.321,253.183],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310235,-0.0270349,0.000213071,-0.0010354,0.204812],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3615436505,-0.1034754049,0.9265953968],\n\t\t\t\t[0.3189620476,0.9201303682,0.2272076531],\n\t\t\t\t[-0.8760989676,0.3776942494,-0.2996625652]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.36947949],\n\t\t\t\t[154.1173845],\n\t\t\t\t[328.14772]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.497,0,337.094],\n\t\t\t\t[0,743.775,230.392],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323522,0.0697077,-0.000922284,-0.00112939,0.0376595],\n\t\t\t\"R\": [\n\t\t\t\t[-0.409013364,-0.03192166586,0.9119698873],\n\t\t\t\t[0.3635432206,0.9109541012,0.1949331996],\n\t\t\t\t[-0.8369853014,0.4112707536,-0.3609874961]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[36.39561956],\n\t\t\t\t[146.2733377],\n\t\t\t\t[330.6860766]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.432,0,350.161],\n\t\t\t\t[0,744.664,216.764],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3138,0.0423232,-0.000980128,0.000347352,0.0411803],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3625324698,0.01191238118,0.9318950067],\n\t\t\t\t[0.4332658145,0.8874493782,0.157207936],\n\t\t\t\t[-0.8251369234,0.4607512304,-0.3268904424]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.02223667],\n\t\t\t\t[146.021886],\n\t\t\t\t[340.9352409]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.59,0,349.499],\n\t\t\t\t[0,745.978,243.824],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328804,0.102744,-0.00034172,-0.00160085,-0.0230968],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3184962228,0.07265474811,0.9451356747],\n\t\t\t\t[0.3862627531,0.9204738181,0.05940568743],\n\t\t\t\t[-0.8656565379,0.3839911948,-0.3212312573]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.04074577],\n\t\t\t\t[180.9741057],\n\t\t\t\t[327.7548666]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.766,0,364.423],\n\t\t\t\t[0,744.926,205.341],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32165,0.0514735,-0.000885848,-0.00113933,0.0656482],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2748509499,0.06379038152,0.9593684081],\n\t\t\t\t[0.3894986417,0.919644886,0.05043898999],\n\t\t\t\t[-0.8790607279,0.3875358962,-0.2776115375]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.802475588],\n\t\t\t\t[164.1613661],\n\t\t\t\t[327.7325897]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.556,0,345.329],\n\t\t\t\t[0,744.551,253.003],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311027,-0.00213006,0.0011289,-0.000863959,0.162024],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3202755169,0.1244082889,0.9391198917],\n\t\t\t\t[0.4530679872,0.8907277919,0.0365157459],\n\t\t\t\t[-0.831957326,0.4371802584,-0.3416437171]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[0.5161253202],\n\t\t\t\t[152.8799295],\n\t\t\t\t[338.113135]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.233,0,347.644],\n\t\t\t\t[0,747.329,227.375],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323105,0.049287,-0.00101918,5.08353e-05,0.100564],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2639942301,0.1219548974,0.9567831779],\n\t\t\t\t[0.4010015368,0.9160569375,-0.006120025947],\n\t\t\t\t[-0.8772142349,0.3820558732,-0.2907378472]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.43280694],\n\t\t\t\t[159.7105652],\n\t\t\t\t[325.8203908]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.634,0,382.866],\n\t\t\t\t[0,744.52,241.14],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320913,0.0518689,0.000556907,0.000900625,0.0851061],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2918914105,0.1153635448,0.9494686183],\n\t\t\t\t[0.4055533141,0.9139698053,0.01362734066],\n\t\t\t\t[-0.8662135499,0.3890378484,-0.3135660035]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.908528],\n\t\t\t\t[135.1916248],\n\t\t\t\t[327.5972929]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.929,0,399.922],\n\t\t\t\t[0,745.76,235.115],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324412,0.0924767,0.000808772,0.00160345,0.0125449],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2332319969,0.1531844985,0.9602798264],\n\t\t\t\t[0.4252056559,0.9041694633,-0.04096012482],\n\t\t\t\t[-0.8745301515,0.3987632018,-0.2760161646]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.90434909],\n\t\t\t\t[120.9469461],\n\t\t\t\t[326.5490528]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.596,0,390.427],\n\t\t\t\t[0,745.457,235.855],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331545,0.0834192,0.000515021,-0.000851112,0.0388274],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2198853867,0.1587089693,0.9625288982],\n\t\t\t\t[0.4990272732,0.8661072571,-0.02880971702],\n\t\t\t\t[-0.8382256244,0.4739933356,-0.2696444333]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-48.83152805],\n\t\t\t\t[73.52609427],\n\t\t\t\t[332.6787653]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[744.284,0,396.863],\n\t\t\t\t[0,744.47,248.804],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318049,0.0444362,0.000417829,0.000948817,0.0847095],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2972813843,0.0975420226,0.9497943632],\n\t\t\t\t[0.4134272643,0.9098266462,0.03596346693],\n\t\t\t\t[-0.8606402708,0.4033621545,-0.3108010564]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.347004052],\n\t\t\t\t[101.4062297],\n\t\t\t\t[328.9550302]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.173,0,391.68],\n\t\t\t\t[0,745.292,239.851],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316891,0.030971,0.000827356,0.00064571,0.114679],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3480625566,0.05516818218,0.9358466372],\n\t\t\t\t[0.3680676982,0.9261498325,0.08229615655],\n\t\t\t\t[-0.8621940769,0.3730991283,-0.3426637043]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.00373906],\n\t\t\t\t[105.1024652],\n\t\t\t\t[325.6162418]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.07,0,385.155],\n\t\t\t\t[0,744.184,238.534],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325321,0.0749068,6.22505e-05,8.78769e-06,0.0274316],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2944173655,-0.00519814937,0.9556628036],\n\t\t\t\t[0.365777539,0.9232287513,0.117709238],\n\t\t\t\t[-0.882907247,0.3842156322,-0.2699132104]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.17424328],\n\t\t\t\t[116.8807078],\n\t\t\t\t[328.2455421]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[747.36,0,358.25],\n\t\t\t\t[0,747.451,237.291],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329867,0.116416,-0.000580151,-0.000763801,-0.0625995],\n\t\t\t\"R\": [\n\t\t\t\t[-0.323867873,0.0530845029,0.9446118972],\n\t\t\t\t[0.387407199,0.9183241349,0.08121850418],\n\t\t\t\t[-0.8631484594,0.3922535134,-0.3179810029]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.53106717],\n\t\t\t\t[133.6738778],\n\t\t\t\t[328.8995429]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[748.813,0,380.156],\n\t\t\t\t[0,748.859,237.356],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333932,0.115832,0.000621747,-0.000254241,-0.0140772],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3097958639,0.0326105921,0.9502436908],\n\t\t\t\t[0.3550951383,0.9310652686,0.08381472691],\n\t\t\t\t[-0.8820056493,0.3633923705,-0.3000200319]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.485061334],\n\t\t\t\t[151.418855],\n\t\t\t\t[323.8858443]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.33,0,360.408],\n\t\t\t\t[0,745.472,237.433],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321653,0.057929,3.69615e-05,-0.000478596,0.0560779],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3250711399,0.1046959739,0.9398763254],\n\t\t\t\t[0.4072848242,0.9124585149,0.03922410658],\n\t\t\t\t[-0.8534915501,0.395547989,-0.3392550109]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.217299854],\n\t\t\t\t[123.8595425],\n\t\t\t\t[329.2221602]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[747.6,0,355.92],\n\t\t\t\t[0,747.783,249.853],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333712,0.144699,-6.46303e-05,-0.0011294,-0.0924471],\n\t\t\t\"R\": [\n\t\t\t\t[0.5138271048,0.01100033104,0.857823233],\n\t\t\t\t[0.08358608019,0.9945184566,-0.06282043172],\n\t\t\t\t[-0.8538120833,0.1039809221,0.5100910647]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-37.95328646],\n\t\t\t\t[135.6435695],\n\t\t\t\t[289.9999799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.227,0,372.15],\n\t\t\t\t[0,743.265,265.407],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306942,-0.0266079,0.000311285,0.000595534,0.199806],\n\t\t\t\"R\": [\n\t\t\t\t[0.4485620057,-0.005900946102,0.8937322339],\n\t\t\t\t[0.06601293956,0.9974655925,-0.02654587691],\n\t\t\t\t[-0.8913105064,0.07090536373,0.4478147055]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-38.28645032],\n\t\t\t\t[133.2984516],\n\t\t\t\t[288.856211]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.538,0,387.516],\n\t\t\t\t[0,746.833,233.181],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322577,0.0715483,-4.90461e-05,0.000787497,0.0326639],\n\t\t\t\"R\": [\n\t\t\t\t[0.5260210271,0.02315422103,0.8501563157],\n\t\t\t\t[0.07372016672,0.9946254291,-0.07270208278],\n\t\t\t\t[-0.8472704504,0.1009164896,0.5214869567]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.0750023],\n\t\t\t\t[105.7642054],\n\t\t\t\t[287.8235486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.864,0,367.763],\n\t\t\t\t[0,745.005,229.771],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318118,0.0367901,0.000364188,-0.000713933,0.0879467],\n\t\t\t\"R\": [\n\t\t\t\t[0.4575577495,0.1623260474,0.8742374736],\n\t\t\t\t[-0.0244195278,0.9851184177,-0.1701334469],\n\t\t\t\t[-0.8888445267,0.05649741078,0.4547124916]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.756699591],\n\t\t\t\t[110.8595803],\n\t\t\t\t[285.3944853]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.026,0,374.462],\n\t\t\t\t[0,744.21,219.295],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309274,-0.00813814,-0.000611939,0.000562163,0.16533],\n\t\t\t\"R\": [\n\t\t\t\t[0.5236500196,-0.01990538858,0.8517009055],\n\t\t\t\t[0.0479853053,0.9988290545,-0.006158764858],\n\t\t\t\t[-0.8505810176,0.04409416531,0.5239920201]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.80347729],\n\t\t\t\t[91.75629107],\n\t\t\t\t[282.6719703]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[746.172,0,347.715],\n\t\t\t\t[0,746.412,223.735],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315889,0.0243673,0.00083413,-0.000596366,0.129203],\n\t\t\t\"R\": [\n\t\t\t\t[0.489601615,0.07237643337,0.8689372305],\n\t\t\t\t[-0.010214584,0.9969567785,-0.07728417735],\n\t\t\t\t[-0.8718864151,0.02896262571,0.488850944]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[7.55259059],\n\t\t\t\t[89.5920217],\n\t\t\t\t[281.8493454]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.619,0,383.372],\n\t\t\t\t[0,745.683,224.508],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315816,0.0424659,0.000456201,0.000714024,0.0879752],\n\t\t\t\"R\": [\n\t\t\t\t[0.5142457137,-0.005076098829,0.8576278792],\n\t\t\t\t[0.07753605572,0.9961627141,-0.04059565316],\n\t\t\t\t[-0.8541308483,0.08737322366,0.5126659866]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.165152848],\n\t\t\t\t[86.80281732],\n\t\t\t\t[287.1451009]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[746.151,0,390.693],\n\t\t\t\t[0,746.159,238.847],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312796,0.0112848,0.00109903,0.000945928,0.138088],\n\t\t\t\"R\": [\n\t\t\t\t[0.5333632905,-0.08775347438,0.841322131],\n\t\t\t\t[0.13459771,0.9907366672,0.0180086874],\n\t\t\t\t[-0.8351090089,0.1036348594,0.5402339855]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[14.59630248],\n\t\t\t\t[78.12680456],\n\t\t\t\t[289.302137]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[744.811,0,365.557],\n\t\t\t\t[0,745.05,239.01],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302561,-0.0588071,-0.000331846,-0.00065645,0.252299],\n\t\t\t\"R\": [\n\t\t\t\t[0.515993865,0.007464548532,0.8565597538],\n\t\t\t\t[0.05311793688,0.9977587535,-0.04069342277],\n\t\t\t\t[-0.8549437502,0.06649624343,0.5144408941]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[47.02842806],\n\t\t\t\t[101.5821868],\n\t\t\t\t[285.7219747]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.185,0,393.537],\n\t\t\t\t[0,744.44,231.354],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321367,0.0639595,-3.49657e-05,0.000800078,0.0579089],\n\t\t\t\"R\": [\n\t\t\t\t[0.5364096096,-0.02345912583,0.8436316733],\n\t\t\t\t[0.07330244032,0.9971310212,-0.01888064639],\n\t\t\t\t[-0.8407683884,0.07196802054,0.536590273]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.38919798],\n\t\t\t\t[122.486781],\n\t\t\t\t[287.1552388]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.973,0,365.594],\n\t\t\t\t[0,746.037,211.677],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32905,0.0977698,-0.000962762,0.000946642,0.0190885],\n\t\t\t\"R\": [\n\t\t\t\t[0.5178117038,0.00482526951,0.8554810087],\n\t\t\t\t[0.01921134431,0.9996663333,-0.01726691564],\n\t\t\t\t[-0.8552788806,0.02537595122,0.5175462273]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.16543019],\n\t\t\t\t[149.3252564],\n\t\t\t\t[279.6241941]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.909,0,358.218],\n\t\t\t\t[0,746.022,220.333],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.338571,0.148871,-0.00100229,-0.000678393,-0.0710162],\n\t\t\t\"R\": [\n\t\t\t\t[0.5368407815,0.02503814463,0.8433119628],\n\t\t\t\t[-0.01156171997,0.9996840035,-0.02232083821],\n\t\t\t\t[-0.8436043516,0.002232599467,0.5369606257]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.57359577],\n\t\t\t\t[176.1957711],\n\t\t\t\t[275.7319623]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[743.068,0,370.139],\n\t\t\t\t[0,743.357,232.303],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302401,-0.0553181,-0.00107418,-0.000672395,0.220417],\n\t\t\t\"R\": [\n\t\t\t\t[0.5299693687,-0.06080201885,0.8458342525],\n\t\t\t\t[0.13849556,0.9902402801,-0.01559383094],\n\t\t\t\t[-0.8366310107,0.1254085412,0.5332178257]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.99243391],\n\t\t\t\t[145.7883087],\n\t\t\t\t[295.0494301]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[743.724,0,347.611],\n\t\t\t\t[0,743.902,235.434],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315484,0.0296225,-0.000529931,-0.000276443,0.110913],\n\t\t\t\"R\": [\n\t\t\t\t[0.5388576125,-0.001120175332,0.8423961174],\n\t\t\t\t[0.06888686412,0.9967085439,-0.04273965901],\n\t\t\t\t[-0.8395755317,0.08106061749,0.5371611517]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.68047362],\n\t\t\t\t[178.4537167],\n\t\t\t\t[288.5132471]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[748.48,0,370.578],\n\t\t\t\t[0,748.498,231.761],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333743,0.123731,0.000274987,0.00129665,-0.0264397],\n\t\t\t\"R\": [\n\t\t\t\t[0.5569883215,-0.02228411773,0.8302213126],\n\t\t\t\t[0.06483002391,0.9977563557,-0.01671294857],\n\t\t\t\t[-0.827986158,0.06313218472,0.5571833177]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.30154925],\n\t\t\t\t[184.6918205],\n\t\t\t\t[284.5865319]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[748.413,0,364.616],\n\t\t\t\t[0,748.358,230.166],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337541,0.138107,0.000557985,-0.000490808,-0.0648839],\n\t\t\t\"R\": [\n\t\t\t\t[0.5035312414,0.04830043061,0.8626258501],\n\t\t\t\t[0.03089895722,0.996790644,-0.07384894344],\n\t\t\t\t[-0.8634243125,0.06383948941,0.5004227975]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.312179267],\n\t\t\t\t[173.5565462],\n\t\t\t\t[284.5085099]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.143,0,372.782],\n\t\t\t\t[0,745.112,223.2],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321603,0.0646008,-0.000584526,0.000805086,0.0603349],\n\t\t\t\"R\": [\n\t\t\t\t[0.5471603314,0.02993221277,0.8364924593],\n\t\t\t\t[0.06649342528,0.9946477166,-0.07908567611],\n\t\t\t\t[-0.8343825239,0.09889379359,0.5422414789]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.63653561],\n\t\t\t\t[167.4383368],\n\t\t\t\t[289.2367997]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.136,0,373.506],\n\t\t\t\t[0,745.259,215.704],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333755,0.12331,-0.00049301,0.00138004,-0.0323155],\n\t\t\t\"R\": [\n\t\t\t\t[0.5039095131,0.07384116584,0.8605943788],\n\t\t\t\t[0.02822760746,0.9943991795,-0.1018502524],\n\t\t\t\t[-0.8632950856,0.07561583139,0.4990028469]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.61131213],\n\t\t\t\t[166.0398843],\n\t\t\t\t[286.9453226]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.638,0,344.046],\n\t\t\t\t[0,743.783,238.416],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319291,0.0355055,-0.000169258,0.000161892,0.118247],\n\t\t\t\"R\": [\n\t\t\t\t[0.5180347054,0.01180967192,0.8552780692],\n\t\t\t\t[0.1057363227,0.9913513706,-0.07773216881],\n\t\t\t\t[-0.8487990775,0.1307019191,0.512305704]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.08174331],\n\t\t\t\t[122.2280138],\n\t\t\t\t[293.3272927]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.321,0,372.761],\n\t\t\t\t[0,745.559,236.547],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320489,0.0479206,-9.03328e-05,-0.000256288,0.0784864],\n\t\t\t\"R\": [\n\t\t\t\t[0.4966252135,-0.01754426777,0.8677877598],\n\t\t\t\t[0.06583916704,0.9976766247,-0.01750875645],\n\t\t\t\t[-0.8654643848,0.06582971318,0.4966264667]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.61163777],\n\t\t\t\t[120.2765647],\n\t\t\t\t[285.1928757]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.539,0,371.886],\n\t\t\t\t[0,745.656,230.519],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326644,0.0839413,-0.000557984,0.000204085,0.0126328],\n\t\t\t\"R\": [\n\t\t\t\t[0.5330371562,-0.03752357961,0.8452593514],\n\t\t\t\t[0.08887796824,0.9959722199,-0.01183402057],\n\t\t\t\t[-0.8414107777,0.08143290645,0.5342252193]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.03247131],\n\t\t\t\t[109.6165459],\n\t\t\t\t[286.9430377]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.018,0,396.717],\n\t\t\t\t[0,744.224,249.141],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315372,0.0205822,-0.000440151,0.000134817,0.105074],\n\t\t\t\"R\": [\n\t\t\t\t[0.4984198723,-0.001673636668,0.8669341554],\n\t\t\t\t[0.03130878513,0.9993805529,-0.01607079461],\n\t\t\t\t[-0.8663702389,0.03515265859,0.4981635271]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.09238071],\n\t\t\t\t[136.8142763],\n\t\t\t\t[280.4949188]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.884,0,382.514],\n\t\t\t\t[0,744.877,235.74],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326378,0.0966908,-9.48994e-05,0.00105607,0.00534895],\n\t\t\t\"R\": [\n\t\t\t\t[0.4908089633,-0.01723518027,0.8710967283],\n\t\t\t\t[0.04978157704,0.9987257364,-0.008288432131],\n\t\t\t\t[-0.8698438688,0.04743260567,0.4910415377]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[21.95453226],\n\t\t\t\t[154.6836493],\n\t\t\t\t[281.6596012]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.481,0,341.813],\n\t\t\t\t[0,744.509,213.322],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310201,-0.0109775,-0.00130948,-0.000370453,0.189258],\n\t\t\t\"R\": [\n\t\t\t\t[0.5283332962,-0.01827851401,0.8488402818],\n\t\t\t\t[0.07383881778,0.996969434,-0.02449033896],\n\t\t\t\t[-0.8458201683,0.0756164244,0.5280818111]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.59416721],\n\t\t\t\t[149.8670778],\n\t\t\t\t[286.3856475]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.639,0,394.42],\n\t\t\t\t[0,745.872,232.374],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317821,0.05701,0.000216723,0.00145431,0.0516441],\n\t\t\t\"R\": [\n\t\t\t\t[0.1117244957,0.006687085701,0.9937167202],\n\t\t\t\t[0.1929264895,0.9808052728,-0.02829110459],\n\t\t\t\t[-0.9748317838,0.1948750877,0.1082898585]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.76838593],\n\t\t\t\t[183.2092961],\n\t\t\t\t[300.2249606]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[744.265,0,384.24],\n\t\t\t\t[0,744.607,234.555],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314122,0.0172489,-0.000351192,-3.05431e-05,0.116521],\n\t\t\t\"R\": [\n\t\t\t\t[0.09126102309,0.01926845044,0.9956405739],\n\t\t\t\t[0.1889483007,0.9813154942,-0.03631033643],\n\t\t\t\t[-0.9777371658,0.191438313,0.08591511501]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.54744948],\n\t\t\t\t[195.8515337],\n\t\t\t\t[299.6149103]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[742.909,0,383.13],\n\t\t\t\t[0,743.051,234.161],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311566,0.0211516,-0.000212815,-9.64233e-05,0.110817],\n\t\t\t\"R\": [\n\t\t\t\t[0.07658267666,-0.01244461629,0.9969855692],\n\t\t\t\t[0.2193131093,0.9756433613,-0.004668149478],\n\t\t\t\t[-0.9726442586,0.2190095044,0.07744664757]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-39.95619704],\n\t\t\t\t[171.7405641],\n\t\t\t\t[305.3439137]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.057,0,349.277],\n\t\t\t\t[0,745.321,214.2],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31581,0.0237721,-0.00140945,-0.000667487,0.124292],\n\t\t\t\"R\": [\n\t\t\t\t[0.09341145846,-0.02354383001,0.9953491787],\n\t\t\t\t[0.2305453591,0.9730606003,0.001380415192],\n\t\t\t\t[-0.9685675696,0.2293441873,0.09632293059]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.73412593],\n\t\t\t\t[146.7921304],\n\t\t\t\t[306.2893961]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.634,0,387.597],\n\t\t\t\t[0,744.752,225.246],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315944,0.0434616,-0.000268259,0.00110436,0.0780237],\n\t\t\t\"R\": [\n\t\t\t\t[0.1133728096,0.0374780752,0.9928454059],\n\t\t\t\t[0.2222309073,0.973014014,-0.06210597779],\n\t\t\t\t[-0.9683801061,0.2276820645,0.1019845459]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.79623552],\n\t\t\t\t[137.113178],\n\t\t\t\t[305.5099477]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.759,0,388.645],\n\t\t\t\t[0,744.666,221.73],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306159,-0.0283273,-0.000508774,0.00094455,0.192402],\n\t\t\t\"R\": [\n\t\t\t\t[0.1564984143,0.01913164242,0.9874928995],\n\t\t\t\t[0.2309282446,0.9713913042,-0.05541732523],\n\t\t\t\t[-0.96030224,0.2367127254,0.1476031622]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-66.24261018],\n\t\t\t\t[112.7515407],\n\t\t\t\t[303.5978047]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.959,0,375.286],\n\t\t\t\t[0,745.092,235.744],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302136,-0.0624017,-0.000302824,-0.00146028,0.239945],\n\t\t\t\"R\": [\n\t\t\t\t[0.0628689268,0.03077162571,0.9975472947],\n\t\t\t\t[0.2444661638,0.9685997585,-0.04528578729],\n\t\t\t\t[-0.967617586,0.2467136292,0.05337220603]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.11814477],\n\t\t\t\t[98.74694092],\n\t\t\t\t[308.9777955]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[746.649,0,384.752],\n\t\t\t\t[0,746.836,237.267],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321628,0.0600031,0.000104796,0.000953791,0.0524376],\n\t\t\t\"R\": [\n\t\t\t\t[0.1158239713,-0.07384920575,0.9905206219],\n\t\t\t\t[0.2473198554,0.9679682291,0.043248082],\n\t\t\t\t[-0.9619863288,0.2399662524,0.1303782992]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.76229918],\n\t\t\t\t[76.40869106],\n\t\t\t\t[305.3733784]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.672,0,372.774],\n\t\t\t\t[0,745.737,209.129],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30917,-0.00857977,-4.68803e-05,-0.000521617,0.17194],\n\t\t\t\"R\": [\n\t\t\t\t[0.1233501146,0.01050711315,0.9923075883],\n\t\t\t\t[0.2153087978,0.9758411417,-0.0370970036],\n\t\t\t\t[-0.9687243523,0.2182284735,0.1181078428]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.44854612],\n\t\t\t\t[78.73632155],\n\t\t\t\t[304.5944309]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.36,0,350.493],\n\t\t\t\t[0,744.605,227.167],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324539,0.0696676,-0.000964917,-0.000688724,0.0453805],\n\t\t\t\"R\": [\n\t\t\t\t[0.0653712546,0.005547467364,0.9978455916],\n\t\t\t\t[0.2748842968,0.9611936881,-0.02335203178],\n\t\t\t\t[-0.9592524289,0.2758186354,0.06130952564]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.36142141],\n\t\t\t\t[73.86484437],\n\t\t\t\t[309.5485763]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.072,0,352.953],\n\t\t\t\t[0,744.032,218.847],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310531,-0.00866492,-5.61729e-06,0.000627577,0.179884],\n\t\t\t\"R\": [\n\t\t\t\t[0.08325845442,0.01268657881,0.9964472292],\n\t\t\t\t[0.1993298125,0.97949952,-0.02912586749],\n\t\t\t\t[-0.9763890903,0.2010466141,0.07902280276]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[33.26019053],\n\t\t\t\t[89.58305599],\n\t\t\t\t[303.0664402]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.677,0,359.077],\n\t\t\t\t[0,743.623,233.815],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305265,-0.0518121,0.000714314,0.000432839,0.265088],\n\t\t\t\"R\": [\n\t\t\t\t[0.06818541392,0.004787243789,0.9976611808],\n\t\t\t\t[0.2533830838,0.9671167716,-0.02195821049],\n\t\t\t\t[-0.9649599796,0.2542876962,0.06473025078]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[54.03449748],\n\t\t\t\t[85.53998459],\n\t\t\t\t[306.9876015]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.736,0,368.122],\n\t\t\t\t[0,742.832,238.615],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303469,-0.0412536,1.82225e-05,-0.000473228,0.205739],\n\t\t\t\"R\": [\n\t\t\t\t[0.1225239282,-0.0735967149,0.9897329996],\n\t\t\t\t[0.2305366224,0.9720798639,0.0437447595],\n\t\t\t\t[-0.9653189902,0.222809923,0.1360697815]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.43625272],\n\t\t\t\t[116.7070017],\n\t\t\t\t[307.0317679]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.328,0,371.219],\n\t\t\t\t[0,745.487,209.713],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318297,0.0286867,-0.0013247,0.000626009,0.137928],\n\t\t\t\"R\": [\n\t\t\t\t[0.06972690557,-0.0276618613,0.9971825209],\n\t\t\t\t[0.2175762615,0.9759712693,0.01185967683],\n\t\t\t\t[-0.9735495514,0.2161363064,0.0740700209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.75964066],\n\t\t\t\t[131.0709572],\n\t\t\t\t[303.578107]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[743.637,0,370.163],\n\t\t\t\t[0,743.479,235.403],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.301307,-0.0600698,0.000220332,0.000264974,0.263845],\n\t\t\t\"R\": [\n\t\t\t\t[0.0871387997,-0.1078492175,0.9903410402],\n\t\t\t\t[0.2171380052,0.9722761796,0.08677624828],\n\t\t\t\t[-0.9722437535,0.2074790999,0.1081411432]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.10934266],\n\t\t\t\t[155.0300785],\n\t\t\t\t[303.8314173]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.749,0,388.765],\n\t\t\t\t[0,747.73,234.855],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320028,0.057848,-0.00103044,0.00101463,0.0716113],\n\t\t\t\"R\": [\n\t\t\t\t[0.09276252326,-0.02731891999,0.9953134134],\n\t\t\t\t[0.2004837996,0.9796626634,0.008204393401],\n\t\t\t\t[-0.9752955246,0.1987831547,0.09635298148]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[25.02944215],\n\t\t\t\t[165.1686099],\n\t\t\t\t[301.5459594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.477,0,358.035],\n\t\t\t\t[0,745.633,228.78],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315933,0.0359808,-0.000244793,0.00106736,0.101835],\n\t\t\t\"R\": [\n\t\t\t\t[0.09323456203,-0.04884472803,0.9944453273],\n\t\t\t\t[0.1997864834,0.9793990461,0.02937464128],\n\t\t\t\t[-0.9753936013,0.1959380031,0.1010723576]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.52671676],\n\t\t\t\t[185.8338565],\n\t\t\t\t[300.6683817]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.962,0,392.223],\n\t\t\t\t[0,747.34,219.936],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325078,0.0885503,-0.00165532,0.000580691,0.0160315],\n\t\t\t\"R\": [\n\t\t\t\t[0.129696032,0.03909405168,0.990782819],\n\t\t\t\t[0.1776002444,0.9821476201,-0.06200165731],\n\t\t\t\t[-0.9755188837,0.1840046397,0.1204375361]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.746570817],\n\t\t\t\t[166.089254],\n\t\t\t\t[298.9402723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.91,0,339.915],\n\t\t\t\t[0,744.956,221.133],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306862,-0.0244375,-6.76743e-05,-0.000102471,0.205298],\n\t\t\t\"R\": [\n\t\t\t\t[0.09943504227,-0.007298095184,0.9950172914],\n\t\t\t\t[0.2125993636,0.9770380132,-0.01407946415],\n\t\t\t\t[-0.9720669642,0.212940035,0.09870338653]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.7866272],\n\t\t\t\t[143.0595857],\n\t\t\t\t[303.8181509]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[743.577,0,349.797],\n\t\t\t\t[0,743.73,227.793],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307046,-0.0206712,-0.000861395,-9.97172e-05,0.196115],\n\t\t\t\"R\": [\n\t\t\t\t[0.09969364468,-0.01462231859,0.9949107322],\n\t\t\t\t[0.2541863771,0.9670897407,-0.01125696175],\n\t\t\t\t[-0.9620033591,0.2540150021,0.1001294952]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.43364439],\n\t\t\t\t[109.4423166],\n\t\t\t\t[308.9174676]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.066,0,381.498],\n\t\t\t\t[0,745.047,229.678],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314894,0.0257947,-0.000483886,0.00117112,0.111876],\n\t\t\t\"R\": [\n\t\t\t\t[0.08696832552,-0.05294226024,0.9948033109],\n\t\t\t\t[0.2154078845,0.9759627551,0.03310806346],\n\t\t\t\t[-0.9726437959,0.2114091239,0.09628202687]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.298071534],\n\t\t\t\t[115.0382234],\n\t\t\t\t[303.8536261]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.602,0,379.206],\n\t\t\t\t[0,746.635,260.689],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319922,0.0568918,0.00103779,-0.000422086,0.0766843],\n\t\t\t\"R\": [\n\t\t\t\t[0.09129519856,-0.01052008078,0.9957683037],\n\t\t\t\t[0.2195471399,0.9755524467,-0.009822274065],\n\t\t\t\t[-0.9713208739,0.2195148095,0.09137290798]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.69590833],\n\t\t\t\t[125.3942709],\n\t\t\t\t[304.7857903]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.388,0,382.392],\n\t\t\t\t[0,745.496,224.015],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302393,-0.0525763,-0.000559682,-6.77e-05,0.234314],\n\t\t\t\"R\": [\n\t\t\t\t[0.08118536371,-0.04636746828,0.9956199047],\n\t\t\t\t[0.1796446798,0.9832385033,0.03114216711],\n\t\t\t\t[-0.9803758084,0.1763295309,0.0881542445]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[8.147122648],\n\t\t\t\t[159.0280693],\n\t\t\t\t[298.1193244]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[747.532,0,374.739],\n\t\t\t\t[0,747.668,233.944],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331439,0.109037,-0.000609362,0.000392501,-0.000621335],\n\t\t\t\"R\": [\n\t\t\t\t[0.7848571462,0.05717032211,0.6170338843],\n\t\t\t\t[0.1817012858,0.9307358272,-0.3173569956],\n\t\t\t\t[-0.5924389444,0.3611957561,0.7201067442]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.59276639],\n\t\t\t\t[102.5270366],\n\t\t\t\t[325.6365462]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.597,0,385.764],\n\t\t\t\t[0,743.786,211.188],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307778,-0.0279819,-0.000454196,0.00143268,0.205643],\n\t\t\t\"R\": [\n\t\t\t\t[0.7963392439,-0.01332837804,0.6047033677],\n\t\t\t\t[0.2601504211,0.910106147,-0.3225345868],\n\t\t\t\t[-0.5460453892,0.4141607847,0.7282206241]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-38.00771612],\n\t\t\t\t[61.10094736],\n\t\t\t\t[329.1235579]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.709,0,382.284],\n\t\t\t\t[0,746.792,243.451],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.343209,0.149416,0.000603517,0.00195788,-0.0395936],\n\t\t\t\"R\": [\n\t\t\t\t[0.7773715491,0.01124156294,0.6289412548],\n\t\t\t\t[0.2547080739,0.908583342,-0.3310590698],\n\t\t\t\t[-0.5751671686,0.4175523175,0.7034435232]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.435783379],\n\t\t\t\t[55.70511308],\n\t\t\t\t[330.3798829]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[743.976,0,365.248],\n\t\t\t\t[0,744.344,229.757],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.297483,-0.106842,0.000162294,-0.00147347,0.393874],\n\t\t\t\"R\": [\n\t\t\t\t[0.7524447247,-0.05297584633,0.6565215122],\n\t\t\t\t[0.2825071426,0.9263759092,-0.2490329079],\n\t\t\t\t[-0.5949929838,0.3728555143,0.7120127209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.049706825],\n\t\t\t\t[87.26745214],\n\t\t\t\t[326.8342451]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[748.766,0,349.367],\n\t\t\t\t[0,748.975,233.229],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.341466,0.149186,0.00133441,-0.000377568,-0.0615035],\n\t\t\t\"R\": [\n\t\t\t\t[0.7609990379,-0.1304343502,0.6355055818],\n\t\t\t\t[0.3323849453,0.9196335935,-0.2092708816],\n\t\t\t\t[-0.5571361704,0.3704874276,0.7431946943]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.029843232],\n\t\t\t\t[83.469382],\n\t\t\t\t[327.9910328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[747.104,0,395.739],\n\t\t\t\t[0,747.205,237.611],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337038,0.14046,-0.00100634,0.00170735,-0.0468264],\n\t\t\t\"R\": [\n\t\t\t\t[0.7339738121,-0.1238803965,0.6677844641],\n\t\t\t\t[0.3595276943,0.9050347286,-0.227270713],\n\t\t\t\t[-0.5762137452,0.4068977603,0.7088102232]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.88470946],\n\t\t\t\t[89.42074723],\n\t\t\t\t[330.2467181]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[743.991,0,393.18],\n\t\t\t\t[0,744.112,255.459],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325283,0.0732539,0.00077889,1.70805e-05,0.0462558],\n\t\t\t\"R\": [\n\t\t\t\t[0.7496842409,-0.1571943749,0.6428557128],\n\t\t\t\t[0.3434403747,0.9227495198,-0.1748771933],\n\t\t\t\t[-0.5657050892,0.3518852828,0.7457576683]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.35233863],\n\t\t\t\t[128.2674639],\n\t\t\t\t[324.6313017]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.616,0,369.102],\n\t\t\t\t[0,744.835,223.742],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336732,0.141968,-0.000206183,0.000677154,-0.0657397],\n\t\t\t\"R\": [\n\t\t\t\t[0.7264947252,-0.2131742795,0.6532703428],\n\t\t\t\t[0.4249899792,0.8864309285,-0.1833677358],\n\t\t\t\t[-0.5399897516,0.4108490422,0.7345843265]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[15.28675757],\n\t\t\t\t[126.0458703],\n\t\t\t\t[333.4285141]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[747.517,0,392.733],\n\t\t\t\t[0,747.836,218.574],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334626,0.113242,0.000443349,0.00121381,-0.00550976],\n\t\t\t\"R\": [\n\t\t\t\t[0.8000319441,0.07155257429,0.5956753458],\n\t\t\t\t[0.1937456116,0.9088549369,-0.3693850858],\n\t\t\t\t[-0.5678129326,0.4109293525,0.7132499848]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-44.09712116],\n\t\t\t\t[90.97242653],\n\t\t\t\t[330.2186197]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.904,0,354.135],\n\t\t\t\t[0,744.494,220.038],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309276,-0.0261099,-0.00127318,0.000283377,0.220693],\n\t\t\t\"R\": [\n\t\t\t\t[0.7314656006,-0.1499734814,0.6651812009],\n\t\t\t\t[0.3639090401,0.9108337109,-0.1948131455],\n\t\t\t\t[-0.576652656,0.3845645668,0.720820233]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.360923884],\n\t\t\t\t[158.0207055],\n\t\t\t\t[327.7017732]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.441,0,366.024],\n\t\t\t\t[0,745.471,238.165],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311636,0.00305556,-0.00136926,0.00112458,0.163822],\n\t\t\t\"R\": [\n\t\t\t\t[0.743215427,-0.1065195831,0.660518287],\n\t\t\t\t[0.3430146167,0.9082888556,-0.2394834597],\n\t\t\t\t[-0.5744317207,0.4045552288,0.7115920636]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.38448511],\n\t\t\t\t[170.5922255],\n\t\t\t\t[331.2143489]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.816,0,384.478],\n\t\t\t\t[0,744.21,221.813],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309294,-0.0116228,-0.000777235,0.00017565,0.174372],\n\t\t\t\"R\": [\n\t\t\t\t[0.799529392,-0.03302696284,0.5997182431],\n\t\t\t\t[0.261290645,0.91817945,-0.2977812898],\n\t\t\t\t[-0.540814155,0.3947856601,0.7427410938]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.11731065],\n\t\t\t\t[179.1857595],\n\t\t\t\t[329.2699106]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.594,0,366.809],\n\t\t\t\t[0,744.805,211.378],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313339,0.0076854,-0.000770441,0.000328229,0.137582],\n\t\t\t\"R\": [\n\t\t\t\t[0.7697001229,-0.07364256128,0.6341439064],\n\t\t\t\t[0.280866324,0.9310898592,-0.2327783971],\n\t\t\t\t[-0.5733025631,0.3572792288,0.7373436945]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.06753178],\n\t\t\t\t[173.6081799],\n\t\t\t\t[322.2797536]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.088,0,376.311],\n\t\t\t\t[0,744.421,235.85],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308902,-0.0157485,-0.000258056,-0.00040893,0.167363],\n\t\t\t\"R\": [\n\t\t\t\t[0.8019727226,0.02030217439,0.5970155559],\n\t\t\t\t[0.20788107,0.9274680659,-0.31078682],\n\t\t\t\t[-0.5600225111,0.3733507848,0.7395836522]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.35663304],\n\t\t\t\t[177.8511702],\n\t\t\t\t[324.3990212]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.471,0,391.786],\n\t\t\t\t[0,745.597,244.782],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319471,0.0520955,-9.03549e-05,0.00103599,0.0679082],\n\t\t\t\"R\": [\n\t\t\t\t[0.7993824794,0.07801580494,0.5957358356],\n\t\t\t\t[0.170767806,0.9211391478,-0.3497728217],\n\t\t\t\t[-0.5760434082,0.3813347671,0.723019908]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.66881494],\n\t\t\t\t[158.8808021],\n\t\t\t\t[326.8395357]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.688,0,372.572],\n\t\t\t\t[0,744.687,232.622],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313079,0.00611683,0.000601543,0.00134427,0.153664],\n\t\t\t\"R\": [\n\t\t\t\t[0.8032635264,0.07397377164,0.5910123419],\n\t\t\t\t[0.1542914416,0.9325457224,-0.3264239985],\n\t\t\t\t[-0.5752928456,0.3533926383,0.7376664456]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.95169554],\n\t\t\t\t[148.2901373],\n\t\t\t\t[322.192073]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[746.029,0,371.631],\n\t\t\t\t[0,745.957,227.751],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328618,0.10871,0.000376647,0.00140085,-0.015131],\n\t\t\t\"R\": [\n\t\t\t\t[0.7930332571,0.09578045983,0.6016014933],\n\t\t\t\t[0.1573865304,0.9218193412,-0.3542295616],\n\t\t\t\t[-0.5884961625,0.3755997947,0.7159588403]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-34.37744536],\n\t\t\t\t[124.5681533],\n\t\t\t\t[326.9926029]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.728,0,355.008],\n\t\t\t\t[0,745.836,235.366],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326785,0.0753795,-0.00141997,0.000421746,0.0593081],\n\t\t\t\"R\": [\n\t\t\t\t[0.7423074724,-0.1183757606,0.6595201254],\n\t\t\t\t[0.3246236378,0.9245812728,-0.1994215728],\n\t\t\t\t[-0.5861732766,0.362127946,0.7247511576]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.16113415],\n\t\t\t\t[163.1800117],\n\t\t\t\t[323.8887405]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.415,0,362.511],\n\t\t\t\t[0,745.431,246.567],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31824,0.0392935,0.000511921,2.0382e-05,0.0980721],\n\t\t\t\"R\": [\n\t\t\t\t[0.7792023734,-0.03485918818,0.6258022837],\n\t\t\t\t[0.250771695,0.9323920084,-0.2603050127],\n\t\t\t\t[-0.5744190268,0.3597637832,0.7352637636]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.21577405],\n\t\t\t\t[116.3982595],\n\t\t\t\t[324.3931588]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.757,0,370.457],\n\t\t\t\t[0,745.798,252.296],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322058,0.058259,0.000816175,0.000770211,0.0698692],\n\t\t\t\"R\": [\n\t\t\t\t[0.7754488131,-0.03297117701,0.6305489986],\n\t\t\t\t[0.2704225106,0.9197540051,-0.2844718542],\n\t\t\t\t[-0.5705705951,0.391108005,0.7221383001]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.5150360293],\n\t\t\t\t[101.3336776],\n\t\t\t\t[328.6175717]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.009,0,385.23],\n\t\t\t\t[0,746.113,244.377],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328614,0.0717398,0.00119782,0.000153035,0.0631847],\n\t\t\t\"R\": [\n\t\t\t\t[0.7150247804,-0.1629175474,0.6798510396],\n\t\t\t\t[0.3900461789,0.9000077369,-0.194550898],\n\t\t\t\t[-0.5801754405,0.4042820134,0.7070732013]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.095653738],\n\t\t\t\t[113.9962742],\n\t\t\t\t[330.0144097]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[747.044,0,384.928],\n\t\t\t\t[0,747.43,218.136],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332061,0.0970763,-0.00131827,0.000796644,0.024739],\n\t\t\t\"R\": [\n\t\t\t\t[0.7476996574,-0.1120966581,0.6545071135],\n\t\t\t\t[0.3349363173,0.9147459603,-0.2259590484],\n\t\t\t\t[-0.5733784838,0.3881677053,0.7215004829]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.202807266],\n\t\t\t\t[138.4357179],\n\t\t\t\t[328.3283502]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.525,0,381.586],\n\t\t\t\t[0,746.566,231.744],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323751,0.0809499,0.00143311,0.000786746,0.0334271],\n\t\t\t\"R\": [\n\t\t\t\t[0.7874675535,-0.04961201835,0.6143561669],\n\t\t\t\t[0.2785108695,0.9178324582,-0.2828697124],\n\t\t\t\t[-0.5498422936,0.3938555906,0.7365807667]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.67007007],\n\t\t\t\t[141.1281207],\n\t\t\t\t[328.549187]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.493,0,392.291],\n\t\t\t\t[0,744.573,223.193],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308278,-0.0176562,-0.000671893,0.00116828,0.17277],\n\t\t\t\"R\": [\n\t\t\t\t[0.7758686755,-0.01407586642,0.6307374005],\n\t\t\t\t[0.2927445364,0.8936390769,-0.3401614861],\n\t\t\t\t[-0.5588635207,0.4485655695,0.6974672]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.05926183],\n\t\t\t\t[105.1778582],\n\t\t\t\t[335.8474538]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.918,0,380.409],\n\t\t\t\t[0,745.86,226.454],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329171,0.0901569,-0.000500393,-0.000311386,0.0200307],\n\t\t\t\"R\": [\n\t\t\t\t[0.8121486446,0.04341076946,0.5818333819],\n\t\t\t\t[-0.0759194996,0.9966126489,0.03161419974],\n\t\t\t\t[-0.5784901112,-0.06984792866,0.8126933358]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[55.6088262],\n\t\t\t\t[125.3657692],\n\t\t\t\t[265.9940479]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.364,0,392.411],\n\t\t\t\t[0,747.161,225.523],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325367,0.0819479,0.000479765,0.00158774,0.0247525],\n\t\t\t\"R\": [\n\t\t\t\t[0.8168932447,0.07701494166,0.5716241121],\n\t\t\t\t[-0.08391193553,0.9963702084,-0.01432462351],\n\t\t\t\t[-0.5706524458,-0.03626439747,0.8203905653]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[75.42528996],\n\t\t\t\t[124.1426197],\n\t\t\t\t[270.1790967]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.743,0,378.771],\n\t\t\t\t[0,744.551,249.858],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319546,0.0369202,-5.08119e-05,0.00111176,0.115068],\n\t\t\t\"R\": [\n\t\t\t\t[0.8437113062,0.07102371173,0.5320778742],\n\t\t\t\t[-0.08587784221,0.9963005803,0.003185889303],\n\t\t\t\t[-0.5298832211,-0.04838167055,0.8466894271]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.15960424],\n\t\t\t\t[150.0301024],\n\t\t\t\t[271.4615922]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.916,0,377.522],\n\t\t\t\t[0,746.078,215.704],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32195,0.0590592,-0.000295617,0.000900619,0.0691531],\n\t\t\t\"R\": [\n\t\t\t\t[0.8298382679,0.121110683,0.5447023514],\n\t\t\t\t[-0.1306769278,0.9911961099,-0.02130286834],\n\t\t\t\t[-0.5424868568,-0.05350209448,0.8383588349]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.00635036],\n\t\t\t\t[157.1807453],\n\t\t\t\t[269.6015294]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.303,0,378.655],\n\t\t\t\t[0,745.572,246.962],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315703,0.0277156,6.06815e-05,0.000389915,0.121683],\n\t\t\t\"R\": [\n\t\t\t\t[0.8187116226,0.05412921644,0.5716478872],\n\t\t\t\t[-0.09011941267,0.9953220251,0.0348218015],\n\t\t\t\t[-0.5670888559,-0.08002558546,0.8197598034]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[44.81120287],\n\t\t\t\t[188.347539],\n\t\t\t\t[263.8787228]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.606,0,364.995],\n\t\t\t\t[0,745.957,239.275],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315328,0.0257972,-0.000148911,-0.000553771,0.11289],\n\t\t\t\"R\": [\n\t\t\t\t[0.8250072615,0.03741598225,0.5638821355],\n\t\t\t\t[-0.06134414867,0.997839028,0.02354080738],\n\t\t\t\t[-0.5617827996,-0.05401220659,0.8255196955]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.96573731],\n\t\t\t\t[189.9536973],\n\t\t\t\t[269.3804852]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[748.144,0,375.351],\n\t\t\t\t[0,748.158,222.981],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330846,0.0923667,0.000924419,-0.000952259,0.0155541],\n\t\t\t\"R\": [\n\t\t\t\t[0.837010476,0.04764620621,0.5451085232],\n\t\t\t\t[-0.06946161724,0.9973944363,0.0194787641],\n\t\t\t\t[-0.542760119,-0.05416804921,0.8381391744]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.044263505],\n\t\t\t\t[177.2440129],\n\t\t\t\t[269.3681033]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.865,0,367.243],\n\t\t\t\t[0,744.958,216.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318901,0.0494498,-4.02299e-05,-0.00132469,0.0675277],\n\t\t\t\"R\": [\n\t\t\t\t[0.820488273,0.02086231711,0.571282555],\n\t\t\t\t[-0.05401864215,0.9976917237,0.04114864192],\n\t\t\t\t[-0.569105421,-0.06462188605,0.8197213134]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.55260409],\n\t\t\t\t[185.7078501],\n\t\t\t\t[268.0867658]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[747.002,0,387.115],\n\t\t\t\t[0,747.11,221.005],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330535,0.106093,-0.000909516,-0.000158007,-0.000767667],\n\t\t\t\"R\": [\n\t\t\t\t[0.7988895638,0.03324884852,0.6005580562],\n\t\t\t\t[-0.04929092881,0.9987315997,0.01027599727],\n\t\t\t\t[-0.5994546431,-0.03781145137,0.7995151187]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.46737596],\n\t\t\t\t[164.4653247],\n\t\t\t\t[274.3468777]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.13,0,370.332],\n\t\t\t\t[0,747.181,215.13],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317083,0.0321021,0.000973109,0.00011315,0.117938],\n\t\t\t\"R\": [\n\t\t\t\t[0.8533830718,-0.04475694932,0.5193593633],\n\t\t\t\t[-0.01101437775,0.9945367161,0.1038046423],\n\t\t\t\t[-0.5211679348,-0.09430554471,0.8482278279]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.15311463],\n\t\t\t\t[154.6074069],\n\t\t\t\t[261.7210039]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.847,0,352.444],\n\t\t\t\t[0,743.813,257.427],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317406,0.0378558,0.000559662,0.00156409,0.0978841],\n\t\t\t\"R\": [\n\t\t\t\t[0.8306368039,-0.006305585156,0.5567788965],\n\t\t\t\t[-0.01286906876,0.999451376,0.03051776569],\n\t\t\t\t[-0.5566658666,-0.03251440526,0.8300999496]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-55.68789985],\n\t\t\t\t[125.5954887],\n\t\t\t\t[272.609285]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.746,0,358.295],\n\t\t\t\t[0,744.902,240.075],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311924,0.00313238,0.000282789,0.000109914,0.161883],\n\t\t\t\"R\": [\n\t\t\t\t[0.8248636519,0.04296544146,0.5636966618],\n\t\t\t\t[-0.06337887364,0.9978500361,0.01668603434],\n\t\t\t\t[-0.5617678116,-0.04949016272,0.8258133262]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.5470475],\n\t\t\t\t[111.3455785],\n\t\t\t\t[270.6081331]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.599,0,373.118],\n\t\t\t\t[0,742.696,232.489],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30659,-0.0244311,-0.000674534,-0.000450328,0.198624],\n\t\t\t\"R\": [\n\t\t\t\t[0.8431633834,0.1596479738,0.5134082522],\n\t\t\t\t[-0.1755645793,0.9843078819,-0.01775026834],\n\t\t\t\t[-0.5081855837,-0.07516992751,0.8579608934]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.27822308],\n\t\t\t\t[119.4613899],\n\t\t\t\t[265.3318331]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.804,0,370.921],\n\t\t\t\t[0,745.998,236.13],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32821,0.0986121,-0.000141995,-6.949e-05,-0.000912797],\n\t\t\t\"R\": [\n\t\t\t\t[0.8387309717,0.02755081107,0.5438486094],\n\t\t\t\t[-0.05712815546,0.9976599438,0.03756341813],\n\t\t\t\t[-0.5415410705,-0.06257467009,0.8383422211]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.56519475],\n\t\t\t\t[90.10611059],\n\t\t\t\t[268.3571691]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.816,0,365.456],\n\t\t\t\t[0,746.849,225.794],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313831,-0.00769663,-0.000408313,0.00132145,0.204366],\n\t\t\t\"R\": [\n\t\t\t\t[0.832563643,0.03033638007,0.5530980784],\n\t\t\t\t[-0.06055031945,0.9974999941,0.03643378343],\n\t\t\t\t[-0.5506100609,-0.06382370879,0.8323191065]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.42740827],\n\t\t\t\t[88.69840867],\n\t\t\t\t[268.7038743]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.958,0,362.302],\n\t\t\t\t[0,745.997,246.977],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334292,0.102923,-0.000499879,-0.000549652,0.00793805],\n\t\t\t\"R\": [\n\t\t\t\t[0.8469636173,0.04048111503,0.5301074517],\n\t\t\t\t[-0.08872767491,0.9938758,0.0658657255],\n\t\t\t\t[-0.5241946497,-0.1028210748,0.8453684379]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.584618298],\n\t\t\t\t[109.8657875],\n\t\t\t\t[264.6056558]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[743.409,0,347.233],\n\t\t\t\t[0,743.501,244.449],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321337,0.060438,0.000289347,-0.000274585,0.0540146],\n\t\t\t\"R\": [\n\t\t\t\t[0.8338949711,0.06176137043,0.5484566622],\n\t\t\t\t[-0.07967791451,0.9967809419,0.008898524832],\n\t\t\t\t[-0.5461415633,-0.05112031815,0.8361316319]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.73506114],\n\t\t\t\t[91.25662398],\n\t\t\t\t[270.2531272]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.291,0,372.769],\n\t\t\t\t[0,745.233,242.994],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333422,0.127228,0.000470045,-0.000171948,-0.0533425],\n\t\t\t\"R\": [\n\t\t\t\t[0.83476387,0.01583088955,0.5503804723],\n\t\t\t\t[-0.006383142992,0.9997976531,-0.01907638369],\n\t\t\t\t[-0.5505711006,0.01241111862,0.8346960089]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.20146308],\n\t\t\t\t[84.31846371],\n\t\t\t\t[276.1979749]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.318,0,365.802],\n\t\t\t\t[0,746.439,228.058],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329752,0.106043,0.000413141,0.00102356,-0.00232913],\n\t\t\t\"R\": [\n\t\t\t\t[0.812564017,0.08482803737,0.576666214],\n\t\t\t\t[-0.09768913876,0.9951785947,-0.008740529432],\n\t\t\t\t[-0.5746273144,-0.04923178609,0.8169330944]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.50134988],\n\t\t\t\t[124.7306793],\n\t\t\t\t[269.4016435]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.104,0,371.377],\n\t\t\t\t[0,745.158,252.192],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317414,0.0233642,0.000269725,0.000539732,0.145301],\n\t\t\t\"R\": [\n\t\t\t\t[0.8445515108,0.05428741136,0.5327153297],\n\t\t\t\t[-0.06949119822,0.9975462456,0.00851241329],\n\t\t\t\t[-0.5309460603,-0.04420819807,0.8462516862]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.33430135],\n\t\t\t\t[146.0606392],\n\t\t\t\t[271.3134014]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.321,0,365.126],\n\t\t\t\t[0,744.44,221.253],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310945,0.00293318,4.64093e-05,-0.000454281,0.146346],\n\t\t\t\"R\": [\n\t\t\t\t[0.8382052649,0.09941648006,0.5362166515],\n\t\t\t\t[-0.1229674254,0.9923765769,0.008230548616],\n\t\t\t\t[-0.531310593,-0.07283607028,0.8440402601]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.636303812],\n\t\t\t\t[160.8368098],\n\t\t\t\t[266.310691]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.695,0,387.973],\n\t\t\t\t[0,745.975,222.039],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325844,0.0780224,-0.000861123,0.000487347,0.0459906],\n\t\t\t\"R\": [\n\t\t\t\t[0.8503320636,-0.003175777979,0.52623692],\n\t\t\t\t[-0.02504000004,0.9986049625,0.04648792516],\n\t\t\t\t[-0.5256504352,-0.05270714583,0.8490662971]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.03965018],\n\t\t\t\t[141.2975723],\n\t\t\t\t[268.9897195]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.757,0,385.384],\n\t\t\t\t[0,746.697,250.739],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330103,0.0993513,0.000581277,0.0005991,0.0043047],\n\t\t\t\"R\": [\n\t\t\t\t[0.8172674448,0.1129970073,0.565071323],\n\t\t\t\t[-0.1204798393,0.992420693,-0.02420281713],\n\t\t\t\t[-0.5635233199,-0.0482995277,0.8246869852]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[1.484048414],\n\t\t\t\t[120.2737991],\n\t\t\t\t[270.3939501]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[743.909,0,365.262],\n\t\t\t\t[0,744.1,225.983],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309366,-0.0151251,-0.000569796,0.000128233,0.192772],\n\t\t\t\"R\": [\n\t\t\t\t[0.8488529257,0.0258708029,0.5279956553],\n\t\t\t\t[-0.02681353424,0.9996232069,-0.005871843729],\n\t\t\t\t[-0.5279486195,-0.009173097852,0.8492267715]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.170097817],\n\t\t\t\t[104.9858918],\n\t\t\t\t[274.723166]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[743.511,0,382.741],\n\t\t\t\t[0,744.07,233.668],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303608,-0.0460126,4.19904e-05,0.000729649,0.232264],\n\t\t\t\"R\": [\n\t\t\t\t[0.7426987355,0.03664601822,-0.6686222084],\n\t\t\t\t[-0.01756201576,0.9992239229,0.035258014],\n\t\t\t\t[0.6693953719,-0.01444372865,0.742765922]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.30884403],\n\t\t\t\t[110.2809812],\n\t\t\t\t[269.7471778]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[744.491,0,371.868],\n\t\t\t\t[0,744.58,223.545],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320104,0.0388113,-0.000303412,-0.00118762,0.0743207],\n\t\t\t\"R\": [\n\t\t\t\t[0.773334615,0.1038173874,-0.6254402635],\n\t\t\t\t[-0.04654036662,0.9931361468,0.107306049],\n\t\t\t\t[0.6322875671,-0.05387526291,0.7728582591]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[68.17402308],\n\t\t\t\t[125.7906344],\n\t\t\t\t[263.8293382]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.096,0,373.775],\n\t\t\t\t[0,744.072,232.317],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314223,0.0332024,-0.000194112,2.11963e-05,0.079313],\n\t\t\t\"R\": [\n\t\t\t\t[0.7946878724,-0.02084896757,-0.6066601239],\n\t\t\t\t[0.03470365887,0.999335828,0.01111570764],\n\t\t\t\t[0.6060254462,-0.02988684405,0.7948835985]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[55.17367606],\n\t\t\t\t[148.0232969],\n\t\t\t\t[266.1261169]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[748.225,0,373.118],\n\t\t\t\t[0,748.618,236.287],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325852,0.0883394,-0.000431944,-0.00077703,0.0075009],\n\t\t\t\"R\": [\n\t\t\t\t[0.7874797118,0.07165214706,-0.6121614766],\n\t\t\t\t[-0.03177741847,0.9966185482,0.07577377574],\n\t\t\t\t[0.6155208357,-0.04021739967,0.7870938073]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[46.04066644],\n\t\t\t\t[153.679907],\n\t\t\t\t[265.8341529]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.23,0,378.585],\n\t\t\t\t[0,745.614,229.474],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323397,0.071697,-0.000659822,0.000678056,0.0530686],\n\t\t\t\"R\": [\n\t\t\t\t[0.7680042357,0.04160049173,-0.6390922414],\n\t\t\t\t[0.01355248597,0.9966090615,0.08115854064],\n\t\t\t\t[0.6403013541,-0.07099139161,0.7648361904]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[29.31016003],\n\t\t\t\t[185.453895],\n\t\t\t\t[261.9380867]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[742.876,0,352.101],\n\t\t\t\t[0,743.303,231.794],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319343,0.0421325,-0.000546468,-1.33187e-05,0.10149],\n\t\t\t\"R\": [\n\t\t\t\t[0.8064347587,0.08751734637,-0.584810819],\n\t\t\t\t[-0.03388642915,0.9942014648,0.1020546777],\n\t\t\t\t[0.5903513275,-0.062483289,0.8047242688]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.39857301],\n\t\t\t\t[188.6248332],\n\t\t\t\t[262.8234665]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.054,0,358.779],\n\t\t\t\t[0,745.36,231.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309912,-0.00132311,-0.00013553,-0.000280643,0.151777],\n\t\t\t\"R\": [\n\t\t\t\t[0.7882500993,-0.004275732235,-0.615340149],\n\t\t\t\t[0.05540043824,0.996408109,0.06404429605],\n\t\t\t\t[0.612856078,-0.08457303664,0.7856556683]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.246792888],\n\t\t\t\t[183.4614511],\n\t\t\t\t[259.402568]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.254,0,343.02],\n\t\t\t\t[0,745.689,227.622],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309897,-0.0109758,-0.00111103,0.000256129,0.180098],\n\t\t\t\"R\": [\n\t\t\t\t[0.7946287881,0.03514926038,-0.6060772382],\n\t\t\t\t[0.01090423253,0.9973351466,0.07213669658],\n\t\t\t\t[0.6069976827,-0.06393070292,0.7921279432]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-18.41109561],\n\t\t\t\t[184.5517176],\n\t\t\t\t[263.9542066]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.379,0,338.137],\n\t\t\t\t[0,745.543,245.392],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314138,0.0142784,0.00088856,-0.00114362,0.123117],\n\t\t\t\"R\": [\n\t\t\t\t[0.7570044814,0.09852948519,-0.6459381981],\n\t\t\t\t[-0.05745310106,0.9947735679,0.08440787789],\n\t\t\t\t[0.6508789107,-0.02678598925,0.7587088733]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-40.16389387],\n\t\t\t\t[164.132571],\n\t\t\t\t[267.7674295]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.633,0,369.381],\n\t\t\t\t[0,743.739,253.863],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313678,0.00191444,-0.000367883,0.000526793,0.16208],\n\t\t\t\"R\": [\n\t\t\t\t[0.7732990879,0.03177464522,-0.6332447335],\n\t\t\t\t[0.01440724919,0.9976050167,0.06765102948],\n\t\t\t\t[0.6338777104,-0.06143779407,0.7709892643]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.17430449],\n\t\t\t\t[148.5957101],\n\t\t\t\t[262.973747]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[749.691,0,360.347],\n\t\t\t\t[0,749.465,221.979],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.36212,0.288042,0.00167589,0.000680745,-0.303613],\n\t\t\t\"R\": [\n\t\t\t\t[0.7747984815,0.06051645956,-0.629305229],\n\t\t\t\t[-0.01350572868,0.9967652932,0.07922465313],\n\t\t\t\t[0.6320640066,-0.05288391526,0.7731095544]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-52.93053536],\n\t\t\t\t[133.9502209],\n\t\t\t\t[264.0833713]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.505,0,357.704],\n\t\t\t\t[0,746.569,217.534],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312272,-0.0352904,0.000404412,-0.00107082,0.237629],\n\t\t\t\"R\": [\n\t\t\t\t[0.7725304823,-0.04233401582,-0.633564902],\n\t\t\t\t[0.05994143841,0.9981814314,0.006391704783],\n\t\t\t\t[0.6321421342,-0.04291457833,0.7736631445]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.64410987],\n\t\t\t\t[104.0188122],\n\t\t\t\t[265.010728]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[745.264,0,354.32],\n\t\t\t\t[0,745.302,226.261],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318398,0.0346929,0.000845692,0.000532231,0.122684],\n\t\t\t\"R\": [\n\t\t\t\t[0.7851484689,0.03204817868,-0.6184778056],\n\t\t\t\t[-0.002225165301,0.9987996914,0.04893081946],\n\t\t\t\t[0.619303585,-0.03704174263,0.784277361]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.19489341],\n\t\t\t\t[103.2650402],\n\t\t\t\t[265.9795804]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.589,0,353.058],\n\t\t\t\t[0,744.664,227.639],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324606,0.0822873,0.00100728,-0.000415736,0.0203245],\n\t\t\t\"R\": [\n\t\t\t\t[0.7765409088,-0.02900211747,-0.6293989944],\n\t\t\t\t[0.06862390156,0.9968904955,0.03873112579],\n\t\t\t\t[0.6263185908,-0.07326811825,0.7761164898]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-35.65491372],\n\t\t\t\t[89.93385082],\n\t\t\t\t[261.6973052]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[744.009,0,351.118],\n\t\t\t\t[0,743.982,227.187],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31768,0.0289626,0.000394183,-0.00106594,0.077624],\n\t\t\t\"R\": [\n\t\t\t\t[0.7703409519,0.009578036972,-0.6375602553],\n\t\t\t\t[0.03762675731,0.9974619202,0.06044786963],\n\t\t\t\t[0.6365210484,-0.07055479443,0.7680253746]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.94306331],\n\t\t\t\t[88.85755459],\n\t\t\t\t[261.4804843]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.298,0,365.044],\n\t\t\t\t[0,745.641,201.543],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315769,0.0139989,-0.000983596,0.000497246,0.155532],\n\t\t\t\"R\": [\n\t\t\t\t[0.7668905855,0.04755147693,-0.6400138177],\n\t\t\t\t[0.009922268647,0.9962536216,0.0859084976],\n\t\t\t\t[0.6417011597,-0.07223280706,0.7635457047]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.594602528],\n\t\t\t\t[99.8882812],\n\t\t\t\t[261.439958]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.772,0,356.238],\n\t\t\t\t[0,744.946,209.811],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307562,-0.0273551,-0.000331097,0.000403566,0.231396],\n\t\t\t\"R\": [\n\t\t\t\t[0.7386328767,0.1026186384,-0.6662513704],\n\t\t\t\t[-0.03586762178,0.992927984,0.1131703685],\n\t\t\t\t[0.6731530192,-0.05969450264,0.7370899397]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.92063539],\n\t\t\t\t[92.1220326],\n\t\t\t\t[263.1909682]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[746.696,0,345.664],\n\t\t\t\t[0,746.883,230.9],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332087,0.135716,-0.000396371,4.15402e-05,-0.0769473],\n\t\t\t\"R\": [\n\t\t\t\t[0.7676740293,0.0869303765,-0.6349170767],\n\t\t\t\t[-0.05592901251,0.9960646798,0.06875390322],\n\t\t\t\t[0.6383952774,-0.01727030079,0.7695149163]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.13164066],\n\t\t\t\t[87.731429],\n\t\t\t\t[267.0873794]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.785,0,363.137],\n\t\t\t\t[0,743.962,239.724],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322076,0.0699752,0.00130957,8.28091e-06,0.0447641],\n\t\t\t\"R\": [\n\t\t\t\t[0.7666015958,0.09362030423,-0.6352615462],\n\t\t\t\t[-0.01827880108,0.9920950944,0.1241499457],\n\t\t\t\t[0.6418628193,-0.08356172708,0.7622529495]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[25.25313987],\n\t\t\t\t[133.2656265],\n\t\t\t\t[259.9680703]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[747.071,0,344.427],\n\t\t\t\t[0,747.404,242.981],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.349964,0.20917,0.0008789,-0.000586258,-0.211765],\n\t\t\t\"R\": [\n\t\t\t\t[0.7775513873,0.03007697302,-0.6280996862],\n\t\t\t\t[-0.01270805589,0.999403059,0.03212523871],\n\t\t\t\t[0.6286909777,-0.01699709801,0.7774694548]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.35278566],\n\t\t\t\t[137.2956705],\n\t\t\t\t[269.3773006]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.669,0,371.314],\n\t\t\t\t[0,744.881,251.475],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32107,0.0528121,0.000172414,0.000961494,0.0921892],\n\t\t\t\"R\": [\n\t\t\t\t[0.7854342878,0.01663631847,-0.6187214337],\n\t\t\t\t[0.02446292583,0.9980232337,0.05788946549],\n\t\t\t\t[0.6184614336,-0.06060410764,0.7834746947]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.039205356],\n\t\t\t\t[155.8049723],\n\t\t\t\t[263.425936]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.126,0,368.359],\n\t\t\t\t[0,744.205,218.365],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306681,-0.0309893,-0.000506643,-0.000551257,0.209183],\n\t\t\t\"R\": [\n\t\t\t\t[0.7742934088,0.08491898973,-0.6271032469],\n\t\t\t\t[-0.02171436959,0.9939373135,0.1077826651],\n\t\t\t\t[0.6324541115,-0.06983825553,0.771443073]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.48615074],\n\t\t\t\t[146.2169272],\n\t\t\t\t[261.8070617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.439,0,363.854],\n\t\t\t\t[0,746.575,224.032],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333494,0.127943,0.00111227,0.000376509,-0.0438307],\n\t\t\t\"R\": [\n\t\t\t\t[0.7741360077,0.05745954338,-0.6304060933],\n\t\t\t\t[-0.01777243196,0.9974520988,0.06909016755],\n\t\t\t\t[0.6327697704,-0.04228133707,0.7731847814]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.18178238],\n\t\t\t\t[117.4047924],\n\t\t\t\t[265.0998909]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.824,0,346.505],\n\t\t\t\t[0,746.017,224.098],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317434,0.0247137,-0.000866957,0.000304145,0.138958],\n\t\t\t\"R\": [\n\t\t\t\t[0.7656627697,0.09930116127,-0.6355311184],\n\t\t\t\t[-0.04982185052,0.99419918,0.09531932471],\n\t\t\t\t[0.6413098365,-0.04131912178,0.7661686654]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[7.35512715],\n\t\t\t\t[111.8344509],\n\t\t\t\t[265.0127015]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.96,0,372.705],\n\t\t\t\t[0,744.564,226.392],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321978,0.0724692,0.000483988,0.000458946,0.0380169],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3520669355,0.03279886428,-0.9353999719],\n\t\t\t\t[0.04913052402,0.9986556534,0.01652505738],\n\t\t\t\t[0.9346844732,-0.04013876447,-0.3532050609]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[47.10128491],\n\t\t\t\t[117.3460549],\n\t\t\t\t[266.6541908]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[748.843,0,358.358],\n\t\t\t\t[0,748.813,225.018],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335266,0.148062,0.000634215,-0.00153008,-0.105518],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3389880085,0.04020239671,-0.9399313259],\n\t\t\t\t[0.04795713663,0.9985260662,0.02541275744],\n\t\t\t\t[0.9395675831,-0.03646179499,-0.3404163544]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[70.51461434],\n\t\t\t\t[125.984952],\n\t\t\t\t[266.5287049]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.557,0,370.525],\n\t\t\t\t[0,746.643,239.094],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336876,0.137869,0.0006954,0.000424607,-0.0538424],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3751735108,0.06869685522,-0.9244055273],\n\t\t\t\t[0.01802710881,0.9976021763,0.06682006625],\n\t\t\t\t[0.9267792942,0.008404759824,-0.3755123165]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[58.58769651],\n\t\t\t\t[133.6261971],\n\t\t\t\t[275.7276294]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.71,0,356.151],\n\t\t\t\t[0,744.769,223.97],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312604,0.00791514,0.000747313,-0.000519594,0.158336],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3438161676,0.01243889994,-0.9389545871],\n\t\t\t\t[0.0251972518,0.9996744288,0.00401683712],\n\t\t\t\t[0.9386988555,-0.02227802162,-0.344017657]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.26546697],\n\t\t\t\t[152.0702476],\n\t\t\t\t[270.0686857]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[743.927,0,355.392],\n\t\t\t\t[0,744.057,262.153],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316206,0.0381773,0.00109867,0.000112775,0.102099],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3913025917,0.04706716523,-0.9190576498],\n\t\t\t\t[0.07535158968,0.9969764632,0.0189755056],\n\t\t\t\t[0.9171719684,-0.0618272904,-0.3936660596]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.50168157],\n\t\t\t\t[183.5367771],\n\t\t\t\t[265.1462318]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.89,0,353.646],\n\t\t\t\t[0,744.816,246.705],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311434,-0.0151537,0.000898898,0.00113623,0.19919],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3540366423,0.02766248657,-0.9348223589],\n\t\t\t\t[0.06855079724,0.9976412764,0.003559761167],\n\t\t\t\t[0.9327158432,-0.06282253209,-0.3550978532]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[15.12228299],\n\t\t\t\t[191.0759947],\n\t\t\t\t[263.959739]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.21,0,382.066],\n\t\t\t\t[0,744.474,221.564],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318836,0.0439442,-0.000310088,0.000693195,0.0844966],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3784097731,0.01208936744,-0.9255592314],\n\t\t\t\t[0.03775536538,0.9992841689,-0.002383732641],\n\t\t\t\t[0.9248678695,-0.03584685469,-0.3785953341]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.73143391],\n\t\t\t\t[170.7040215],\n\t\t\t\t[268.2801795]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.996,0,378.911],\n\t\t\t\t[0,745.249,217.173],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317298,0.0439499,-0.000470842,0.000645598,0.0800391],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3573644405,-0.02168005213,-0.9337133564],\n\t\t\t\t[0.09030348924,0.9942444419,-0.05764780686],\n\t\t\t\t[0.9295891224,-0.1049188503,-0.3533498244]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.18764663],\n\t\t\t\t[193.5958696],\n\t\t\t\t[255.9258617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.488,0,367.703],\n\t\t\t\t[0,745.136,254.274],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333608,0.117291,0.00107107,0.000590786,-0.0167148],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3755971335,-0.01611847579,-0.9266428589],\n\t\t\t\t[0.03486308067,0.9988953473,-0.03150636014],\n\t\t\t\t[0.9261270749,-0.0441393233,-0.3746202894]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-52.11061688],\n\t\t\t\t[162.8813669],\n\t\t\t\t[265.66749]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.691,0,377.016],\n\t\t\t\t[0,746.35,247.895],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324348,0.0759263,0.000632098,0.000973799,0.0365142],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3979832561,-0.05264507275,-0.9158809007],\n\t\t\t\t[0.03842303812,0.9965195246,-0.07397639654],\n\t\t\t\t[0.9165876925,-0.06463229393,-0.3945753015]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-58.47639535],\n\t\t\t\t[144.7851801],\n\t\t\t\t[261.4908418]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.499,0,383.73],\n\t\t\t\t[0,743.269,228.607],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318101,0.0343673,-0.000192972,9.02677e-05,0.0940376],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3591156591,-0.0799459609,-0.9298626709],\n\t\t\t\t[0.01693912278,0.9956019804,-0.09213990831],\n\t\t\t\t[0.9331393302,-0.04883994185,-0.356182047]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-65.19666066],\n\t\t\t\t[124.1115675],\n\t\t\t\t[265.1913912]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.847,0,377.843],\n\t\t\t\t[0,744.539,240.133],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322594,0.0777366,0.000608553,0.000730506,0.0395492],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3599917326,-0.04959232233,-0.9316364924],\n\t\t\t\t[0.02914279324,0.9975011607,-0.0643593979],\n\t\t\t\t[0.9325002145,-0.05031934083,-0.3576469123]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.61171896],\n\t\t\t\t[105.5688064],\n\t\t\t\t[264.3974594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.264,0,386.065],\n\t\t\t\t[0,742.375,236.247],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316238,0.0182785,-0.000395794,0.00144239,0.136479],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3232019546,0.03338047233,-0.9457411066],\n\t\t\t\t[0.05161368011,0.9985119503,0.01760435083],\n\t\t\t\t[0.9449214383,-0.04312341834,-0.324443903]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.04698375],\n\t\t\t\t[97.35388185],\n\t\t\t\t[264.1973208]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.531,0,362.517],\n\t\t\t\t[0,744.694,222.936],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323155,0.0551,-0.000315217,0.00114443,0.0791805],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3124904102,0.02154150537,-0.9496766329],\n\t\t\t\t[-0.004629448499,0.999696432,0.02419942065],\n\t\t\t\t[0.9499096335,0.01195856595,-0.3122958229]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.02426098],\n\t\t\t\t[68.46079663],\n\t\t\t\t[270.3325449]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.429,0,398.562],\n\t\t\t\t[0,747.425,233.615],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333617,0.122405,0.000303778,0.00134383,-0.0202721],\n\t\t\t\"R\": [\n\t\t\t\t[-0.358025731,-0.0142572014,-0.9336028643],\n\t\t\t\t[0.04081564607,0.9986886699,-0.03090345813],\n\t\t\t\t[0.9328191995,-0.04916983726,-0.3569743242]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.683192747],\n\t\t\t\t[83.02873835],\n\t\t\t\t[264.4620974]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[742.757,0,357.304],\n\t\t\t\t[0,742.66,220.331],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305443,-0.0527047,-0.000521453,0.00022453,0.250047],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3364590891,0.05374146283,-0.9401633563],\n\t\t\t\t[0.05791647683,0.99766121,0.03630140184],\n\t\t\t\t[0.9399154021,-0.04223701264,-0.3387846981]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.062846],\n\t\t\t\t[91.33983095],\n\t\t\t\t[265.2581766]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[750.787,0,361.922],\n\t\t\t\t[0,750.723,216.611],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.368257,0.303211,-0.00101236,-0.000679192,-0.335284],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3521002367,0.0154136189,-0.9358353721],\n\t\t\t\t[0.04957845599,0.9987678018,-0.002203336065],\n\t\t\t\t[0.9346482761,-0.04717306796,-0.3524305629]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.75189895],\n\t\t\t\t[90.38015946],\n\t\t\t\t[265.2110414]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.69,0,366.196],\n\t\t\t\t[0,745.645,224.452],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325076,0.0695314,0.000207452,8.09151e-05,0.0569118],\n\t\t\t\"R\": [\n\t\t\t\t[-0.369329094,-0.008664471876,-0.929258278],\n\t\t\t\t[0.06369637747,0.997368813,-0.03461534879],\n\t\t\t\t[0.9271131494,-0.07197484145,-0.3678054246]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-35.28307581],\n\t\t\t\t[111.055802],\n\t\t\t\t[261.8818226]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.552,0,357.301],\n\t\t\t\t[0,745.545,223.113],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320101,0.042192,0.00043748,0.000103204,0.104558],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3584191226,-0.04877846794,-0.9322855752],\n\t\t\t\t[0.07086164718,0.9943315632,-0.07926770686],\n\t\t\t\t[0.9308675306,-0.09447435344,-0.3529309238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.14340371],\n\t\t\t\t[139.4376601],\n\t\t\t\t[259.6452388]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[746.078,0,363.03],\n\t\t\t\t[0,746.077,221.582],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321359,0.0569666,0.000169599,0.000938787,0.0797635],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3631410096,0.0448531679,-0.9306539639],\n\t\t\t\t[0.06634832184,0.9975497918,0.02218813063],\n\t\t\t\t[0.9293688758,-0.05368990856,-0.3652271709]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[21.37501917],\n\t\t\t\t[147.345749],\n\t\t\t\t[265.5705493]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.043,0,372.293],\n\t\t\t\t[0,745.076,222.901],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317484,0.0404748,0.000192535,-0.000111527,0.0957966],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3461967977,-0.005928135698,-0.9381431844],\n\t\t\t\t[0.04577092509,0.9986824948,-0.02320122706],\n\t\t\t\t[0.937044716,-0.05097187193,-0.3454693453]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.5259425122],\n\t\t\t\t[153.3372726],\n\t\t\t\t[265.7616305]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.252,0,401.788],\n\t\t\t\t[0,745.346,245.295],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315494,0.0267895,-0.000624877,0.000210937,0.0993279],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3267831921,-0.004575639121,-0.9450882546],\n\t\t\t\t[0.07739750703,0.9964998407,-0.03158628616],\n\t\t\t\t[0.9419248225,-0.08346934224,-0.3252852558]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.3938656],\n\t\t\t\t[148.3069178],\n\t\t\t\t[261.1183693]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[747.114,0,358.608],\n\t\t\t\t[0,746.941,217.398],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324507,0.0792141,-0.000227367,0.0013287,0.0357905],\n\t\t\t\"R\": [\n\t\t\t\t[-0.356358404,-0.03218270054,-0.9337949248],\n\t\t\t\t[0.02645826287,0.9986582749,-0.04451528213],\n\t\t\t\t[0.9339746507,-0.04056998648,-0.3550287707]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-18.04448695],\n\t\t\t\t[115.7023496],\n\t\t\t\t[266.3010308]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[747.28,0,383.407],\n\t\t\t\t[0,747.414,233.333],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321806,0.0494121,-0.000677773,0.00106862,0.0725344],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3696831614,0.01690678518,-0.9290040478],\n\t\t\t\t[0.03916078476,0.9992295361,0.002601362608],\n\t\t\t\t[0.9283322644,-0.03541884761,-0.3700604169]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.487638933],\n\t\t\t\t[110.8874693],\n\t\t\t\t[266.9764809]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[742.815,0,376.349],\n\t\t\t\t[0,742.96,226.412],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311242,0.000676611,0.00127048,0.000398816,0.145683],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9986287013,0.0334613179,0.04026235479],\n\t\t\t\t[0.03051664863,0.9969627365,-0.07165218936],\n\t\t\t\t[-0.04253764409,-0.07032526067,-0.99661673]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[47.87451164],\n\t\t\t\t[124.5257469],\n\t\t\t\t[265.3025885]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.352,0,362.211],\n\t\t\t\t[0,746.799,224.495],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.33354,0.113916,-0.000650978,0.00200875,0.00369896],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9978769066,0.0627015602,0.01761231284],\n\t\t\t\t[0.06225819076,0.9977547513,-0.02468550225],\n\t\t\t\t[-0.01912058832,-0.02353658189,-0.9995401105]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[76.18899734],\n\t\t\t\t[119.4504319],\n\t\t\t\t[269.470097]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.923,0,335.897],\n\t\t\t\t[0,744.843,232.622],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310786,-0.00740435,0.000477261,-0.00048183,0.169837],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9959217828,0.05942221639,0.06788816328],\n\t\t\t\t[0.05820019172,0.9981077555,-0.01984051806],\n\t\t\t\t[-0.06893866983,-0.0158085,-0.9974956397]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.6907282],\n\t\t\t\t[139.716188],\n\t\t\t\t[274.5941587]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.3,0,371.455],\n\t\t\t\t[0,745.339,223.979],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316788,0.039021,-0.00160053,-0.000126119,0.09467],\n\t\t\t\"R\": [\n\t\t\t\t[-0.995350133,0.07444232287,0.06112653567],\n\t\t\t\t[0.06997485872,0.994930028,-0.0722340534],\n\t\t\t\t[-0.06619389658,-0.06762085396,-0.9955128267]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[42.04206067],\n\t\t\t\t[161.4993909],\n\t\t\t\t[266.5642499]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[741.339,0,353.354],\n\t\t\t\t[0,741.563,231.192],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.304803,-0.0634451,-0.00114618,-0.000982934,0.282182],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9964181101,0.07478982294,0.03946431643],\n\t\t\t\t[0.07096423127,0.993341211,-0.09075966339],\n\t\t\t\t[-0.04598943103,-0.08763401739,-0.9950905744]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.56899486],\n\t\t\t\t[188.2245222],\n\t\t\t\t[262.1501617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.947,0,350.894],\n\t\t\t\t[0,746.217,234.332],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313212,0.0178381,0.000340441,0.00055626,0.126083],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9969018679,0.07865171151,0.0007576151751],\n\t\t\t\t[0.07854654264,0.9959829876,-0.04299219736],\n\t\t\t\t[-0.004135981729,-0.0427994938,-0.9990751208]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.2742824],\n\t\t\t\t[183.4195047],\n\t\t\t\t[270.0123608]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[748.821,0,355.822],\n\t\t\t\t[0,748.684,217.17],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.342444,0.16602,-0.000477836,-0.000195363,-0.106824],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9928808048,-0.04900785176,0.10856306],\n\t\t\t\t[-0.05236016128,0.998228751,-0.02824489671],\n\t\t\t\t[-0.106986546,-0.0337281951,-0.9936882247]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-31.49326377],\n\t\t\t\t[168.7489309],\n\t\t\t\t[271.4480177]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[747.238,0,359.034],\n\t\t\t\t[0,747.474,233.038],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313675,0.00436645,0.000419802,0.000604189,0.154068],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9913876468,0.02931278851,0.127637354],\n\t\t\t\t[0.0192008625,0.9966303068,-0.07974558542],\n\t\t\t\t[-0.1295448208,-0.07660804099,-0.9886098055]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-44.88902211],\n\t\t\t\t[188.5485089],\n\t\t\t\t[261.5304555]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[743.415,0,332.333],\n\t\t\t\t[0,743.715,235.337],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308464,-0.0208585,-0.00102455,0.000256502,0.207947],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9954977047,0.04566149696,0.08306231217],\n\t\t\t\t[0.04175753042,0.9979670543,-0.04814631117],\n\t\t\t\t[-0.08509188364,-0.04446106523,-0.9953806232]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.35184093],\n\t\t\t\t[166.6378451],\n\t\t\t\t[268.6077116]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.206,0,362.728],\n\t\t\t\t[0,747.412,248.496],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.340118,0.138855,0.000965068,4.5306e-05,-0.0441245],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9935175509,0.05252798067,0.1008151146],\n\t\t\t\t[0.05439486481,0.9983935823,0.01585728578],\n\t\t\t\t[-0.09982021218,0.02123831626,-0.9947787991]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.95074625],\n\t\t\t\t[127.5778656],\n\t\t\t\t[276.6370715]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.45,0,355.141],\n\t\t\t\t[0,745.641,249.232],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326245,0.10077,0.000216744,-2.37583e-05,-0.0259903],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9983050345,-0.001439505441,0.05818063101],\n\t\t\t\t[-0.002578079686,0.9998065462,-0.01949932386],\n\t\t\t\t[-0.05814130636,-0.01961626748,-0.9981156198]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-58.09544547],\n\t\t\t\t[121.7224759],\n\t\t\t\t[272.659258]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.805,0,368.42],\n\t\t\t\t[0,744.013,242.015],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323306,0.0785457,-0.00106293,0.000187763,0.0236672],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9954771119,0.0748660766,0.05848410323],\n\t\t\t\t[0.07512966129,0.9971710788,0.002318097681],\n\t\t\t\t[-0.05814510944,0.006701504052,-0.9982856485]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-47.8147621],\n\t\t\t\t[97.15541342],\n\t\t\t\t[274.4212668]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.693,0,353.966],\n\t\t\t\t[0,742.776,227.014],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307193,-0.0103139,0.000109263,-0.000950495,0.159317],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9933059489,0.1045971031,0.04901773034],\n\t\t\t\t[0.1016362638,0.9930442478,-0.05944065861],\n\t\t\t\t[-0.05489409585,-0.05406078084,-0.9970276176]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.5323637],\n\t\t\t\t[109.7713479],\n\t\t\t\t[268.3161895]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[742.837,0,362.248],\n\t\t\t\t[0,743.502,226.37],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308934,-0.00321353,-0.0010059,0.000705591,0.156528],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9919154966,0.0987006026,0.07976113456],\n\t\t\t\t[0.09553429302,0.9945144894,-0.04259259489],\n\t\t\t\t[-0.08352751879,-0.03462833131,-0.995903626]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.66946365],\n\t\t\t\t[84.06052642],\n\t\t\t\t[268.8728165]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[742.618,0,345.237],\n\t\t\t\t[0,742.923,230.439],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302695,-0.0546693,-0.000167537,-0.000784726,0.259585],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9885523252,0.1391044686,0.05843155954],\n\t\t\t\t[0.1381120085,0.9902000007,-0.02071308279],\n\t\t\t\t[-0.06074021267,-0.01240586611,-0.9980765106]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.26146274],\n\t\t\t\t[74.12977283],\n\t\t\t\t[271.0351679]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.088,0,370.473],\n\t\t\t\t[0,744.417,231.755],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.300902,-0.0664899,-0.000333311,0.000589361,0.253926],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9917390399,0.06178336486,0.1124121551],\n\t\t\t\t[0.06447509535,0.9977094298,0.02046596672],\n\t\t\t\t[-0.1108902109,0.02754468261,-0.9934508803]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.269853258],\n\t\t\t\t[73.62667861],\n\t\t\t\t[274.8694227]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.582,0,373.528],\n\t\t\t\t[0,745.86,237.254],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322134,0.0530706,-0.000603814,0.00101303,0.0846746],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9897330936,0.1313546283,0.05634150462],\n\t\t\t\t[0.1318000226,0.9912672261,0.00424742025],\n\t\t\t\t[-0.05529156869,0.01162962396,-0.9984025212]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.3391924],\n\t\t\t\t[70.20661568],\n\t\t\t\t[273.1392775]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[742.542,0,374.105],\n\t\t\t\t[0,742.758,223.273],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306762,-0.0452572,-0.00032402,-0.000364469,0.245651],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9920842372,0.1065981921,0.06637538524],\n\t\t\t\t[0.106818653,0.9942784937,-0.0002288198192],\n\t\t\t\t[-0.06602000984,0.006863120707,-0.9977946963]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[52.26513597],\n\t\t\t\t[79.91641464],\n\t\t\t\t[273.9509772]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[744.378,0,361.433],\n\t\t\t\t[0,744.589,244.618],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310422,-0.000364242,-0.000710118,0.000839407,0.169675],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9919054981,0.126974259,0.001010166835],\n\t\t\t\t[0.1269495258,0.9918188066,-0.01338927975],\n\t\t\t\t[-0.002701996339,-0.01315266,-0.9999098493]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[49.23489662],\n\t\t\t\t[110.9052228],\n\t\t\t\t[271.6142806]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.72,0,364.99],\n\t\t\t\t[0,745.913,248.461],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32476,0.0791445,0.000409065,0.000522525,0.0385155],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9808466558,0.1869185946,0.05478391053],\n\t\t\t\t[0.1851721888,0.9820671342,-0.03543168776],\n\t\t\t\t[-0.06042431929,-0.02460859583,-0.9978693896]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.23583817],\n\t\t\t\t[134.9359413],\n\t\t\t\t[272.7493911]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.966,0,347.023],\n\t\t\t\t[0,745.905,254.016],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312122,-0.0171046,0.00101358,-9.38575e-05,0.213424],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9944456328,0.07811965146,0.07053512206],\n\t\t\t\t[0.07435713108,0.9957422838,-0.0544823029],\n\t\t\t\t[-0.07449094204,-0.04893489886,-0.9960203187]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.247391851],\n\t\t\t\t[153.0572023],\n\t\t\t\t[268.8284628]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[743.607,0,364.935],\n\t\t\t\t[0,743.756,243.53],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311531,0.000696399,0.00010932,-0.000314324,0.159615],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9924188487,0.09367860135,0.07955594568],\n\t\t\t\t[0.08900119243,0.9941960017,-0.06044086279],\n\t\t\t\t[-0.0847562186,-0.05290207743,-0.9949963586]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.3150092],\n\t\t\t\t[142.5037842],\n\t\t\t\t[267.7211288]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[743.508,0,369.721],\n\t\t\t\t[0,743.449,243.575],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309744,-0.0191119,0.000292611,0.000847107,0.198605],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9987856124,0.03694807636,0.03259049098],\n\t\t\t\t[0.03470669556,0.9971594314,-0.06684694127],\n\t\t\t\t[-0.03496778135,-0.06563465492,-0.997230839]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.799650163],\n\t\t\t\t[123.3743131],\n\t\t\t\t[267.1549958]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[742.775,0,379.613],\n\t\t\t\t[0,742.864,224.449],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316586,0.0333112,-0.000180777,0.00112675,0.112087],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9947573056,0.06853183176,0.07590316848],\n\t\t\t\t[0.05765365411,0.9888586451,-0.1372393391],\n\t\t\t\t[-0.08446276764,-0.1321437401,-0.9876254719]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.340029177],\n\t\t\t\t[136.5307812],\n\t\t\t\t[258.2193706]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.267,0,367.511],\n\t\t\t\t[0,745.253,228.976],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316421,0.0232694,0.000233523,0.00095017,0.129164],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2595515744,0.03264633198,0.965177288],\n\t\t\t\t[-0.02439656235,0.9988878376,-0.04034718866],\n\t\t\t\t[-0.9654210418,-0.03401918423,-0.2584664527]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[43.91564589],\n\t\t\t\t[114.6472759],\n\t\t\t\t[269.2437955]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.737,0,383.621],\n\t\t\t\t[0,746.553,234.139],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330711,0.126048,0.000259954,-0.000232797,-0.067441],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2600597375,0.03354081135,0.965009817],\n\t\t\t\t[-0.06475754991,0.9965406566,-0.05208818886],\n\t\t\t\t[-0.9634185968,-0.07603771211,-0.2569880808]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[63.03617994],\n\t\t\t\t[136.0112472],\n\t\t\t\t[264.2112923]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[748.567,0,371.842],\n\t\t\t\t[0,748.646,223.378],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332561,0.132401,-0.000978802,0.0010132,-0.0596871],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2517963519,0.03200567411,0.967250864],\n\t\t\t\t[0.0115205721,0.9994813079,-0.03007310314],\n\t\t\t\t[-0.9677116686,0.003570985655,-0.2520344708]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[55.32226207],\n\t\t\t\t[135.5872215],\n\t\t\t\t[276.5287505]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.412,0,375.731],\n\t\t\t\t[0,747.545,213.638],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324984,0.0823763,-0.00190711,0.0010176,0.0382164],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2864406942,-0.001302983566,0.9580970885],\n\t\t\t\t[-0.1193951903,0.9922525608,-0.03434594761],\n\t\t\t\t[-0.9506295373,-0.1242302613,-0.2843770823]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.5108683],\n\t\t\t\t[178.4576708],\n\t\t\t\t[254.9563649]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[747.818,0,377.646],\n\t\t\t\t[0,748.63,232.294],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327048,0.100477,-0.00250563,-0.000951363,0.00505748],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2682590325,-0.01756457816,0.9631866782],\n\t\t\t\t[-0.1175373506,0.9929607203,-0.014628026],\n\t\t\t\t[-0.9561496027,-0.1171345104,-0.2684351761]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[28.10870602],\n\t\t\t\t[198.6254244],\n\t\t\t\t[256.0861594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.281,0,376.164],\n\t\t\t\t[0,744.733,212.764],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314115,0.0261091,-0.00186017,0.000146826,0.111047],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2995512244,0.02650351378,0.9537120256],\n\t\t\t\t[-0.1164678133,0.9911222418,-0.06412449085],\n\t\t\t\t[-0.9469447251,-0.1302853239,-0.2938050747]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.38602287],\n\t\t\t\t[207.7342285],\n\t\t\t\t[252.6787249]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.844,0,367.199],\n\t\t\t\t[0,744.885,234.874],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307447,-0.0235368,-0.000447762,-0.000552595,0.198481],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2246138655,-0.03605175288,0.9737807158],\n\t\t\t\t[-0.1345418425,0.9908917963,0.005651603877],\n\t\t\t\t[-0.965115073,-0.1297448231,-0.2274185059]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.57828512],\n\t\t\t\t[193.807989],\n\t\t\t\t[253.6581871]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.265,0,373.297],\n\t\t\t\t[0,745.204,222.406],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322725,0.0753011,-0.00198414,9.48962e-05,0.0496562],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2740281164,0.007089557403,0.9616955493],\n\t\t\t\t[-0.08615117171,0.9957715968,-0.0318889104],\n\t\t\t\t[-0.9578551911,-0.09158965645,-0.2722586413]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.40184383],\n\t\t\t\t[190.6520913],\n\t\t\t\t[261.5790911]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[743.742,0,376.404],\n\t\t\t\t[0,743.442,252.182],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310951,0.0101818,-0.000165117,0.000699519,0.141452],\n\t\t\t\"R\": [\n\t\t\t\t[-0.234740558,-0.05401621619,0.9705560874],\n\t\t\t\t[-0.06709368181,0.9969740023,0.03925909634],\n\t\t\t\t[-0.9697398147,-0.05590247913,-0.2376543804]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-60.89112675],\n\t\t\t\t[163.1020008],\n\t\t\t\t[266.420435]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.237,0,381.452],\n\t\t\t\t[0,745.998,235.104],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321635,0.0804606,-0.000793429,0.000500703,0.0308776],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2327490461,-0.03063038999,0.9720543507],\n\t\t\t\t[-0.1073579574,0.9942045343,0.005622535858],\n\t\t\t\t[-0.9665930636,-0.1030491297,-0.2346885731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-52.7687065],\n\t\t\t\t[155.650502],\n\t\t\t\t[258.7092289]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.465,0,352.406],\n\t\t\t\t[0,744.368,231.635],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307896,-0.0267024,-0.00138959,-0.000489454,0.213952],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2568719183,-0.003646201445,0.9664385768],\n\t\t\t\t[-0.06909534804,0.997503196,-0.01460160774],\n\t\t\t\t[-0.9639723287,-0.07052715282,-0.256482495]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-58.11810551],\n\t\t\t\t[133.8270577],\n\t\t\t\t[264.378006]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.557,0,351.376],\n\t\t\t\t[0,744.424,216.683],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317479,0.0158652,-0.000659121,-0.00059258,0.147681],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2372383683,-0.02274879941,0.9711850744],\n\t\t\t\t[-0.1004253449,0.9949438408,-0.001226302928],\n\t\t\t\t[-0.9662467111,-0.09782252214,-0.2383234094]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.35654103],\n\t\t\t\t[118.4734964],\n\t\t\t\t[259.8400796]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[743.07,0,377.102],\n\t\t\t\t[0,743.158,222.988],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.29868,-0.0827266,-0.00133003,-0.00119832,0.273178],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2367527853,-0.03686088138,0.9708704311],\n\t\t\t\t[-0.08746956632,0.9960307636,0.01648614259],\n\t\t\t\t[-0.9676245107,-0.08101847538,-0.2390372628]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.43038274],\n\t\t\t\t[111.3831569],\n\t\t\t\t[262.4188123]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.597,0,372.306],\n\t\t\t\t[0,745.414,237.499],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320131,0.0615197,0.00113665,-0.000991542,0.0414761],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2769894269,0.05383368349,0.9593637433],\n\t\t\t\t[-0.05406721308,0.9959742516,-0.07149843787],\n\t\t\t\t[-0.9593506105,-0.07167443526,-0.2729636999]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.49417033],\n\t\t\t\t[90.7530727],\n\t\t\t\t[264.2254974]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.296,0,380.788],\n\t\t\t\t[0,746.161,226.883],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321885,0.0553182,0.000132369,-0.000878491,0.0778662],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2870302882,0.01079685294,0.9578606588],\n\t\t\t\t[-0.05665486447,0.9979947406,-0.02822630231],\n\t\t\t\t[-0.9562446549,-0.06236926949,-0.2858430237]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.106709776],\n\t\t\t\t[85.82297146],\n\t\t\t\t[264.8070963]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.119,0,345.288],\n\t\t\t\t[0,744.112,227.607],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302547,-0.0664079,0.000893953,-0.000627784,0.303861],\n\t\t\t\"R\": [\n\t\t\t\t[-0.252548592,0.05539030986,0.9659974753],\n\t\t\t\t[-0.08640189331,0.9930807476,-0.07953201617],\n\t\t\t\t[-0.963718798,-0.1035497095,-0.2460153169]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[10.51473419],\n\t\t\t\t[107.4721829],\n\t\t\t\t[260.872486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.831,0,353.784],\n\t\t\t\t[0,745.87,219.754],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321082,0.0599511,-0.000750204,0.000386726,0.0615888],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3124433364,0.0857084176,0.9460619582],\n\t\t\t\t[-0.03834810703,0.9939715084,-0.1027135007],\n\t\t\t\t[-0.9491620432,-0.06837183409,-0.3072730188]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.17882687],\n\t\t\t\t[91.39390134],\n\t\t\t\t[262.9120903]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.227,0,385.13],\n\t\t\t\t[0,745.129,233.897],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311291,0.0180828,0.00116452,0.000576614,0.0928398],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2786751196,0.05379991941,0.9588773365],\n\t\t\t\t[-0.03740853519,0.9970639104,-0.06681437094],\n\t\t\t\t[-0.9596565944,-0.0544896994,-0.2758443282]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.04086511],\n\t\t\t\t[98.35557378],\n\t\t\t\t[265.4113916]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.424,0,373.724],\n\t\t\t\t[0,746.378,215.089],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317589,0.0452179,0.000839363,0.00087423,0.0858828],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2053627335,-0.023863444,0.9783949528],\n\t\t\t\t[-0.1366627843,0.9906072975,-0.004523879826],\n\t\t\t\t[-0.9690972248,-0.1346392148,-0.2066950671]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.454839771],\n\t\t\t\t[148.020868],\n\t\t\t\t[256.5149472]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.35,0,378.361],\n\t\t\t\t[0,744.386,245.706],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305792,-0.0298413,-5.26611e-05,9.57392e-05,0.206854],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2653224987,0.04663873586,0.9630310483],\n\t\t\t\t[-0.08123292055,0.9941966424,-0.07052835541],\n\t\t\t\t[-0.9607315881,-0.09694258412,-0.2599941366]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.42848118],\n\t\t\t\t[157.616994],\n\t\t\t\t[260.7931406]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[747.371,0,368.768],\n\t\t\t\t[0,747.344,231.897],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308946,-0.0139041,-0.000755627,-0.000244894,0.190547],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2375675449,-0.01520768023,0.9712519694],\n\t\t\t\t[-0.09352440886,0.9955903179,-0.007287238765],\n\t\t\t\t[-0.966858235,-0.09256697771,-0.2379422368]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.76210059],\n\t\t\t\t[163.3748289],\n\t\t\t\t[261.1782343]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[746.314,0,371.788],\n\t\t\t\t[0,745.992,237.732],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315167,0.0352154,-0.000828301,0.000312219,0.0891012],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2145858088,0.0004599306573,0.9767050318],\n\t\t\t\t[-0.07749764501,0.9968390076,-0.017495939],\n\t\t\t\t[-0.9736257216,-0.07944672006,-0.2138718611]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-33.0373727],\n\t\t\t\t[146.3668194],\n\t\t\t\t[262.1626174]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.318,0,371.868],\n\t\t\t\t[0,746.096,236.531],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318459,0.0405311,0.000489761,-0.000285822,0.0876741],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2554085937,0.004734611177,0.9668216142],\n\t\t\t\t[-0.07039835709,0.9972425561,-0.02348096154],\n\t\t\t\t[-0.9642668311,-0.0740598926,-0.25437101]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-17.40671779],\n\t\t\t\t[124.2252344],\n\t\t\t\t[264.0602836]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.832,0,382.965],\n\t\t\t\t[0,745.816,231.317],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320385,0.0446211,0.00028801,0.00167617,0.104376],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2362773498,-0.02089730322,0.9714609188],\n\t\t\t\t[-0.1013714927,0.9948433166,-0.003255144035],\n\t\t\t\t[-0.9663833786,-0.09924756028,-0.2371773332]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.093436327],\n\t\t\t\t[126.6662443],\n\t\t\t\t[260.9183094]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_00\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 0,\n\t\t\t\"K\": [\n\t\t\t\t[1634.03,0,942.792],\n\t\t\t\t[0,1629.73,558.29],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.222445,0.199192,8.73054e-05,0.000982243,0.0238445],\n\t\t\t\"R\": [\n\t\t\t\t[0.1369296663,0.03357591931,-0.9900115778],\n\t\t\t\t[-0.09021094677,0.9956950625,0.02129149064],\n\t\t\t\t[0.9864645212,0.08639444504,0.1393691081]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.90028135],\n\t\t\t\t[127.2202879],\n\t\t\t\t[283.1159034]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_01\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[1395.91,0,951.559],\n\t\t\t\t[0,1392.24,561.398],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286227,0.183082,-4.29815e-05,0.000644874,-0.0479635],\n\t\t\t\"R\": [\n\t\t\t\t[0.05337497606,0.02479711619,0.9982666052],\n\t\t\t\t[0.6376765256,0.7684660834,-0.05318390075],\n\t\t\t\t[-0.7684528356,0.6394098699,0.0252043199]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.299256813],\n\t\t\t\t[104.397182],\n\t\t\t\t[363.078698]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_02\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[1397.02,0,939.355],\n\t\t\t\t[0,1394.04,556.611],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.28229,0.173658,-0.000610716,0.000955319,-0.0398628],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9970491806,0.05290586318,-0.05562284625],\n\t\t\t\t[-0.01182874156,0.6100448884,0.792278559],\n\t\t\t\t[0.07584861407,0.7905986364,-0.6076189463]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.22360931],\n\t\t\t\t[63.30660163],\n\t\t\t\t[381.0181823]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_03\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[1395.71,0,949.456],\n\t\t\t\t[0,1392.06,566.648],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.281728,0.168097,-0.00021431,1.8072e-05,-0.0371786],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6216465312,-0.0285781748,0.7827763909],\n\t\t\t\t[0.07448493547,0.9926490654,0.09539301533],\n\t\t\t\t[-0.7797484111,0.117605786,-0.6149482047]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.50346059],\n\t\t\t\t[117.4297203],\n\t\t\t\t[290.1984382]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_04\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[1633.26,0,949.479],\n\t\t\t\t[0,1629.32,572.374],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.223003,0.185095,-0.000261654,0.00109433,0.0657602],\n\t\t\t\"R\": [\n\t\t\t\t[-0.5292732399,-0.01229259603,0.8483623811],\n\t\t\t\t[0.636650989,0.6551966806,0.4066851706],\n\t\t\t\t[-0.5608434325,0.7553583268,-0.3389519765]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.411400695],\n\t\t\t\t[80.12176746],\n\t\t\t\t[379.8488129]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_05\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[1396.29,0,933.34],\n\t\t\t\t[0,1392.95,560.462],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.28733,0.185523,-0.000225825,-0.000143128,-0.0508452],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9314658579,-0.01073438439,-0.363670357],\n\t\t\t\t[-0.021313424,0.9994579907,0.02508909603],\n\t\t\t\t[0.3632039283,0.03112069687,-0.9311897813]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.050515741],\n\t\t\t\t[143.9213951],\n\t\t\t\t[280.3813532]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_06\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[1396.11,0,950.228],\n\t\t\t\t[0,1392.54,548.78],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286481,0.183173,-0.000152555,0.0010664,-0.0482263],\n\t\t\t\"R\": [\n\t\t\t\t[0.9448241112,-0.04876703013,-0.3239277321],\n\t\t\t\t[-0.2141569626,0.6563150135,-0.7234551806],\n\t\t\t\t[0.2478793944,0.7529092773,0.6096584503]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.023614],\n\t\t\t\t[84.45695974],\n\t\t\t\t[376.925635]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_07\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[1395.51,0,947.67],\n\t\t\t\t[0,1392.41,549.081],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286691,0.185163,-6.53256e-05,4.32858e-06,-0.052639],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9419632708,-0.03700247277,0.3336705164],\n\t\t\t\t[0.180351898,0.7825307202,0.5959185052],\n\t\t\t\t[-0.2831578878,0.6215114552,-0.7304417305]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.250326149],\n\t\t\t\t[112.5645453],\n\t\t\t\t[360.2387508]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_08\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[1642.7,0,945.082],\n\t\t\t\t[0,1638.64,562.465],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.22444,0.208938,-0.000569838,0.000484927,0.0287248],\n\t\t\t\"R\": [\n\t\t\t\t[0.9544726119,0.01685383959,-0.2978220632],\n\t\t\t\t[-0.03362017317,0.9981191009,-0.05126347965],\n\t\t\t\t[0.2963979035,0.05894241665,0.9532439742]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.67808464],\n\t\t\t\t[136.6798831],\n\t\t\t\t[282.6801175]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_09\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[1396.79,0,945.482],\n\t\t\t\t[0,1393.03,542.64],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.284259,0.175176,-0.000406823,0.000640552,-0.0406716],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3169419478,-0.08460972789,0.9446634298],\n\t\t\t\t[-0.1243350249,0.9911238917,0.04705563528],\n\t\t\t\t[-0.9402598595,-0.1025408464,-0.3246486894]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.780958613],\n\t\t\t\t[147.0057696],\n\t\t\t\t[260.6395044]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_10\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[1393.87,0,944.546],\n\t\t\t\t[0,1390.36,563.199],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.285353,0.177704,-0.000109708,0.000471392,-0.0432146],\n\t\t\t\"R\": [\n\t\t\t\t[0.9503475669,0.04849461332,0.3073886376],\n\t\t\t\t[0.1560494297,0.7803459045,-0.6055648973],\n\t\t\t\t[-0.2692360999,0.6234649483,0.734032275]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.71992555],\n\t\t\t\t[112.7759402],\n\t\t\t\t[360.0009328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_11\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[1492.96,0,934.544],\n\t\t\t\t[0,1489.74,547.466],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.259288,0.190057,-5.50625e-05,0.00031915,-0.0281283],\n\t\t\t\"R\": [\n\t\t\t\t[0.8129763959,0.04080422416,-0.5808652124],\n\t\t\t\t[-0.2848486357,0.8979062573,-0.3355973896],\n\t\t\t\t[0.5078687177,0.4382914196,0.7415996205]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.03199165418],\n\t\t\t\t[105.1487628],\n\t\t\t\t[331.4862369]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_12\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[1395.93,0,964.611],\n\t\t\t\t[0,1392.67,564.875],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.290995,0.19463,-0.000241491,0.000727782,-0.0582663],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9950957343,0.04321912909,-0.08897520145],\n\t\t\t\t[-0.001969290489,0.8906636271,0.454658581],\n\t\t\t\t[0.09889692354,0.4526040326,-0.886210465]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.66653867],\n\t\t\t\t[97.49188585],\n\t\t\t\t[334.8897626]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_13\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[1592.21,0,937.375],\n\t\t\t\t[0,1588.39,560.919],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.239248,0.229218,0.000137317,0.000315934,-0.0358302],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2862766934,0.07452649614,-0.9552441867],\n\t\t\t\t[-0.7557457469,0.5952786327,0.2729317047],\n\t\t\t\t[0.588977097,0.8000557173,-0.1140913162]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.47943966],\n\t\t\t\t[60.20818768],\n\t\t\t\t[381.0821849]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_14\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[1649.51,0,934.882],\n\t\t\t\t[0,1644.85,568.024],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.22365,0.220791,-0.000591343,0.000286172,0.0121962],\n\t\t\t\"R\": [\n\t\t\t\t[0.827339054,-0.07848137689,0.5561930989],\n\t\t\t\t[0.02005408661,0.9936867625,0.110383204],\n\t\t\t\t[-0.5613447456,-0.08017039095,0.8236897383]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.23447972],\n\t\t\t\t[142.1657406],\n\t\t\t\t[267.9541185]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_15\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[1430.11,0,948.926],\n\t\t\t\t[0,1426.48,561.705],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.277948,0.185701,0.000192514,0.000149713,-0.0424254],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9997414125,0.006454955712,0.02180462522],\n\t\t\t\t[0.005192647027,0.9983342904,-0.05746025644],\n\t\t\t\t[-0.02213920846,-0.05733217422,-0.9981096519]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.642162177],\n\t\t\t\t[134.9258555],\n\t\t\t\t[268.2324221]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_16\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[1427.34,0,949.618],\n\t\t\t\t[0,1423.13,548.132],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.279453,0.188683,-0.000345265,0.000583475,-0.0479414],\n\t\t\t\"R\": [\n\t\t\t\t[0.7694875517,0.002369830201,0.6386574134],\n\t\t\t\t[0.2539259376,0.9164213706,-0.3093436433],\n\t\t\t\t[-0.586012394,0.4002077652,0.7045730755]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.866150988],\n\t\t\t\t[118.1652356],\n\t\t\t\t[330.6340665]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_17\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[1393.35,0,916.395],\n\t\t\t\t[0,1390.34,563.652],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.287138,0.186145,7.50854e-05,0.000557424,-0.0513205],\n\t\t\t\"R\": [\n\t\t\t\t[0.5039250676,0.09465184024,-0.8585456047],\n\t\t\t\t[-0.6050310345,0.7480627966,-0.2726527087],\n\t\t\t\t[0.6164389455,0.6568432701,0.4342348962]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.2296155],\n\t\t\t\t[97.71531857],\n\t\t\t\t[361.6667015]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_18\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[1542.2,0,947.567],\n\t\t\t\t[0,1538.02,555.168],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.245751,0.182006,3.81269e-06,0.000651097,0.00472657],\n\t\t\t\"R\": [\n\t\t\t\t[-0.4048875531,-0.001022756131,0.9143659133],\n\t\t\t\t[0.3656410889,0.9163838146,0.1629334173],\n\t\t\t\t[-0.8380767647,0.4002994608,-0.3706584387]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.25260358],\n\t\t\t\t[116.7586119],\n\t\t\t\t[329.7529305]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_19\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[1396.57,0,949.242],\n\t\t\t\t[0,1393.19,554.872],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.280864,0.167216,-6.6519e-05,0.000917406,-0.0342733],\n\t\t\t\"R\": [\n\t\t\t\t[0.7360342296,0.009501079563,0.6768776421],\n\t\t\t\t[0.5173282683,0.6370082142,-0.5714822813],\n\t\t\t\t[-0.4366063167,0.7707984591,0.4639446731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.15514071],\n\t\t\t\t[74.04862943],\n\t\t\t\t[379.5076537]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_20\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[1403.46,0,940.386],\n\t\t\t\t[0,1400.1,552.684],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.287177,0.194004,-0.000120001,8.41526e-05,-0.0604614],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6201222217,0.04052054618,-0.7834580496],\n\t\t\t\t[-0.1302964194,0.9794749929,0.1537907063],\n\t\t\t\t[0.773609251,0.1974508131,-0.6021145267]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.4496252],\n\t\t\t\t[140.6900046],\n\t\t\t\t[300.8290806]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_21\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[1397.56,0,932.828],\n\t\t\t\t[0,1393.91,562.186],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.28642,0.185674,-0.000229601,1.91211e-05,-0.052608],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2617478675,-0.05032313647,-0.9638234464],\n\t\t\t\t[-0.4532392419,0.8880813121,0.07671878938],\n\t\t\t\t[0.8520928608,0.4569235877,-0.2552618099]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.784671236],\n\t\t\t\t[98.11062797],\n\t\t\t\t[332.9193692]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_22\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[1514.1,0,945.861],\n\t\t\t\t[0,1510.18,558.694],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.260535,0.216046,-0.000156491,0.000677315,-0.0506741],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9239818557,-0.0613765916,0.3774790647],\n\t\t\t\t[0.05486070575,0.9555572213,0.289656175],\n\t\t\t\t[-0.3784809549,0.288345818,-0.8795503715]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.224239691],\n\t\t\t\t[110.7456244],\n\t\t\t\t[313.8855054]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_23\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[1572.86,0,941.716],\n\t\t\t\t[0,1568.17,560.048],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.240801,0.195963,-0.000444179,0.000458513,0.00455186],\n\t\t\t\"R\": [\n\t\t\t\t[0.5162966551,0.01335424781,0.856305686],\n\t\t\t\t[0.1418829708,0.9847272537,-0.100903213],\n\t\t\t\t[-0.8445750331,0.173591186,0.506516647]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.417701344],\n\t\t\t\t[102.3557555],\n\t\t\t\t[298.3746617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_24\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[1399.63,0,954.539],\n\t\t\t\t[0,1396.27,546.388],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.288761,0.190789,4.23479e-05,6.78832e-05,-0.0577764],\n\t\t\t\"R\": [\n\t\t\t\t[-0.388991142,-0.05987834367,-0.9192934653],\n\t\t\t\t[0.02928793432,0.9965772059,-0.07730517199],\n\t\t\t\t[0.9207758187,-0.05699523376,-0.3859059924]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.12220678],\n\t\t\t\t[134.1751339],\n\t\t\t\t[265.239245]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_25\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 25,\n\t\t\t\"K\": [\n\t\t\t\t[1397.66,0,935.585],\n\t\t\t\t[0,1394.65,559.251],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.285722,0.183994,-0.000502702,0.000494145,-0.0515729],\n\t\t\t\"R\": [\n\t\t\t\t[0.7926422733,0.00130484237,-0.6096855943],\n\t\t\t\t[0.04487405742,0.9971605675,0.06047414042],\n\t\t\t\t[0.6080333424,-0.07529342651,0.7903330655]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.539475053],\n\t\t\t\t[139.2223569],\n\t\t\t\t[261.6293171]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_26\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 26,\n\t\t\t\"K\": [\n\t\t\t\t[1616.8,0,950.116],\n\t\t\t\t[0,1613.47,551.417],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.223464,0.185279,-0.00090721,0.000127112,0.0351947],\n\t\t\t\"R\": [\n\t\t\t\t[-0.7556190155,-0.04350579001,-0.6535649545],\n\t\t\t\t[0.1389994774,0.9644159151,-0.2249023966],\n\t\t\t\t[0.6400930001,-0.2607857146,-0.7226837222]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.5475419],\n\t\t\t\t[141.1612209],\n\t\t\t\t[240.8579734]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_27\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 27,\n\t\t\t\"K\": [\n\t\t\t\t[1861.86,0,934.556],\n\t\t\t\t[0,1857.26,552.106],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.171511,0.209759,-1.83176e-05,-3.41566e-05,0.211418],\n\t\t\t\"R\": [\n\t\t\t\t[0.9782876177,0.02697940456,0.2054883178],\n\t\t\t\t[0.02691509764,0.9665557486,-0.2550403151],\n\t\t\t\t[-0.2054967507,0.2550335204,0.9448433674]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.5131666478],\n\t\t\t\t[123.4498457],\n\t\t\t\t[311.6401591]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_28\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 28,\n\t\t\t\"K\": [\n\t\t\t\t[1395.57,0,953.143],\n\t\t\t\t[0,1392.36,561.982],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.284934,0.181016,0.000127361,0.000271191,-0.0471616],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6310677524,-0.02949081954,-0.775166939],\n\t\t\t\t[-0.5128354354,0.7656140117,0.3883748207],\n\t\t\t\t[0.5820251782,0.6426238999,-0.4982782509]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.508070023],\n\t\t\t\t[104.2896072],\n\t\t\t\t[361.3816814]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_29\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 29,\n\t\t\t\"K\": [\n\t\t\t\t[1400.36,0,939.608],\n\t\t\t\t[0,1397.25,572.603],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286109,0.1878,-0.000309515,0.000886248,-0.0523515],\n\t\t\t\"R\": [\n\t\t\t\t[0.4887300705,-0.07268882749,-0.8694016635],\n\t\t\t\t[-0.08227020668,0.9882426049,-0.1288726774],\n\t\t\t\t[0.8685473685,0.1345098073,0.4770037531]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.72850042],\n\t\t\t\t[158.8912224],\n\t\t\t\t[289.281465]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_30\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 30,\n\t\t\t\"K\": [\n\t\t\t\t[1407.21,0,946.883],\n\t\t\t\t[0,1403.86,563.032],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.285813,0.195568,-0.000394067,0.000468367,-0.0600751],\n\t\t\t\"R\": [\n\t\t\t\t[0.08635045426,0.06174190292,0.9943498059],\n\t\t\t\t[0.2147800801,0.9734543185,-0.07909618832],\n\t\t\t\t[-0.9728376618,0.2203965227,0.07079729175]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.79078928],\n\t\t\t\t[132.1300437],\n\t\t\t\t[306.0754676]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_01\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[1053.92,0,947.294],\n\t\t\t\t[0,1054.32,535.405],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0476403,-0.053786,0.000733314,-0.000579648,0.0122759],\n\t\t\t\"R\": [\n\t\t\t\t[0.9095307192,0.0006254166507,-0.4156362348],\n\t\t\t\t[-0.003349684277,0.999977422,-0.0058253781],\n\t\t\t\t[0.4156232073,0.006690610494,0.9095122788]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.84850815],\n\t\t\t\t[103.1392168],\n\t\t\t\t[269.3362326]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_02\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[1058.92,0,971.224],\n\t\t\t\t[0,1059.3,541.276],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0485216,-0.0529886,-0.000413578,-0.000171659,0.00909728],\n\t\t\t\"R\": [\n\t\t\t\t[-0.08404700998,-0.006825065684,-0.9964384169],\n\t\t\t\t[-0.04073006897,0.9991643735,-0.003408260769],\n\t\t\t\t[0.9956290281,0.04029855131,-0.08425476347]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.246538185],\n\t\t\t\t[93.69672118],\n\t\t\t\t[271.0169727]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_03\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[1050.35,0,971.069],\n\t\t\t\t[0,1050.88,535.343],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0482196,-0.0555053,0.000460862,0.000594278,0.0128034],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9791929995,-0.0009192386581,-0.2029291126],\n\t\t\t\t[0.004325206908,0.9996680429,-0.02539875018],\n\t\t\t\t[0.2028850964,-0.02574798878,-0.9788639736]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.71273011],\n\t\t\t\t[112.0293664],\n\t\t\t\t[269.2258843]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_04\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[1053.76,0,952.563],\n\t\t\t\t[0,1053.62,535.073],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0534802,-0.059505,0.000265754,-0.00038559,0.0128987],\n\t\t\t\"R\": [\n\t\t\t\t[-0.4973721867,-0.01252789009,0.8674468052],\n\t\t\t\t[-0.05725964091,0.9981894693,-0.01841512904],\n\t\t\t\t[-0.8656455634,-0.05882886558,-0.4971890215]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.12207689],\n\t\t\t\t[119.639642],\n\t\t\t\t[263.8142799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_05\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[1061.53,0,963.346],\n\t\t\t\t[0,1061.99,535.689],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0450742,-0.0483577,0.000117724,0.00131017,0.00746483],\n\t\t\t\"R\": [\n\t\t\t\t[0.6332975321,0.02789684006,0.7734054578],\n\t\t\t\t[-0.04440403331,0.9990136015,0.0003253688515],\n\t\t\t\t[-0.772633495,-0.034548377,0.6339115806]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.398197962],\n\t\t\t\t[114.449943],\n\t\t\t\t[269.0646085]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_06\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[1053.8,0,975.87],\n\t\t\t\t[0,1054.44,518.546],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0608578,-0.0758877,0.000572907,0.000423304,0.0232485],\n\t\t\t\"R\": [\n\t\t\t\t[0.9936973916,-0.01776547634,0.1106791841],\n\t\t\t\t[0.08238304881,0.7853099766,-0.6135969963],\n\t\t\t\t[-0.07601662453,0.6188478234,0.7818240495]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.36095562],\n\t\t\t\t[58.01362542],\n\t\t\t\t[350.0526212]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_07\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[1058.37,0,951.456],\n\t\t\t\t[0,1058.06,537.752],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0510704,-0.0625189,-0.000144014,6.68608e-05,0.016463],\n\t\t\t\"R\": [\n\t\t\t\t[0.4325769754,-0.03234243573,-0.9010167186],\n\t\t\t\t[-0.4868424381,0.832758343,-0.2636247005],\n\t\t\t\t[0.7588554545,0.5526911516,0.344486415]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.0385587],\n\t\t\t\t[87.13576568],\n\t\t\t\t[341.2560709]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_08\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[1051.92,0,937.937],\n\t\t\t\t[0,1051.86,554.246],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0499863,-0.0613843,-4.12419e-05,-0.000155211,0.0174279],\n\t\t\t\"R\": [\n\t\t\t\t[-0.7043873056,-0.07078753835,-0.7062773168],\n\t\t\t\t[-0.4398115151,0.8245196459,0.3559960458],\n\t\t\t\t[0.5571394394,0.5613879923,-0.6119143463]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.03532832],\n\t\t\t\t[82.26745729],\n\t\t\t\t[344.5100871]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_09\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[1054,0,961.563],\n\t\t\t\t[0,1054.08,544.179],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0446773,-0.0530941,0.000226286,-0.000324258,0.0121913],\n\t\t\t\"R\": [\n\t\t\t\t[-0.8728623151,-0.0989156561,0.4778358211],\n\t\t\t\t[0.2068965126,0.8118396582,0.5459946908],\n\t\t\t\t[-0.4419334927,0.5754407548,-0.6881589393]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-36.30074608],\n\t\t\t\t[73.0041962],\n\t\t\t\t[346.5857858]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_10\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[1050.04,0,941.59],\n\t\t\t\t[0,1050.6,559.398],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0506861,-0.0636966,0.000195295,-6.41025e-06,0.0181857],\n\t\t\t\"R\": [\n\t\t\t\t[0.1849149694,0.002001709126,0.9827524852],\n\t\t\t\t[0.5894867579,0.7998990427,-0.1125472514],\n\t\t\t\t[-0.786328059,0.6001312479,0.146733326]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.26435316],\n\t\t\t\t[64.88453925],\n\t\t\t\t[349.5293231]\n\t\t\t]\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "tests/data/panoptic_body3d/160906_band1/hdPose3d_stage1_coco19/body3DScene_00000168.json",
    "content": "{ \"version\": 0.7, \r\n\"univTime\" :47896.621,\r\n\"fpsType\" :\"hd_29_97\",\r\n\"bodies\" :\r\n[\r\n{ \"id\": 0,\r\n\"joints19\": [124.136, -105.991, -30.2854, 0.709717, 104.413, -117.401, -25.8053, 0.686829, 127.045, -63.7183, -29.9739, 0.446899, 120.248, -106.955, -45.6063, 0.575806, 111.254, -82.5488, -60.3606, 0.579651, 97.5534, -67.5661, -41.9563, 0.475403, 124.375, -63.6942, -41.0662, 0.417236, 83.4269, -47.7217, -38.6838, 0.203247, 0, 0, 0, -1, 128.266, -105.85, -14.7877, 0.602417, 127.309, -81.7486, 0.513331, 0.651978, 111.735, -70.4044, -14.4066, 0.506653, 129.716, -63.7424, -18.8814, 0.444885, 96.4134, -42.8902, 0.798849, 0.232483, 69.8839, -9.69057, 2.89286, 0.157349, 104.805, -121.062, -29.0914, 0.532288, 112.683, -122.17, -35.3427, 0.396851, 106.05, -121.316, -23.1694, 0.572449, 115.614, -122.634, -20.4819, 0.516724]\r\n},\r\n{ \"id\": 1,\r\n\"joints19\": [5.6087, -91.7251, 5.67075, 0.482361, 9.08691, -85.5182, -11.6583, 0.199097, 1.66692, -67.5066, 46.3826, 0.227905, 19.3811, -92.0237, 9.78557, 0.396667, 16.9647, -71.8503, 24.8387, 0.320435, 12.7281, -59.21, 8.82053, 0.295654, 9.3541, -67.7975, 46.523, 0.236145, 18.8347, -41.2812, 16.8548, 0.281738, 12.0261, -7.27261, 26.7646, 0.333557, -7.55927, -92.2895, 3.18333, 0.382874, -27.683, -73.6808, 6.9749, 0.261841, -13.6486, -60.4171, 9.29562, 0.138, -6.02027, -67.2158, 46.2422, 0.18158, -16.8764, -40.5201, 19.3464, 0.276733, -8.86912, -6.4542, 26.0121, 0.28595, 9.95262, -88.5757, -11.2162, 0.143005, 13.9014, -94.8183, -5.44828, 0.313904, 4.81003, -88.1194, -11.7807, 0.144226, -0.772542, -94.5733, -6.32695, 0.250549]\r\n},\r\n{ \"id\": 2,\r\n\"joints19\": [-46.623, -91.9748, -46.2094, 0.432495, -24.8662, -90.1627, -46.21, 0.392395, -75.3649, -54.9062, -38.0726, 0.157349, -43.6166, -91.045, -29.2171, 0.349304, -39.1777, -59.7671, -26.5732, 0.293274, -27.2637, -45.0868, -41.3075, 0.192017, -74.8994, -55.0912, -27.8377, 0.165894, -31.1378, -46.3092, -19.0025, 0.293518, -55.7049, -13.0915, -25.5646, 0.224976, -48.6966, -91.4388, -65.3742, 0.311768, -41.5079, -71.8104, -84.3137, 0.330261, -38.8408, -64.6871, -61.4434, 0.23877, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, -24.2805, -94.9466, -43.9519, 0.356812, -31.8517, -101.665, -40.2811, 0.385071, -24.9661, -93.5623, -49.2523, 0.2229, -31.0232, -98.0451, -55.4795, 0.279053]\r\n}\r\n] }"
  },
  {
    "path": "tests/data/panoptic_body3d/160906_band1/hdPose3d_stage1_coco19/body3DScene_00000169.json",
    "content": "{ \"version\": 0.7, \r\n\"univTime\" :47929.977,\r\n\"fpsType\" :\"hd_29_97\",\r\n\"bodies\" :\r\n[\r\n{ \"id\": 0,\r\n\"joints19\": [124.147, -105.973, -30.3072, 0.709717, 104.374, -117.36, -25.733, 0.686829, 127.183, -63.4893, -30.0803, 0.446899, 120.073, -106.823, -45.7773, 0.575806, 111.752, -82.4054, -59.6925, 0.579651, 98.0636, -68.2993, -41.7845, 0.475403, 124.546, -63.5584, -41.3032, 0.417236, 82.7474, -47.6873, -38.9817, 0.203247, 0, 0, 0, -1, 128.539, -105.963, -14.9304, 0.602417, 127.104, -81.4156, 0.247136, 0.651978, 111.693, -68.1563, -14.442, 0.506653, 129.82, -63.4201, -18.8574, 0.444885, 96.2478, -42.7821, 0.805848, 0.232483, 69.9732, -9.8122, 2.74933, 0.157349, 104.724, -121.033, -28.9868, 0.532288, 112.609, -122.205, -35.2695, 0.396851, 105.982, -121.283, -23.115, 0.572449, 115.59, -122.596, -20.5341, 0.516724]\r\n},\r\n{ \"id\": 1,\r\n\"joints19\": [5.04299, -94.3889, 5.11889, 0.482361, 7.96533, -87.0756, -12.5883, 0.199097, 1.01761, -67.6827, 45.8372, 0.227905, 18.8279, -94.4092, 9.16816, 0.396667, 16.9833, -73.798, 24.051, 0.320435, 13.7023, -60.619, 8.29119, 0.295654, 9.38785, -67.9091, 45.5134, 0.236145, 18.7713, -41.7337, 15.9782, 0.281738, 12.1838, -7.47727, 26.3543, 0.333557, -8.15184, -94.0344, 2.74916, 0.382874, -27.5733, -74.6123, 6.71778, 0.261841, -11.5391, -62.3807, 6.49904, 0.138, -7.35263, -67.4562, 46.1611, 0.18158, -16.292, -40.381, 19.0151, 0.276733, -8.81955, -6.61585, 25.9785, 0.28595, 9.40427, -90.5736, -11.3424, 0.143005, 13.4035, -96.5672, -5.99329, 0.313904, 3.80369, -90.1657, -12.6569, 0.144226, -1.05309, -95.823, -6.96162, 0.250549]\r\n},\r\n{ \"id\": 2,\r\n\"joints19\": [-47.6019, -93.4704, -46.6587, 0.432495, -26.2199, -91.5537, -46.2747, 0.392395, -75.3649, -54.9062, -38.0726, 0.157349, -44.5263, -91.3939, -29.3512, 0.349304, -40.4455, -62.5189, -26.2502, 0.293274, -28.7968, -47.0727, -40.3408, 0.192017, -75.2261, -55.2629, -28.1895, 0.165894, -31.459, -46.5397, -18.7491, 0.293518, -55.7543, -13.1495, -25.2371, 0.224976, -50.2673, -93.2394, -65.8827, 0.311768, -41.5254, -72.5218, -84.4612, 0.330261, -38.9596, -65.8381, -61.5105, 0.23877, 0, 0, 0, -1, 0, 0, 0, -1, 0, 0, 0, -1, -25.5114, -96.8998, -43.1621, 0.356812, -33.2547, -102.681, -40.4011, 0.385071, -26.3223, -94.9484, -49.0802, 0.2229, -32.1236, -99.3278, -55.4444, 0.279053]\r\n}\r\n] }"
  },
  {
    "path": "tests/data/panoptic_body3d/160906_band2/calibration_160906_band2.json",
    "content": "{\n\t\"calibDataSource\": \"160906_calib_norm\",\n\t\"cameras\": [\n\t\t{\n\t\t\t\"name\": \"01_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.698,0,375.512],\n\t\t\t\t[0,745.89,226.023],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324009,0.0732398,-0.000601245,0.000808154,0.0311011],\n\t\t\t\"R\": [\n\t\t\t\t[0.9609979695,0.02878724306,-0.2750530807],\n\t\t\t\t[-0.05024448072,0.9961896773,-0.07128547526],\n\t\t\t\t[0.2719529274,0.08232509619,0.9587826572]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-51.56945892],\n\t\t\t\t[143.9587601],\n\t\t\t\t[282.5664691]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[745.462,0,369.225],\n\t\t\t\t[0,745.627,226.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336594,0.141798,-0.000612176,0.000160485,-0.0646767],\n\t\t\t\"R\": [\n\t\t\t\t[0.9715220842,-0.01574832828,-0.2364251047],\n\t\t\t\t[0.005323209906,0.998987679,-0.04466856407],\n\t\t\t\t[0.2368892218,0.042137956,0.9706224236]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-66.22242206],\n\t\t\t\t[142.1317177],\n\t\t\t\t[278.6626087]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.261,0,378.952],\n\t\t\t\t[0,746.496,239.595],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322069,0.0440329,-0.000951664,0.000892653,0.103376],\n\t\t\t\"R\": [\n\t\t\t\t[0.9665011873,0.05534363601,-0.2506242943],\n\t\t\t\t[-0.07024277085,0.996230894,-0.05089164033],\n\t\t\t\t[0.2468631364,0.06679137568,0.9667458322]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-54.75524211],\n\t\t\t\t[118.3584455],\n\t\t\t\t[281.78809]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.661,0,366.929],\n\t\t\t\t[0,747.759,234.022],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32333,0.0462607,-0.000972333,-0.000898261,0.102804],\n\t\t\t\"R\": [\n\t\t\t\t[0.9662588837,0.08601234823,-0.2427872436],\n\t\t\t\t[-0.1112831564,0.9894890375,-0.09234448444],\n\t\t\t\t[0.23229255,0.1162468093,0.9656742984]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.08626445],\n\t\t\t\t[96.75744843],\n\t\t\t\t[287.7183779]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[742.413,0,353.224],\n\t\t\t\t[0,742.622,209.478],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.297729,-0.0985766,-0.000505185,-0.000773418,0.328727],\n\t\t\t\"R\": [\n\t\t\t\t[0.9718071292,0.05098345905,-0.2301990238],\n\t\t\t\t[-0.07271497659,0.9935575811,-0.0869244798],\n\t\t\t\t[0.2242842746,0.1012127458,0.9692536016]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-26.91018729],\n\t\t\t\t[77.97642882],\n\t\t\t\t[285.7140393]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[743.487,0,372.277],\n\t\t\t\t[0,743.725,241.821],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317534,0.0281748,0.00130284,-0.000186889,0.119129],\n\t\t\t\"R\": [\n\t\t\t\t[0.9681278444,0.07458666466,-0.2390926732],\n\t\t\t\t[-0.09383510211,0.9931135585,-0.07014580141],\n\t\t\t\t[0.2322142341,0.09034538891,0.968459736]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.038020326],\n\t\t\t\t[73.51221006],\n\t\t\t\t[284.7303027]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[748.393,0,380.919],\n\t\t\t\t[0,748.388,229.353],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.344193,0.174813,-0.00034307,0.00107023,-0.0968505],\n\t\t\t\"R\": [\n\t\t\t\t[0.9670535143,-0.02995409712,-0.2528047715],\n\t\t\t\t[0.01712365053,0.9984582116,-0.0528013286],\n\t\t\t\t[0.2539966162,0.04673276982,0.9660754459]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.52170598],\n\t\t\t\t[98.55800179],\n\t\t\t\t[280.6705064]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.37,0,362.362],\n\t\t\t\t[0,745.56,217.483],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326014,0.0789588,-0.000462463,-0.00138061,0.0222432],\n\t\t\t\"R\": [\n\t\t\t\t[0.9652282485,0.06485174985,-0.2532364089],\n\t\t\t\t[-0.07898708824,0.9958116468,-0.0460456736],\n\t\t\t\t[0.2491896228,0.06444699145,0.9663079826]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.28384049],\n\t\t\t\t[86.2200762],\n\t\t\t\t[282.8912643]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.037,0,338.236],\n\t\t\t\t[0,746.053,236.859],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314486,0.0395532,0.000625849,-0.000232478,0.0599275],\n\t\t\t\"R\": [\n\t\t\t\t[0.9656569777,0.07278005487,-0.2494186543],\n\t\t\t\t[-0.09030273149,0.9941334749,-0.05953193019],\n\t\t\t\t[0.2436226964,0.08001060955,0.9665641645]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.35508632],\n\t\t\t\t[94.7965848],\n\t\t\t\t[284.0947744]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.938,0,379.271],\n\t\t\t\t[0,748.269,227.432],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3484,0.205218,-0.00110069,0.000562921,-0.151344],\n\t\t\t\"R\": [\n\t\t\t\t[0.9662738854,-0.001312373382,-0.2575132151],\n\t\t\t\t[-0.009587322107,0.9991104143,-0.04106657164],\n\t\t\t\t[0.2573380297,0.04215041788,0.9654017199]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.05861189],\n\t\t\t\t[130.0028668],\n\t\t\t\t[279.9552314]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[746.12,0,364.693],\n\t\t\t\t[0,745.844,223.621],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335335,0.119703,0.000192218,0.00118296,-0.00812072],\n\t\t\t\"R\": [\n\t\t\t\t[0.9869891455,-0.01212212734,-0.1603292883],\n\t\t\t\t[0.00355647539,0.9985558958,-0.05360479805],\n\t\t\t\t[0.1607475603,0.05233714665,0.9856069424]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[71.07099717],\n\t\t\t\t[142.6182462],\n\t\t\t\t[275.3539702]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.407,0,358.691],\n\t\t\t\t[0,745.503,226.329],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325389,0.0923962,-0.00061832,-0.00189678,-0.0159561],\n\t\t\t\"R\": [\n\t\t\t\t[0.9589650047,0.08538224277,-0.2703627054],\n\t\t\t\t[-0.09708669181,0.9948178626,-0.03019262438],\n\t\t\t\t[0.2663837347,0.05520229083,0.9622849957]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[54.63033668],\n\t\t\t\t[157.9150468],\n\t\t\t\t[281.9236261]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.389,0,339.442],\n\t\t\t\t[0,744.512,216.258],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320138,0.0543285,-0.000196977,-0.00116274,0.0473598],\n\t\t\t\"R\": [\n\t\t\t\t[0.9724830194,-0.06319437739,-0.2242392645],\n\t\t\t\t[0.03959405574,0.9933373951,-0.1082272161],\n\t\t\t\t[0.2295845984,0.09637058799,0.9685058709]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[19.90234626],\n\t\t\t\t[154.6647449],\n\t\t\t\t[286.7518211]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[746.213,0,363.165],\n\t\t\t\t[0,746.641,235.418],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.33414,0.127633,-0.000792357,0.000136075,-0.0405619],\n\t\t\t\"R\": [\n\t\t\t\t[0.9643490552,0.006836134333,-0.2645452079],\n\t\t\t\t[-0.02440508255,0.9977035557,-0.06318233054],\n\t\t\t\t[0.2635057717,0.0673860684,0.9623013177]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[19.24633902],\n\t\t\t\t[182.0747755],\n\t\t\t\t[282.9928946]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.225,0,366.568],\n\t\t\t\t[0,745.569,216.05],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319743,0.046174,-0.00158438,-0.000953331,0.0743504],\n\t\t\t\"R\": [\n\t\t\t\t[0.9602661069,0.03565913048,-0.2767985376],\n\t\t\t\t[-0.06162250151,0.9944158624,-0.08567239854],\n\t\t\t\t[0.2721978533,0.09932531892,0.9571012536]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[0.9330302863],\n\t\t\t\t[174.5612072],\n\t\t\t\t[288.1067574]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.633,0,371.752],\n\t\t\t\t[0,747.88,230.613],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.347758,0.198029,0.00072103,0.00029865,-0.136932],\n\t\t\t\"R\": [\n\t\t\t\t[0.9682573711,0.05614690975,-0.2435676248],\n\t\t\t\t[-0.07153002565,0.9959334273,-0.05477283913],\n\t\t\t\t[0.2395018137,0.07045660367,0.968336072]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.74774],\n\t\t\t\t[172.5737662],\n\t\t\t\t[282.7618788]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[748.152,0,373.9],\n\t\t\t\t[0,748.508,234.452],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.345127,0.177692,-0.00116897,0.00210199,-0.0818461],\n\t\t\t\"R\": [\n\t\t\t\t[0.9639501783,0.02458774974,-0.264944327],\n\t\t\t\t[-0.04477053879,0.9965129817,-0.07040934697],\n\t\t\t\t[0.2622892538,0.07973280283,0.9616896732]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-36.08309916],\n\t\t\t\t[173.4726636],\n\t\t\t\t[283.4522322]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[743.791,0,363.617],\n\t\t\t\t[0,744.126,236.963],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312734,0.0122172,-0.00120247,-0.000963953,0.133944],\n\t\t\t\"R\": [\n\t\t\t\t[0.9523198878,0.06045552763,-0.2990517689],\n\t\t\t\t[-0.07234112338,0.9969633514,-0.02882425707],\n\t\t\t\t[0.2964010681,0.04908365416,0.9538014478]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.80984395],\n\t\t\t\t[175.8598769],\n\t\t\t\t[275.2458542]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.162,0,364.748],\n\t\t\t\t[0,743.331,220.785],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311505,0.00290054,-0.000860754,-0.000437091,0.146397],\n\t\t\t\"R\": [\n\t\t\t\t[0.9677776267,0.05243241618,-0.246287042],\n\t\t\t\t[-0.06515666231,0.9969134625,-0.04379677618],\n\t\t\t\t[0.243230497,0.05843278173,0.968206866]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.88792012],\n\t\t\t\t[144.796335],\n\t\t\t\t[280.8929426]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.661,0,343.237],\n\t\t\t\t[0,744.907,246.044],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326994,0.0904776,0.000984855,-0.00107766,-0.0214165],\n\t\t\t\"R\": [\n\t\t\t\t[0.9717064093,0.03462931454,-0.2336396043],\n\t\t\t\t[-0.0436324388,0.998486683,-0.03347468014],\n\t\t\t\t[0.2321268283,0.04272182698,0.9717468709]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.15244103],\n\t\t\t\t[127.7778149],\n\t\t\t\t[279.5122056]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[742.462,0,365.246],\n\t\t\t\t[0,742.468,221.387],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311193,-0.0017069,-0.0010044,-5.33063e-05,0.168374],\n\t\t\t\"R\": [\n\t\t\t\t[0.9650420793,0.04068979072,-0.2589172188],\n\t\t\t\t[-0.04945049005,0.9984003719,-0.02741069744],\n\t\t\t\t[0.257387712,0.03925605981,0.965510501]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.672862451],\n\t\t\t\t[122.1992626],\n\t\t\t\t[279.1232554]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.021,0,363.587],\n\t\t\t\t[0,744.301,226.764],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330855,0.115198,-0.00111581,-0.000578883,-0.0257811],\n\t\t\t\"R\": [\n\t\t\t\t[0.9624230562,-0.007741542698,-0.2714441553],\n\t\t\t\t[-0.003557050749,0.9991484058,-0.04110730506],\n\t\t\t\t[0.271531229,0.0405281588,0.9615759252]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.289641778],\n\t\t\t\t[135.1743597],\n\t\t\t\t[279.2863723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[745.029,0,358.645],\n\t\t\t\t[0,745.162,224.101],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31925,0.0412999,-0.000788365,0.000625647,0.108146],\n\t\t\t\"R\": [\n\t\t\t\t[0.9553340738,0.01211961015,-0.2952793973],\n\t\t\t\t[-0.03701510886,0.9961975848,-0.07886858543],\n\t\t\t\t[0.293200766,0.08627564605,0.9521501057]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-2.968489269],\n\t\t\t\t[143.230855],\n\t\t\t\t[285.3382881]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"01_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 1,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.501,0,369.38],\n\t\t\t\t[0,744.575,244.409],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317214,0.0306635,-5.65201e-05,-0.000305408,0.106933],\n\t\t\t\"R\": [\n\t\t\t\t[0.9627375442,0.05351140442,-0.2650904574],\n\t\t\t\t[-0.07422624073,0.9948691584,-0.06874462026],\n\t\t\t\t[0.2600516991,0.08585969499,0.9617698408]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.333655278],\n\t\t\t\t[148.0612654],\n\t\t\t\t[284.8699573]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[746.79,0,376.022],\n\t\t\t\t[0,747.048,234.17],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317408,0.0301922,-0.000108969,-0.00027109,0.105931],\n\t\t\t\"R\": [\n\t\t\t\t[0.977473966,0.04697618088,0.2057617172],\n\t\t\t\t[0.001487552662,0.9733575223,-0.2292878562],\n\t\t\t\t[-0.211050783,0.2244289915,0.9513617581]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.729507611],\n\t\t\t\t[175.3460492],\n\t\t\t\t[304.9109171]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.689,0,367.065],\n\t\t\t\t[0,747.811,212.158],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333664,0.117162,0.000577725,-0.000310896,-0.0327554],\n\t\t\t\"R\": [\n\t\t\t\t[0.9812751339,-0.05714257326,0.183939767],\n\t\t\t\t[0.09271495859,0.9771941455,-0.1910380552],\n\t\t\t\t[-0.1688284573,0.2045148611,0.9641942873]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-50.62568249],\n\t\t\t\t[190.9654762],\n\t\t\t\t[299.6250374]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[745.627,0,353.486],\n\t\t\t\t[0,745.817,252.683],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321416,0.0392112,-0.00107045,-0.00134198,0.0908854],\n\t\t\t\"R\": [\n\t\t\t\t[0.9757098845,0.1270834984,0.1784376802],\n\t\t\t\t[-0.07601456941,0.9603325594,-0.2682967771],\n\t\t\t\t[-0.2054556071,0.248215954,0.946666168]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.13649132],\n\t\t\t\t[169.3490841],\n\t\t\t\t[309.2380875]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[746.11,0,381.584],\n\t\t\t\t[0,746.321,224.917],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323963,0.0585021,-0.000871966,0.000552522,0.0715102],\n\t\t\t\"R\": [\n\t\t\t\t[0.979331342,0.07410153523,0.1881995881],\n\t\t\t\t[-0.02608477747,0.9689731658,-0.2457856551],\n\t\t\t\t[-0.2005734451,0.2357964511,0.950878713]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.63906075],\n\t\t\t\t[150.8763932],\n\t\t\t\t[306.9317958]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.11,0,378.377],\n\t\t\t\t[0,744.035,244.823],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323078,0.0494134,-0.000238923,-0.000981516,0.0727453],\n\t\t\t\"R\": [\n\t\t\t\t[0.9857440106,0.05652749171,0.1584720428],\n\t\t\t\t[-0.01525193411,0.9680163878,-0.250422945],\n\t\t\t\t[-0.1675593154,0.244435913,0.95507851]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.3494258],\n\t\t\t\t[135.8190029],\n\t\t\t\t[306.0165552]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[743.928,0,352.844],\n\t\t\t\t[0,744.181,228.627],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303908,-0.0528673,-0.000528541,8.08764e-05,0.267531],\n\t\t\t\"R\": [\n\t\t\t\t[0.9814194485,0.06212733968,0.1815380393],\n\t\t\t\t[-0.0101664424,0.9616367605,-0.2741375282],\n\t\t\t\t[-0.1916050874,0.2671983057,0.9444006332]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.86742917],\n\t\t\t\t[106.6702196],\n\t\t\t\t[310.2214119]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.501,0,376.178],\n\t\t\t\t[0,746.591,217.394],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323449,0.0621904,-0.000592526,0.000355354,0.0689781],\n\t\t\t\"R\": [\n\t\t\t\t[0.9775323693,0.09704954661,0.1871145437],\n\t\t\t\t[-0.05094527723,0.9701636443,-0.2370381445],\n\t\t\t\t[-0.2045361721,0.2221798567,0.9533105819]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.21830655],\n\t\t\t\t[111.2122483],\n\t\t\t\t[305.8578091]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[747.056,0,346.722],\n\t\t\t\t[0,747.425,231.954],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331626,0.0978711,0.000923123,-0.00170198,0.0128988],\n\t\t\t\"R\": [\n\t\t\t\t[0.9738310577,0.04398424166,0.222976361],\n\t\t\t\t[0.006459505741,0.9753414162,-0.2206068824],\n\t\t\t\t[-0.2271813062,0.2162741507,0.9495336465]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.1615402],\n\t\t\t\t[89.62617671],\n\t\t\t\t[306.715437]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.084,0,344.827],\n\t\t\t\t[0,746.456,222.936],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31385,0.00765504,0.000335804,0.000338293,0.157318],\n\t\t\t\"R\": [\n\t\t\t\t[0.9708044988,0.02558390192,0.2385038556],\n\t\t\t\t[0.01777728087,0.9838878899,-0.1779005014],\n\t\t\t\t[-0.2392124442,0.1769465571,0.9547079776]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.622489705],\n\t\t\t\t[92.86686988],\n\t\t\t\t[302.6276511]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.875,0,345.16],\n\t\t\t\t[0,744.131,231.932],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309364,-0.0158069,0.000435688,-0.000318284,0.167974],\n\t\t\t\"R\": [\n\t\t\t\t[0.9837217555,0.04774800386,0.1732386674],\n\t\t\t\t[-0.008457215477,0.9752859506,-0.220784488],\n\t\t\t\t[-0.179499257,0.2157253874,0.9598138226]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[0.6070589451],\n\t\t\t\t[94.58504844],\n\t\t\t\t[305.3954199]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[748.642,0,372.727],\n\t\t\t\t[0,749.029,221.349],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329743,0.0894243,0.000705225,0.000452301,0.0255748],\n\t\t\t\"R\": [\n\t\t\t\t[0.9762818677,-0.03993432779,0.2127885436],\n\t\t\t\t[0.08495434643,0.9746762651,-0.20685487],\n\t\t\t\t[-0.1991393328,0.2200259705,0.9549513592]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.17502224],\n\t\t\t\t[86.30258496],\n\t\t\t\t[305.899008]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.297,0,386.393],\n\t\t\t\t[0,746.341,223.432],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329805,0.088881,-0.000101498,-0.000342857,0.0238941],\n\t\t\t\"R\": [\n\t\t\t\t[0.9769251111,-0.05225372472,0.2070914666],\n\t\t\t\t[0.09392861168,0.9759243238,-0.1968479875],\n\t\t\t\t[-0.1918195589,0.211757556,0.9583130982]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.97904484],\n\t\t\t\t[101.8192368],\n\t\t\t\t[305.2554798]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[746.887,0,386.903],\n\t\t\t\t[0,746.77,241.912],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330222,0.0894843,0.000608161,-0.000202457,0.0188277],\n\t\t\t\"R\": [\n\t\t\t\t[0.9805035597,0.07291108666,0.1824739514],\n\t\t\t\t[-0.03359954242,0.9771464723,-0.2098948364],\n\t\t\t\t[-0.1936074385,0.199671593,0.9605453736]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.8755561],\n\t\t\t\t[121.0360498],\n\t\t\t\t[302.8306622]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.399,0,359.381],\n\t\t\t\t[0,745.103,221.453],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32351,0.0564367,0.000553752,0.000358328,0.0789504],\n\t\t\t\"R\": [\n\t\t\t\t[0.9639890244,-0.01369700088,0.2655890681],\n\t\t\t\t[0.06651808592,0.9793475216,-0.1909287203],\n\t\t\t\t[-0.2574888447,0.2017196672,0.9449913601]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[64.66924198],\n\t\t\t\t[136.2834945],\n\t\t\t\t[299.1868513]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.343,0,376.035],\n\t\t\t\t[0,746.136,233.449],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332319,0.10939,0.000552685,0.00121175,-0.00685584],\n\t\t\t\"R\": [\n\t\t\t\t[0.9739293667,-0.02993852249,0.2248672353],\n\t\t\t\t[0.07982373372,0.9730868608,-0.2161715356],\n\t\t\t\t[-0.2123434957,0.2284855491,0.9501076748]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.67937397],\n\t\t\t\t[146.9667487],\n\t\t\t\t[305.3208703]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.983,0,369.069],\n\t\t\t\t[0,747.865,212.357],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333814,0.119177,-0.00123283,0.000206724,-0.0313224],\n\t\t\t\"R\": [\n\t\t\t\t[0.9828420813,0.01261378295,0.1840172159],\n\t\t\t\t[0.03080156014,0.9724259604,-0.2311688027],\n\t\t\t\t[-0.181859031,0.2328704445,0.9553526307]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.33056427],\n\t\t\t\t[154.6384713],\n\t\t\t\t[307.0242051]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[743.255,0,372.405],\n\t\t\t\t[0,743.629,259.514],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.301911,-0.0577323,-0.000292445,-0.000537705,0.240913],\n\t\t\t\"R\": [\n\t\t\t\t[0.9702237144,0.05425789408,0.2360551311],\n\t\t\t\t[-0.004184220731,0.978195713,-0.2076430576],\n\t\t\t\t[-0.2421743923,0.2004725119,0.9492957051]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.95715372],\n\t\t\t\t[182.9757461],\n\t\t\t\t[299.4720725]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[746.171,0,380.016],\n\t\t\t\t[0,746.628,215.7],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310416,0.0111871,-0.00156578,-0.000885002,0.110566],\n\t\t\t\"R\": [\n\t\t\t\t[0.9751942313,0.01121985931,0.2210663386],\n\t\t\t\t[0.02134458651,0.9892938663,-0.1443677759],\n\t\t\t\t[-0.220319359,0.1455051918,0.9645141882]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.159436194],\n\t\t\t\t[213.6293599],\n\t\t\t\t[288.3403437]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.09,0,380.114],\n\t\t\t\t[0,745.176,232.983],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31746,0.043353,-0.000108725,0.000220738,0.0862213],\n\t\t\t\"R\": [\n\t\t\t\t[0.9809185988,0.05584586521,0.1862255137],\n\t\t\t\t[-0.01423917048,0.975920974,-0.2176591338],\n\t\t\t\t[-0.1938967473,0.2108541957,0.9580942331]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.989355998],\n\t\t\t\t[159.4183424],\n\t\t\t\t[303.0216832]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[746.359,0,393.165],\n\t\t\t\t[0,746.438,228.007],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32236,0.0673245,-0.000115957,0.00130444,0.0588071],\n\t\t\t\"R\": [\n\t\t\t\t[0.9826018096,0.03015545669,0.1832602856],\n\t\t\t\t[0.01576123022,0.9696317731,-0.2440610748],\n\t\t\t\t[-0.1850547688,0.2427032613,0.9522866477]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-25.36954265],\n\t\t\t\t[136.7143691],\n\t\t\t\t[307.7149997]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[747.137,0,358.509],\n\t\t\t\t[0,747.202,238.678],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327929,0.0852816,0.000460613,0.000357406,0.0365027],\n\t\t\t\"R\": [\n\t\t\t\t[0.9780966382,0.08951991601,0.1879179366],\n\t\t\t\t[-0.04045439222,0.9673344336,-0.2502549415],\n\t\t\t\t[-0.2041822921,0.2371714111,0.9497680314]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.00427836],\n\t\t\t\t[118.005594],\n\t\t\t\t[307.3165834]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.847,0,374.568],\n\t\t\t\t[0,746.074,247.807],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32052,0.063252,0.000743322,-0.000945252,0.0534877],\n\t\t\t\"R\": [\n\t\t\t\t[0.9839840132,0.07804627455,0.160263036],\n\t\t\t\t[-0.03749054936,0.9695570383,-0.2419785283],\n\t\t\t\t[-0.1742696772,0.2320946541,0.9569546233]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.458572059],\n\t\t\t\t[110.2636917],\n\t\t\t\t[306.6072245]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.851,0,375.128],\n\t\t\t\t[0,744.899,236.672],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328747,0.0731957,0.000409854,0.000115616,0.0573405],\n\t\t\t\"R\": [\n\t\t\t\t[0.9798731388,0.006836815724,0.1995041098],\n\t\t\t\t[0.04188111895,0.9701291749,-0.2389463451],\n\t\t\t\t[-0.1951783896,0.2424925605,0.9503171862]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.92766978],\n\t\t\t\t[118.8861106],\n\t\t\t\t[308.0337581]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"02_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 2,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[748.108,0,365.63],\n\t\t\t\t[0,748.409,236.546],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337502,0.145226,-9.99404e-05,-0.000712599,-0.0768278],\n\t\t\t\"R\": [\n\t\t\t\t[0.9858983234,-0.01937546959,0.166219996],\n\t\t\t\t[0.057736328,0.9716683618,-0.2291879382],\n\t\t\t\t[-0.1570700873,0.2355529362,0.9590848773]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.69779309],\n\t\t\t\t[141.0775615],\n\t\t\t\t[307.1963385]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.205,0,364.445],\n\t\t\t\t[0,745.671,223.278],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321278,0.0550501,-0.000663141,0.000431329,0.0680735],\n\t\t\t\"R\": [\n\t\t\t\t[0.789168654,0.1464091436,-0.5964706181],\n\t\t\t\t[-0.3274382264,0.921936374,-0.2069239719],\n\t\t\t\t[0.5196123973,0.3586051937,0.7755032377]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.48720347],\n\t\t\t\t[106.8731646],\n\t\t\t\t[321.197831]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.402,0,367.989],\n\t\t\t\t[0,746.656,218.884],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319108,0.0415571,-0.000289565,0.00121415,0.0978966],\n\t\t\t\"R\": [\n\t\t\t\t[0.7844411333,0.123213727,-0.6078408392],\n\t\t\t\t[-0.3461950886,0.9001611021,-0.2643084389],\n\t\t\t\t[0.5145882519,0.4177659246,0.7487793823]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-25.69855827],\n\t\t\t\t[65.19717944],\n\t\t\t\t[326.035328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[747.999,0,350.415],\n\t\t\t\t[0,748.222,213.374],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322361,0.0444301,-0.000132478,-4.14576e-05,0.110213],\n\t\t\t\"R\": [\n\t\t\t\t[0.8075592295,0.0617799019,-0.5865418439],\n\t\t\t\t[-0.2672496857,0.9248714179,-0.2705373648],\n\t\t\t\t[0.525762015,0.3752280693,0.763399109]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.799326732],\n\t\t\t\t[72.40249706],\n\t\t\t\t[323.1224723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.819,0,376.394],\n\t\t\t\t[0,744.912,212.894],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335892,0.121706,-0.00015411,0.0017688,-0.0013985],\n\t\t\t\"R\": [\n\t\t\t\t[0.8410364559,-0.03582960221,-0.5397906256],\n\t\t\t\t[-0.192384631,0.9127679401,-0.3603371217],\n\t\t\t\t[0.5056143132,0.4069040761,0.7607780486]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.728898504],\n\t\t\t\t[75.32503712],\n\t\t\t\t[325.8417248]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[746.446,0,376.523],\n\t\t\t\t[0,746.682,251.012],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330943,0.0996499,0.00144142,-0.000113946,0.0131394],\n\t\t\t\"R\": [\n\t\t\t\t[0.8610606531,-0.05437396314,-0.5055868113],\n\t\t\t\t[-0.176556083,0.9004429458,-0.3975304402],\n\t\t\t\t[0.4768673833,0.4315622475,0.7657359371]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.93527518],\n\t\t\t\t[62.43528973],\n\t\t\t\t[326.764058]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.998,0,378.484],\n\t\t\t\t[0,744.973,240.788],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31652,0.0338012,-0.0010118,-0.000122735,0.0959735],\n\t\t\t\"R\": [\n\t\t\t\t[0.8769583834,-0.06555368648,-0.4760742674],\n\t\t\t\t[-0.1128149484,0.9348860407,-0.3365425358],\n\t\t\t\t[0.4671367907,0.348842092,0.8124607151]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[52.69213606],\n\t\t\t\t[109.2131316],\n\t\t\t\t[317.2562433]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.942,0,394.454],\n\t\t\t\t[0,745.513,230.902],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322593,0.0669124,0.000685625,0.000650135,0.0435827],\n\t\t\t\"R\": [\n\t\t\t\t[0.8511772215,-0.03734239681,-0.5235483579],\n\t\t\t\t[-0.1521244983,0.9371023984,-0.3141611561],\n\t\t\t\t[0.5023499524,0.3470513512,0.7919595223]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.57000229],\n\t\t\t\t[127.8421428],\n\t\t\t\t[318.5564893]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.592,0,375.596],\n\t\t\t\t[0,744.695,234.586],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314208,0.0115966,-0.0002404,-0.00129875,0.131833],\n\t\t\t\"R\": [\n\t\t\t\t[0.863242284,-0.08735605341,-0.4971736911],\n\t\t\t\t[-0.1241310572,0.9179337282,-0.3768144785],\n\t\t\t\t[0.4892895255,0.386996887,0.7815556088]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.3076273],\n\t\t\t\t[133.8669044],\n\t\t\t\t[323.1008342]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.083,0,388.49],\n\t\t\t\t[0,746.196,219.485],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327776,0.0952708,0.000477894,0.00116098,0.0130168],\n\t\t\t\"R\": [\n\t\t\t\t[0.8627791791,-0.162720556,-0.478679547],\n\t\t\t\t[-0.06768333431,0.9010943873,-0.4283081501],\n\t\t\t\t[0.5010299935,0.401933982,0.766432006]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.91664651],\n\t\t\t\t[150.3571005],\n\t\t\t\t[326.7446808]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.984,0,374.291],\n\t\t\t\t[0,745.244,231.69],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317288,0.0201616,0.000340337,0.000302133,0.135473],\n\t\t\t\"R\": [\n\t\t\t\t[0.8433461687,-0.104156761,-0.5271798639],\n\t\t\t\t[-0.1611508321,0.8868626272,-0.433018579],\n\t\t\t\t[0.5126379318,0.4501400333,0.7311472501]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.809004706],\n\t\t\t\t[133.1751931],\n\t\t\t\t[335.4888131]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[746.325,0,369.755],\n\t\t\t\t[0,746.606,238.315],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330117,0.107892,0.000853042,-0.00148033,-0.0192727],\n\t\t\t\"R\": [\n\t\t\t\t[0.8487877999,-0.06352852013,-0.5249032272],\n\t\t\t\t[-0.1660312052,0.9105147821,-0.3786772643],\n\t\t\t\t[0.5019889537,0.4085669574,0.7622861219]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[10.90299391],\n\t\t\t\t[168.9126588],\n\t\t\t\t[328.8547345]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.397,0,373.191],\n\t\t\t\t[0,745.394,241.989],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315431,0.0239438,0.00152043,8.78247e-05,0.132462],\n\t\t\t\"R\": [\n\t\t\t\t[0.7899500519,0.01447673769,-0.613000277],\n\t\t\t\t[-0.2772192125,0.9001468868,-0.3359837649],\n\t\t\t\t[0.5469263421,0.4353458466,0.7150843098]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.01289772],\n\t\t\t\t[165.4412244],\n\t\t\t\t[333.9391633]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[746.289,0,356.696],\n\t\t\t\t[0,746.559,221.83],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307674,-0.0320128,-0.000713248,-0.000212304,0.187939],\n\t\t\t\"R\": [\n\t\t\t\t[0.7812025858,0.003231301473,-0.6242692358],\n\t\t\t\t[-0.256925784,0.9130359895,-0.316787663],\n\t\t\t\t[0.5689566429,0.4078662043,0.7140962805]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.04397497],\n\t\t\t\t[158.6113997],\n\t\t\t\t[327.0561852]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.216,0,367.374],\n\t\t\t\t[0,744.503,234.384],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313106,0.0107213,0.00051099,0.000391129,0.137335],\n\t\t\t\"R\": [\n\t\t\t\t[0.7647493291,0.08765142393,-0.6383382266],\n\t\t\t\t[-0.3090501184,0.9192036391,-0.2440342068],\n\t\t\t\t[0.5653728752,0.3839035005,0.7300490493]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.23656889],\n\t\t\t\t[178.7825502],\n\t\t\t\t[321.7207122]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.827,0,380.852],\n\t\t\t\t[0,747.806,237.021],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329904,0.102056,0.000500868,0.000776535,0.0163276],\n\t\t\t\"R\": [\n\t\t\t\t[0.8420936086,0.09442452017,-0.5310012847],\n\t\t\t\t[-0.2692856411,0.9266613257,-0.2622670985],\n\t\t\t\t[0.4672939095,0.3638444688,0.8057627471]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.683781844],\n\t\t\t\t[164.2881649],\n\t\t\t\t[322.7392687]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.289,0,371.652],\n\t\t\t\t[0,745.447,216.538],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317152,0.0301694,-0.000847782,0.000226416,0.100881],\n\t\t\t\"R\": [\n\t\t\t\t[0.7751085928,0.08020770062,-0.6267163586],\n\t\t\t\t[-0.2817854267,0.9316829094,-0.2292682483],\n\t\t\t\t[0.5655118413,0.3543073259,0.74475679]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.18053512],\n\t\t\t\t[150.9579844],\n\t\t\t\t[316.9204289]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.591,0,386.471],\n\t\t\t\t[0,744.601,243.766],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308716,-0.020066,-0.000742984,7.36231e-05,0.18193],\n\t\t\t\"R\": [\n\t\t\t\t[0.8000888793,0.13985822,-0.5833502066],\n\t\t\t\t[-0.3086873752,0.9298003917,-0.2004578159],\n\t\t\t\t[0.5143635773,0.3404569133,0.7870954202]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.24407076],\n\t\t\t\t[139.76037],\n\t\t\t\t[318.5389184]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[747.091,0,388.41],\n\t\t\t\t[0,747.213,245.147],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331947,0.109947,-0.00018029,-0.000335458,-0.0100282],\n\t\t\t\"R\": [\n\t\t\t\t[0.7812031275,0.143907843,-0.6074637489],\n\t\t\t\t[-0.3493109676,0.9072427652,-0.2342912992],\n\t\t\t\t[0.5174007358,0.3952228456,0.7590094735]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-39.38157975],\n\t\t\t\t[101.9329028],\n\t\t\t\t[324.6812046]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.815,0,380.782],\n\t\t\t\t[0,743.921,233.579],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31618,0.0384848,0.000240219,0.000426998,0.0977231],\n\t\t\t\"R\": [\n\t\t\t\t[0.8097086682,0.09665101941,-0.578818152],\n\t\t\t\t[-0.2718115959,0.9359285209,-0.2239559336],\n\t\t\t\t[0.5200868476,0.3386685464,0.784100304]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.817362892],\n\t\t\t\t[126.1763792],\n\t\t\t\t[318.2990602]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[746.163,0,356.033],\n\t\t\t\t[0,746.281,215.327],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323416,0.0556958,5.62358e-06,-0.000684023,0.0815018],\n\t\t\t\"R\": [\n\t\t\t\t[0.8690981447,0.003405692177,-0.4946279574],\n\t\t\t\t[-0.1831744592,0.9310985933,-0.3154402114],\n\t\t\t\t[0.4594731031,0.3647517111,0.8098398958]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.15812523],\n\t\t\t\t[111.197586],\n\t\t\t\t[320.9871724]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.277,0,370.698],\n\t\t\t\t[0,745.633,251.594],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309423,-0.0154759,-0.000871178,-0.000110471,0.185828],\n\t\t\t\"R\": [\n\t\t\t\t[0.8519925598,-0.01534543221,-0.5233289556],\n\t\t\t\t[-0.157671027,0.9456449668,-0.2844212441],\n\t\t\t\t[0.4992479597,0.3248385977,0.8032629458]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.66925749],\n\t\t\t\t[140.0971121],\n\t\t\t\t[315.3107012]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[749.812,0,361.025],\n\t\t\t\t[0,750.052,224.033],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333335,0.0892582,3.32371e-05,-0.00136116,0.0353235],\n\t\t\t\"R\": [\n\t\t\t\t[0.8242021998,-0.0118106517,-0.5661724493],\n\t\t\t\t[-0.2609232338,0.8794144434,-0.3981824994],\n\t\t\t\t[0.5026030242,0.4759104383,0.7217336453]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.739100305],\n\t\t\t\t[105.8858326],\n\t\t\t\t[336.9710973]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.781,0,365.976],\n\t\t\t\t[0,744.836,235.682],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319452,0.032528,0.000754874,-0.000913445,0.102166],\n\t\t\t\"R\": [\n\t\t\t\t[0.8233335342,0.02583843362,-0.5669693703],\n\t\t\t\t[-0.2570181529,0.9076367155,-0.3318693443],\n\t\t\t\t[0.506027233,0.4189605805,0.7539286912]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.103462359],\n\t\t\t\t[133.5127669],\n\t\t\t\t[329.5726238]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"03_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 3,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[746.135,0,373.553],\n\t\t\t\t[0,746.515,225.298],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323756,0.0623909,2.70614e-05,0.000962707,0.0761173],\n\t\t\t\"R\": [\n\t\t\t\t[0.8557458945,0.0294251088,-0.5165589289],\n\t\t\t\t[-0.2234217673,0.921515875,-0.3176337608],\n\t\t\t\t[0.4666708454,0.3872242956,0.7951576366]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.49693002],\n\t\t\t\t[128.5290469],\n\t\t\t\t[325.1203285]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.756,0,368.953],\n\t\t\t\t[0,745.945,245.188],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3245,0.0724334,-0.000312337,0.000678015,0.0415529],\n\t\t\t\"R\": [\n\t\t\t\t[0.04501388353,-0.06073969189,-0.9971381249],\n\t\t\t\t[-0.08162898106,0.9945884367,-0.06426936354],\n\t\t\t\t[0.9956457501,0.08428838276,0.03981216889]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-59.71104012],\n\t\t\t\t[137.3658878],\n\t\t\t\t[280.4259077]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[745.144,0,382.474],\n\t\t\t\t[0,745.286,222.525],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322843,0.0690658,-0.000684608,-0.000275864,0.0370253],\n\t\t\t\"R\": [\n\t\t\t\t[0.1096717734,-0.01795980665,-0.9938055884],\n\t\t\t\t[-0.007042199406,0.9997976117,-0.01884523745],\n\t\t\t\t[0.9939429106,0.009065367736,0.1095231006]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.83503278],\n\t\t\t\t[149.6185443],\n\t\t\t\t[272.7820927]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[742.832,0,377.499],\n\t\t\t\t[0,742.665,258.984],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312355,-0.00257413,0.000454129,0.00111055,0.151137],\n\t\t\t\"R\": [\n\t\t\t\t[0.07040546321,0.04162572676,-0.9966495721],\n\t\t\t\t[-0.08610880414,0.9956530214,0.03550119457],\n\t\t\t\t[0.9937949208,0.08332082476,0.07368375372]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-50.21742462],\n\t\t\t\t[111.4103034],\n\t\t\t\t[280.5940976]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[743.339,0,393.561],\n\t\t\t\t[0,743.571,223.626],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307228,-0.0295629,-0.000661125,6.4492e-05,0.183577],\n\t\t\t\"R\": [\n\t\t\t\t[0.09450112049,0.05679880598,-0.993903131],\n\t\t\t\t[-0.03670643306,0.9978910099,0.05353662459],\n\t\t\t\t[0.9948478155,0.03142336774,0.09638670013]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.9069],\n\t\t\t\t[118.1273376],\n\t\t\t\t[275.8163164]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[746.019,0,364.58],\n\t\t\t\t[0,746.273,258.887],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327759,0.0738839,0.000801649,0.000211169,0.0604088],\n\t\t\t\"R\": [\n\t\t\t\t[0.135847977,0.01131634816,-0.9906650632],\n\t\t\t\t[-0.049797809,0.9987488181,0.004580011864],\n\t\t\t\t[0.98947739,0.04871076425,0.1362415358]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.12624478],\n\t\t\t\t[90.71810202],\n\t\t\t\t[278.5550143]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.588,0,362.328],\n\t\t\t\t[0,745.695,224.495],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317313,0.0342325,-0.00011624,0.00140051,0.0955503],\n\t\t\t\"R\": [\n\t\t\t\t[0.09768474559,0.09486669264,-0.9906856217],\n\t\t\t\t[-0.08671696061,0.9924717325,0.0864871607],\n\t\t\t\t[0.9914322262,0.07746076975,0.1051758999]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.120914551],\n\t\t\t\t[75.66522558],\n\t\t\t\t[280.1538331]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.949,0,374.902],\n\t\t\t\t[0,744.948,218.152],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307279,-0.0368619,-0.000928182,-0.000206153,0.214368],\n\t\t\t\"R\": [\n\t\t\t\t[0.08413477249,-0.05845821559,-0.994738145],\n\t\t\t\t[-0.03729096802,0.9973936317,-0.06176833509],\n\t\t\t\t[0.9957563576,0.04229161317,0.08173552284]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.352563309],\n\t\t\t\t[99.7043349],\n\t\t\t\t[277.3248716]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.851,0,365.832],\n\t\t\t\t[0,744.82,236.655],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313642,0.00106915,0.000461187,-0.00049658,0.163492],\n\t\t\t\"R\": [\n\t\t\t\t[0.1068294918,-0.02053293437,-0.9940653189],\n\t\t\t\t[-0.04471775106,0.998675844,-0.02543386204],\n\t\t\t\t[0.9932712532,0.04716945203,0.1057698462]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.88142403],\n\t\t\t\t[92.93282517],\n\t\t\t\t[277.1804593]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.947,0,354.92],\n\t\t\t\t[0,745.962,217.292],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332252,0.114802,-0.000779302,-0.000175195,-0.0220414],\n\t\t\t\"R\": [\n\t\t\t\t[0.0951039165,0.01286389124,-0.99538423],\n\t\t\t\t[-0.04378002227,0.9990030715,0.008727700331],\n\t\t\t\t[0.9945041753,0.04274790527,0.09557228614]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.3876018],\n\t\t\t\t[107.4685168],\n\t\t\t\t[276.8925649]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.419,0,373.623],\n\t\t\t\t[0,743.493,209.714],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312784,-0.00205334,-0.00151839,-4.48796e-05,0.146707],\n\t\t\t\"R\": [\n\t\t\t\t[0.07554192003,-0.02015366607,-0.996938939],\n\t\t\t\t[-0.05402378201,0.9982445697,-0.02427365106],\n\t\t\t\t[0.9956780852,0.05569209012,0.07432053419]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[36.95032578],\n\t\t\t\t[126.4783785],\n\t\t\t\t[278.9862968]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.168,0,378.723],\n\t\t\t\t[0,743.196,231.359],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312654,0.00616666,0.000125459,-0.000163635,0.137741],\n\t\t\t\"R\": [\n\t\t\t\t[0.104627794,-0.01026277171,-0.994458496],\n\t\t\t\t[-0.05855646041,0.9981483637,-0.01646162423],\n\t\t\t\t[0.9927860624,0.05995431298,0.1038331098]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.78762978],\n\t\t\t\t[139.882294],\n\t\t\t\t[278.0088471]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.755,0,377.564],\n\t\t\t\t[0,747.014,231.526],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.342661,0.169314,0.000669193,0.000564241,-0.092518],\n\t\t\t\"R\": [\n\t\t\t\t[0.09069981891,0.03748374052,-0.9951726041],\n\t\t\t\t[-0.02832816732,0.9989841486,0.03504548138],\n\t\t\t\t[0.9954752924,0.02501279723,0.09166952704]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[63.18640006],\n\t\t\t\t[168.1511303],\n\t\t\t\t[272.7093484]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[745.766,0,371.377],\n\t\t\t\t[0,745.897,229.211],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323265,0.06437,0.000357726,0.000480753,0.061899],\n\t\t\t\"R\": [\n\t\t\t\t[0.03414536791,0.03842962758,-0.9986777546],\n\t\t\t\t[-0.02717943982,0.9989265658,0.03750992125],\n\t\t\t\t[0.9990472321,0.02586271187,0.03515321085]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.04698548],\n\t\t\t\t[171.5967975],\n\t\t\t\t[274.5649723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.965,0,366.266],\n\t\t\t\t[0,745.319,235.632],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317134,0.0349168,5.85303e-05,0.000379707,0.110605],\n\t\t\t\"R\": [\n\t\t\t\t[0.05221731101,0.04748668842,-0.9975060736],\n\t\t\t\t[0.03426805086,0.9981953182,0.04931335942],\n\t\t\t\t[0.9980476207,-0.03675759989,0.05049579913]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.93275734],\n\t\t\t\t[208.7852536],\n\t\t\t\t[260.7309393]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[744.586,0,371.051],\n\t\t\t\t[0,745.106,212.085],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332822,0.11382,-0.000911903,0.000640183,-0.00904196],\n\t\t\t\"R\": [\n\t\t\t\t[0.0693166226,0.04834029473,-0.9964228127],\n\t\t\t\t[-0.01396942206,0.9987743784,0.04748258878],\n\t\t\t\t[0.9974968978,0.01062811814,0.06990695264]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.12425569],\n\t\t\t\t[198.357827],\n\t\t\t\t[269.7404532]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[742.58,0,362.432],\n\t\t\t\t[0,742.717,222.722],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316061,0.0181932,0.000637155,-0.000119442,0.122715],\n\t\t\t\"R\": [\n\t\t\t\t[0.07545496093,-0.0349426896,-0.9965367817],\n\t\t\t\t[-0.03652359913,0.9986183515,-0.03778114217],\n\t\t\t\t[0.9964800929,0.03924788454,0.07407447592]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.86676392],\n\t\t\t\t[179.6369531],\n\t\t\t\t[275.0674259]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.044,0,350.241],\n\t\t\t\t[0,745.211,214.104],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330556,0.0995367,-0.000406045,-3.83783e-05,-0.00374247],\n\t\t\t\"R\": [\n\t\t\t\t[0.0837025501,0.02221656332,-0.9962430965],\n\t\t\t\t[-0.04478154079,0.9988252756,0.01851168242],\n\t\t\t\t[0.9954840515,0.04306382584,0.08459911461]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.0620205],\n\t\t\t\t[182.4550181],\n\t\t\t\t[276.0013748]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[747.543,0,399.307],\n\t\t\t\t[0,747.43,229.515],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337874,0.152604,0.000377489,0.002871,-0.0603327],\n\t\t\t\"R\": [\n\t\t\t\t[0.03967719066,0.06607189882,-0.9970256891],\n\t\t\t\t[-0.02383145062,0.9975901546,0.06516091958],\n\t\t\t\t[0.998928317,0.02117516625,0.04115616396]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.47747339],\n\t\t\t\t[181.8911988],\n\t\t\t\t[269.8403328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.963,0,369.391],\n\t\t\t\t[0,744.08,218.072],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320196,0.0539371,0.000417857,0.00192962,0.0700112],\n\t\t\t\"R\": [\n\t\t\t\t[0.0434323362,0.03783761887,-0.9983395949],\n\t\t\t\t[-0.08481170801,0.9958149524,0.03405223652],\n\t\t\t\t[0.9954499517,0.08319191804,0.04645964289]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.42650241],\n\t\t\t\t[136.5925943],\n\t\t\t\t[281.0885176]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.858,0,356.253],\n\t\t\t\t[0,746.045,207.418],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328012,0.0801152,-7.74627e-05,-0.000454429,0.0269942],\n\t\t\t\"R\": [\n\t\t\t\t[0.0976780849,0.06705669278,-0.9929563896],\n\t\t\t\t[-0.1171365339,0.9915671608,0.05544004021],\n\t\t\t\t[0.9883005738,0.1108961929,0.1047091699]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.775430866],\n\t\t\t\t[107.2147587],\n\t\t\t\t[285.054156]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.156,0,369.678],\n\t\t\t\t[0,746.129,226.325],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331296,0.10434,-0.000526263,0.0017798,0.0107539],\n\t\t\t\"R\": [\n\t\t\t\t[0.06864954522,0.009029787974,-0.9975999714],\n\t\t\t\t[-0.09824772164,0.9951594531,0.00224680986],\n\t\t\t\t[0.9927913301,0.09785768182,0.06920439997]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.330018678],\n\t\t\t\t[104.6606406],\n\t\t\t\t[283.2576255]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[746.305,0,363.016],\n\t\t\t\t[0,746.511,222.294],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313633,0.00103632,0.000318828,-0.000294887,0.154057],\n\t\t\t\"R\": [\n\t\t\t\t[0.08441946195,-0.0784287402,-0.9933389588],\n\t\t\t\t[-0.07957536672,0.9931828981,-0.08517917513],\n\t\t\t\t[0.9932477614,0.08623609206,0.07760297012]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.995164317],\n\t\t\t\t[122.6888691],\n\t\t\t\t[282.4272415]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[745.178,0,358.539],\n\t\t\t\t[0,745.299,233.674],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315081,0.0210219,-6.99317e-06,-0.000330658,0.115227],\n\t\t\t\"R\": [\n\t\t\t\t[0.1162513982,0.03935918122,-0.9924396542],\n\t\t\t\t[-0.02556811677,0.999001962,0.03662446354],\n\t\t\t\t[0.9928906706,0.02111716788,0.117141715]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.91845612],\n\t\t\t\t[159.7823772],\n\t\t\t\t[272.1694603]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"04_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 4,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[746.014,0,365.199],\n\t\t\t\t[0,746.411,216.584],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320661,0.0432533,-0.00136099,-0.000113861,0.0956118],\n\t\t\t\"R\": [\n\t\t\t\t[0.1001711426,-0.0639180002,-0.9929150172],\n\t\t\t\t[-0.0054812292,0.9978838124,-0.06479084071],\n\t\t\t\t[0.9949551238,0.01193256733,0.09960881242]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.066812064],\n\t\t\t\t[167.2144724],\n\t\t\t\t[271.0944115]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.506,0,379.212],\n\t\t\t\t[0,745.093,221.816],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322425,0.0503962,-0.00139268,-0.000488272,0.0792831],\n\t\t\t\"R\": [\n\t\t\t\t[0.4832137358,-0.07031409603,-0.8726742883],\n\t\t\t\t[-0.1214142278,0.9817563233,-0.14633218],\n\t\t\t\t[0.8670427157,0.1766647942,0.465861009]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-31.81590772],\n\t\t\t\t[187.5269902],\n\t\t\t\t[291.8752718]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.146,0,379.909],\n\t\t\t\t[0,746.274,243.237],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327102,0.0750235,0.00051439,0.000830868,0.0552106],\n\t\t\t\"R\": [\n\t\t\t\t[0.559561068,-0.04316954181,-0.8276640634],\n\t\t\t\t[-0.1711397799,0.9711012062,-0.1663539088],\n\t\t\t\t[0.8109269924,0.2347314165,0.5360024022]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.47998338],\n\t\t\t\t[182.028679],\n\t\t\t\t[304.5116426]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.598,0,366.137],\n\t\t\t\t[0,746.916,245.497],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.34673,0.191883,-0.000717065,0.000142378,-0.151818],\n\t\t\t\"R\": [\n\t\t\t\t[0.4493443217,0.06721032382,-0.8908268367],\n\t\t\t\t[-0.2833621033,0.9563979118,-0.07077395533],\n\t\t\t\t[0.8472281859,0.2842284411,0.4487968296]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.79170468],\n\t\t\t\t[156.78227],\n\t\t\t\t[309.5144468]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.97,0,361.533],\n\t\t\t\t[0,745.268,216.194],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320215,0.0355127,-0.000935438,6.82351e-05,0.107335],\n\t\t\t\"R\": [\n\t\t\t\t[0.5139859054,0.07264601249,-0.8547169391],\n\t\t\t\t[-0.2477501277,0.96651576,-0.06683681477],\n\t\t\t\t[0.8212419639,0.2461094116,0.5147735369]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.66847624],\n\t\t\t\t[145.8563675],\n\t\t\t\t[305.5618637]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[743.904,0,367.466],\n\t\t\t\t[0,744.108,216.808],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328736,0.086922,-0.000934339,0.000214876,0.0243362],\n\t\t\t\"R\": [\n\t\t\t\t[0.4889793362,0.07185582001,-0.8693307483],\n\t\t\t\t[-0.2209595119,0.9743010874,-0.0437525441],\n\t\t\t\t[0.8438460185,0.2134809878,0.4922903259]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-47.80972546],\n\t\t\t\t[144.3254019],\n\t\t\t\t[299.7644507]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.323,0,383.952],\n\t\t\t\t[0,745.526,234.808],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334223,0.133657,-0.000107051,0.00148947,-0.0461754],\n\t\t\t\"R\": [\n\t\t\t\t[0.4969854565,0.0559027949,-0.8659563116],\n\t\t\t\t[-0.2018212488,0.978003949,-0.05269211703],\n\t\t\t\t[0.8439630558,0.2009556001,0.4973361109]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.56558119],\n\t\t\t\t[125.7186081],\n\t\t\t\t[298.6423415]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.158,0,356.674],\n\t\t\t\t[0,746.317,240.893],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334568,0.11153,0.000321304,-0.000871385,-0.0157856],\n\t\t\t\"R\": [\n\t\t\t\t[0.5541201274,0.02610072644,-0.8320274253],\n\t\t\t\t[-0.1769665492,0.9803549196,-0.08710380092],\n\t\t\t\t[0.8134087072,0.1955069916,0.5478533484]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.70019562],\n\t\t\t\t[115.5481293],\n\t\t\t\t[299.4445791]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.96,0,386.044],\n\t\t\t\t[0,745.46,258.776],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325919,0.068823,-0.000458274,0.000477805,0.0465958],\n\t\t\t\"R\": [\n\t\t\t\t[0.4763065258,-0.004539644313,-0.8792675845],\n\t\t\t\t[-0.1710253429,0.980409884,-0.09770768372],\n\t\t\t\t[0.8624861886,0.1969158475,0.4661992314]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-40.46029545],\n\t\t\t\t[93.91456762],\n\t\t\t\t[297.4902987]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.188,0,367.116],\n\t\t\t\t[0,745.437,236.843],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328194,0.058828,0.000388874,-0.00143808,0.0829656],\n\t\t\t\"R\": [\n\t\t\t\t[0.5065601345,-0.04543027129,-0.8610069225],\n\t\t\t\t[-0.1705921502,0.9735884993,-0.1517357977],\n\t\t\t\t[0.845159836,0.2237443283,0.4854310735]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.55300824],\n\t\t\t\t[76.93410209],\n\t\t\t\t[300.8962768]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.452,0,374.886],\n\t\t\t\t[0,747.648,257.28],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337728,0.123608,0.00138141,5.97732e-05,-0.0225942],\n\t\t\t\"R\": [\n\t\t\t\t[0.4549222289,-0.02855444123,-0.8900732608],\n\t\t\t\t[-0.1699899924,0.9783230281,-0.1182685721],\n\t\t\t\t[0.8741562607,0.2051065493,0.4402069233]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-13.61854908],\n\t\t\t\t[96.6157071],\n\t\t\t\t[299.0141417]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[746.39,0,405.604],\n\t\t\t\t[0,746.458,241.87],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333064,0.100943,0.000870611,0.00103156,0.0180409],\n\t\t\t\"R\": [\n\t\t\t\t[0.5002384593,-0.05591048228,-0.8640807264],\n\t\t\t\t[-0.1916757277,0.9660062257,-0.1734715752],\n\t\t\t\t[0.8444062406,0.2524004556,0.4725167836]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.55277765],\n\t\t\t\t[75.44647006],\n\t\t\t\t[303.7304898]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.943,0,392.757],\n\t\t\t\t[0,746.143,272.1],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323245,0.0770562,0.00168738,0.000666505,0.0382015],\n\t\t\t\"R\": [\n\t\t\t\t[0.5344619138,-0.0483612619,-0.8438078283],\n\t\t\t\t[-0.2099054746,0.9594877737,-0.1879438847],\n\t\t\t\t[0.818712498,0.277568731,0.5026583782]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.5535171],\n\t\t\t\t[81.37072912],\n\t\t\t\t[304.8427161]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[748.463,0,383.471],\n\t\t\t\t[0,748.465,243.614],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.34071,0.149034,0.000455623,0.000254671,-0.0668973],\n\t\t\t\"R\": [\n\t\t\t\t[0.550270912,-0.09726860505,-0.8293013577],\n\t\t\t\t[-0.1127468592,0.975440235,-0.1892207537],\n\t\t\t\t[0.82733915,0.1976238001,0.525789658]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.15956958],\n\t\t\t\t[127.9842494],\n\t\t\t\t[295.9545727]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.467,0,372.192],\n\t\t\t\t[0,744.287,242.67],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321164,0.0557106,-0.000170048,0.000249902,0.0584864],\n\t\t\t\"R\": [\n\t\t\t\t[0.5607110475,-0.1151130063,-0.8199708025],\n\t\t\t\t[-0.101866971,0.9731761842,-0.2062795062],\n\t\t\t\t[0.8217215109,0.1991911399,0.5339444244]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.41224037],\n\t\t\t\t[142.3474205],\n\t\t\t\t[294.74195]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.542,0,352.38],\n\t\t\t\t[0,746.666,240.759],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327959,0.100036,-0.000636984,-0.00122606,-0.0366604],\n\t\t\t\"R\": [\n\t\t\t\t[0.5029624145,-0.05772144518,-0.8623787128],\n\t\t\t\t[-0.198700467,0.9633205664,-0.180365215],\n\t\t\t\t[0.8411580909,0.262071977,0.4730447599]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.04469815],\n\t\t\t\t[136.31759],\n\t\t\t\t[307.4406203]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.042,0,371.719],\n\t\t\t\t[0,747.231,244.896],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323957,0.0675271,-0.000219383,0.00030566,0.0452733],\n\t\t\t\"R\": [\n\t\t\t\t[0.5145114331,-0.105655334,-0.8509494319],\n\t\t\t\t[-0.1209004538,0.9735279663,-0.1939752023],\n\t\t\t\t[0.8489175846,0.2026826318,0.4881174913]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.341169646],\n\t\t\t\t[165.8735131],\n\t\t\t\t[297.8569993]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.814,0,386.675],\n\t\t\t\t[0,746.085,252.153],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320652,0.0597547,0.000647483,5.56623e-05,0.0523558],\n\t\t\t\"R\": [\n\t\t\t\t[0.5123119379,-0.06682282728,-0.856195765],\n\t\t\t\t[-0.1341513719,0.9785027468,-0.1566390244],\n\t\t\t\t[0.8482569703,0.1951078787,0.4923342645]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.076647729],\n\t\t\t\t[186.6487394],\n\t\t\t\t[296.0424945]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[744.362,0,367.747],\n\t\t\t\t[0,744.705,261.961],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317525,0.0240072,0.000331,-0.000409781,0.122239],\n\t\t\t\"R\": [\n\t\t\t\t[0.5214772573,-0.05602259067,-0.8514240656],\n\t\t\t\t[-0.1526209796,0.9756261952,-0.1576716965],\n\t\t\t\t[0.8395047985,0.2121673788,0.5002166498]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-2.829687906],\n\t\t\t\t[192.8140289],\n\t\t\t\t[298.6606918]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[744.259,0,353.379],\n\t\t\t\t[0,744.524,245.823],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320328,0.0298824,0.00026675,-0.00161079,0.123162],\n\t\t\t\"R\": [\n\t\t\t\t[0.5556726344,-0.05485450779,-0.8295896012],\n\t\t\t\t[-0.2099711545,0.9562161648,-0.2038694692],\n\t\t\t\t[0.8044501462,0.2874745713,0.519825291]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.476630227],\n\t\t\t\t[134.2745178],\n\t\t\t\t[310.4571486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[743.679,0,405.845],\n\t\t\t\t[0,743.856,234.88],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326644,0.0646831,0.000108119,5.73367e-05,0.058946],\n\t\t\t\"R\": [\n\t\t\t\t[0.447769915,-0.01338423954,-0.894048637],\n\t\t\t\t[-0.18660487,0.9764723016,-0.1080762074],\n\t\t\t\t[0.8744602482,0.2152271039,0.4347373552]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.39083575],\n\t\t\t\t[143.2049031],\n\t\t\t\t[297.8732354]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.956,0,354.763],\n\t\t\t\t[0,747.081,232.068],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333648,0.0797639,-0.000768992,-0.00091097,0.0508097],\n\t\t\t\"R\": [\n\t\t\t\t[0.5053420531,-0.009379958189,-0.8628681393],\n\t\t\t\t[-0.2526298673,0.9545207072,-0.1583299394],\n\t\t\t\t[0.8251106347,0.2979970402,0.4799897963]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.66925616],\n\t\t\t\t[96.29580053],\n\t\t\t\t[309.4868577]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[748.369,0,375.575],\n\t\t\t\t[0,748.642,247.648],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.339087,0.143465,-0.000470446,0.00132222,-0.0624301],\n\t\t\t\"R\": [\n\t\t\t\t[0.54260376,-0.05746408722,-0.8380209057],\n\t\t\t\t[-0.1470082191,0.975763273,-0.1620944744],\n\t\t\t\t[0.8270246327,0.2111490322,0.5210051277]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.173863757],\n\t\t\t\t[116.0988382],\n\t\t\t\t[299.4207466]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.544,0,368.615],\n\t\t\t\t[0,744.426,281.181],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322575,0.0664483,0.00114224,0.000391788,0.0483369],\n\t\t\t\"R\": [\n\t\t\t\t[0.5347472888,-0.05715349527,-0.8430769924],\n\t\t\t\t[-0.1466458645,0.9762943366,-0.1591991164],\n\t\t\t\t[0.832190079,0.2087650503,0.5136894259]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.7223507],\n\t\t\t\t[130.5590862],\n\t\t\t\t[298.5444367]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"05_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 5,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[743.308,0,356.74],\n\t\t\t\t[0,743.243,228.93],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321093,0.0447792,0.000127467,-8.40104e-05,0.095825],\n\t\t\t\"R\": [\n\t\t\t\t[0.5706235669,-0.133891243,-0.8102233519],\n\t\t\t\t[-0.1678811389,0.9467635938,-0.2746900447],\n\t\t\t\t[0.8038685639,0.2927658322,0.5177678046]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.742844805],\n\t\t\t\t[124.9131408],\n\t\t\t\t[309.8640068]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.518,0,344.042],\n\t\t\t\t[0,744.512,240.289],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313532,-0.0139368,0.00116047,-0.000125352,0.195046],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3305715804,0.1011846603,-0.9383411399],\n\t\t\t\t[-0.314462461,0.9256148845,0.2105954561],\n\t\t\t\t[0.8898515555,0.3646899369,-0.2741631979]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.56718534],\n\t\t\t\t[104.1648487],\n\t\t\t\t[320.754952]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[748.956,0,345.566],\n\t\t\t\t[0,748.875,227.82],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335662,0.0955564,-6.0167e-05,-0.0012999,0.0278092],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2903396332,0.1603112194,-0.9433998147],\n\t\t\t\t[-0.341086429,0.9037763758,0.2585504022],\n\t\t\t\t[0.8940709957,0.3968483028,-0.2077221201]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-2.499901432],\n\t\t\t\t[69.14355517],\n\t\t\t\t[325.2941984]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[743.901,0,369.68],\n\t\t\t\t[0,743.816,251.042],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320568,0.044977,0.000366128,-0.00033077,0.103335],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3123459653,0.110763308,-0.943488997],\n\t\t\t\t[-0.3278062139,0.9196080197,0.216481353],\n\t\t\t\t[0.891618239,0.3768986331,-0.250926954]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.578346941],\n\t\t\t\t[71.05917793],\n\t\t\t\t[323.4074447]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.814,0,378.476],\n\t\t\t\t[0,745.908,222.393],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316287,0.0251632,0.000357033,0.00145486,0.13215],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2756543214,0.09031338143,-0.9570048005],\n\t\t\t\t[-0.3333214643,0.9248259371,0.1832860813],\n\t\t\t\t[0.9016160472,0.3695138418,-0.2248288776]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.15902854],\n\t\t\t\t[86.10496093],\n\t\t\t\t[322.4382284]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[750.419,0,363.736],\n\t\t\t\t[0,750.614,222.964],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.344753,0.14329,-0.000836382,-0.000451111,-0.060951],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2930259634,0.06094491301,-0.9541601031],\n\t\t\t\t[-0.3875087878,0.9047544541,0.1767945619],\n\t\t\t\t[0.8740553324,0.4215508218,-0.2414998562]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[36.26889278],\n\t\t\t\t[61.41890121],\n\t\t\t\t[327.3260635]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[747.394,0,354.724],\n\t\t\t\t[0,747.506,211.184],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329009,0.0921746,-0.00050966,0.000333806,0.021085],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2297156979,0.02557529828,-0.9729216835],\n\t\t\t\t[-0.3964529538,0.9104994627,0.1175405629],\n\t\t\t\t[0.888850805,0.4127185877,-0.199016617]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[62.78312093],\n\t\t\t\t[81.38139883],\n\t\t\t\t[324.7093469]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.623,0,374.989],\n\t\t\t\t[0,746.758,209.923],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319339,0.0433323,-0.00139256,0.000754597,0.0938733],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2846142448,0.03267216609,-0.9580852056],\n\t\t\t\t[-0.3313740809,0.934457856,0.1303063082],\n\t\t\t\t[0.8995476364,0.3545716359,-0.255133308]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.81195811],\n\t\t\t\t[121.7115234],\n\t\t\t\t[320.8009986]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.971,0,357.954],\n\t\t\t\t[0,746.024,209.947],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314348,0.0246684,-0.0014997,0.000635776,0.111152],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3038162213,-0.0261928812,-0.9523705354],\n\t\t\t\t[-0.3441704234,0.9351353343,0.08407512184],\n\t\t\t\t[0.8883931693,0.3533211563,-0.2931240987]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.47715732],\n\t\t\t\t[140.438376],\n\t\t\t\t[322.3540865]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[742.648,0,362.103],\n\t\t\t\t[0,742.703,220.817],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.304218,-0.0643312,-0.000139411,-0.000234647,0.289172],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2807259034,-0.0411671215,-0.958904706],\n\t\t\t\t[-0.3740921558,0.9247597922,0.06981680165],\n\t\t\t\t[0.8838823599,0.3783181134,-0.2750043253]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.64720227],\n\t\t\t\t[153.3424109],\n\t\t\t\t[325.0305142]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.72,0,366.165],\n\t\t\t\t[0,747.851,213.209],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324647,0.0523798,-0.00077308,-0.000271098,0.0916616],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2880158499,0.02777358159,-0.957222805],\n\t\t\t\t[-0.3788720768,0.9147158267,0.1405379157],\n\t\t\t\t[0.8794900907,0.4031421393,-0.2529300217]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[33.16578395],\n\t\t\t\t[147.9736193],\n\t\t\t\t[327.8869733]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.331,0,369.444],\n\t\t\t\t[0,745.587,207.732],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317455,0.0357855,-0.00041249,0.000556817,0.0920153],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3142048567,0.04518634316,-0.9482792323],\n\t\t\t\t[-0.3166241188,0.9366885696,0.1495449465],\n\t\t\t\t[0.8949997069,0.3472358248,-0.2800050117]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.61359186],\n\t\t\t\t[187.9055539],\n\t\t\t\t[317.8889871]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[747.25,0,346.366],\n\t\t\t\t[0,747.394,225.779],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328454,0.0750084,3.92686e-05,0.00130952,0.0669429],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2993781475,0.05639323365,-0.9524665495],\n\t\t\t\t[-0.3171785116,0.9355987261,0.1550897014],\n\t\t\t\t[0.8998725002,0.3485323901,-0.2622110915]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.58039626],\n\t\t\t\t[195.4066632],\n\t\t\t\t[317.2443523]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[743.861,0,344.414],\n\t\t\t\t[0,743.872,231.421],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307564,-0.0231037,-0.000140407,-0.000635225,0.208058],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2583036736,0.07116007646,-0.9634393887],\n\t\t\t\t[-0.3357690773,0.9284960528,0.1586007776],\n\t\t\t\t[0.905835713,0.3644603181,-0.2159405881]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[14.66480509],\n\t\t\t\t[172.1699927],\n\t\t\t\t[320.6722019]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.949,0,378.98],\n\t\t\t\t[0,744.921,225.408],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321047,0.0567081,-0.000162218,0.000699701,0.0634367],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3208579847,0.07871363947,-0.9438507915],\n\t\t\t\t[-0.3472646452,0.9173632389,0.1945557869],\n\t\t\t\t[0.8811682132,0.3901907879,-0.267008856]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.70363788],\n\t\t\t\t[100.2282059],\n\t\t\t\t[322.9364507]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.712,0,360.895],\n\t\t\t\t[0,745.741,234.163],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31006,-0.0103454,0.000398478,0.000813845,0.181221],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3227895896,0.1367774117,-0.9365355415],\n\t\t\t\t[-0.3406635237,0.9063958148,0.2497898928],\n\t\t\t\t[0.8830375102,0.3996730746,-0.245980058]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.93002532],\n\t\t\t\t[154.0180569],\n\t\t\t\t[326.396188]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.931,0,372.193],\n\t\t\t\t[0,746.03,212.813],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325757,0.0830346,-0.000419051,0.00216162,0.0290765],\n\t\t\t\"R\": [\n\t\t\t\t[-0.311559769,0.02363818266,-0.9499324958],\n\t\t\t\t[-0.312276077,0.9416182622,0.1258518973],\n\t\t\t\t[0.8974486961,0.3358515813,-0.2859887293]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.03283731],\n\t\t\t\t[153.3338286],\n\t\t\t\t[314.9665339]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.756,0,368.403],\n\t\t\t\t[0,744.752,202.816],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313223,0.00720848,-0.00119606,0.000542174,0.130737],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3236003046,0.09291211415,-0.9416210394],\n\t\t\t\t[-0.3175516679,0.9267842511,0.2005788875],\n\t\t\t\t[0.8913157584,0.3639207207,-0.2704032691]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.098271],\n\t\t\t\t[130.5289196],\n\t\t\t\t[319.7107876]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[744.889,0,373.989],\n\t\t\t\t[0,745.092,230.989],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319065,0.0283013,-0.000935078,-0.000739787,0.111424],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3391260928,0.0773602665,-0.9375547357],\n\t\t\t\t[-0.3008220503,0.9353680392,0.1859911968],\n\t\t\t\t[0.8913470633,0.3451116057,-0.2939360344]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.38901828],\n\t\t\t\t[189.8595323],\n\t\t\t\t[315.0907711]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.21,0,358.424],\n\t\t\t\t[0,743.138,251.445],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316603,0.00648778,0.000375455,-0.000277526,0.16085],\n\t\t\t\"R\": [\n\t\t\t\t[-0.34774011,0.09728469559,-0.9325301624],\n\t\t\t\t[-0.3453355468,0.9113903597,0.2238548019],\n\t\t\t\t[0.8716766465,0.399879107,-0.2833311204]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-13.32995299],\n\t\t\t\t[105.9918293],\n\t\t\t\t[324.8353482]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.315,0,375.798],\n\t\t\t\t[0,745.342,214.671],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317661,0.021421,-0.000865931,0.000266434,0.124612],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2889220833,0.06736289331,-0.9549797225],\n\t\t\t\t[-0.355115135,0.918816287,0.172249446],\n\t\t\t\t[0.8890541438,0.3888944219,-0.2415447329]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.18922492],\n\t\t\t\t[101.394333],\n\t\t\t\t[324.5371374]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[743.803,0,341.335],\n\t\t\t\t[0,743.805,238.935],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305727,-0.0577903,-0.000702133,-0.00085287,0.249773],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2867564999,0.0564691645,-0.9563377767],\n\t\t\t\t[-0.3641939053,0.9168870998,0.1633427245],\n\t\t\t\t[0.8860775977,0.3951319776,-0.24235761]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[29.77890794],\n\t\t\t\t[113.785435],\n\t\t\t\t[325.4988706]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.285,0,373.625],\n\t\t\t\t[0,745.232,235.431],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319503,0.0483306,-0.000362012,0.00120612,0.080115],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3458253526,0.08893014684,-0.9340750797],\n\t\t\t\t[-0.3902640321,0.8916714915,0.2293816395],\n\t\t\t\t[0.8532870623,0.4438618933,-0.2736563703]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.96316513],\n\t\t\t\t[116.1979138],\n\t\t\t\t[333.2100324]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.536,0,366.592],\n\t\t\t\t[0,744.501,224.531],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312705,-0.014521,0.000375544,8.36622e-05,0.188212],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3181142509,0.09038767844,-0.94373375],\n\t\t\t\t[-0.4081954831,0.8853909401,0.2223945386],\n\t\t\t\t[0.8556750382,0.455974726,-0.2447596336]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.972278595],\n\t\t\t\t[119.3141773],\n\t\t\t\t[334.5341124]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"06_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 6,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.6,0,358.514],\n\t\t\t\t[0,744.655,220.515],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30152,-0.0573254,-0.000856409,-0.000288003,0.227002],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3545583501,0.05661769889,-0.9333181732],\n\t\t\t\t[-0.3227337004,0.929412527,0.1789841147],\n\t\t\t\t[0.8775712706,0.3646735401,-0.3112585327]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-25.22428756],\n\t\t\t\t[139.0090865],\n\t\t\t\t[319.514146]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.635,0,384.154],\n\t\t\t\t[0,745.75,223.733],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328279,0.104082,-0.000872931,0.00144148,0.00404207],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9078071857,0.03344162453,-0.4180523547],\n\t\t\t\t[0.00958043905,0.9982092569,0.05904654639],\n\t\t\t\t[0.4192783428,0.049597754,-0.9065019217]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.31434773],\n\t\t\t\t[152.0493649],\n\t\t\t\t[282.3431498]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.944,0,375.746],\n\t\t\t\t[0,747.112,207.581],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321827,0.078307,-0.00112183,4.35862e-05,0.0396046],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9306435439,0.005427673037,-0.3658867782],\n\t\t\t\t[-0.02457764723,0.9967049447,0.07729936951],\n\t\t\t\t[0.3651007167,0.08093079535,-0.9274436225]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.01828104],\n\t\t\t\t[131.8151818],\n\t\t\t\t[284.3018088]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[743.881,0,383.122],\n\t\t\t\t[0,743.965,237.105],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311008,0.000325185,-0.000782967,0.00055371,0.154469],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9217631286,0.06528892794,-0.3822173342],\n\t\t\t\t[0.03992506463,0.996464058,0.07392814261],\n\t\t\t\t[0.3856925251,0.05288418425,-0.9211104924]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.22640533],\n\t\t\t\t[121.5976731],\n\t\t\t\t[282.3432951]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[743.69,0,370.307],\n\t\t\t\t[0,743.828,227.79],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303025,-0.0263668,-0.000445815,0.00071591,0.180166],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9409979296,0.06863452498,-0.3313792366],\n\t\t\t\t[0.04529042225,0.9959498431,0.07767037874],\n\t\t\t\t[0.3353679682,0.05807936004,-0.9402952269]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-38.37277115],\n\t\t\t\t[113.0266013],\n\t\t\t\t[281.4230584]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[743.998,0,375.484],\n\t\t\t\t[0,744.299,220.79],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310908,0.00595719,-5.69241e-05,0.000519591,0.131448],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9269484075,0.08594630429,-0.3652121064],\n\t\t\t\t[0.04467826469,0.9917683984,0.1199970688],\n\t\t\t\t[0.3725191305,0.09491404865,-0.9231580692]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.36597135],\n\t\t\t\t[80.23534001],\n\t\t\t\t[286.4206576]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.602,0,379.444],\n\t\t\t\t[0,745.67,224.268],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303286,-0.0402497,-0.00132196,0.00012981,0.210105],\n\t\t\t\"R\": [\n\t\t\t\t[-0.923694641,0.09319000989,-0.3716232396],\n\t\t\t\t[0.04673933936,0.9901316615,0.1321163393],\n\t\t\t\t[0.3802678586,0.1046657299,-0.9189349491]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.9450645075],\n\t\t\t\t[68.69008136],\n\t\t\t\t[287.3198917]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.731,0,365.823],\n\t\t\t\t[0,745.481,229.263],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308219,-0.0231519,0.000110727,0.000180113,0.209056],\n\t\t\t\"R\": [\n\t\t\t\t[-0.917494877,0.04967698427,-0.3946331815],\n\t\t\t\t[0.001316203411,0.9925436367,0.1218827179],\n\t\t\t\t[0.3977454189,0.1113073518,-0.9107190869]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.92434207],\n\t\t\t\t[79.05208738],\n\t\t\t\t[288.1952445]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.611,0,393.911],\n\t\t\t\t[0,745.863,244.069],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318705,0.0460564,0.000184451,0.000507881,0.0745222],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9083609307,0.09070031,-0.4082326216],\n\t\t\t\t[0.05268537174,0.9932388068,0.1034452715],\n\t\t\t\t[0.4148550001,0.07245775567,-0.9069979066]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.31394514],\n\t\t\t\t[81.42535523],\n\t\t\t\t[283.8217571]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.77,0,370.33],\n\t\t\t\t[0,746.047,217.48],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321786,0.069205,4.67533e-05,5.58471e-05,0.0372207],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9211612824,0.007939579541,-0.3891000576],\n\t\t\t\t[-0.02433705705,0.996659961,0.07795274024],\n\t\t\t\t[0.3884193603,0.08127659646,-0.9178913418]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[49.65486911],\n\t\t\t\t[97.0413663],\n\t\t\t\t[285.6851525]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.504,0,363.969],\n\t\t\t\t[0,744.833,247.068],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335916,0.144192,-0.000823922,-0.000462503,-0.076361],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9225918644,-0.01579725191,-0.3854538864],\n\t\t\t\t[-0.05416624958,0.9945677902,0.08888716518],\n\t\t\t\t[0.381955847,0.1028851669,-0.9184358297]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.86826856],\n\t\t\t\t[113.0714764],\n\t\t\t\t[288.4804376]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.999,0,387.199],\n\t\t\t\t[0,745.384,239.21],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313806,0.0330336,-7.01628e-05,0.00132279,0.0985619],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9109471902,-0.006922747781,-0.4124648981],\n\t\t\t\t[-0.04540685091,0.9954664163,0.08357530662],\n\t\t\t\t[0.4100163832,0.09486142287,-0.9071316751]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[65.64483344],\n\t\t\t\t[130.0336458],\n\t\t\t\t[285.8729547]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.664,0,350.646],\n\t\t\t\t[0,743.861,222.503],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.300623,-0.0667329,-0.000394627,-0.00107967,0.272621],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9268683851,0.02536908581,-0.3745282449],\n\t\t\t\t[0.006256924582,0.9986192343,0.0521581796],\n\t\t\t\t[0.3753343145,0.04600037271,-0.9257473295]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.10937388],\n\t\t\t\t[163.0891099],\n\t\t\t\t[280.8513179]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.176,0,390.977],\n\t\t\t\t[0,744.332,246.666],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327257,0.10216,-0.000582688,0.00201022,0.0126373],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9290120658,-0.01909429991,-0.3695564765],\n\t\t\t\t[-0.04453762663,0.9971777882,0.06043888335],\n\t\t\t\t[0.3673594716,0.07260762025,-0.9272406117]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.5211548],\n\t\t\t\t[160.1280328],\n\t\t\t\t[285.2494721]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.044,0,360.721],\n\t\t\t\t[0,744.333,226.474],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311296,-0.00746755,-0.00165304,-0.000168766,0.17966],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9305033137,0.06302128148,-0.3608211486],\n\t\t\t\t[0.03165130136,0.9952368859,0.09220485899],\n\t\t\t\t[0.3649133847,0.07437646791,-0.9280659258]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.8814582],\n\t\t\t\t[178.0304645],\n\t\t\t\t[285.6034633]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[744.03,0,362.147],\n\t\t\t\t[0,744.447,229.329],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314413,0.0379836,-0.000745365,2.01034e-05,0.0898919],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9265853662,0.03975182478,-0.373977742],\n\t\t\t\t[0.01411888978,0.9973739765,0.07103385017],\n\t\t\t\t[0.3758193929,0.06053877555,-0.9247133829]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.14446289],\n\t\t\t\t[185.021862],\n\t\t\t\t[282.5666312]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[743.673,0,368.897],\n\t\t\t\t[0,743.962,238.378],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314216,0.0200058,-0.0002257,-0.000345788,0.11969],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9350006114,0.024774913,-0.3537796777],\n\t\t\t\t[-0.006073372197,0.9962920776,0.08582080369],\n\t\t\t\t[0.354594093,0.08239113958,-0.9313832344]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.51100446],\n\t\t\t\t[168.6528502],\n\t\t\t\t[285.9762696]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.686,0,385.346],\n\t\t\t\t[0,745.049,227.767],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317176,0.0455424,-0.000136917,0.000534438,0.0739505],\n\t\t\t\"R\": [\n\t\t\t\t[-0.908638426,0.05327873405,-0.4141709639],\n\t\t\t\t[0.04010861029,0.9983767379,0.04043746577],\n\t\t\t\t[0.4156531128,0.02013121347,-0.9093004036]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.322164421],\n\t\t\t\t[189.4505625],\n\t\t\t\t[275.8940033]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[746.282,0,378.432],\n\t\t\t\t[0,746.624,237.775],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320382,0.058651,0.000451819,0.000534403,0.062414],\n\t\t\t\"R\": [\n\t\t\t\t[-0.916555331,0.01769811564,-0.3995160846],\n\t\t\t\t[-0.01470055472,0.9968539618,0.07788499561],\n\t\t\t\t[0.3996376094,0.077259016,-0.9134116408]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-37.37478029],\n\t\t\t\t[164.0712496],\n\t\t\t\t[285.8486829]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.687,0,374.362],\n\t\t\t\t[0,743.883,225.048],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322503,0.0715253,7.77555e-05,0.000517375,0.0539586],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9239544056,0.01616424802,-0.3821609261],\n\t\t\t\t[-0.020576852,0.9955594902,0.09185801365],\n\t\t\t\t[0.3819487525,0.09273628522,-0.9195189677]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-17.14443298],\n\t\t\t\t[133.4982453],\n\t\t\t\t[287.2304165]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.801,0,368.555],\n\t\t\t\t[0,746.033,233.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317685,0.0475287,-3.52395e-05,0.000512076,0.0805211],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9241543321,-0.01069440692,-0.3818696113],\n\t\t\t\t[-0.04324692472,0.9961108974,0.076764468],\n\t\t\t\t[0.3795635307,0.08745690199,-0.9210227014]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.56758847],\n\t\t\t\t[113.8864258],\n\t\t\t\t[286.5218078]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.1,0,390.405],\n\t\t\t\t[0,744.284,237.593],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322514,0.0588182,0.000321804,0.00147162,0.0689104],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9369369296,0.006948104691,-0.3494294118],\n\t\t\t\t[-0.02026391849,0.9970404822,0.07415962808],\n\t\t\t\t[0.3489105381,0.07656370335,-0.9340232522]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.618393153],\n\t\t\t\t[111.1940513],\n\t\t\t\t[285.5030449]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[747.001,0,381.032],\n\t\t\t\t[0,747.132,234.437],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324882,0.0577225,-0.00134011,-0.00135265,0.0819201],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9282296861,0.06047570579,-0.3670590401],\n\t\t\t\t[0.02337036389,0.9942284933,0.1047068731],\n\t\t\t\t[0.3712727784,0.08861372459,-0.9242857414]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[25.6408869],\n\t\t\t\t[119.8980517],\n\t\t\t\t[286.9452799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[743.981,0,363.51],\n\t\t\t\t[0,744.339,258.582],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313768,0.0101513,0.00111395,-0.00104272,0.1345],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9138255678,-0.001018785166,-0.4061056435],\n\t\t\t\t[-0.03060482875,0.9973259054,0.06636552484],\n\t\t\t\t[0.4049520663,0.0730753071,-0.9114130916]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.3580015],\n\t\t\t\t[146.5427691],\n\t\t\t\t[284.2261849]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"07_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 7,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.847,0,398.685],\n\t\t\t\t[0,745.01,270.264],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328511,0.106892,0.000179407,0.00152869,-0.00291861],\n\t\t\t\"R\": [\n\t\t\t\t[-0.915939158,0.01937877811,-0.4008490012],\n\t\t\t\t[-0.01852012751,0.9957282098,0.09045627137],\n\t\t\t\t[0.4008895904,0.09027621565,-0.9116675607]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.147743662],\n\t\t\t\t[145.7157982],\n\t\t\t\t[287.1579534]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[743.703,0,360.221],\n\t\t\t\t[0,744.108,227.682],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309411,-0.0239561,-0.001159,0.000249551,0.191643],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6256262875,-0.004424555618,-0.7801103586],\n\t\t\t\t[-0.1745259617,0.9754325172,0.134432485],\n\t\t\t\t[0.7603502068,0.2202540071,-0.6110284243]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.656398722],\n\t\t\t\t[175.9817187],\n\t\t\t\t[302.7764948]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.203,0,376.344],\n\t\t\t\t[0,747.435,209.923],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331616,0.11313,4.7739e-05,0.00134479,-0.0154118],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6724252099,0.1092176997,-0.7320627235],\n\t\t\t\t[-0.09964199407,0.9666926758,0.2357472025],\n\t\t\t\t[0.7334274403,0.2314665517,-0.6391458561]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.9742570867],\n\t\t\t\t[185.4525058],\n\t\t\t\t[305.0714088]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[747.234,0,368.091],\n\t\t\t\t[0,747.404,224.293],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329137,0.0905459,-0.000565165,-0.000329878,0.0231933],\n\t\t\t\"R\": [\n\t\t\t\t[-0.656899377,0.0205246652,-0.7536988435],\n\t\t\t\t[-0.2005757989,0.9588523348,0.2009267253],\n\t\t\t\t[0.7268098496,0.2831623883,-0.6257527502]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.7353206],\n\t\t\t\t[153.4285774],\n\t\t\t\t[313.8994992]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.386,0,362.788],\n\t\t\t\t[0,747.713,235.953],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.341304,0.154379,-0.000777774,-0.000654564,-0.0867958],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6631685233,0.06657565756,-0.7455033143],\n\t\t\t\t[-0.1433461882,0.9663011288,0.2138083224],\n\t\t\t\t[0.7346151238,0.2486560079,-0.6312771259]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.98714967],\n\t\t\t\t[144.6795235],\n\t\t\t\t[307.788251]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.746,0,376.748],\n\t\t\t\t[0,745.752,233.642],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32088,0.0642866,0.000720856,0.00118823,0.0489989],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6568191598,0.04935682433,-0.7524310568],\n\t\t\t\t[-0.1452125328,0.970898021,0.19044777],\n\t\t\t\t[0.7399337211,0.2343521638,-0.6305371929]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.15667108],\n\t\t\t\t[135.9397275],\n\t\t\t\t[306.138018]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[743.581,0,359.642],\n\t\t\t\t[0,743.625,223.766],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309434,-0.0145066,-0.000137344,-0.000208072,0.169515],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6714433509,-0.01781555577,-0.7408417054],\n\t\t\t\t[-0.2359597182,0.9528188479,0.1909430659],\n\t\t\t\t[0.7024861834,0.3030162521,-0.6439676336]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.25895983],\n\t\t\t\t[89.79547495],\n\t\t\t\t[311.6502108]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.148,0,371.237],\n\t\t\t\t[0,745.103,220.621],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318768,0.034703,-0.000217256,0.000447556,0.0954449],\n\t\t\t\"R\": [\n\t\t\t\t[-0.7012843801,0.01049644172,-0.7128043511],\n\t\t\t\t[-0.1276034542,0.9818947595,0.1400001421],\n\t\t\t\t[0.7013683602,0.1891362102,-0.6872480755]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.70728874],\n\t\t\t\t[118.2041714],\n\t\t\t\t[298.0588141]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[743.06,0,391.891],\n\t\t\t\t[0,743.237,230.861],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322908,0.0553375,0.000339696,0.00130059,0.0777268],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6299217379,0.07604043096,-0.7729272003],\n\t\t\t\t[-0.1362742651,0.9689348188,0.2063846932],\n\t\t\t\t[0.7646096578,0.2353362908,-0.5999907511]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.915515028],\n\t\t\t\t[82.19520224],\n\t\t\t\t[306.2551203]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.456,0,356.955],\n\t\t\t\t[0,746.592,233.352],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320498,0.0507213,0.000550471,0.000126643,0.0741224],\n\t\t\t\"R\": [\n\t\t\t\t[-0.684872543,0.06612723284,-0.7256561093],\n\t\t\t\t[-0.09767122593,0.9785553778,0.1813551881],\n\t\t\t\t[0.7220872049,0.1950809107,-0.6637269822]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.194765679],\n\t\t\t\t[87.40737989],\n\t\t\t\t[301.7039487]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.33,0,361.528],\n\t\t\t\t[0,747.71,220.883],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322455,0.0389243,0.00118705,0.000768992,0.12227],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6055801648,0.01225702185,-0.7956899079],\n\t\t\t\t[-0.1760343759,0.973047512,0.1489645524],\n\t\t\t\t[0.7760699469,0.2302787546,-0.5871006154]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.64204154],\n\t\t\t\t[89.24589085],\n\t\t\t\t[303.2777117]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[747.774,0,350.264],\n\t\t\t\t[0,747.981,233.163],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312094,-0.0263709,0.00148203,-0.000526901,0.233175],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6738094891,0.06987822761,-0.7355935058],\n\t\t\t\t[-0.1142917175,0.9736808734,0.1971876265],\n\t\t\t\t[0.730012449,0.216939139,-0.6480889092]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.79986479],\n\t\t\t\t[83.7107121],\n\t\t\t\t[303.8218457]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.899,0,366.47],\n\t\t\t\t[0,744.848,222.726],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30396,-0.0418844,-0.00058576,-0.000160605,0.231689],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6160341517,-0.01803679921,-0.7875129191],\n\t\t\t\t[-0.1884772348,0.9740736778,0.1251271436],\n\t\t\t\t[0.7648387123,0.2255108512,-0.6034621779]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.57356311],\n\t\t\t\t[97.36793025],\n\t\t\t\t[301.4047959]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[746.859,0,368.586],\n\t\t\t\t[0,747.139,224.684],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318047,0.0428323,-0.000551709,0.000692584,0.0895927],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6485099772,-0.04236983322,-0.7600260566],\n\t\t\t\t[-0.2235198928,0.9650338886,0.1369249841],\n\t\t\t\t[0.7276494121,0.258678161,-0.6353046057]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[38.13208236],\n\t\t\t\t[106.9572182],\n\t\t\t\t[307.8393222]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.505,0,357.32],\n\t\t\t\t[0,744.53,228.165],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303025,-0.0702212,0.000533599,-0.000753966,0.269146],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6825611814,-0.04644305139,-0.729351271],\n\t\t\t\t[-0.1871280484,0.9758162042,0.1129859684],\n\t\t\t\t[0.7064653757,0.213601916,-0.6747450588]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.82592662],\n\t\t\t\t[132.5834032],\n\t\t\t\t[304.3020009]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.837,0,357.73],\n\t\t\t\t[0,745.88,221.629],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3197,0.0439542,-0.00136466,0.00170195,0.109142],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6069626381,-0.02117938565,-0.7944481037],\n\t\t\t\t[-0.2107505505,0.968144583,0.1352045554],\n\t\t\t\t[0.7662770787,0.2494944888,-0.5920911574]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[64.87618524],\n\t\t\t\t[141.1933336],\n\t\t\t\t[303.6799609]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.767,0,345.102],\n\t\t\t\t[0,744.781,229.581],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307131,-0.033453,0.0002274,-0.000565369,0.224073],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6350262321,-0.03398669713,-0.7717425665],\n\t\t\t\t[-0.2527580664,0.9531820242,0.1660041824],\n\t\t\t\t[0.7299692079,0.3004811693,-0.6138860012]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.611726],\n\t\t\t\t[134.434862],\n\t\t\t\t[314.3473002]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[743.543,0,370.548],\n\t\t\t\t[0,743.847,224.118],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308645,-0.0111516,9.80345e-05,-0.000744439,0.160705],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6124225565,-0.05791042639,-0.7884066177],\n\t\t\t\t[-0.1936876385,0.977907652,0.07862393367],\n\t\t\t\t[0.7664357188,0.2008556864,-0.610109238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[28.62018644],\n\t\t\t\t[186.6213498],\n\t\t\t\t[297.6164741]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[743.39,0,376.249],\n\t\t\t\t[0,743.751,216.723],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319375,0.0602092,-1.05699e-05,0.00110696,0.0487054],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6887185447,0.08181736584,-0.720397588],\n\t\t\t\t[-0.1043667464,0.9720764384,0.2101784484],\n\t\t\t\t[0.7174777686,0.2199393475,-0.6609480577]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.48604056],\n\t\t\t\t[189.7333893],\n\t\t\t\t[302.8177068]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[747.038,0,360.923],\n\t\t\t\t[0,747.259,204.023],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32724,0.0825647,-0.000697091,0.000733699,0.0397455],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6726100217,0.03848005322,-0.7389959704],\n\t\t\t\t[-0.1487286588,0.9712392562,0.1859411014],\n\t\t\t\t[0.7248969201,0.2349757278,-0.6475421705]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.177324598],\n\t\t\t\t[151.0352965],\n\t\t\t\t[305.3818706]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[747.914,0,388.693],\n\t\t\t\t[0,747.835,242.83],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.338429,0.134609,0.00136964,0.000561914,-0.0365273],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6685313457,0.02780025068,-0.7431641715],\n\t\t\t\t[-0.1765857142,0.9647874561,0.194942684],\n\t\t\t\t[0.722414926,0.2615574708,-0.6400815293]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.15175066],\n\t\t\t\t[129.456494],\n\t\t\t\t[308.9585645]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.296,0,369.274],\n\t\t\t\t[0,746.424,219.198],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312598,-0.010091,-0.000298989,-0.000771876,0.160922],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6341455554,-0.01222382885,-0.7731170626],\n\t\t\t\t[-0.1896201401,0.9718007188,0.1401697733],\n\t\t\t\t[0.7496023059,0.2354866044,-0.6185809907]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.414673774],\n\t\t\t\t[116.5175191],\n\t\t\t\t[305.5663378]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[743.609,0,361.562],\n\t\t\t\t[0,743.794,221.87],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314273,0.00142644,4.14402e-05,0.000150079,0.159707],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6552794634,-0.0176584532,-0.7551801135],\n\t\t\t\t[-0.2007508014,0.9678470127,0.1515627784],\n\t\t\t\t[0.7282224527,0.2509189891,-0.6377552198]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.541098798],\n\t\t\t\t[103.6271831],\n\t\t\t\t[307.0310837]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[748.435,0,354.117],\n\t\t\t\t[0,748.457,219.552],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324308,0.0627041,-0.000215295,-0.000444561,0.0758056],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6485698923,-0.03356212054,-0.7604148071],\n\t\t\t\t[-0.2015811272,0.9709293787,0.1290782349],\n\t\t\t\t[0.733976937,0.2370015309,-0.6364810526]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.56445448],\n\t\t\t\t[121.4098798],\n\t\t\t\t[305.3725739]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"08_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 8,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.572,0,350.678],\n\t\t\t\t[0,745.729,218.826],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313081,0.00890587,-0.000465969,-0.00023462,0.141032],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6716141,0.00283216084,-0.7408957278],\n\t\t\t\t[-0.1390702972,0.9817365211,0.1298185488],\n\t\t\t\t[0.7277320613,0.1902245569,-0.6589542206]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.95231346],\n\t\t\t\t[154.9907046],\n\t\t\t\t[298.6967118]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.377,0,383.314],\n\t\t\t\t[0,745.581,229.65],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311824,0.0113225,-0.000890232,0.000288511,0.13186],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9888207636,0.1490770148,-0.003088867539],\n\t\t\t\t[0.1339941062,0.8974831076,0.420201917],\n\t\t\t\t[0.06541465384,0.4150904904,-0.9074253732]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.5065201],\n\t\t\t\t[83.70733211],\n\t\t\t\t[330.6651976]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[745.133,0,380.598],\n\t\t\t\t[0,746.347,248.499],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.340543,0.0603048,-0.00219925,-0.00194065,0.128165],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9728033822,0.2090533065,0.09975116351],\n\t\t\t\t[0.2316107347,0.8720009628,0.4312433055],\n\t\t\t\t[0.003169728315,0.4426183864,-0.8967044758]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.76195567],\n\t\t\t\t[58.26386366],\n\t\t\t\t[329.69794]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[745.787,0,382.41],\n\t\t\t\t[0,745.973,216.203],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309439,0.00115788,-0.000439278,0.00154239,0.140783],\n\t\t\t\"R\": [\n\t\t\t\t[-0.995096801,0.09728424012,-0.01783629191],\n\t\t\t\t[0.08253738581,0.9161639792,0.3922131349],\n\t\t\t\t[0.05449712496,0.3888178749,-0.9197014317]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.72584843],\n\t\t\t\t[65.39953055],\n\t\t\t\t[327.4514754]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.782,0,384.335],\n\t\t\t\t[0,745.051,230.833],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319171,0.0452003,0.000841339,0.00114337,0.0902557],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9962766095,0.08536470964,0.01207409478],\n\t\t\t\t[0.0830687393,0.9129812009,0.3994557689],\n\t\t\t\t[0.02307600417,0.3989714189,-0.9166729542]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.91980994],\n\t\t\t\t[75.72355875],\n\t\t\t\t[328.4117918]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.938,0,386.124],\n\t\t\t\t[0,746.151,234.663],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322825,0.0563734,0.000659785,0.00216478,0.0846192],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9996885429,0.02460566921,0.004168718214],\n\t\t\t\t[0.02372582958,0.8852416043,0.464525981],\n\t\t\t\t[0.007739649829,0.4644802074,-0.8855496794]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.79490616],\n\t\t\t\t[45.57973364],\n\t\t\t\t[333.4360246]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.533,0,376.456],\n\t\t\t\t[0,745.938,237.583],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324418,0.0645728,-2.52302e-05,0.000695669,0.0784542],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9996292032,0.0242501169,-0.01238498622],\n\t\t\t\t[0.01720849374,0.9151046106,0.4028491273],\n\t\t\t\t[0.02110269642,0.4024866252,-0.9151826008]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[44.50201086],\n\t\t\t\t[83.15135806],\n\t\t\t\t[329.4460526]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.538,0,357.165],\n\t\t\t\t[0,745.859,222.198],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30448,-0.0356601,-0.000261684,-0.000249049,0.226264],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9994703128,-0.005373675551,-0.03209699996],\n\t\t\t\t[-0.01769948118,0.9174086112,0.3975527241],\n\t\t\t\t[0.02730974481,0.3979102457,-0.9170177829]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.28939518],\n\t\t\t\t[107.3778293],\n\t\t\t\t[329.1138759]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[746.393,0,361.584],\n\t\t\t\t[0,746.73,220.937],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31726,0.0513551,0.000643529,-0.000795525,0.0635312],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9973050313,-0.005865573042,-0.0731318648],\n\t\t\t\t[-0.03181904441,0.9327538711,0.3591068981],\n\t\t\t\t[0.06610766226,0.3604661023,-0.9304267656]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[64.05594666],\n\t\t\t\t[137.6750859],\n\t\t\t\t[322.0323762]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[750.271,0,344.156],\n\t\t\t\t[0,750.817,228.346],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.379154,0.391779,0.000225814,-0.000528714,-0.53339],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9991212371,-0.002089946585,-0.04186150665],\n\t\t\t\t[-0.01685937738,0.9344344151,0.355735977],\n\t\t\t\t[0.03837336329,0.3561291283,-0.933648504]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.49527243],\n\t\t\t\t[159.1149955],\n\t\t\t\t[322.66132]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.897,0,366.998],\n\t\t\t\t[0,745.389,227.752],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317307,0.0499201,-0.000255849,-0.000414203,0.0689696],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9956077306,0.03830608065,-0.08542769468],\n\t\t\t\t[0.005132094192,0.9334237661,0.3587390896],\n\t\t\t\t[0.093482129,0.3567249879,-0.9295205079]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.9897871],\n\t\t\t\t[163.3127669],\n\t\t\t\t[320.2676037]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.812,0,365.568],\n\t\t\t\t[0,746.463,243.927],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334591,0.135033,-0.000586766,0.000648781,-0.0516408],\n\t\t\t\"R\": [\n\t\t\t\t[-0.998272905,0.02856351314,-0.05133549401],\n\t\t\t\t[0.007150624435,0.926422355,0.3764179707],\n\t\t\t\t[0.05831016891,0.3754007803,-0.9250265825]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.7749059],\n\t\t\t\t[177.7642897],\n\t\t\t\t[325.0135255]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.195,0,380.908],\n\t\t\t\t[0,743.577,227.789],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308886,-0.0148964,-0.00146189,1.64512e-05,0.167268],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9994731762,0.02727182579,0.01759595347],\n\t\t\t\t[0.03184982914,0.9284235071,0.3701558858],\n\t\t\t\t[-0.006241669996,0.370521307,-0.9288029945]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.9618436208],\n\t\t\t\t[187.4005014],\n\t\t\t\t[324.424529]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[745.52,0,396.637],\n\t\t\t\t[0,745.641,231.295],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327971,0.0908214,-0.00010844,0.00165709,0.0286999],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9916965419,0.1263943494,0.02371575794],\n\t\t\t\t[0.1244737261,0.8970729317,0.4239887342],\n\t\t\t\t[0.03231501572,0.4234201503,-0.9053568998]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.62306638],\n\t\t\t\t[150.537484],\n\t\t\t\t[333.7640249]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.91,0,372.463],\n\t\t\t\t[0,744.965,226.423],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308854,-0.0214085,8.99951e-05,0.000256405,0.180188],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9924146786,0.1180105859,0.03444716585],\n\t\t\t\t[0.1215225705,0.8993517426,0.4199984619],\n\t\t\t\t[0.01858414592,0.4209987468,-0.9068708203]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.68067405],\n\t\t\t\t[162.2988485],\n\t\t\t\t[333.0026074]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.246,0,368.718],\n\t\t\t\t[0,747.604,232.745],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3413,0.139342,-0.00187439,-0.000934376,-0.0485015],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9858543141,0.1593536378,0.05193928607],\n\t\t\t\t[0.1663907088,0.8933064559,0.4175137217],\n\t\t\t\t[0.02013463084,0.4202499184,-0.9071849882]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.61956214],\n\t\t\t\t[147.1949584],\n\t\t\t\t[331.9981158]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[743.705,0,367.288],\n\t\t\t\t[0,743.835,246.124],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316616,0.0215265,-3.02132e-05,0.000242548,0.131229],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9974602961,0.07055123587,0.009771425173],\n\t\t\t\t[0.06902048446,0.9235857212,0.3771280794],\n\t\t\t\t[0.01758210332,0.3768447143,-0.9261095675]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.73982653],\n\t\t\t\t[139.9628037],\n\t\t\t\t[324.9351286]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[742.776,0,376.251],\n\t\t\t\t[0,742.956,242.934],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317736,0.0249159,0.000195501,0.000659428,0.110976],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9810894361,0.1806813104,0.06941024814],\n\t\t\t\t[0.1934432758,0.9031273242,0.3833284952],\n\t\t\t\t[0.006574003146,0.389506483,-0.9210002618]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.91453507],\n\t\t\t\t[125.2651482],\n\t\t\t\t[325.9500645]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[744.563,0,383.579],\n\t\t\t\t[0,744.554,245.613],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324188,0.0688729,0.000784842,0.000316148,0.0548859],\n\t\t\t\"R\": [\n\t\t\t\t[-0.970594512,0.2257141743,0.08366244524],\n\t\t\t\t[0.2406675117,0.9026066179,0.3569039677],\n\t\t\t\t[0.005044007626,0.3665438649,-0.9303870985]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.64851648],\n\t\t\t\t[114.5848432],\n\t\t\t\t[323.1694161]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.897,0,369.27],\n\t\t\t\t[0,746.007,226.27],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314378,0.0131268,-0.000749673,-0.000436078,0.140449],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9929061616,0.1118291068,0.04039313118],\n\t\t\t\t[0.1187797946,0.9175946163,0.3793566667],\n\t\t\t\t[0.005358597494,0.3814634596,-0.9243683867]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.348770156],\n\t\t\t\t[111.4514571],\n\t\t\t\t[325.9373984]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[743.647,0,378.532],\n\t\t\t\t[0,743.859,221.629],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312883,-0.00145442,-0.000725648,-1.91192e-05,0.160115],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9995005243,0.01416777706,-0.02824846864],\n\t\t\t\t[0.002450265794,0.9259270935,0.3776943389],\n\t\t\t\t[0.03150711165,0.3774364735,-0.9254993303]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.861259295],\n\t\t\t\t[105.360829],\n\t\t\t\t[326.1962043]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.35,0,364.423],\n\t\t\t\t[0,745.51,242.824],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317615,0.0309367,1.60295e-05,-0.00084218,0.138729],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9983267687,0.03243769532,-0.0478691851],\n\t\t\t\t[0.01510269673,0.9453721551,0.3256430514],\n\t\t\t\t[0.05581730476,0.3243752215,-0.9442802255]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.85545331],\n\t\t\t\t[138.1219419],\n\t\t\t\t[318.1793043]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.248,0,356.027],\n\t\t\t\t[0,744.436,238.226],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308137,-0.0481761,0.000357682,-8.3696e-05,0.245728],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9955839097,0.09158830299,-0.0205976113],\n\t\t\t\t[0.07579544873,0.9137019347,0.3992540852],\n\t\t\t\t[0.05538708142,0.3959297379,-0.9166089209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.25988756],\n\t\t\t\t[131.4528362],\n\t\t\t\t[328.3382973]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.535,0,363.359],\n\t\t\t\t[0,744.632,254.668],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311847,-0.00198079,0.000462082,-0.000460419,0.174118],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9946906764,0.1028474748,0.003585412436],\n\t\t\t\t[0.09771594436,0.9329851386,0.346396197],\n\t\t\t\t[0.03228083764,0.3449074195,-0.9380814567]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.3985171],\n\t\t\t\t[157.8437238],\n\t\t\t\t[320.5381764]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"09_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 9,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[743.311,0,385.98],\n\t\t\t\t[0,743.511,229.743],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319602,0.0480118,-0.000790169,0.000699953,0.0704098],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9986396845,0.04700092247,-0.02257640097],\n\t\t\t\t[0.03617494752,0.9363507866,0.3491970469],\n\t\t\t\t[0.03755201414,0.3479053287,-0.93677731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.936415104],\n\t\t\t\t[142.1371611],\n\t\t\t\t[321.4431282]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.128,0,369.511],\n\t\t\t\t[0,744.056,233.67],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31156,0.00550691,-0.000430053,0.000410016,0.149166],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6229970612,0.0209936641,0.781942407],\n\t\t\t\t[0.05250109858,0.9985078863,0.01502117145],\n\t\t\t\t[-0.7804603106,0.05041098106,-0.6231696692]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.84686717],\n\t\t\t\t[150.7389104],\n\t\t\t\t[280.0083694]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.282,0,357.827],\n\t\t\t\t[0,743.347,211.632],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30948,-0.00718458,0.000285593,0.000547399,0.164062],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6512046155,0.0977241901,0.7525839032],\n\t\t\t\t[0.103617117,0.9938368806,-0.03939223155],\n\t\t\t\t[-0.7517952126,0.05232817138,-0.6573170626]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.32005533],\n\t\t\t\t[143.0774393],\n\t\t\t\t[282.200902]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.012,0,361.17],\n\t\t\t\t[0,744.101,225.217],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303567,-0.0563565,0.000757602,-0.000519388,0.263551],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6320598226,0.04182219841,0.773790207],\n\t\t\t\t[0.06737176964,0.9977273282,0.001106034268],\n\t\t\t\t[-0.771985379,0.05283069539,-0.6334409935]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-54.02554254],\n\t\t\t\t[119.7786683],\n\t\t\t\t[280.9354705]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.209,0,380.966],\n\t\t\t\t[0,744.256,205.476],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315194,0.0249601,-0.000765583,0.001001,0.10286],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6566261636,0.06356030055,0.7515332125],\n\t\t\t\t[0.0713368826,0.9972094103,-0.02201002698],\n\t\t\t\t[-0.7508349555,0.03915967697,-0.6593279831]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.38173011],\n\t\t\t\t[115.5645607],\n\t\t\t\t[280.9145253]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.499,0,353.834],\n\t\t\t\t[0,744.652,215.524],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317042,0.0236932,-0.00147688,-0.000206715,0.11602],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6480155592,0.1057846486,0.754244949],\n\t\t\t\t[0.1559047408,0.9877614348,-0.004589090624],\n\t\t\t\t[-0.7454995284,0.1146165612,-0.6565771067]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-17.37690425],\n\t\t\t\t[72.84298088],\n\t\t\t\t[287.4167752]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[746.493,0,367.328],\n\t\t\t\t[0,746.754,207.575],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323089,0.0587326,-0.000981175,-0.000221417,0.0550321],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6607542091,0.07289791872,0.74705406],\n\t\t\t\t[0.1340507848,0.9907326878,0.02188900409],\n\t\t\t\t[-0.738535214,0.1146064347,-0.6644028167]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.021864726],\n\t\t\t\t[64.04371811],\n\t\t\t\t[286.9062935]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.949,0,365.308],\n\t\t\t\t[0,744.944,217.014],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320697,0.0459897,0.000335318,2.89241e-06,0.0947246],\n\t\t\t\"R\": [\n\t\t\t\t[-0.643287111,0.03528116955,0.764811697],\n\t\t\t\t[0.0902182212,0.9954712387,0.02996140018],\n\t\t\t\t[-0.7602909742,0.08827373343,-0.6435568215]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.776307982],\n\t\t\t\t[84.51813798],\n\t\t\t\t[285.3816638]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[748.112,0,395.78],\n\t\t\t\t[0,748.17,229.575],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325424,0.0774932,-0.000546,0.000524276,0.0351183],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6241633069,0.05185263499,0.7795713377],\n\t\t\t\t[0.04102617023,0.9985938587,-0.03357318505],\n\t\t\t\t[-0.7802160084,0.0110276762,-0.6254129601]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.24758235],\n\t\t\t\t[183.5392889],\n\t\t\t\t[272.6641799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[746.122,0,370.333],\n\t\t\t\t[0,746.261,210.753],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323285,0.0813962,-0.00031195,0.00117949,0.0118242],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6717702835,0.002860846795,0.7407540089],\n\t\t\t\t[0.1085475528,0.9895782107,0.09461708989],\n\t\t\t\t[-0.7327633417,0.1439679842,-0.6650797731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[53.6134591],\n\t\t\t\t[78.01841366],\n\t\t\t\t[288.9552018]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.498,0,355.775],\n\t\t\t\t[0,746.616,218.183],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320479,0.0482256,-0.000295345,0.000515541,0.088746],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6274497943,0.01735785812,0.7784635254],\n\t\t\t\t[0.05740772193,0.9980618939,0.02401685623],\n\t\t\t\t[-0.7765378993,0.0597591891,-0.6272302051]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.32452291],\n\t\t\t\t[122.8912729],\n\t\t\t\t[283.9520693]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.209,0,387.948],\n\t\t\t\t[0,745.058,237.868],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312054,0.0106095,2.04654e-05,-0.000407432,0.122509],\n\t\t\t\"R\": [\n\t\t\t\t[-0.663538187,0.0558857692,0.74605218],\n\t\t\t\t[0.09086672278,0.9958436408,0.006219474654],\n\t\t\t\t[-0.742603739,0.07191817555,-0.6658584406]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[70.41193089],\n\t\t\t\t[130.903078],\n\t\t\t\t[283.3216663]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.923,0,359.191],\n\t\t\t\t[0,746.955,219.728],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.34193,0.180291,-0.0011698,0.000387434,-0.142263],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6573529902,0.02662022179,0.7531124817],\n\t\t\t\t[0.0203979596,0.9996382488,-0.01752982786],\n\t\t\t\t[-0.7533066902,0.003838673213,-0.6576581901]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.18715226],\n\t\t\t\t[173.543055],\n\t\t\t\t[273.2477614]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[747.063,0,362.554],\n\t\t\t\t[0,747.091,228.588],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334743,0.115617,-0.000133435,0.000763825,-0.0142674],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6314178936,0.07344004486,0.771957255],\n\t\t\t\t[0.07624079511,0.9965613541,-0.03244701456],\n\t\t\t\t[-0.7716856775,0.03836700932,-0.6348457984]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.63694261],\n\t\t\t\t[165.7689372],\n\t\t\t\t[279.8275089]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.722,0,380.721],\n\t\t\t\t[0,745.932,237.231],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319645,0.0532601,-0.00105825,0.00148804,0.0812854],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6464741699,0.0407242176,0.7618482039],\n\t\t\t\t[0.05782238306,0.998317631,-0.004298792509],\n\t\t\t\t[-0.7607415591,0.04127282036,-0.6477413331]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.16059778],\n\t\t\t\t[187.0284564],\n\t\t\t\t[279.5510011]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.212,0,345.945],\n\t\t\t\t[0,745.407,234.052],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.345973,0.208044,0.00063894,-0.000591324,-0.26389],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6892736753,0.06991501806,0.7211197479],\n\t\t\t\t[0.04097555303,0.9975016565,-0.0575451947],\n\t\t\t\t[-0.7233414164,-0.01011610737,-0.6904164394]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[38.38229011],\n\t\t\t\t[201.7157692],\n\t\t\t\t[268.6124541]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[746.402,0,351.743],\n\t\t\t\t[0,746.432,235.34],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332074,0.123634,0.000553061,0.000200886,-0.050504],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6626903808,0.1069713565,0.7412142659],\n\t\t\t\t[0.1159650419,0.9924654921,-0.03955194002],\n\t\t\t\t[-0.7398605059,0.05974425322,-0.6701022728]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.24762504],\n\t\t\t\t[172.5928493],\n\t\t\t\t[282.9657885]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.425,0,381.954],\n\t\t\t\t[0,745.576,234.397],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316953,0.0361047,-0.000329948,0.00146685,0.0995591],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6439914485,0.08005681888,0.7608323863],\n\t\t\t\t[0.04150323442,0.9967010496,-0.06974596286],\n\t\t\t\t[-0.7639060779,-0.01333879876,-0.6451895695]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.39474973],\n\t\t\t\t[198.5707312],\n\t\t\t\t[268.934139]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[742.866,0,374.357],\n\t\t\t\t[0,743.163,216.484],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313801,-0.00472223,0.00105562,-0.000883374,0.146196],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6735625977,0.03695414336,0.7382058102],\n\t\t\t\t[0.08136680684,0.9963864104,0.02436316713],\n\t\t\t\t[-0.7346379174,0.07647556771,-0.6741354596]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[41.81793908],\n\t\t\t\t[81.57199105],\n\t\t\t\t[283.0241236]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[747.195,0,374.317],\n\t\t\t\t[0,747.324,252.705],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325848,0.0754879,0.000850799,-0.000494425,0.0423325],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6398121174,0.03550225829,0.7677109118],\n\t\t\t\t[0.06489671873,0.9978603994,0.00793971962],\n\t\t\t\t[-0.7657864391,0.05490184793,-0.6407471551]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-18.67539454],\n\t\t\t\t[143.739157],\n\t\t\t\t[281.6554752]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.074,0,359.595],\n\t\t\t\t[0,744.232,222.54],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312038,-0.00652471,0.000517579,-0.000473896,0.154037],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6341018605,0.07503908623,0.769599874],\n\t\t\t\t[0.1134623387,0.9935365213,-0.003387984729],\n\t\t\t\t[-0.7648798129,0.08517227417,-0.6385174669]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.64771601],\n\t\t\t\t[114.6784971],\n\t\t\t\t[285.5473806]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.669,0,353.595],\n\t\t\t\t[0,745.986,221.41],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331248,0.0956435,-0.00124938,0.0010706,0.0394747],\n\t\t\t\"R\": [\n\t\t\t\t[-0.618235149,0.02815342604,0.7854888192],\n\t\t\t\t[0.09838720035,0.994269895,0.04180113162],\n\t\t\t\t[-0.7798110408,0.1031249747,-0.6174625335]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.462045404],\n\t\t\t\t[102.4105128],\n\t\t\t\t[287.5712577]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.836,0,367.536],\n\t\t\t\t[0,745.883,217.602],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306908,-0.0326669,-0.000283909,0.000278093,0.200484],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6189078213,0.03804187807,0.7845418563],\n\t\t\t\t[0.07413417155,0.9971968305,0.01012945108],\n\t\t\t\t[-0.7819573092,0.06443055706,-0.6199931209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[14.73270812],\n\t\t\t\t[126.5060302],\n\t\t\t\t[283.9045417]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[742.749,0,379.273],\n\t\t\t\t[0,742.868,231.204],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310394,-0.00460726,-0.000822068,-0.000336616,0.147608],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6037549899,0.1086195044,0.7897352186],\n\t\t\t\t[0.1215591915,0.9916324658,-0.04345590495],\n\t\t\t\t[-0.787847241,0.0697628552,-0.6119067485]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[19.26192194],\n\t\t\t\t[145.0128457],\n\t\t\t\t[284.7838402]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"10_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 10,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.597,0,368.627],\n\t\t\t\t[0,745.598,227.731],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309585,-0.00749389,-0.000770097,-0.000330202,0.147896],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6450785239,0.075478584,0.760379301],\n\t\t\t\t[0.07622559694,0.9965021766,-0.03425011393],\n\t\t\t\t[-0.7603047786,0.03586635318,-0.6485755533]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[7.856697427],\n\t\t\t\t[160.1393432],\n\t\t\t\t[279.1413867]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[742.855,0,374.596],\n\t\t\t\t[0,743.116,213.495],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312561,0.00631745,-0.000399255,9.31566e-05,0.13435],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9229364354,0.00164792287,0.3849488544],\n\t\t\t\t[0.08421827064,0.9766305816,0.1977371741],\n\t\t\t\t[-0.3756269679,0.2149185694,-0.9015067329]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.777017447],\n\t\t\t\t[176.3500352],\n\t\t\t\t[303.9155303]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.543,0,362.467],\n\t\t\t\t[0,743.612,228.587],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311508,-0.0063044,0.000209199,0.000389142,0.157517],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9382305089,-0.009495783218,0.3458805319],\n\t\t\t\t[0.07354737957,0.9713073762,0.226169768],\n\t\t\t\t[-0.338103971,0.2376379833,-0.9106118238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.88478771],\n\t\t\t\t[180.6527832],\n\t\t\t\t[308.9268929]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[749.382,0,384.698],\n\t\t\t\t[0,749.44,241.756],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334994,0.135003,0.000819921,0.00199466,-0.05032],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9215516186,0.03410543981,0.3867550042],\n\t\t\t\t[0.1287847641,0.966589567,0.2216282778],\n\t\t\t\t[-0.3662746221,0.2540500501,-0.895154441]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-28.84627719],\n\t\t\t\t[162.2565593],\n\t\t\t\t[311.7587167]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.478,0,355.1],\n\t\t\t\t[0,747.786,237.425],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332665,0.125805,0.000559145,-0.000285828,-0.0488142],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9186497576,-0.03493542623,0.3935252708],\n\t\t\t\t[0.05923251482,0.9726444983,0.2246200995],\n\t\t\t\t[-0.3906073886,0.2296566914,-0.8914503195]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.73591523],\n\t\t\t\t[146.455357],\n\t\t\t\t[306.7233507]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.546,0,358.346],\n\t\t\t\t[0,744.606,240.06],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319412,0.0357687,0.00118284,-0.000939418,0.105494],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9252091585,0.02778676908,0.3784387777],\n\t\t\t\t[0.1130706466,0.9721977994,0.2050523536],\n\t\t\t\t[-0.3622196044,0.2325066328,-0.9026281759]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.43063623],\n\t\t\t\t[134.4377466],\n\t\t\t\t[308.7383564]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.682,0,386.644],\n\t\t\t\t[0,744.47,247.576],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310524,-0.0156223,-0.000288596,-3.26402e-05,0.156674],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9144551399,0.0484228537,0.4017798207],\n\t\t\t\t[0.1449564791,0.9661327489,0.2134833264],\n\t\t\t\t[-0.3778351707,0.2534615133,-0.8905042645]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-44.21957265],\n\t\t\t\t[107.5274508],\n\t\t\t\t[309.8949628]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[746.436,0,349.001],\n\t\t\t\t[0,746.553,211.863],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330393,0.0902383,-0.000783974,-0.000712996,0.00481592],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9105637485,0.003264968682,0.4133557789],\n\t\t\t\t[0.1001837456,0.9718993559,0.2130137535],\n\t\t\t\t[-0.401044732,0.2353741321,-0.8853034174]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-36.21090107],\n\t\t\t\t[102.2867759],\n\t\t\t\t[306.6852556]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.743,0,370.625],\n\t\t\t\t[0,745.85,233.671],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3257,0.0614375,0.00126654,-0.000627381,0.0722474],\n\t\t\t\"R\": [\n\t\t\t\t[-0.8981193216,-0.01090147501,0.4396166989],\n\t\t\t\t[0.09488580103,0.9713398361,0.2179348702],\n\t\t\t\t[-0.4293930238,0.2374449004,-0.8713446794]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.17364239],\n\t\t\t\t[80.07059019],\n\t\t\t\t[305.3107943]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[743.294,0,376.993],\n\t\t\t\t[0,743.306,225.516],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315184,-0.00458353,0.00085295,-0.000315923,0.19344],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9287334953,0.02657190893,0.369794576],\n\t\t\t\t[0.1072763174,0.9740215576,0.1994336907],\n\t\t\t\t[-0.354888555,0.2248909489,-0.9074569822]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.627896612],\n\t\t\t\t[76.0139061],\n\t\t\t\t[305.925361]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.981,0,373.015],\n\t\t\t\t[0,746.916,231.087],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31553,-0.0133214,-7.49701e-05,-0.000474937,0.183355],\n\t\t\t\"R\": [\n\t\t\t\t[-0.897589008,-0.01428097087,0.4406018914],\n\t\t\t\t[0.092180686,0.9712994893,0.219271574],\n\t\t\t\t[-0.431087803,0.2374307391,-0.8705113154]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.834972436],\n\t\t\t\t[85.69962032],\n\t\t\t\t[306.7617687]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.956,0,385.014],\n\t\t\t\t[0,743.968,233.944],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321873,0.0619652,-0.000204505,0.000631491,0.0680901],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9171447001,-0.01735780695,0.3981762243],\n\t\t\t\t[0.08629809142,0.9667012777,0.2409175774],\n\t\t\t\t[-0.3890992656,0.2553181275,-0.8851070078]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.82061991],\n\t\t\t\t[73.01187567],\n\t\t\t\t[307.7528197]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[749.192,0,349.167],\n\t\t\t\t[0,749.113,221.266],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334032,0.094759,-0.000689735,0.000727903,0.0409048],\n\t\t\t\"R\": [\n\t\t\t\t[-0.937850977,-0.03419002209,0.345349949],\n\t\t\t\t[0.06230645433,0.9623765935,0.2644791068],\n\t\t\t\t[-0.341399254,0.2695595196,-0.9004355695]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.17130279],\n\t\t\t\t[82.80130245],\n\t\t\t\t[306.825197]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.715,0,367.122],\n\t\t\t\t[0,744.786,220.538],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315954,0.0180051,3.91318e-05,0.000697083,0.145396],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9312656673,-0.01667316508,0.3639591494],\n\t\t\t\t[0.07039560041,0.9718946087,0.2246448954],\n\t\t\t\t[-0.3574754765,0.2348252013,-0.9039183639]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[46.96203938],\n\t\t\t\t[112.2947483],\n\t\t\t\t[304.8878272]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[746.505,0,367.697],\n\t\t\t\t[0,746.62,222.237],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323622,0.0629014,0.000917096,0.00064017,0.0716359],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9260527677,-0.07925799212,0.3689775632],\n\t\t\t\t[0.02937617957,0.9595934278,0.279852628],\n\t\t\t\t[-0.3762490021,0.2699974518,-0.8863058527]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.81898209],\n\t\t\t\t[116.0290364],\n\t\t\t\t[310.1255555]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.042,0,355.995],\n\t\t\t\t[0,745.821,261.077],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321065,0.0443736,0.000927074,0.000280863,0.106789],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9208600933,-0.04678508348,0.387076019],\n\t\t\t\t[0.03581020852,0.9784294414,0.2034538209],\n\t\t\t\t[-0.3882451771,0.2012137775,-0.8993212431]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[43.08113165],\n\t\t\t\t[154.6066575],\n\t\t\t\t[301.5640854]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[741.668,0,363.735],\n\t\t\t\t[0,741.796,217.06],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309875,-0.0179015,-1.19394e-05,-0.000437783,0.188022],\n\t\t\t\"R\": [\n\t\t\t\t[-0.8991061052,-0.0185684781,0.437336739],\n\t\t\t\t[0.0842559957,0.9730755765,0.214534029],\n\t\t\t\t[-0.4295452698,0.2297370977,-0.873333686]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.70791642],\n\t\t\t\t[154.14567],\n\t\t\t\t[307.2679797]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[747.822,0,361.761],\n\t\t\t\t[0,747.76,222.34],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334628,0.097635,0.00152491,-0.000486737,0.0213673],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9162397179,0.01033450945,0.4004971626],\n\t\t\t\t[0.1187416248,0.9617552428,0.2468345183],\n\t\t\t\t[-0.3826293322,0.2737152732,-0.8824254888]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.8785048],\n\t\t\t\t[159.3368695],\n\t\t\t\t[313.9971646]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.448,0,360.818],\n\t\t\t\t[0,745.84,214.85],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329534,0.0903331,0.00014069,0.000717079,0.0211508],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9101418911,0.04432675398,0.411918532],\n\t\t\t\t[0.1391589893,0.9692024732,0.2031781034],\n\t\t\t\t[-0.3902262342,0.2422430698,-0.888280238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.35209076],\n\t\t\t\t[181.679224],\n\t\t\t\t[308.9632727]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.167,0,363.996],\n\t\t\t\t[0,746.229,234.387],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310901,-0.0147285,-0.000729007,-0.000655789,0.178193],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9157731435,-0.03755396433,0.3999365568],\n\t\t\t\t[0.06406747528,0.9692207168,0.2377110865],\n\t\t\t\t[-0.3965537899,0.2433123544,-0.8851803149]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.79527777],\n\t\t\t\t[146.8696803],\n\t\t\t\t[308.5271108]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.588,0,384.664],\n\t\t\t\t[0,744.662,240.853],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307863,-0.0295446,-0.000517465,0.000242427,0.189333],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9170523574,0.0431160901,0.396429031],\n\t\t\t\t[0.124694228,0.9752892469,0.1823793695],\n\t\t\t\t[-0.3787694858,0.2166838427,-0.8997676305]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.200936127],\n\t\t\t\t[142.5227957],\n\t\t\t\t[304.9039442]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.832,0,378.426],\n\t\t\t\t[0,745.825,230.649],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317765,0.041948,0.000140897,0.000331931,0.0876249],\n\t\t\t\"R\": [\n\t\t\t\t[-0.903416406,0.009580467792,0.4286572198],\n\t\t\t\t[0.1299134284,0.9588705554,0.2523683006],\n\t\t\t\t[-0.4086089801,0.2836819921,-0.8675040223]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.38884391],\n\t\t\t\t[100.2357286],\n\t\t\t\t[311.942278]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.759,0,381.189],\n\t\t\t\t[0,746.033,229.615],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307738,-0.0303832,0.000694314,-0.000395606,0.211723],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9121889441,-0.007451044875,0.4097021017],\n\t\t\t\t[0.1102495844,0.9585035751,0.2628990789],\n\t\t\t\t[-0.394659802,0.2849831196,-0.8735148895]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.4671669308],\n\t\t\t\t[91.25062129],\n\t\t\t\t[311.8622342]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[748.678,0,358.839],\n\t\t\t\t[0,748.651,239.635],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328983,0.0919887,-1.22475e-05,-0.000911096,0.0194744],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9251940915,-0.06790089301,0.3733702744],\n\t\t\t\t[0.01633387562,0.9758259889,0.2179377065],\n\t\t\t\t[-0.3791425821,0.207733262,-0.9017193545]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[15.23843998],\n\t\t\t\t[129.776393],\n\t\t\t\t[302.9631654]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"11_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 11,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[747.741,0,374.843],\n\t\t\t\t[0,747.8,238.972],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320184,0.0453956,8.07771e-05,-0.000586724,0.0799959],\n\t\t\t\"R\": [\n\t\t\t\t[-0.901120423,0.005145678853,0.4335383549],\n\t\t\t\t[0.1030532182,0.9738156258,0.2026404726],\n\t\t\t\t[-0.4211437016,0.2272809911,-0.8780554275]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.522845915],\n\t\t\t\t[142.0951003],\n\t\t\t\t[306.255293]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.397,0,350.188],\n\t\t\t\t[0,745.422,244.528],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318784,0.0421446,0.000567418,-0.000208,0.092208],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2717431751,0.1656287556,0.9480098956],\n\t\t\t\t[0.4128654434,0.9098857043,-0.04062180222],\n\t\t\t\t[-0.86930879,0.3803618284,-0.3156376199]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-13.70303847],\n\t\t\t\t[97.1923903],\n\t\t\t\t[326.2673629]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.727,0,370.501],\n\t\t\t\t[0,747.788,234.298],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.349811,0.202844,-0.00194754,-0.000389321,-0.178679],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3883456032,0.1438043201,0.9102241537],\n\t\t\t\t[0.3131714459,0.9495549238,-0.01640403197],\n\t\t\t\t[-0.8666667975,0.2786857806,-0.4137908865]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.37192963],\n\t\t\t\t[105.5473845],\n\t\t\t\t[318.08591]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.831,0,387.09],\n\t\t\t\t[0,746.752,242.092],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.338844,0.109538,-0.000689346,-0.00140957,-0.0011227],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2489409576,0.07810816372,0.9653639285],\n\t\t\t\t[0.3865744043,0.9219167609,0.0250941395],\n\t\t\t\t[-0.8880251289,0.3794319447,-0.2596974581]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.03334166],\n\t\t\t\t[70.50216381],\n\t\t\t\t[325.3775618]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[746.601,0,360.45],\n\t\t\t\t[0,746.776,222.063],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336822,0.124774,0.000206697,-0.000417774,-0.0398672],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3081671276,0.03567998316,0.9506629057],\n\t\t\t\t[0.4212102042,0.9011275261,0.1027187694],\n\t\t\t\t[-0.8530035084,0.4320834647,-0.2927266543]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.764737811],\n\t\t\t\t[63.41476985],\n\t\t\t\t[331.1517594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[748.2,0,362.212],\n\t\t\t\t[0,748.363,218.877],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337789,0.133894,-0.000945522,-0.000498923,-0.0570031],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2841336654,-0.004801876737,0.9587726541],\n\t\t\t\t[0.3831436474,0.9161034097,0.118133349],\n\t\t\t\t[-0.8789021593,0.4009133132,-0.2584560111]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[10.92507323],\n\t\t\t\t[68.32263664],\n\t\t\t\t[329.7866549]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[747.371,0,350.388],\n\t\t\t\t[0,747.497,231.124],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.351189,0.233364,-0.000450075,-0.00118874,-0.265042],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3878504716,-0.01635524947,0.9215771902],\n\t\t\t\t[0.3346075558,0.9291346168,0.1573106717],\n\t\t\t\t[-0.8588421248,0.3693797093,-0.3548927092]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[53.76493542],\n\t\t\t\t[97.09757883],\n\t\t\t\t[324.1315487]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[747.196,0,383.602],\n\t\t\t\t[0,747.258,260.076],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.340453,0.149462,7.57635e-05,-0.00150211,-0.0810731],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3567494973,0.01375486298,0.934098817],\n\t\t\t\t[0.3428523716,0.9320474424,0.1172169629],\n\t\t\t\t[-0.8690121101,0.3620750873,-0.3372233439]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[46.87962376],\n\t\t\t\t[118.8343508],\n\t\t\t\t[324.070693]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[748.388,0,360.952],\n\t\t\t\t[0,748.584,220.934],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.353387,0.236369,0.000317101,-0.000350889,-0.25062],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3882650784,-0.0538394581,0.9199736636],\n\t\t\t\t[0.3529834406,0.9134681838,0.2024316376],\n\t\t\t\t[-0.8512654812,0.4033326047,-0.3356633588]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[53.63586961],\n\t\t\t\t[124.5990463],\n\t\t\t\t[329.2926486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.023,0,373.202],\n\t\t\t\t[0,745.321,253.183],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310235,-0.0270349,0.000213071,-0.0010354,0.204812],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3615436505,-0.1034754049,0.9265953968],\n\t\t\t\t[0.3189620476,0.9201303682,0.2272076531],\n\t\t\t\t[-0.8760989676,0.3776942494,-0.2996625652]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.36947949],\n\t\t\t\t[154.1173845],\n\t\t\t\t[328.14772]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.497,0,337.094],\n\t\t\t\t[0,743.775,230.392],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323522,0.0697077,-0.000922284,-0.00112939,0.0376595],\n\t\t\t\"R\": [\n\t\t\t\t[-0.409013364,-0.03192166586,0.9119698873],\n\t\t\t\t[0.3635432206,0.9109541012,0.1949331996],\n\t\t\t\t[-0.8369853014,0.4112707536,-0.3609874961]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[36.39561956],\n\t\t\t\t[146.2733377],\n\t\t\t\t[330.6860766]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.432,0,350.161],\n\t\t\t\t[0,744.664,216.764],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.3138,0.0423232,-0.000980128,0.000347352,0.0411803],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3625324698,0.01191238118,0.9318950067],\n\t\t\t\t[0.4332658145,0.8874493782,0.157207936],\n\t\t\t\t[-0.8251369234,0.4607512304,-0.3268904424]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.02223667],\n\t\t\t\t[146.021886],\n\t\t\t\t[340.9352409]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.59,0,349.499],\n\t\t\t\t[0,745.978,243.824],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328804,0.102744,-0.00034172,-0.00160085,-0.0230968],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3184962228,0.07265474811,0.9451356747],\n\t\t\t\t[0.3862627531,0.9204738181,0.05940568743],\n\t\t\t\t[-0.8656565379,0.3839911948,-0.3212312573]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.04074577],\n\t\t\t\t[180.9741057],\n\t\t\t\t[327.7548666]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.766,0,364.423],\n\t\t\t\t[0,744.926,205.341],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32165,0.0514735,-0.000885848,-0.00113933,0.0656482],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2748509499,0.06379038152,0.9593684081],\n\t\t\t\t[0.3894986417,0.919644886,0.05043898999],\n\t\t\t\t[-0.8790607279,0.3875358962,-0.2776115375]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-9.802475588],\n\t\t\t\t[164.1613661],\n\t\t\t\t[327.7325897]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.556,0,345.329],\n\t\t\t\t[0,744.551,253.003],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311027,-0.00213006,0.0011289,-0.000863959,0.162024],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3202755169,0.1244082889,0.9391198917],\n\t\t\t\t[0.4530679872,0.8907277919,0.0365157459],\n\t\t\t\t[-0.831957326,0.4371802584,-0.3416437171]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[0.5161253202],\n\t\t\t\t[152.8799295],\n\t\t\t\t[338.113135]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.233,0,347.644],\n\t\t\t\t[0,747.329,227.375],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323105,0.049287,-0.00101918,5.08353e-05,0.100564],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2639942301,0.1219548974,0.9567831779],\n\t\t\t\t[0.4010015368,0.9160569375,-0.006120025947],\n\t\t\t\t[-0.8772142349,0.3820558732,-0.2907378472]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.43280694],\n\t\t\t\t[159.7105652],\n\t\t\t\t[325.8203908]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.634,0,382.866],\n\t\t\t\t[0,744.52,241.14],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320913,0.0518689,0.000556907,0.000900625,0.0851061],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2918914105,0.1153635448,0.9494686183],\n\t\t\t\t[0.4055533141,0.9139698053,0.01362734066],\n\t\t\t\t[-0.8662135499,0.3890378484,-0.3135660035]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.908528],\n\t\t\t\t[135.1916248],\n\t\t\t\t[327.5972929]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.929,0,399.922],\n\t\t\t\t[0,745.76,235.115],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324412,0.0924767,0.000808772,0.00160345,0.0125449],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2332319969,0.1531844985,0.9602798264],\n\t\t\t\t[0.4252056559,0.9041694633,-0.04096012482],\n\t\t\t\t[-0.8745301515,0.3987632018,-0.2760161646]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.90434909],\n\t\t\t\t[120.9469461],\n\t\t\t\t[326.5490528]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.596,0,390.427],\n\t\t\t\t[0,745.457,235.855],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331545,0.0834192,0.000515021,-0.000851112,0.0388274],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2198853867,0.1587089693,0.9625288982],\n\t\t\t\t[0.4990272732,0.8661072571,-0.02880971702],\n\t\t\t\t[-0.8382256244,0.4739933356,-0.2696444333]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-48.83152805],\n\t\t\t\t[73.52609427],\n\t\t\t\t[332.6787653]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[744.284,0,396.863],\n\t\t\t\t[0,744.47,248.804],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318049,0.0444362,0.000417829,0.000948817,0.0847095],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2972813843,0.0975420226,0.9497943632],\n\t\t\t\t[0.4134272643,0.9098266462,0.03596346693],\n\t\t\t\t[-0.8606402708,0.4033621545,-0.3108010564]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.347004052],\n\t\t\t\t[101.4062297],\n\t\t\t\t[328.9550302]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.173,0,391.68],\n\t\t\t\t[0,745.292,239.851],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316891,0.030971,0.000827356,0.00064571,0.114679],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3480625566,0.05516818218,0.9358466372],\n\t\t\t\t[0.3680676982,0.9261498325,0.08229615655],\n\t\t\t\t[-0.8621940769,0.3730991283,-0.3426637043]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.00373906],\n\t\t\t\t[105.1024652],\n\t\t\t\t[325.6162418]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.07,0,385.155],\n\t\t\t\t[0,744.184,238.534],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325321,0.0749068,6.22505e-05,8.78769e-06,0.0274316],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2944173655,-0.00519814937,0.9556628036],\n\t\t\t\t[0.365777539,0.9232287513,0.117709238],\n\t\t\t\t[-0.882907247,0.3842156322,-0.2699132104]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.17424328],\n\t\t\t\t[116.8807078],\n\t\t\t\t[328.2455421]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[747.36,0,358.25],\n\t\t\t\t[0,747.451,237.291],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329867,0.116416,-0.000580151,-0.000763801,-0.0625995],\n\t\t\t\"R\": [\n\t\t\t\t[-0.323867873,0.0530845029,0.9446118972],\n\t\t\t\t[0.387407199,0.9183241349,0.08121850418],\n\t\t\t\t[-0.8631484594,0.3922535134,-0.3179810029]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.53106717],\n\t\t\t\t[133.6738778],\n\t\t\t\t[328.8995429]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[748.813,0,380.156],\n\t\t\t\t[0,748.859,237.356],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333932,0.115832,0.000621747,-0.000254241,-0.0140772],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3097958639,0.0326105921,0.9502436908],\n\t\t\t\t[0.3550951383,0.9310652686,0.08381472691],\n\t\t\t\t[-0.8820056493,0.3633923705,-0.3000200319]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.485061334],\n\t\t\t\t[151.418855],\n\t\t\t\t[323.8858443]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"12_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 12,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.33,0,360.408],\n\t\t\t\t[0,745.472,237.433],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321653,0.057929,3.69615e-05,-0.000478596,0.0560779],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3250711399,0.1046959739,0.9398763254],\n\t\t\t\t[0.4072848242,0.9124585149,0.03922410658],\n\t\t\t\t[-0.8534915501,0.395547989,-0.3392550109]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.217299854],\n\t\t\t\t[123.8595425],\n\t\t\t\t[329.2221602]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[747.6,0,355.92],\n\t\t\t\t[0,747.783,249.853],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333712,0.144699,-6.46303e-05,-0.0011294,-0.0924471],\n\t\t\t\"R\": [\n\t\t\t\t[0.5138271048,0.01100033104,0.857823233],\n\t\t\t\t[0.08358608019,0.9945184566,-0.06282043172],\n\t\t\t\t[-0.8538120833,0.1039809221,0.5100910647]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-37.95328646],\n\t\t\t\t[135.6435695],\n\t\t\t\t[289.9999799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.227,0,372.15],\n\t\t\t\t[0,743.265,265.407],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306942,-0.0266079,0.000311285,0.000595534,0.199806],\n\t\t\t\"R\": [\n\t\t\t\t[0.4485620057,-0.005900946102,0.8937322339],\n\t\t\t\t[0.06601293956,0.9974655925,-0.02654587691],\n\t\t\t\t[-0.8913105064,0.07090536373,0.4478147055]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-38.28645032],\n\t\t\t\t[133.2984516],\n\t\t\t\t[288.856211]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.538,0,387.516],\n\t\t\t\t[0,746.833,233.181],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322577,0.0715483,-4.90461e-05,0.000787497,0.0326639],\n\t\t\t\"R\": [\n\t\t\t\t[0.5260210271,0.02315422103,0.8501563157],\n\t\t\t\t[0.07372016672,0.9946254291,-0.07270208278],\n\t\t\t\t[-0.8472704504,0.1009164896,0.5214869567]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.0750023],\n\t\t\t\t[105.7642054],\n\t\t\t\t[287.8235486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.864,0,367.763],\n\t\t\t\t[0,745.005,229.771],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318118,0.0367901,0.000364188,-0.000713933,0.0879467],\n\t\t\t\"R\": [\n\t\t\t\t[0.4575577495,0.1623260474,0.8742374736],\n\t\t\t\t[-0.0244195278,0.9851184177,-0.1701334469],\n\t\t\t\t[-0.8888445267,0.05649741078,0.4547124916]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.756699591],\n\t\t\t\t[110.8595803],\n\t\t\t\t[285.3944853]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.026,0,374.462],\n\t\t\t\t[0,744.21,219.295],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309274,-0.00813814,-0.000611939,0.000562163,0.16533],\n\t\t\t\"R\": [\n\t\t\t\t[0.5236500196,-0.01990538858,0.8517009055],\n\t\t\t\t[0.0479853053,0.9988290545,-0.006158764858],\n\t\t\t\t[-0.8505810176,0.04409416531,0.5239920201]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.80347729],\n\t\t\t\t[91.75629107],\n\t\t\t\t[282.6719703]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[746.172,0,347.715],\n\t\t\t\t[0,746.412,223.735],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315889,0.0243673,0.00083413,-0.000596366,0.129203],\n\t\t\t\"R\": [\n\t\t\t\t[0.489601615,0.07237643337,0.8689372305],\n\t\t\t\t[-0.010214584,0.9969567785,-0.07728417735],\n\t\t\t\t[-0.8718864151,0.02896262571,0.488850944]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[7.55259059],\n\t\t\t\t[89.5920217],\n\t\t\t\t[281.8493454]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.619,0,383.372],\n\t\t\t\t[0,745.683,224.508],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315816,0.0424659,0.000456201,0.000714024,0.0879752],\n\t\t\t\"R\": [\n\t\t\t\t[0.5142457137,-0.005076098829,0.8576278792],\n\t\t\t\t[0.07753605572,0.9961627141,-0.04059565316],\n\t\t\t\t[-0.8541308483,0.08737322366,0.5126659866]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.165152848],\n\t\t\t\t[86.80281732],\n\t\t\t\t[287.1451009]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[746.151,0,390.693],\n\t\t\t\t[0,746.159,238.847],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312796,0.0112848,0.00109903,0.000945928,0.138088],\n\t\t\t\"R\": [\n\t\t\t\t[0.5333632905,-0.08775347438,0.841322131],\n\t\t\t\t[0.13459771,0.9907366672,0.0180086874],\n\t\t\t\t[-0.8351090089,0.1036348594,0.5402339855]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[14.59630248],\n\t\t\t\t[78.12680456],\n\t\t\t\t[289.302137]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[744.811,0,365.557],\n\t\t\t\t[0,745.05,239.01],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302561,-0.0588071,-0.000331846,-0.00065645,0.252299],\n\t\t\t\"R\": [\n\t\t\t\t[0.515993865,0.007464548532,0.8565597538],\n\t\t\t\t[0.05311793688,0.9977587535,-0.04069342277],\n\t\t\t\t[-0.8549437502,0.06649624343,0.5144408941]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[47.02842806],\n\t\t\t\t[101.5821868],\n\t\t\t\t[285.7219747]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.185,0,393.537],\n\t\t\t\t[0,744.44,231.354],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321367,0.0639595,-3.49657e-05,0.000800078,0.0579089],\n\t\t\t\"R\": [\n\t\t\t\t[0.5364096096,-0.02345912583,0.8436316733],\n\t\t\t\t[0.07330244032,0.9971310212,-0.01888064639],\n\t\t\t\t[-0.8407683884,0.07196802054,0.536590273]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[31.38919798],\n\t\t\t\t[122.486781],\n\t\t\t\t[287.1552388]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.973,0,365.594],\n\t\t\t\t[0,746.037,211.677],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32905,0.0977698,-0.000962762,0.000946642,0.0190885],\n\t\t\t\"R\": [\n\t\t\t\t[0.5178117038,0.00482526951,0.8554810087],\n\t\t\t\t[0.01921134431,0.9996663333,-0.01726691564],\n\t\t\t\t[-0.8552788806,0.02537595122,0.5175462273]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.16543019],\n\t\t\t\t[149.3252564],\n\t\t\t\t[279.6241941]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[745.909,0,358.218],\n\t\t\t\t[0,746.022,220.333],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.338571,0.148871,-0.00100229,-0.000678393,-0.0710162],\n\t\t\t\"R\": [\n\t\t\t\t[0.5368407815,0.02503814463,0.8433119628],\n\t\t\t\t[-0.01156171997,0.9996840035,-0.02232083821],\n\t\t\t\t[-0.8436043516,0.002232599467,0.5369606257]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[51.57359577],\n\t\t\t\t[176.1957711],\n\t\t\t\t[275.7319623]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[743.068,0,370.139],\n\t\t\t\t[0,743.357,232.303],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302401,-0.0553181,-0.00107418,-0.000672395,0.220417],\n\t\t\t\"R\": [\n\t\t\t\t[0.5299693687,-0.06080201885,0.8458342525],\n\t\t\t\t[0.13849556,0.9902402801,-0.01559383094],\n\t\t\t\t[-0.8366310107,0.1254085412,0.5332178257]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.99243391],\n\t\t\t\t[145.7883087],\n\t\t\t\t[295.0494301]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[743.724,0,347.611],\n\t\t\t\t[0,743.902,235.434],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315484,0.0296225,-0.000529931,-0.000276443,0.110913],\n\t\t\t\"R\": [\n\t\t\t\t[0.5388576125,-0.001120175332,0.8423961174],\n\t\t\t\t[0.06888686412,0.9967085439,-0.04273965901],\n\t\t\t\t[-0.8395755317,0.08106061749,0.5371611517]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.68047362],\n\t\t\t\t[178.4537167],\n\t\t\t\t[288.5132471]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[748.48,0,370.578],\n\t\t\t\t[0,748.498,231.761],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333743,0.123731,0.000274987,0.00129665,-0.0264397],\n\t\t\t\"R\": [\n\t\t\t\t[0.5569883215,-0.02228411773,0.8302213126],\n\t\t\t\t[0.06483002391,0.9977563557,-0.01671294857],\n\t\t\t\t[-0.827986158,0.06313218472,0.5571833177]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.30154925],\n\t\t\t\t[184.6918205],\n\t\t\t\t[284.5865319]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[748.413,0,364.616],\n\t\t\t\t[0,748.358,230.166],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337541,0.138107,0.000557985,-0.000490808,-0.0648839],\n\t\t\t\"R\": [\n\t\t\t\t[0.5035312414,0.04830043061,0.8626258501],\n\t\t\t\t[0.03089895722,0.996790644,-0.07384894344],\n\t\t\t\t[-0.8634243125,0.06383948941,0.5004227975]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.312179267],\n\t\t\t\t[173.5565462],\n\t\t\t\t[284.5085099]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.143,0,372.782],\n\t\t\t\t[0,745.112,223.2],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321603,0.0646008,-0.000584526,0.000805086,0.0603349],\n\t\t\t\"R\": [\n\t\t\t\t[0.5471603314,0.02993221277,0.8364924593],\n\t\t\t\t[0.06649342528,0.9946477166,-0.07908567611],\n\t\t\t\t[-0.8343825239,0.09889379359,0.5422414789]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.63653561],\n\t\t\t\t[167.4383368],\n\t\t\t\t[289.2367997]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.136,0,373.506],\n\t\t\t\t[0,745.259,215.704],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333755,0.12331,-0.00049301,0.00138004,-0.0323155],\n\t\t\t\"R\": [\n\t\t\t\t[0.5039095131,0.07384116584,0.8605943788],\n\t\t\t\t[0.02822760746,0.9943991795,-0.1018502524],\n\t\t\t\t[-0.8632950856,0.07561583139,0.4990028469]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.61131213],\n\t\t\t\t[166.0398843],\n\t\t\t\t[286.9453226]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.638,0,344.046],\n\t\t\t\t[0,743.783,238.416],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319291,0.0355055,-0.000169258,0.000161892,0.118247],\n\t\t\t\"R\": [\n\t\t\t\t[0.5180347054,0.01180967192,0.8552780692],\n\t\t\t\t[0.1057363227,0.9913513706,-0.07773216881],\n\t\t\t\t[-0.8487990775,0.1307019191,0.512305704]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.08174331],\n\t\t\t\t[122.2280138],\n\t\t\t\t[293.3272927]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.321,0,372.761],\n\t\t\t\t[0,745.559,236.547],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320489,0.0479206,-9.03328e-05,-0.000256288,0.0784864],\n\t\t\t\"R\": [\n\t\t\t\t[0.4966252135,-0.01754426777,0.8677877598],\n\t\t\t\t[0.06583916704,0.9976766247,-0.01750875645],\n\t\t\t\t[-0.8654643848,0.06582971318,0.4966264667]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.61163777],\n\t\t\t\t[120.2765647],\n\t\t\t\t[285.1928757]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.539,0,371.886],\n\t\t\t\t[0,745.656,230.519],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326644,0.0839413,-0.000557984,0.000204085,0.0126328],\n\t\t\t\"R\": [\n\t\t\t\t[0.5330371562,-0.03752357961,0.8452593514],\n\t\t\t\t[0.08887796824,0.9959722199,-0.01183402057],\n\t\t\t\t[-0.8414107777,0.08143290645,0.5342252193]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.03247131],\n\t\t\t\t[109.6165459],\n\t\t\t\t[286.9430377]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.018,0,396.717],\n\t\t\t\t[0,744.224,249.141],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315372,0.0205822,-0.000440151,0.000134817,0.105074],\n\t\t\t\"R\": [\n\t\t\t\t[0.4984198723,-0.001673636668,0.8669341554],\n\t\t\t\t[0.03130878513,0.9993805529,-0.01607079461],\n\t\t\t\t[-0.8663702389,0.03515265859,0.4981635271]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[26.09238071],\n\t\t\t\t[136.8142763],\n\t\t\t\t[280.4949188]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[744.884,0,382.514],\n\t\t\t\t[0,744.877,235.74],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326378,0.0966908,-9.48994e-05,0.00105607,0.00534895],\n\t\t\t\"R\": [\n\t\t\t\t[0.4908089633,-0.01723518027,0.8710967283],\n\t\t\t\t[0.04978157704,0.9987257364,-0.008288432131],\n\t\t\t\t[-0.8698438688,0.04743260567,0.4910415377]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[21.95453226],\n\t\t\t\t[154.6836493],\n\t\t\t\t[281.6596012]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"13_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 13,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.481,0,341.813],\n\t\t\t\t[0,744.509,213.322],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310201,-0.0109775,-0.00130948,-0.000370453,0.189258],\n\t\t\t\"R\": [\n\t\t\t\t[0.5283332962,-0.01827851401,0.8488402818],\n\t\t\t\t[0.07383881778,0.996969434,-0.02449033896],\n\t\t\t\t[-0.8458201683,0.0756164244,0.5280818111]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.59416721],\n\t\t\t\t[149.8670778],\n\t\t\t\t[286.3856475]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.639,0,394.42],\n\t\t\t\t[0,745.872,232.374],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317821,0.05701,0.000216723,0.00145431,0.0516441],\n\t\t\t\"R\": [\n\t\t\t\t[0.1117244957,0.006687085701,0.9937167202],\n\t\t\t\t[0.1929264895,0.9808052728,-0.02829110459],\n\t\t\t\t[-0.9748317838,0.1948750877,0.1082898585]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.76838593],\n\t\t\t\t[183.2092961],\n\t\t\t\t[300.2249606]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[744.265,0,384.24],\n\t\t\t\t[0,744.607,234.555],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314122,0.0172489,-0.000351192,-3.05431e-05,0.116521],\n\t\t\t\"R\": [\n\t\t\t\t[0.09126102309,0.01926845044,0.9956405739],\n\t\t\t\t[0.1889483007,0.9813154942,-0.03631033643],\n\t\t\t\t[-0.9777371658,0.191438313,0.08591511501]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.54744948],\n\t\t\t\t[195.8515337],\n\t\t\t\t[299.6149103]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[742.909,0,383.13],\n\t\t\t\t[0,743.051,234.161],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311566,0.0211516,-0.000212815,-9.64233e-05,0.110817],\n\t\t\t\"R\": [\n\t\t\t\t[0.07658267666,-0.01244461629,0.9969855692],\n\t\t\t\t[0.2193131093,0.9756433613,-0.004668149478],\n\t\t\t\t[-0.9726442586,0.2190095044,0.07744664757]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-39.95619704],\n\t\t\t\t[171.7405641],\n\t\t\t\t[305.3439137]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.057,0,349.277],\n\t\t\t\t[0,745.321,214.2],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31581,0.0237721,-0.00140945,-0.000667487,0.124292],\n\t\t\t\"R\": [\n\t\t\t\t[0.09341145846,-0.02354383001,0.9953491787],\n\t\t\t\t[0.2305453591,0.9730606003,0.001380415192],\n\t\t\t\t[-0.9685675696,0.2293441873,0.09632293059]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-43.73412593],\n\t\t\t\t[146.7921304],\n\t\t\t\t[306.2893961]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[744.634,0,387.597],\n\t\t\t\t[0,744.752,225.246],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315944,0.0434616,-0.000268259,0.00110436,0.0780237],\n\t\t\t\"R\": [\n\t\t\t\t[0.1133728096,0.0374780752,0.9928454059],\n\t\t\t\t[0.2222309073,0.973014014,-0.06210597779],\n\t\t\t\t[-0.9683801061,0.2276820645,0.1019845459]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-53.79623552],\n\t\t\t\t[137.113178],\n\t\t\t\t[305.5099477]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.759,0,388.645],\n\t\t\t\t[0,744.666,221.73],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306159,-0.0283273,-0.000508774,0.00094455,0.192402],\n\t\t\t\"R\": [\n\t\t\t\t[0.1564984143,0.01913164242,0.9874928995],\n\t\t\t\t[0.2309282446,0.9713913042,-0.05541732523],\n\t\t\t\t[-0.96030224,0.2367127254,0.1476031622]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-66.24261018],\n\t\t\t\t[112.7515407],\n\t\t\t\t[303.5978047]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.959,0,375.286],\n\t\t\t\t[0,745.092,235.744],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302136,-0.0624017,-0.000302824,-0.00146028,0.239945],\n\t\t\t\"R\": [\n\t\t\t\t[0.0628689268,0.03077162571,0.9975472947],\n\t\t\t\t[0.2444661638,0.9685997585,-0.04528578729],\n\t\t\t\t[-0.967617586,0.2467136292,0.05337220603]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.11814477],\n\t\t\t\t[98.74694092],\n\t\t\t\t[308.9777955]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[746.649,0,384.752],\n\t\t\t\t[0,746.836,237.267],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321628,0.0600031,0.000104796,0.000953791,0.0524376],\n\t\t\t\"R\": [\n\t\t\t\t[0.1158239713,-0.07384920575,0.9905206219],\n\t\t\t\t[0.2473198554,0.9679682291,0.043248082],\n\t\t\t\t[-0.9619863288,0.2399662524,0.1303782992]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.76229918],\n\t\t\t\t[76.40869106],\n\t\t\t\t[305.3733784]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.672,0,372.774],\n\t\t\t\t[0,745.737,209.129],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30917,-0.00857977,-4.68803e-05,-0.000521617,0.17194],\n\t\t\t\"R\": [\n\t\t\t\t[0.1233501146,0.01050711315,0.9923075883],\n\t\t\t\t[0.2153087978,0.9758411417,-0.0370970036],\n\t\t\t\t[-0.9687243523,0.2182284735,0.1181078428]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.44854612],\n\t\t\t\t[78.73632155],\n\t\t\t\t[304.5944309]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[744.36,0,350.493],\n\t\t\t\t[0,744.605,227.167],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324539,0.0696676,-0.000964917,-0.000688724,0.0453805],\n\t\t\t\"R\": [\n\t\t\t\t[0.0653712546,0.005547467364,0.9978455916],\n\t\t\t\t[0.2748842968,0.9611936881,-0.02335203178],\n\t\t\t\t[-0.9592524289,0.2758186354,0.06130952564]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.36142141],\n\t\t\t\t[73.86484437],\n\t\t\t\t[309.5485763]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.072,0,352.953],\n\t\t\t\t[0,744.032,218.847],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310531,-0.00866492,-5.61729e-06,0.000627577,0.179884],\n\t\t\t\"R\": [\n\t\t\t\t[0.08325845442,0.01268657881,0.9964472292],\n\t\t\t\t[0.1993298125,0.97949952,-0.02912586749],\n\t\t\t\t[-0.9763890903,0.2010466141,0.07902280276]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[33.26019053],\n\t\t\t\t[89.58305599],\n\t\t\t\t[303.0664402]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.677,0,359.077],\n\t\t\t\t[0,743.623,233.815],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305265,-0.0518121,0.000714314,0.000432839,0.265088],\n\t\t\t\"R\": [\n\t\t\t\t[0.06818541392,0.004787243789,0.9976611808],\n\t\t\t\t[0.2533830838,0.9671167716,-0.02195821049],\n\t\t\t\t[-0.9649599796,0.2542876962,0.06473025078]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[54.03449748],\n\t\t\t\t[85.53998459],\n\t\t\t\t[306.9876015]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.736,0,368.122],\n\t\t\t\t[0,742.832,238.615],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303469,-0.0412536,1.82225e-05,-0.000473228,0.205739],\n\t\t\t\"R\": [\n\t\t\t\t[0.1225239282,-0.0735967149,0.9897329996],\n\t\t\t\t[0.2305366224,0.9720798639,0.0437447595],\n\t\t\t\t[-0.9653189902,0.222809923,0.1360697815]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.43625272],\n\t\t\t\t[116.7070017],\n\t\t\t\t[307.0317679]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.328,0,371.219],\n\t\t\t\t[0,745.487,209.713],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318297,0.0286867,-0.0013247,0.000626009,0.137928],\n\t\t\t\"R\": [\n\t\t\t\t[0.06972690557,-0.0276618613,0.9971825209],\n\t\t\t\t[0.2175762615,0.9759712693,0.01185967683],\n\t\t\t\t[-0.9735495514,0.2161363064,0.0740700209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.75964066],\n\t\t\t\t[131.0709572],\n\t\t\t\t[303.578107]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[743.637,0,370.163],\n\t\t\t\t[0,743.479,235.403],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.301307,-0.0600698,0.000220332,0.000264974,0.263845],\n\t\t\t\"R\": [\n\t\t\t\t[0.0871387997,-0.1078492175,0.9903410402],\n\t\t\t\t[0.2171380052,0.9722761796,0.08677624828],\n\t\t\t\t[-0.9722437535,0.2074790999,0.1081411432]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.10934266],\n\t\t\t\t[155.0300785],\n\t\t\t\t[303.8314173]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[747.749,0,388.765],\n\t\t\t\t[0,747.73,234.855],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320028,0.057848,-0.00103044,0.00101463,0.0716113],\n\t\t\t\"R\": [\n\t\t\t\t[0.09276252326,-0.02731891999,0.9953134134],\n\t\t\t\t[0.2004837996,0.9796626634,0.008204393401],\n\t\t\t\t[-0.9752955246,0.1987831547,0.09635298148]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[25.02944215],\n\t\t\t\t[165.1686099],\n\t\t\t\t[301.5459594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.477,0,358.035],\n\t\t\t\t[0,745.633,228.78],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315933,0.0359808,-0.000244793,0.00106736,0.101835],\n\t\t\t\"R\": [\n\t\t\t\t[0.09323456203,-0.04884472803,0.9944453273],\n\t\t\t\t[0.1997864834,0.9793990461,0.02937464128],\n\t\t\t\t[-0.9753936013,0.1959380031,0.1010723576]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.52671676],\n\t\t\t\t[185.8338565],\n\t\t\t\t[300.6683817]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.962,0,392.223],\n\t\t\t\t[0,747.34,219.936],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325078,0.0885503,-0.00165532,0.000580691,0.0160315],\n\t\t\t\"R\": [\n\t\t\t\t[0.129696032,0.03909405168,0.990782819],\n\t\t\t\t[0.1776002444,0.9821476201,-0.06200165731],\n\t\t\t\t[-0.9755188837,0.1840046397,0.1204375361]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.746570817],\n\t\t\t\t[166.089254],\n\t\t\t\t[298.9402723]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.91,0,339.915],\n\t\t\t\t[0,744.956,221.133],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306862,-0.0244375,-6.76743e-05,-0.000102471,0.205298],\n\t\t\t\"R\": [\n\t\t\t\t[0.09943504227,-0.007298095184,0.9950172914],\n\t\t\t\t[0.2125993636,0.9770380132,-0.01407946415],\n\t\t\t\t[-0.9720669642,0.212940035,0.09870338653]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-22.7866272],\n\t\t\t\t[143.0595857],\n\t\t\t\t[303.8181509]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[743.577,0,349.797],\n\t\t\t\t[0,743.73,227.793],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307046,-0.0206712,-0.000861395,-9.97172e-05,0.196115],\n\t\t\t\"R\": [\n\t\t\t\t[0.09969364468,-0.01462231859,0.9949107322],\n\t\t\t\t[0.2541863771,0.9670897407,-0.01125696175],\n\t\t\t\t[-0.9620033591,0.2540150021,0.1001294952]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.43364439],\n\t\t\t\t[109.4423166],\n\t\t\t\t[308.9174676]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.066,0,381.498],\n\t\t\t\t[0,745.047,229.678],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314894,0.0257947,-0.000483886,0.00117112,0.111876],\n\t\t\t\"R\": [\n\t\t\t\t[0.08696832552,-0.05294226024,0.9948033109],\n\t\t\t\t[0.2154078845,0.9759627551,0.03310806346],\n\t\t\t\t[-0.9726437959,0.2114091239,0.09628202687]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.298071534],\n\t\t\t\t[115.0382234],\n\t\t\t\t[303.8536261]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.602,0,379.206],\n\t\t\t\t[0,746.635,260.689],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319922,0.0568918,0.00103779,-0.000422086,0.0766843],\n\t\t\t\"R\": [\n\t\t\t\t[0.09129519856,-0.01052008078,0.9957683037],\n\t\t\t\t[0.2195471399,0.9755524467,-0.009822274065],\n\t\t\t\t[-0.9713208739,0.2195148095,0.09137290798]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.69590833],\n\t\t\t\t[125.3942709],\n\t\t\t\t[304.7857903]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"14_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 14,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.388,0,382.392],\n\t\t\t\t[0,745.496,224.015],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302393,-0.0525763,-0.000559682,-6.77e-05,0.234314],\n\t\t\t\"R\": [\n\t\t\t\t[0.08118536371,-0.04636746828,0.9956199047],\n\t\t\t\t[0.1796446798,0.9832385033,0.03114216711],\n\t\t\t\t[-0.9803758084,0.1763295309,0.0881542445]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[8.147122648],\n\t\t\t\t[159.0280693],\n\t\t\t\t[298.1193244]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[747.532,0,374.739],\n\t\t\t\t[0,747.668,233.944],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.331439,0.109037,-0.000609362,0.000392501,-0.000621335],\n\t\t\t\"R\": [\n\t\t\t\t[0.7848571462,0.05717032211,0.6170338843],\n\t\t\t\t[0.1817012858,0.9307358272,-0.3173569956],\n\t\t\t\t[-0.5924389444,0.3611957561,0.7201067442]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.59276639],\n\t\t\t\t[102.5270366],\n\t\t\t\t[325.6365462]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[743.597,0,385.764],\n\t\t\t\t[0,743.786,211.188],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307778,-0.0279819,-0.000454196,0.00143268,0.205643],\n\t\t\t\"R\": [\n\t\t\t\t[0.7963392439,-0.01332837804,0.6047033677],\n\t\t\t\t[0.2601504211,0.910106147,-0.3225345868],\n\t\t\t\t[-0.5460453892,0.4141607847,0.7282206241]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-38.00771612],\n\t\t\t\t[61.10094736],\n\t\t\t\t[329.1235579]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.709,0,382.284],\n\t\t\t\t[0,746.792,243.451],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.343209,0.149416,0.000603517,0.00195788,-0.0395936],\n\t\t\t\"R\": [\n\t\t\t\t[0.7773715491,0.01124156294,0.6289412548],\n\t\t\t\t[0.2547080739,0.908583342,-0.3310590698],\n\t\t\t\t[-0.5751671686,0.4175523175,0.7034435232]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.435783379],\n\t\t\t\t[55.70511308],\n\t\t\t\t[330.3798829]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[743.976,0,365.248],\n\t\t\t\t[0,744.344,229.757],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.297483,-0.106842,0.000162294,-0.00147347,0.393874],\n\t\t\t\"R\": [\n\t\t\t\t[0.7524447247,-0.05297584633,0.6565215122],\n\t\t\t\t[0.2825071426,0.9263759092,-0.2490329079],\n\t\t\t\t[-0.5949929838,0.3728555143,0.7120127209]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.049706825],\n\t\t\t\t[87.26745214],\n\t\t\t\t[326.8342451]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[748.766,0,349.367],\n\t\t\t\t[0,748.975,233.229],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.341466,0.149186,0.00133441,-0.000377568,-0.0615035],\n\t\t\t\"R\": [\n\t\t\t\t[0.7609990379,-0.1304343502,0.6355055818],\n\t\t\t\t[0.3323849453,0.9196335935,-0.2092708816],\n\t\t\t\t[-0.5571361704,0.3704874276,0.7431946943]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.029843232],\n\t\t\t\t[83.469382],\n\t\t\t\t[327.9910328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[747.104,0,395.739],\n\t\t\t\t[0,747.205,237.611],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.337038,0.14046,-0.00100634,0.00170735,-0.0468264],\n\t\t\t\"R\": [\n\t\t\t\t[0.7339738121,-0.1238803965,0.6677844641],\n\t\t\t\t[0.3595276943,0.9050347286,-0.227270713],\n\t\t\t\t[-0.5762137452,0.4068977603,0.7088102232]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[34.88470946],\n\t\t\t\t[89.42074723],\n\t\t\t\t[330.2467181]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[743.991,0,393.18],\n\t\t\t\t[0,744.112,255.459],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325283,0.0732539,0.00077889,1.70805e-05,0.0462558],\n\t\t\t\"R\": [\n\t\t\t\t[0.7496842409,-0.1571943749,0.6428557128],\n\t\t\t\t[0.3434403747,0.9227495198,-0.1748771933],\n\t\t\t\t[-0.5657050892,0.3518852828,0.7457576683]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[12.35233863],\n\t\t\t\t[128.2674639],\n\t\t\t\t[324.6313017]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.616,0,369.102],\n\t\t\t\t[0,744.835,223.742],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336732,0.141968,-0.000206183,0.000677154,-0.0657397],\n\t\t\t\"R\": [\n\t\t\t\t[0.7264947252,-0.2131742795,0.6532703428],\n\t\t\t\t[0.4249899792,0.8864309285,-0.1833677358],\n\t\t\t\t[-0.5399897516,0.4108490422,0.7345843265]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[15.28675757],\n\t\t\t\t[126.0458703],\n\t\t\t\t[333.4285141]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[747.517,0,392.733],\n\t\t\t\t[0,747.836,218.574],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334626,0.113242,0.000443349,0.00121381,-0.00550976],\n\t\t\t\"R\": [\n\t\t\t\t[0.8000319441,0.07155257429,0.5956753458],\n\t\t\t\t[0.1937456116,0.9088549369,-0.3693850858],\n\t\t\t\t[-0.5678129326,0.4109293525,0.7132499848]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-44.09712116],\n\t\t\t\t[90.97242653],\n\t\t\t\t[330.2186197]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.904,0,354.135],\n\t\t\t\t[0,744.494,220.038],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309276,-0.0261099,-0.00127318,0.000283377,0.220693],\n\t\t\t\"R\": [\n\t\t\t\t[0.7314656006,-0.1499734814,0.6651812009],\n\t\t\t\t[0.3639090401,0.9108337109,-0.1948131455],\n\t\t\t\t[-0.576652656,0.3845645668,0.720820233]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.360923884],\n\t\t\t\t[158.0207055],\n\t\t\t\t[327.7017732]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.441,0,366.024],\n\t\t\t\t[0,745.471,238.165],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311636,0.00305556,-0.00136926,0.00112458,0.163822],\n\t\t\t\"R\": [\n\t\t\t\t[0.743215427,-0.1065195831,0.660518287],\n\t\t\t\t[0.3430146167,0.9082888556,-0.2394834597],\n\t\t\t\t[-0.5744317207,0.4045552288,0.7115920636]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.38448511],\n\t\t\t\t[170.5922255],\n\t\t\t\t[331.2143489]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.816,0,384.478],\n\t\t\t\t[0,744.21,221.813],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309294,-0.0116228,-0.000777235,0.00017565,0.174372],\n\t\t\t\"R\": [\n\t\t\t\t[0.799529392,-0.03302696284,0.5997182431],\n\t\t\t\t[0.261290645,0.91817945,-0.2977812898],\n\t\t\t\t[-0.540814155,0.3947856601,0.7427410938]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.11731065],\n\t\t\t\t[179.1857595],\n\t\t\t\t[329.2699106]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[744.594,0,366.809],\n\t\t\t\t[0,744.805,211.378],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313339,0.0076854,-0.000770441,0.000328229,0.137582],\n\t\t\t\"R\": [\n\t\t\t\t[0.7697001229,-0.07364256128,0.6341439064],\n\t\t\t\t[0.280866324,0.9310898592,-0.2327783971],\n\t\t\t\t[-0.5733025631,0.3572792288,0.7373436945]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.06753178],\n\t\t\t\t[173.6081799],\n\t\t\t\t[322.2797536]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.088,0,376.311],\n\t\t\t\t[0,744.421,235.85],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308902,-0.0157485,-0.000258056,-0.00040893,0.167363],\n\t\t\t\"R\": [\n\t\t\t\t[0.8019727226,0.02030217439,0.5970155559],\n\t\t\t\t[0.20788107,0.9274680659,-0.31078682],\n\t\t\t\t[-0.5600225111,0.3733507848,0.7395836522]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.35663304],\n\t\t\t\t[177.8511702],\n\t\t\t\t[324.3990212]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[745.471,0,391.786],\n\t\t\t\t[0,745.597,244.782],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319471,0.0520955,-9.03549e-05,0.00103599,0.0679082],\n\t\t\t\"R\": [\n\t\t\t\t[0.7993824794,0.07801580494,0.5957358356],\n\t\t\t\t[0.170767806,0.9211391478,-0.3497728217],\n\t\t\t\t[-0.5760434082,0.3813347671,0.723019908]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.66881494],\n\t\t\t\t[158.8808021],\n\t\t\t\t[326.8395357]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.688,0,372.572],\n\t\t\t\t[0,744.687,232.622],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313079,0.00611683,0.000601543,0.00134427,0.153664],\n\t\t\t\"R\": [\n\t\t\t\t[0.8032635264,0.07397377164,0.5910123419],\n\t\t\t\t[0.1542914416,0.9325457224,-0.3264239985],\n\t\t\t\t[-0.5752928456,0.3533926383,0.7376664456]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.95169554],\n\t\t\t\t[148.2901373],\n\t\t\t\t[322.192073]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[746.029,0,371.631],\n\t\t\t\t[0,745.957,227.751],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328618,0.10871,0.000376647,0.00140085,-0.015131],\n\t\t\t\"R\": [\n\t\t\t\t[0.7930332571,0.09578045983,0.6016014933],\n\t\t\t\t[0.1573865304,0.9218193412,-0.3542295616],\n\t\t\t\t[-0.5884961625,0.3755997947,0.7159588403]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-34.37744536],\n\t\t\t\t[124.5681533],\n\t\t\t\t[326.9926029]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.728,0,355.008],\n\t\t\t\t[0,745.836,235.366],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326785,0.0753795,-0.00141997,0.000421746,0.0593081],\n\t\t\t\"R\": [\n\t\t\t\t[0.7423074724,-0.1183757606,0.6595201254],\n\t\t\t\t[0.3246236378,0.9245812728,-0.1994215728],\n\t\t\t\t[-0.5861732766,0.362127946,0.7247511576]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[30.16113415],\n\t\t\t\t[163.1800117],\n\t\t\t\t[323.8887405]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.415,0,362.511],\n\t\t\t\t[0,745.431,246.567],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31824,0.0392935,0.000511921,2.0382e-05,0.0980721],\n\t\t\t\"R\": [\n\t\t\t\t[0.7792023734,-0.03485918818,0.6258022837],\n\t\t\t\t[0.250771695,0.9323920084,-0.2603050127],\n\t\t\t\t[-0.5744190268,0.3597637832,0.7352637636]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.21577405],\n\t\t\t\t[116.3982595],\n\t\t\t\t[324.3931588]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.757,0,370.457],\n\t\t\t\t[0,745.798,252.296],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322058,0.058259,0.000816175,0.000770211,0.0698692],\n\t\t\t\"R\": [\n\t\t\t\t[0.7754488131,-0.03297117701,0.6305489986],\n\t\t\t\t[0.2704225106,0.9197540051,-0.2844718542],\n\t\t\t\t[-0.5705705951,0.391108005,0.7221383001]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.5150360293],\n\t\t\t\t[101.3336776],\n\t\t\t\t[328.6175717]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[746.009,0,385.23],\n\t\t\t\t[0,746.113,244.377],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.328614,0.0717398,0.00119782,0.000153035,0.0631847],\n\t\t\t\"R\": [\n\t\t\t\t[0.7150247804,-0.1629175474,0.6798510396],\n\t\t\t\t[0.3900461789,0.9000077369,-0.194550898],\n\t\t\t\t[-0.5801754405,0.4042820134,0.7070732013]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.095653738],\n\t\t\t\t[113.9962742],\n\t\t\t\t[330.0144097]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[747.044,0,384.928],\n\t\t\t\t[0,747.43,218.136],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332061,0.0970763,-0.00131827,0.000796644,0.024739],\n\t\t\t\"R\": [\n\t\t\t\t[0.7476996574,-0.1120966581,0.6545071135],\n\t\t\t\t[0.3349363173,0.9147459603,-0.2259590484],\n\t\t\t\t[-0.5733784838,0.3881677053,0.7215004829]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.202807266],\n\t\t\t\t[138.4357179],\n\t\t\t\t[328.3283502]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.525,0,381.586],\n\t\t\t\t[0,746.566,231.744],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323751,0.0809499,0.00143311,0.000786746,0.0334271],\n\t\t\t\"R\": [\n\t\t\t\t[0.7874675535,-0.04961201835,0.6143561669],\n\t\t\t\t[0.2785108695,0.9178324582,-0.2828697124],\n\t\t\t\t[-0.5498422936,0.3938555906,0.7365807667]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.67007007],\n\t\t\t\t[141.1281207],\n\t\t\t\t[328.549187]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"15_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 15,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[744.493,0,392.291],\n\t\t\t\t[0,744.573,223.193],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308278,-0.0176562,-0.000671893,0.00116828,0.17277],\n\t\t\t\"R\": [\n\t\t\t\t[0.7758686755,-0.01407586642,0.6307374005],\n\t\t\t\t[0.2927445364,0.8936390769,-0.3401614861],\n\t\t\t\t[-0.5588635207,0.4485655695,0.6974672]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.05926183],\n\t\t\t\t[105.1778582],\n\t\t\t\t[335.8474538]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.918,0,380.409],\n\t\t\t\t[0,745.86,226.454],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329171,0.0901569,-0.000500393,-0.000311386,0.0200307],\n\t\t\t\"R\": [\n\t\t\t\t[0.8121486446,0.04341076946,0.5818333819],\n\t\t\t\t[-0.0759194996,0.9966126489,0.03161419974],\n\t\t\t\t[-0.5784901112,-0.06984792866,0.8126933358]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[55.6088262],\n\t\t\t\t[125.3657692],\n\t\t\t\t[265.9940479]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[747.364,0,392.411],\n\t\t\t\t[0,747.161,225.523],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325367,0.0819479,0.000479765,0.00158774,0.0247525],\n\t\t\t\"R\": [\n\t\t\t\t[0.8168932447,0.07701494166,0.5716241121],\n\t\t\t\t[-0.08391193553,0.9963702084,-0.01432462351],\n\t\t\t\t[-0.5706524458,-0.03626439747,0.8203905653]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[75.42528996],\n\t\t\t\t[124.1426197],\n\t\t\t\t[270.1790967]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.743,0,378.771],\n\t\t\t\t[0,744.551,249.858],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319546,0.0369202,-5.08119e-05,0.00111176,0.115068],\n\t\t\t\"R\": [\n\t\t\t\t[0.8437113062,0.07102371173,0.5320778742],\n\t\t\t\t[-0.08587784221,0.9963005803,0.003185889303],\n\t\t\t\t[-0.5298832211,-0.04838167055,0.8466894271]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.15960424],\n\t\t\t\t[150.0301024],\n\t\t\t\t[271.4615922]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.916,0,377.522],\n\t\t\t\t[0,746.078,215.704],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32195,0.0590592,-0.000295617,0.000900619,0.0691531],\n\t\t\t\"R\": [\n\t\t\t\t[0.8298382679,0.121110683,0.5447023514],\n\t\t\t\t[-0.1306769278,0.9911961099,-0.02130286834],\n\t\t\t\t[-0.5424868568,-0.05350209448,0.8383588349]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.00635036],\n\t\t\t\t[157.1807453],\n\t\t\t\t[269.6015294]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.303,0,378.655],\n\t\t\t\t[0,745.572,246.962],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315703,0.0277156,6.06815e-05,0.000389915,0.121683],\n\t\t\t\"R\": [\n\t\t\t\t[0.8187116226,0.05412921644,0.5716478872],\n\t\t\t\t[-0.09011941267,0.9953220251,0.0348218015],\n\t\t\t\t[-0.5670888559,-0.08002558546,0.8197598034]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[44.81120287],\n\t\t\t\t[188.347539],\n\t\t\t\t[263.8787228]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.606,0,364.995],\n\t\t\t\t[0,745.957,239.275],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315328,0.0257972,-0.000148911,-0.000553771,0.11289],\n\t\t\t\"R\": [\n\t\t\t\t[0.8250072615,0.03741598225,0.5638821355],\n\t\t\t\t[-0.06134414867,0.997839028,0.02354080738],\n\t\t\t\t[-0.5617827996,-0.05401220659,0.8255196955]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.96573731],\n\t\t\t\t[189.9536973],\n\t\t\t\t[269.3804852]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[748.144,0,375.351],\n\t\t\t\t[0,748.158,222.981],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330846,0.0923667,0.000924419,-0.000952259,0.0155541],\n\t\t\t\"R\": [\n\t\t\t\t[0.837010476,0.04764620621,0.5451085232],\n\t\t\t\t[-0.06946161724,0.9973944363,0.0194787641],\n\t\t\t\t[-0.542760119,-0.05416804921,0.8381391744]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.044263505],\n\t\t\t\t[177.2440129],\n\t\t\t\t[269.3681033]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.865,0,367.243],\n\t\t\t\t[0,744.958,216.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318901,0.0494498,-4.02299e-05,-0.00132469,0.0675277],\n\t\t\t\"R\": [\n\t\t\t\t[0.820488273,0.02086231711,0.571282555],\n\t\t\t\t[-0.05401864215,0.9976917237,0.04114864192],\n\t\t\t\t[-0.569105421,-0.06462188605,0.8197213134]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.55260409],\n\t\t\t\t[185.7078501],\n\t\t\t\t[268.0867658]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[747.002,0,387.115],\n\t\t\t\t[0,747.11,221.005],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330535,0.106093,-0.000909516,-0.000158007,-0.000767667],\n\t\t\t\"R\": [\n\t\t\t\t[0.7988895638,0.03324884852,0.6005580562],\n\t\t\t\t[-0.04929092881,0.9987315997,0.01027599727],\n\t\t\t\t[-0.5994546431,-0.03781145137,0.7995151187]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.46737596],\n\t\t\t\t[164.4653247],\n\t\t\t\t[274.3468777]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.13,0,370.332],\n\t\t\t\t[0,747.181,215.13],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317083,0.0321021,0.000973109,0.00011315,0.117938],\n\t\t\t\"R\": [\n\t\t\t\t[0.8533830718,-0.04475694932,0.5193593633],\n\t\t\t\t[-0.01101437775,0.9945367161,0.1038046423],\n\t\t\t\t[-0.5211679348,-0.09430554471,0.8482278279]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.15311463],\n\t\t\t\t[154.6074069],\n\t\t\t\t[261.7210039]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.847,0,352.444],\n\t\t\t\t[0,743.813,257.427],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317406,0.0378558,0.000559662,0.00156409,0.0978841],\n\t\t\t\"R\": [\n\t\t\t\t[0.8306368039,-0.006305585156,0.5567788965],\n\t\t\t\t[-0.01286906876,0.999451376,0.03051776569],\n\t\t\t\t[-0.5566658666,-0.03251440526,0.8300999496]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-55.68789985],\n\t\t\t\t[125.5954887],\n\t\t\t\t[272.609285]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.746,0,358.295],\n\t\t\t\t[0,744.902,240.075],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311924,0.00313238,0.000282789,0.000109914,0.161883],\n\t\t\t\"R\": [\n\t\t\t\t[0.8248636519,0.04296544146,0.5636966618],\n\t\t\t\t[-0.06337887364,0.9978500361,0.01668603434],\n\t\t\t\t[-0.5617678116,-0.04949016272,0.8258133262]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-45.5470475],\n\t\t\t\t[111.3455785],\n\t\t\t\t[270.6081331]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.599,0,373.118],\n\t\t\t\t[0,742.696,232.489],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.30659,-0.0244311,-0.000674534,-0.000450328,0.198624],\n\t\t\t\"R\": [\n\t\t\t\t[0.8431633834,0.1596479738,0.5134082522],\n\t\t\t\t[-0.1755645793,0.9843078819,-0.01775026834],\n\t\t\t\t[-0.5081855837,-0.07516992751,0.8579608934]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-27.27822308],\n\t\t\t\t[119.4613899],\n\t\t\t\t[265.3318331]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.804,0,370.921],\n\t\t\t\t[0,745.998,236.13],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32821,0.0986121,-0.000141995,-6.949e-05,-0.000912797],\n\t\t\t\"R\": [\n\t\t\t\t[0.8387309717,0.02755081107,0.5438486094],\n\t\t\t\t[-0.05712815546,0.9976599438,0.03756341813],\n\t\t\t\t[-0.5415410705,-0.06257467009,0.8383422211]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.56519475],\n\t\t\t\t[90.10611059],\n\t\t\t\t[268.3571691]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.816,0,365.456],\n\t\t\t\t[0,746.849,225.794],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313831,-0.00769663,-0.000408313,0.00132145,0.204366],\n\t\t\t\"R\": [\n\t\t\t\t[0.832563643,0.03033638007,0.5530980784],\n\t\t\t\t[-0.06055031945,0.9974999941,0.03643378343],\n\t\t\t\t[-0.5506100609,-0.06382370879,0.8323191065]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.42740827],\n\t\t\t\t[88.69840867],\n\t\t\t\t[268.7038743]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.958,0,362.302],\n\t\t\t\t[0,745.997,246.977],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.334292,0.102923,-0.000499879,-0.000549652,0.00793805],\n\t\t\t\"R\": [\n\t\t\t\t[0.8469636173,0.04048111503,0.5301074517],\n\t\t\t\t[-0.08872767491,0.9938758,0.0658657255],\n\t\t\t\t[-0.5241946497,-0.1028210748,0.8453684379]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.584618298],\n\t\t\t\t[109.8657875],\n\t\t\t\t[264.6056558]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[743.409,0,347.233],\n\t\t\t\t[0,743.501,244.449],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321337,0.060438,0.000289347,-0.000274585,0.0540146],\n\t\t\t\"R\": [\n\t\t\t\t[0.8338949711,0.06176137043,0.5484566622],\n\t\t\t\t[-0.07967791451,0.9967809419,0.008898524832],\n\t\t\t\t[-0.5461415633,-0.05112031815,0.8361316319]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.73506114],\n\t\t\t\t[91.25662398],\n\t\t\t\t[270.2531272]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.291,0,372.769],\n\t\t\t\t[0,745.233,242.994],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333422,0.127228,0.000470045,-0.000171948,-0.0533425],\n\t\t\t\"R\": [\n\t\t\t\t[0.83476387,0.01583088955,0.5503804723],\n\t\t\t\t[-0.006383142992,0.9997976531,-0.01907638369],\n\t\t\t\t[-0.5505711006,0.01241111862,0.8346960089]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.20146308],\n\t\t\t\t[84.31846371],\n\t\t\t\t[276.1979749]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.318,0,365.802],\n\t\t\t\t[0,746.439,228.058],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.329752,0.106043,0.000413141,0.00102356,-0.00232913],\n\t\t\t\"R\": [\n\t\t\t\t[0.812564017,0.08482803737,0.576666214],\n\t\t\t\t[-0.09768913876,0.9951785947,-0.008740529432],\n\t\t\t\t[-0.5746273144,-0.04923178609,0.8169330944]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[39.50134988],\n\t\t\t\t[124.7306793],\n\t\t\t\t[269.4016435]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.104,0,371.377],\n\t\t\t\t[0,745.158,252.192],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317414,0.0233642,0.000269725,0.000539732,0.145301],\n\t\t\t\"R\": [\n\t\t\t\t[0.8445515108,0.05428741136,0.5327153297],\n\t\t\t\t[-0.06949119822,0.9975462456,0.00851241329],\n\t\t\t\t[-0.5309460603,-0.04420819807,0.8462516862]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.33430135],\n\t\t\t\t[146.0606392],\n\t\t\t\t[271.3134014]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.321,0,365.126],\n\t\t\t\t[0,744.44,221.253],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310945,0.00293318,4.64093e-05,-0.000454281,0.146346],\n\t\t\t\"R\": [\n\t\t\t\t[0.8382052649,0.09941648006,0.5362166515],\n\t\t\t\t[-0.1229674254,0.9923765769,0.008230548616],\n\t\t\t\t[-0.531310593,-0.07283607028,0.8440402601]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[5.636303812],\n\t\t\t\t[160.8368098],\n\t\t\t\t[266.310691]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.695,0,387.973],\n\t\t\t\t[0,745.975,222.039],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325844,0.0780224,-0.000861123,0.000487347,0.0459906],\n\t\t\t\"R\": [\n\t\t\t\t[0.8503320636,-0.003175777979,0.52623692],\n\t\t\t\t[-0.02504000004,0.9986049625,0.04648792516],\n\t\t\t\t[-0.5256504352,-0.05270714583,0.8490662971]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.03965018],\n\t\t\t\t[141.2975723],\n\t\t\t\t[268.9897195]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.757,0,385.384],\n\t\t\t\t[0,746.697,250.739],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330103,0.0993513,0.000581277,0.0005991,0.0043047],\n\t\t\t\"R\": [\n\t\t\t\t[0.8172674448,0.1129970073,0.565071323],\n\t\t\t\t[-0.1204798393,0.992420693,-0.02420281713],\n\t\t\t\t[-0.5635233199,-0.0482995277,0.8246869852]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[1.484048414],\n\t\t\t\t[120.2737991],\n\t\t\t\t[270.3939501]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"16_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 16,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[743.909,0,365.262],\n\t\t\t\t[0,744.1,225.983],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309366,-0.0151251,-0.000569796,0.000128233,0.192772],\n\t\t\t\"R\": [\n\t\t\t\t[0.8488529257,0.0258708029,0.5279956553],\n\t\t\t\t[-0.02681353424,0.9996232069,-0.005871843729],\n\t\t\t\t[-0.5279486195,-0.009173097852,0.8492267715]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.170097817],\n\t\t\t\t[104.9858918],\n\t\t\t\t[274.723166]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[743.511,0,382.741],\n\t\t\t\t[0,744.07,233.668],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.303608,-0.0460126,4.19904e-05,0.000729649,0.232264],\n\t\t\t\"R\": [\n\t\t\t\t[0.7426987355,0.03664601822,-0.6686222084],\n\t\t\t\t[-0.01756201576,0.9992239229,0.035258014],\n\t\t\t\t[0.6693953719,-0.01444372865,0.742765922]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.30884403],\n\t\t\t\t[110.2809812],\n\t\t\t\t[269.7471778]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[744.491,0,371.868],\n\t\t\t\t[0,744.58,223.545],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320104,0.0388113,-0.000303412,-0.00118762,0.0743207],\n\t\t\t\"R\": [\n\t\t\t\t[0.773334615,0.1038173874,-0.6254402635],\n\t\t\t\t[-0.04654036662,0.9931361468,0.107306049],\n\t\t\t\t[0.6322875671,-0.05387526291,0.7728582591]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[68.17402308],\n\t\t\t\t[125.7906344],\n\t\t\t\t[263.8293382]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.096,0,373.775],\n\t\t\t\t[0,744.072,232.317],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314223,0.0332024,-0.000194112,2.11963e-05,0.079313],\n\t\t\t\"R\": [\n\t\t\t\t[0.7946878724,-0.02084896757,-0.6066601239],\n\t\t\t\t[0.03470365887,0.999335828,0.01111570764],\n\t\t\t\t[0.6060254462,-0.02988684405,0.7948835985]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[55.17367606],\n\t\t\t\t[148.0232969],\n\t\t\t\t[266.1261169]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[748.225,0,373.118],\n\t\t\t\t[0,748.618,236.287],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325852,0.0883394,-0.000431944,-0.00077703,0.0075009],\n\t\t\t\"R\": [\n\t\t\t\t[0.7874797118,0.07165214706,-0.6121614766],\n\t\t\t\t[-0.03177741847,0.9966185482,0.07577377574],\n\t\t\t\t[0.6155208357,-0.04021739967,0.7870938073]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[46.04066644],\n\t\t\t\t[153.679907],\n\t\t\t\t[265.8341529]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[745.23,0,378.585],\n\t\t\t\t[0,745.614,229.474],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323397,0.071697,-0.000659822,0.000678056,0.0530686],\n\t\t\t\"R\": [\n\t\t\t\t[0.7680042357,0.04160049173,-0.6390922414],\n\t\t\t\t[0.01355248597,0.9966090615,0.08115854064],\n\t\t\t\t[0.6403013541,-0.07099139161,0.7648361904]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[29.31016003],\n\t\t\t\t[185.453895],\n\t\t\t\t[261.9380867]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[742.876,0,352.101],\n\t\t\t\t[0,743.303,231.794],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.319343,0.0421325,-0.000546468,-1.33187e-05,0.10149],\n\t\t\t\"R\": [\n\t\t\t\t[0.8064347587,0.08751734637,-0.584810819],\n\t\t\t\t[-0.03388642915,0.9942014648,0.1020546777],\n\t\t\t\t[0.5903513275,-0.062483289,0.8047242688]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[35.39857301],\n\t\t\t\t[188.6248332],\n\t\t\t\t[262.8234665]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[745.054,0,358.779],\n\t\t\t\t[0,745.36,231.687],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309912,-0.00132311,-0.00013553,-0.000280643,0.151777],\n\t\t\t\"R\": [\n\t\t\t\t[0.7882500993,-0.004275732235,-0.615340149],\n\t\t\t\t[0.05540043824,0.996408109,0.06404429605],\n\t\t\t\t[0.612856078,-0.08457303664,0.7856556683]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.246792888],\n\t\t\t\t[183.4614511],\n\t\t\t\t[259.402568]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.254,0,343.02],\n\t\t\t\t[0,745.689,227.622],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309897,-0.0109758,-0.00111103,0.000256129,0.180098],\n\t\t\t\"R\": [\n\t\t\t\t[0.7946287881,0.03514926038,-0.6060772382],\n\t\t\t\t[0.01090423253,0.9973351466,0.07213669658],\n\t\t\t\t[0.6069976827,-0.06393070292,0.7921279432]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-18.41109561],\n\t\t\t\t[184.5517176],\n\t\t\t\t[263.9542066]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.379,0,338.137],\n\t\t\t\t[0,745.543,245.392],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314138,0.0142784,0.00088856,-0.00114362,0.123117],\n\t\t\t\"R\": [\n\t\t\t\t[0.7570044814,0.09852948519,-0.6459381981],\n\t\t\t\t[-0.05745310106,0.9947735679,0.08440787789],\n\t\t\t\t[0.6508789107,-0.02678598925,0.7587088733]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-40.16389387],\n\t\t\t\t[164.132571],\n\t\t\t\t[267.7674295]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[743.633,0,369.381],\n\t\t\t\t[0,743.739,253.863],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313678,0.00191444,-0.000367883,0.000526793,0.16208],\n\t\t\t\"R\": [\n\t\t\t\t[0.7732990879,0.03177464522,-0.6332447335],\n\t\t\t\t[0.01440724919,0.9976050167,0.06765102948],\n\t\t\t\t[0.6338777104,-0.06143779407,0.7709892643]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-41.17430449],\n\t\t\t\t[148.5957101],\n\t\t\t\t[262.973747]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[749.691,0,360.347],\n\t\t\t\t[0,749.465,221.979],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.36212,0.288042,0.00167589,0.000680745,-0.303613],\n\t\t\t\"R\": [\n\t\t\t\t[0.7747984815,0.06051645956,-0.629305229],\n\t\t\t\t[-0.01350572868,0.9967652932,0.07922465313],\n\t\t\t\t[0.6320640066,-0.05288391526,0.7731095544]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-52.93053536],\n\t\t\t\t[133.9502209],\n\t\t\t\t[264.0833713]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[746.505,0,357.704],\n\t\t\t\t[0,746.569,217.534],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312272,-0.0352904,0.000404412,-0.00107082,0.237629],\n\t\t\t\"R\": [\n\t\t\t\t[0.7725304823,-0.04233401582,-0.633564902],\n\t\t\t\t[0.05994143841,0.9981814314,0.006391704783],\n\t\t\t\t[0.6321421342,-0.04291457833,0.7736631445]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.64410987],\n\t\t\t\t[104.0188122],\n\t\t\t\t[265.010728]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[745.264,0,354.32],\n\t\t\t\t[0,745.302,226.261],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318398,0.0346929,0.000845692,0.000532231,0.122684],\n\t\t\t\"R\": [\n\t\t\t\t[0.7851484689,0.03204817868,-0.6184778056],\n\t\t\t\t[-0.002225165301,0.9987996914,0.04893081946],\n\t\t\t\t[0.619303585,-0.03704174263,0.784277361]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-29.19489341],\n\t\t\t\t[103.2650402],\n\t\t\t\t[265.9795804]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.589,0,353.058],\n\t\t\t\t[0,744.664,227.639],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324606,0.0822873,0.00100728,-0.000415736,0.0203245],\n\t\t\t\"R\": [\n\t\t\t\t[0.7765409088,-0.02900211747,-0.6293989944],\n\t\t\t\t[0.06862390156,0.9968904955,0.03873112579],\n\t\t\t\t[0.6263185908,-0.07326811825,0.7761164898]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-35.65491372],\n\t\t\t\t[89.93385082],\n\t\t\t\t[261.6973052]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[744.009,0,351.118],\n\t\t\t\t[0,743.982,227.187],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.31768,0.0289626,0.000394183,-0.00106594,0.077624],\n\t\t\t\"R\": [\n\t\t\t\t[0.7703409519,0.009578036972,-0.6375602553],\n\t\t\t\t[0.03762675731,0.9974619202,0.06044786963],\n\t\t\t\t[0.6365210484,-0.07055479443,0.7680253746]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.94306331],\n\t\t\t\t[88.85755459],\n\t\t\t\t[261.4804843]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[745.298,0,365.044],\n\t\t\t\t[0,745.641,201.543],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315769,0.0139989,-0.000983596,0.000497246,0.155532],\n\t\t\t\"R\": [\n\t\t\t\t[0.7668905855,0.04755147693,-0.6400138177],\n\t\t\t\t[0.009922268647,0.9962536216,0.0859084976],\n\t\t\t\t[0.6417011597,-0.07223280706,0.7635457047]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.594602528],\n\t\t\t\t[99.8882812],\n\t\t\t\t[261.439958]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[744.772,0,356.238],\n\t\t\t\t[0,744.946,209.811],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307562,-0.0273551,-0.000331097,0.000403566,0.231396],\n\t\t\t\"R\": [\n\t\t\t\t[0.7386328767,0.1026186384,-0.6662513704],\n\t\t\t\t[-0.03586762178,0.992927984,0.1131703685],\n\t\t\t\t[0.6731530192,-0.05969450264,0.7370899397]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.92063539],\n\t\t\t\t[92.1220326],\n\t\t\t\t[263.1909682]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[746.696,0,345.664],\n\t\t\t\t[0,746.883,230.9],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332087,0.135716,-0.000396371,4.15402e-05,-0.0769473],\n\t\t\t\"R\": [\n\t\t\t\t[0.7676740293,0.0869303765,-0.6349170767],\n\t\t\t\t[-0.05592901251,0.9960646798,0.06875390322],\n\t\t\t\t[0.6383952774,-0.01727030079,0.7695149163]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[48.13164066],\n\t\t\t\t[87.731429],\n\t\t\t\t[267.0873794]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[743.785,0,363.137],\n\t\t\t\t[0,743.962,239.724],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322076,0.0699752,0.00130957,8.28091e-06,0.0447641],\n\t\t\t\"R\": [\n\t\t\t\t[0.7666015958,0.09362030423,-0.6352615462],\n\t\t\t\t[-0.01827880108,0.9920950944,0.1241499457],\n\t\t\t\t[0.6418628193,-0.08356172708,0.7622529495]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[25.25313987],\n\t\t\t\t[133.2656265],\n\t\t\t\t[259.9680703]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[747.071,0,344.427],\n\t\t\t\t[0,747.404,242.981],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.349964,0.20917,0.0008789,-0.000586258,-0.211765],\n\t\t\t\"R\": [\n\t\t\t\t[0.7775513873,0.03007697302,-0.6280996862],\n\t\t\t\t[-0.01270805589,0.999403059,0.03212523871],\n\t\t\t\t[0.6286909777,-0.01699709801,0.7774694548]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[17.35278566],\n\t\t\t\t[137.2956705],\n\t\t\t\t[269.3773006]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[744.669,0,371.314],\n\t\t\t\t[0,744.881,251.475],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32107,0.0528121,0.000172414,0.000961494,0.0921892],\n\t\t\t\"R\": [\n\t\t\t\t[0.7854342878,0.01663631847,-0.6187214337],\n\t\t\t\t[0.02446292583,0.9980232337,0.05788946549],\n\t\t\t\t[0.6184614336,-0.06060410764,0.7834746947]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.039205356],\n\t\t\t\t[155.8049723],\n\t\t\t\t[263.425936]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[744.126,0,368.359],\n\t\t\t\t[0,744.205,218.365],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306681,-0.0309893,-0.000506643,-0.000551257,0.209183],\n\t\t\t\"R\": [\n\t\t\t\t[0.7742934088,0.08491898973,-0.6271032469],\n\t\t\t\t[-0.02171436959,0.9939373135,0.1077826651],\n\t\t\t\t[0.6324541115,-0.06983825553,0.771443073]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.48615074],\n\t\t\t\t[146.2169272],\n\t\t\t\t[261.8070617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.439,0,363.854],\n\t\t\t\t[0,746.575,224.032],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333494,0.127943,0.00111227,0.000376509,-0.0438307],\n\t\t\t\"R\": [\n\t\t\t\t[0.7741360077,0.05745954338,-0.6304060933],\n\t\t\t\t[-0.01777243196,0.9974520988,0.06909016755],\n\t\t\t\t[0.6327697704,-0.04228133707,0.7731847814]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.18178238],\n\t\t\t\t[117.4047924],\n\t\t\t\t[265.0998909]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"17_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 17,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.824,0,346.505],\n\t\t\t\t[0,746.017,224.098],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317434,0.0247137,-0.000866957,0.000304145,0.138958],\n\t\t\t\"R\": [\n\t\t\t\t[0.7656627697,0.09930116127,-0.6355311184],\n\t\t\t\t[-0.04982185052,0.99419918,0.09531932471],\n\t\t\t\t[0.6413098365,-0.04131912178,0.7661686654]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[7.35512715],\n\t\t\t\t[111.8344509],\n\t\t\t\t[265.0127015]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[744.96,0,372.705],\n\t\t\t\t[0,744.564,226.392],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321978,0.0724692,0.000483988,0.000458946,0.0380169],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3520669355,0.03279886428,-0.9353999719],\n\t\t\t\t[0.04913052402,0.9986556534,0.01652505738],\n\t\t\t\t[0.9346844732,-0.04013876447,-0.3532050609]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[47.10128491],\n\t\t\t\t[117.3460549],\n\t\t\t\t[266.6541908]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[748.843,0,358.358],\n\t\t\t\t[0,748.813,225.018],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.335266,0.148062,0.000634215,-0.00153008,-0.105518],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3389880085,0.04020239671,-0.9399313259],\n\t\t\t\t[0.04795713663,0.9985260662,0.02541275744],\n\t\t\t\t[0.9395675831,-0.03646179499,-0.3404163544]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[70.51461434],\n\t\t\t\t[125.984952],\n\t\t\t\t[266.5287049]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[746.557,0,370.525],\n\t\t\t\t[0,746.643,239.094],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.336876,0.137869,0.0006954,0.000424607,-0.0538424],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3751735108,0.06869685522,-0.9244055273],\n\t\t\t\t[0.01802710881,0.9976021763,0.06682006625],\n\t\t\t\t[0.9267792942,0.008404759824,-0.3755123165]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[58.58769651],\n\t\t\t\t[133.6261971],\n\t\t\t\t[275.7276294]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[744.71,0,356.151],\n\t\t\t\t[0,744.769,223.97],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312604,0.00791514,0.000747313,-0.000519594,0.158336],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3438161676,0.01243889994,-0.9389545871],\n\t\t\t\t[0.0251972518,0.9996744288,0.00401683712],\n\t\t\t\t[0.9386988555,-0.02227802162,-0.344017657]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.26546697],\n\t\t\t\t[152.0702476],\n\t\t\t\t[270.0686857]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[743.927,0,355.392],\n\t\t\t\t[0,744.057,262.153],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316206,0.0381773,0.00109867,0.000112775,0.102099],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3913025917,0.04706716523,-0.9190576498],\n\t\t\t\t[0.07535158968,0.9969764632,0.0189755056],\n\t\t\t\t[0.9171719684,-0.0618272904,-0.3936660596]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[27.50168157],\n\t\t\t\t[183.5367771],\n\t\t\t\t[265.1462318]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.89,0,353.646],\n\t\t\t\t[0,744.816,246.705],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311434,-0.0151537,0.000898898,0.00113623,0.19919],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3540366423,0.02766248657,-0.9348223589],\n\t\t\t\t[0.06855079724,0.9976412764,0.003559761167],\n\t\t\t\t[0.9327158432,-0.06282253209,-0.3550978532]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[15.12228299],\n\t\t\t\t[191.0759947],\n\t\t\t\t[263.959739]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.21,0,382.066],\n\t\t\t\t[0,744.474,221.564],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318836,0.0439442,-0.000310088,0.000693195,0.0844966],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3784097731,0.01208936744,-0.9255592314],\n\t\t\t\t[0.03775536538,0.9992841689,-0.002383732641],\n\t\t\t\t[0.9248678695,-0.03584685469,-0.3785953341]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-11.73143391],\n\t\t\t\t[170.7040215],\n\t\t\t\t[268.2801795]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[744.996,0,378.911],\n\t\t\t\t[0,745.249,217.173],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317298,0.0439499,-0.000470842,0.000645598,0.0800391],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3573644405,-0.02168005213,-0.9337133564],\n\t\t\t\t[0.09030348924,0.9942444419,-0.05764780686],\n\t\t\t\t[0.9295891224,-0.1049188503,-0.3533498244]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-32.18764663],\n\t\t\t\t[193.5958696],\n\t\t\t\t[255.9258617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[745.488,0,367.703],\n\t\t\t\t[0,745.136,254.274],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333608,0.117291,0.00107107,0.000590786,-0.0167148],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3755971335,-0.01611847579,-0.9266428589],\n\t\t\t\t[0.03486308067,0.9988953473,-0.03150636014],\n\t\t\t\t[0.9261270749,-0.0441393233,-0.3746202894]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-52.11061688],\n\t\t\t\t[162.8813669],\n\t\t\t\t[265.66749]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.691,0,377.016],\n\t\t\t\t[0,746.35,247.895],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324348,0.0759263,0.000632098,0.000973799,0.0365142],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3979832561,-0.05264507275,-0.9158809007],\n\t\t\t\t[0.03842303812,0.9965195246,-0.07397639654],\n\t\t\t\t[0.9165876925,-0.06463229393,-0.3945753015]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-58.47639535],\n\t\t\t\t[144.7851801],\n\t\t\t\t[261.4908418]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[743.499,0,383.73],\n\t\t\t\t[0,743.269,228.607],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318101,0.0343673,-0.000192972,9.02677e-05,0.0940376],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3591156591,-0.0799459609,-0.9298626709],\n\t\t\t\t[0.01693912278,0.9956019804,-0.09213990831],\n\t\t\t\t[0.9331393302,-0.04883994185,-0.356182047]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-65.19666066],\n\t\t\t\t[124.1115675],\n\t\t\t\t[265.1913912]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.847,0,377.843],\n\t\t\t\t[0,744.539,240.133],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322594,0.0777366,0.000608553,0.000730506,0.0395492],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3599917326,-0.04959232233,-0.9316364924],\n\t\t\t\t[0.02914279324,0.9975011607,-0.0643593979],\n\t\t\t\t[0.9325002145,-0.05031934083,-0.3576469123]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-57.61171896],\n\t\t\t\t[105.5688064],\n\t\t\t\t[264.3974594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.264,0,386.065],\n\t\t\t\t[0,742.375,236.247],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316238,0.0182785,-0.000395794,0.00144239,0.136479],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3232019546,0.03338047233,-0.9457411066],\n\t\t\t\t[0.05161368011,0.9985119503,0.01760435083],\n\t\t\t\t[0.9449214383,-0.04312341834,-0.324443903]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[61.04698375],\n\t\t\t\t[97.35388185],\n\t\t\t\t[264.1973208]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[744.531,0,362.517],\n\t\t\t\t[0,744.694,222.936],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323155,0.0551,-0.000315217,0.00114443,0.0791805],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3124904102,0.02154150537,-0.9496766329],\n\t\t\t\t[-0.004629448499,0.999696432,0.02419942065],\n\t\t\t\t[0.9499096335,0.01195856595,-0.3122958229]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.02426098],\n\t\t\t\t[68.46079663],\n\t\t\t\t[270.3325449]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[747.429,0,398.562],\n\t\t\t\t[0,747.425,233.615],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.333617,0.122405,0.000303778,0.00134383,-0.0202721],\n\t\t\t\"R\": [\n\t\t\t\t[-0.358025731,-0.0142572014,-0.9336028643],\n\t\t\t\t[0.04081564607,0.9986886699,-0.03090345813],\n\t\t\t\t[0.9328191995,-0.04916983726,-0.3569743242]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.683192747],\n\t\t\t\t[83.02873835],\n\t\t\t\t[264.4620974]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[742.757,0,357.304],\n\t\t\t\t[0,742.66,220.331],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305443,-0.0527047,-0.000521453,0.00022453,0.250047],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3364590891,0.05374146283,-0.9401633563],\n\t\t\t\t[0.05791647683,0.99766121,0.03630140184],\n\t\t\t\t[0.9399154021,-0.04223701264,-0.3387846981]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.062846],\n\t\t\t\t[91.33983095],\n\t\t\t\t[265.2581766]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[750.787,0,361.922],\n\t\t\t\t[0,750.723,216.611],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.368257,0.303211,-0.00101236,-0.000679192,-0.335284],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3521002367,0.0154136189,-0.9358353721],\n\t\t\t\t[0.04957845599,0.9987678018,-0.002203336065],\n\t\t\t\t[0.9346482761,-0.04717306796,-0.3524305629]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[32.75189895],\n\t\t\t\t[90.38015946],\n\t\t\t\t[265.2110414]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.69,0,366.196],\n\t\t\t\t[0,745.645,224.452],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.325076,0.0695314,0.000207452,8.09151e-05,0.0569118],\n\t\t\t\"R\": [\n\t\t\t\t[-0.369329094,-0.008664471876,-0.929258278],\n\t\t\t\t[0.06369637747,0.997368813,-0.03461534879],\n\t\t\t\t[0.9271131494,-0.07197484145,-0.3678054246]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-35.28307581],\n\t\t\t\t[111.055802],\n\t\t\t\t[261.8818226]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[745.552,0,357.301],\n\t\t\t\t[0,745.545,223.113],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320101,0.042192,0.00043748,0.000103204,0.104558],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3584191226,-0.04877846794,-0.9322855752],\n\t\t\t\t[0.07086164718,0.9943315632,-0.07926770686],\n\t\t\t\t[0.9308675306,-0.09447435344,-0.3529309238]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.14340371],\n\t\t\t\t[139.4376601],\n\t\t\t\t[259.6452388]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[746.078,0,363.03],\n\t\t\t\t[0,746.077,221.582],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321359,0.0569666,0.000169599,0.000938787,0.0797635],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3631410096,0.0448531679,-0.9306539639],\n\t\t\t\t[0.06634832184,0.9975497918,0.02218813063],\n\t\t\t\t[0.9293688758,-0.05368990856,-0.3652271709]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[21.37501917],\n\t\t\t\t[147.345749],\n\t\t\t\t[265.5705493]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.043,0,372.293],\n\t\t\t\t[0,745.076,222.901],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317484,0.0404748,0.000192535,-0.000111527,0.0957966],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3461967977,-0.005928135698,-0.9381431844],\n\t\t\t\t[0.04577092509,0.9986824948,-0.02320122706],\n\t\t\t\t[0.937044716,-0.05097187193,-0.3454693453]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.5259425122],\n\t\t\t\t[153.3372726],\n\t\t\t\t[265.7616305]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[745.252,0,401.788],\n\t\t\t\t[0,745.346,245.295],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315494,0.0267895,-0.000624877,0.000210937,0.0993279],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3267831921,-0.004575639121,-0.9450882546],\n\t\t\t\t[0.07739750703,0.9964998407,-0.03158628616],\n\t\t\t\t[0.9419248225,-0.08346934224,-0.3252852558]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.3938656],\n\t\t\t\t[148.3069178],\n\t\t\t\t[261.1183693]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[747.114,0,358.608],\n\t\t\t\t[0,746.941,217.398],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324507,0.0792141,-0.000227367,0.0013287,0.0357905],\n\t\t\t\"R\": [\n\t\t\t\t[-0.356358404,-0.03218270054,-0.9337949248],\n\t\t\t\t[0.02645826287,0.9986582749,-0.04451528213],\n\t\t\t\t[0.9339746507,-0.04056998648,-0.3550287707]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-18.04448695],\n\t\t\t\t[115.7023496],\n\t\t\t\t[266.3010308]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"18_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 18,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[747.28,0,383.407],\n\t\t\t\t[0,747.414,233.333],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321806,0.0494121,-0.000677773,0.00106862,0.0725344],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3696831614,0.01690678518,-0.9290040478],\n\t\t\t\t[0.03916078476,0.9992295361,0.002601362608],\n\t\t\t\t[0.9283322644,-0.03541884761,-0.3700604169]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[3.487638933],\n\t\t\t\t[110.8874693],\n\t\t\t\t[266.9764809]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[742.815,0,376.349],\n\t\t\t\t[0,742.96,226.412],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311242,0.000676611,0.00127048,0.000398816,0.145683],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9986287013,0.0334613179,0.04026235479],\n\t\t\t\t[0.03051664863,0.9969627365,-0.07165218936],\n\t\t\t\t[-0.04253764409,-0.07032526067,-0.99661673]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[47.87451164],\n\t\t\t\t[124.5257469],\n\t\t\t\t[265.3025885]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.352,0,362.211],\n\t\t\t\t[0,746.799,224.495],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.33354,0.113916,-0.000650978,0.00200875,0.00369896],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9978769066,0.0627015602,0.01761231284],\n\t\t\t\t[0.06225819076,0.9977547513,-0.02468550225],\n\t\t\t\t[-0.01912058832,-0.02353658189,-0.9995401105]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[76.18899734],\n\t\t\t\t[119.4504319],\n\t\t\t\t[269.470097]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[744.923,0,335.897],\n\t\t\t\t[0,744.843,232.622],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310786,-0.00740435,0.000477261,-0.00048183,0.169837],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9959217828,0.05942221639,0.06788816328],\n\t\t\t\t[0.05820019172,0.9981077555,-0.01984051806],\n\t\t\t\t[-0.06893866983,-0.0158085,-0.9974956397]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.6907282],\n\t\t\t\t[139.716188],\n\t\t\t\t[274.5941587]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[745.3,0,371.455],\n\t\t\t\t[0,745.339,223.979],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316788,0.039021,-0.00160053,-0.000126119,0.09467],\n\t\t\t\"R\": [\n\t\t\t\t[-0.995350133,0.07444232287,0.06112653567],\n\t\t\t\t[0.06997485872,0.994930028,-0.0722340534],\n\t\t\t\t[-0.06619389658,-0.06762085396,-0.9955128267]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[42.04206067],\n\t\t\t\t[161.4993909],\n\t\t\t\t[266.5642499]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[741.339,0,353.354],\n\t\t\t\t[0,741.563,231.192],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.304803,-0.0634451,-0.00114618,-0.000982934,0.282182],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9964181101,0.07478982294,0.03946431643],\n\t\t\t\t[0.07096423127,0.993341211,-0.09075966339],\n\t\t\t\t[-0.04598943103,-0.08763401739,-0.9950905744]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[45.56899486],\n\t\t\t\t[188.2245222],\n\t\t\t\t[262.1501617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[745.947,0,350.894],\n\t\t\t\t[0,746.217,234.332],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313212,0.0178381,0.000340441,0.00055626,0.126083],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9969018679,0.07865171151,0.0007576151751],\n\t\t\t\t[0.07854654264,0.9959829876,-0.04299219736],\n\t\t\t\t[-0.004135981729,-0.0427994938,-0.9990751208]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.2742824],\n\t\t\t\t[183.4195047],\n\t\t\t\t[270.0123608]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[748.821,0,355.822],\n\t\t\t\t[0,748.684,217.17],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.342444,0.16602,-0.000477836,-0.000195363,-0.106824],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9928808048,-0.04900785176,0.10856306],\n\t\t\t\t[-0.05236016128,0.998228751,-0.02824489671],\n\t\t\t\t[-0.106986546,-0.0337281951,-0.9936882247]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-31.49326377],\n\t\t\t\t[168.7489309],\n\t\t\t\t[271.4480177]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[747.238,0,359.034],\n\t\t\t\t[0,747.474,233.038],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.313675,0.00436645,0.000419802,0.000604189,0.154068],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9913876468,0.02931278851,0.127637354],\n\t\t\t\t[0.0192008625,0.9966303068,-0.07974558542],\n\t\t\t\t[-0.1295448208,-0.07660804099,-0.9886098055]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-44.88902211],\n\t\t\t\t[188.5485089],\n\t\t\t\t[261.5304555]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[743.415,0,332.333],\n\t\t\t\t[0,743.715,235.337],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308464,-0.0208585,-0.00102455,0.000256502,0.207947],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9954977047,0.04566149696,0.08306231217],\n\t\t\t\t[0.04175753042,0.9979670543,-0.04814631117],\n\t\t\t\t[-0.08509188364,-0.04446106523,-0.9953806232]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.35184093],\n\t\t\t\t[166.6378451],\n\t\t\t\t[268.6077116]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[747.206,0,362.728],\n\t\t\t\t[0,747.412,248.496],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.340118,0.138855,0.000965068,4.5306e-05,-0.0441245],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9935175509,0.05252798067,0.1008151146],\n\t\t\t\t[0.05439486481,0.9983935823,0.01585728578],\n\t\t\t\t[-0.09982021218,0.02123831626,-0.9947787991]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-46.95074625],\n\t\t\t\t[127.5778656],\n\t\t\t\t[276.6370715]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[745.45,0,355.141],\n\t\t\t\t[0,745.641,249.232],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.326245,0.10077,0.000216744,-2.37583e-05,-0.0259903],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9983050345,-0.001439505441,0.05818063101],\n\t\t\t\t[-0.002578079686,0.9998065462,-0.01949932386],\n\t\t\t\t[-0.05814130636,-0.01961626748,-0.9981156198]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-58.09544547],\n\t\t\t\t[121.7224759],\n\t\t\t\t[272.659258]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[743.805,0,368.42],\n\t\t\t\t[0,744.013,242.015],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.323306,0.0785457,-0.00106293,0.000187763,0.0236672],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9954771119,0.0748660766,0.05848410323],\n\t\t\t\t[0.07512966129,0.9971710788,0.002318097681],\n\t\t\t\t[-0.05814510944,0.006701504052,-0.9982856485]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-47.8147621],\n\t\t\t\t[97.15541342],\n\t\t\t\t[274.4212668]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[742.693,0,353.966],\n\t\t\t\t[0,742.776,227.014],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307193,-0.0103139,0.000109263,-0.000950495,0.159317],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9933059489,0.1045971031,0.04901773034],\n\t\t\t\t[0.1016362638,0.9930442478,-0.05944065861],\n\t\t\t\t[-0.05489409585,-0.05406078084,-0.9970276176]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.5323637],\n\t\t\t\t[109.7713479],\n\t\t\t\t[268.3161895]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[742.837,0,362.248],\n\t\t\t\t[0,743.502,226.37],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308934,-0.00321353,-0.0010059,0.000705591,0.156528],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9919154966,0.0987006026,0.07976113456],\n\t\t\t\t[0.09553429302,0.9945144894,-0.04259259489],\n\t\t\t\t[-0.08352751879,-0.03462833131,-0.995903626]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-30.66946365],\n\t\t\t\t[84.06052642],\n\t\t\t\t[268.8728165]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[742.618,0,345.237],\n\t\t\t\t[0,742.923,230.439],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302695,-0.0546693,-0.000167537,-0.000784726,0.259585],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9885523252,0.1391044686,0.05843155954],\n\t\t\t\t[0.1381120085,0.9902000007,-0.02071308279],\n\t\t\t\t[-0.06074021267,-0.01240586611,-0.9980765106]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.26146274],\n\t\t\t\t[74.12977283],\n\t\t\t\t[271.0351679]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.088,0,370.473],\n\t\t\t\t[0,744.417,231.755],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.300902,-0.0664899,-0.000333311,0.000589361,0.253926],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9917390399,0.06178336486,0.1124121551],\n\t\t\t\t[0.06447509535,0.9977094298,0.02046596672],\n\t\t\t\t[-0.1108902109,0.02754468261,-0.9934508803]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-3.269853258],\n\t\t\t\t[73.62667861],\n\t\t\t\t[274.8694227]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.582,0,373.528],\n\t\t\t\t[0,745.86,237.254],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322134,0.0530706,-0.000603814,0.00101303,0.0846746],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9897330936,0.1313546283,0.05634150462],\n\t\t\t\t[0.1318000226,0.9912672261,0.00424742025],\n\t\t\t\t[-0.05529156869,0.01162962396,-0.9984025212]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[37.3391924],\n\t\t\t\t[70.20661568],\n\t\t\t\t[273.1392775]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[742.542,0,374.105],\n\t\t\t\t[0,742.758,223.273],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.306762,-0.0452572,-0.00032402,-0.000364469,0.245651],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9920842372,0.1065981921,0.06637538524],\n\t\t\t\t[0.106818653,0.9942784937,-0.0002288198192],\n\t\t\t\t[-0.06602000984,0.006863120707,-0.9977946963]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[52.26513597],\n\t\t\t\t[79.91641464],\n\t\t\t\t[273.9509772]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[744.378,0,361.433],\n\t\t\t\t[0,744.589,244.618],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310422,-0.000364242,-0.000710118,0.000839407,0.169675],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9919054981,0.126974259,0.001010166835],\n\t\t\t\t[0.1269495258,0.9918188066,-0.01338927975],\n\t\t\t\t[-0.002701996339,-0.01315266,-0.9999098493]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[49.23489662],\n\t\t\t\t[110.9052228],\n\t\t\t\t[271.6142806]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[745.72,0,364.99],\n\t\t\t\t[0,745.913,248.461],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.32476,0.0791445,0.000409065,0.000522525,0.0385155],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9808466558,0.1869185946,0.05478391053],\n\t\t\t\t[0.1851721888,0.9820671342,-0.03543168776],\n\t\t\t\t[-0.06042431929,-0.02460859583,-0.9978693896]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.23583817],\n\t\t\t\t[134.9359413],\n\t\t\t\t[272.7493911]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[745.966,0,347.023],\n\t\t\t\t[0,745.905,254.016],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.312122,-0.0171046,0.00101358,-9.38575e-05,0.213424],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9944456328,0.07811965146,0.07053512206],\n\t\t\t\t[0.07435713108,0.9957422838,-0.0544823029],\n\t\t\t\t[-0.07449094204,-0.04893489886,-0.9960203187]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.247391851],\n\t\t\t\t[153.0572023],\n\t\t\t\t[268.8284628]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[743.607,0,364.935],\n\t\t\t\t[0,743.756,243.53],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311531,0.000696399,0.00010932,-0.000314324,0.159615],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9924188487,0.09367860135,0.07955594568],\n\t\t\t\t[0.08900119243,0.9941960017,-0.06044086279],\n\t\t\t\t[-0.0847562186,-0.05290207743,-0.9949963586]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.3150092],\n\t\t\t\t[142.5037842],\n\t\t\t\t[267.7211288]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[743.508,0,369.721],\n\t\t\t\t[0,743.449,243.575],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.309744,-0.0191119,0.000292611,0.000847107,0.198605],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9987856124,0.03694807636,0.03259049098],\n\t\t\t\t[0.03470669556,0.9971594314,-0.06684694127],\n\t\t\t\t[-0.03496778135,-0.06563465492,-0.997230839]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.799650163],\n\t\t\t\t[123.3743131],\n\t\t\t\t[267.1549958]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"19_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 19,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[742.775,0,379.613],\n\t\t\t\t[0,742.864,224.449],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316586,0.0333112,-0.000180777,0.00112675,0.112087],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9947573056,0.06853183176,0.07590316848],\n\t\t\t\t[0.05765365411,0.9888586451,-0.1372393391],\n\t\t\t\t[-0.08446276764,-0.1321437401,-0.9876254719]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.340029177],\n\t\t\t\t[136.5307812],\n\t\t\t\t[258.2193706]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_01\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[745.267,0,367.511],\n\t\t\t\t[0,745.253,228.976],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.316421,0.0232694,0.000233523,0.00095017,0.129164],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2595515744,0.03264633198,0.965177288],\n\t\t\t\t[-0.02439656235,0.9988878376,-0.04034718866],\n\t\t\t\t[-0.9654210418,-0.03401918423,-0.2584664527]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[43.91564589],\n\t\t\t\t[114.6472759],\n\t\t\t\t[269.2437955]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_02\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[746.737,0,383.621],\n\t\t\t\t[0,746.553,234.139],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.330711,0.126048,0.000259954,-0.000232797,-0.067441],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2600597375,0.03354081135,0.965009817],\n\t\t\t\t[-0.06475754991,0.9965406566,-0.05208818886],\n\t\t\t\t[-0.9634185968,-0.07603771211,-0.2569880808]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[63.03617994],\n\t\t\t\t[136.0112472],\n\t\t\t\t[264.2112923]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_03\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[748.567,0,371.842],\n\t\t\t\t[0,748.646,223.378],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.332561,0.132401,-0.000978802,0.0010132,-0.0596871],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2517963519,0.03200567411,0.967250864],\n\t\t\t\t[0.0115205721,0.9994813079,-0.03007310314],\n\t\t\t\t[-0.9677116686,0.003570985655,-0.2520344708]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[55.32226207],\n\t\t\t\t[135.5872215],\n\t\t\t\t[276.5287505]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_04\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[747.412,0,375.731],\n\t\t\t\t[0,747.545,213.638],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.324984,0.0823763,-0.00190711,0.0010176,0.0382164],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2864406942,-0.001302983566,0.9580970885],\n\t\t\t\t[-0.1193951903,0.9922525608,-0.03434594761],\n\t\t\t\t[-0.9506295373,-0.1242302613,-0.2843770823]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[40.5108683],\n\t\t\t\t[178.4576708],\n\t\t\t\t[254.9563649]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_05\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[747.818,0,377.646],\n\t\t\t\t[0,748.63,232.294],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.327048,0.100477,-0.00250563,-0.000951363,0.00505748],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2682590325,-0.01756457816,0.9631866782],\n\t\t\t\t[-0.1175373506,0.9929607203,-0.014628026],\n\t\t\t\t[-0.9561496027,-0.1171345104,-0.2684351761]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[28.10870602],\n\t\t\t\t[198.6254244],\n\t\t\t\t[256.0861594]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_06\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[744.281,0,376.164],\n\t\t\t\t[0,744.733,212.764],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.314115,0.0261091,-0.00186017,0.000146826,0.111047],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2995512244,0.02650351378,0.9537120256],\n\t\t\t\t[-0.1164678133,0.9911222418,-0.06412449085],\n\t\t\t\t[-0.9469447251,-0.1302853239,-0.2938050747]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.38602287],\n\t\t\t\t[207.7342285],\n\t\t\t\t[252.6787249]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_07\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[744.844,0,367.199],\n\t\t\t\t[0,744.885,234.874],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307447,-0.0235368,-0.000447762,-0.000552595,0.198481],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2246138655,-0.03605175288,0.9737807158],\n\t\t\t\t[-0.1345418425,0.9908917963,0.005651603877],\n\t\t\t\t[-0.965115073,-0.1297448231,-0.2274185059]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.57828512],\n\t\t\t\t[193.807989],\n\t\t\t\t[253.6581871]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_08\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[745.265,0,373.297],\n\t\t\t\t[0,745.204,222.406],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.322725,0.0753011,-0.00198414,9.48962e-05,0.0496562],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2740281164,0.007089557403,0.9616955493],\n\t\t\t\t[-0.08615117171,0.9957715968,-0.0318889104],\n\t\t\t\t[-0.9578551911,-0.09158965645,-0.2722586413]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.40184383],\n\t\t\t\t[190.6520913],\n\t\t\t\t[261.5790911]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_09\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[743.742,0,376.404],\n\t\t\t\t[0,743.442,252.182],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.310951,0.0101818,-0.000165117,0.000699519,0.141452],\n\t\t\t\"R\": [\n\t\t\t\t[-0.234740558,-0.05401621619,0.9705560874],\n\t\t\t\t[-0.06709368181,0.9969740023,0.03925909634],\n\t\t\t\t[-0.9697398147,-0.05590247913,-0.2376543804]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-60.89112675],\n\t\t\t\t[163.1020008],\n\t\t\t\t[266.420435]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_10\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[746.237,0,381.452],\n\t\t\t\t[0,745.998,235.104],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321635,0.0804606,-0.000793429,0.000500703,0.0308776],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2327490461,-0.03063038999,0.9720543507],\n\t\t\t\t[-0.1073579574,0.9942045343,0.005622535858],\n\t\t\t\t[-0.9665930636,-0.1030491297,-0.2346885731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-52.7687065],\n\t\t\t\t[155.650502],\n\t\t\t\t[258.7092289]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_11\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[744.465,0,352.406],\n\t\t\t\t[0,744.368,231.635],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.307896,-0.0267024,-0.00138959,-0.000489454,0.213952],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2568719183,-0.003646201445,0.9664385768],\n\t\t\t\t[-0.06909534804,0.997503196,-0.01460160774],\n\t\t\t\t[-0.9639723287,-0.07052715282,-0.256482495]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-58.11810551],\n\t\t\t\t[133.8270577],\n\t\t\t\t[264.378006]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_12\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[744.557,0,351.376],\n\t\t\t\t[0,744.424,216.683],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317479,0.0158652,-0.000659121,-0.00059258,0.147681],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2372383683,-0.02274879941,0.9711850744],\n\t\t\t\t[-0.1004253449,0.9949438408,-0.001226302928],\n\t\t\t\t[-0.9662467111,-0.09782252214,-0.2383234094]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-62.35654103],\n\t\t\t\t[118.4734964],\n\t\t\t\t[259.8400796]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_13\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[743.07,0,377.102],\n\t\t\t\t[0,743.158,222.988],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.29868,-0.0827266,-0.00133003,-0.00119832,0.273178],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2367527853,-0.03686088138,0.9708704311],\n\t\t\t\t[-0.08746956632,0.9960307636,0.01648614259],\n\t\t\t\t[-0.9676245107,-0.08101847538,-0.2390372628]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-42.43038274],\n\t\t\t\t[111.3831569],\n\t\t\t\t[262.4188123]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_14\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[745.597,0,372.306],\n\t\t\t\t[0,745.414,237.499],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320131,0.0615197,0.00113665,-0.000991542,0.0414761],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2769894269,0.05383368349,0.9593637433],\n\t\t\t\t[-0.05406721308,0.9959742516,-0.07149843787],\n\t\t\t\t[-0.9593506105,-0.07167443526,-0.2729636999]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.49417033],\n\t\t\t\t[90.7530727],\n\t\t\t\t[264.2254974]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_15\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[746.296,0,380.788],\n\t\t\t\t[0,746.161,226.883],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321885,0.0553182,0.000132369,-0.000878491,0.0778662],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2870302882,0.01079685294,0.9578606588],\n\t\t\t\t[-0.05665486447,0.9979947406,-0.02822630231],\n\t\t\t\t[-0.9562446549,-0.06236926949,-0.2858430237]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-1.106709776],\n\t\t\t\t[85.82297146],\n\t\t\t\t[264.8070963]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_16\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[744.119,0,345.288],\n\t\t\t\t[0,744.112,227.607],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.302547,-0.0664079,0.000893953,-0.000627784,0.303861],\n\t\t\t\"R\": [\n\t\t\t\t[-0.252548592,0.05539030986,0.9659974753],\n\t\t\t\t[-0.08640189331,0.9930807476,-0.07953201617],\n\t\t\t\t[-0.963718798,-0.1035497095,-0.2460153169]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[10.51473419],\n\t\t\t\t[107.4721829],\n\t\t\t\t[260.872486]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_17\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[745.831,0,353.784],\n\t\t\t\t[0,745.87,219.754],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.321082,0.0599511,-0.000750204,0.000386726,0.0615888],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3124433364,0.0857084176,0.9460619582],\n\t\t\t\t[-0.03834810703,0.9939715084,-0.1027135007],\n\t\t\t\t[-0.9491620432,-0.06837183409,-0.3072730188]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[50.17882687],\n\t\t\t\t[91.39390134],\n\t\t\t\t[262.9120903]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_18\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[745.227,0,385.13],\n\t\t\t\t[0,745.129,233.897],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.311291,0.0180828,0.00116452,0.000576614,0.0928398],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2786751196,0.05379991941,0.9588773365],\n\t\t\t\t[-0.03740853519,0.9970639104,-0.06681437094],\n\t\t\t\t[-0.9596565944,-0.0544896994,-0.2758443282]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[57.04086511],\n\t\t\t\t[98.35557378],\n\t\t\t\t[265.4113916]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_19\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[746.424,0,373.724],\n\t\t\t\t[0,746.378,215.089],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.317589,0.0452179,0.000839363,0.00087423,0.0858828],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2053627335,-0.023863444,0.9783949528],\n\t\t\t\t[-0.1366627843,0.9906072975,-0.004523879826],\n\t\t\t\t[-0.9690972248,-0.1346392148,-0.2066950671]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.454839771],\n\t\t\t\t[148.020868],\n\t\t\t\t[256.5149472]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_20\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[744.35,0,378.361],\n\t\t\t\t[0,744.386,245.706],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.305792,-0.0298413,-5.26611e-05,9.57392e-05,0.206854],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2653224987,0.04663873586,0.9630310483],\n\t\t\t\t[-0.08123292055,0.9941966424,-0.07052835541],\n\t\t\t\t[-0.9607315881,-0.09694258412,-0.2599941366]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[23.42848118],\n\t\t\t\t[157.616994],\n\t\t\t\t[260.7931406]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_21\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[747.371,0,368.768],\n\t\t\t\t[0,747.344,231.897],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.308946,-0.0139041,-0.000755627,-0.000244894,0.190547],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2375675449,-0.01520768023,0.9712519694],\n\t\t\t\t[-0.09352440886,0.9955903179,-0.007287238765],\n\t\t\t\t[-0.966858235,-0.09256697771,-0.2379422368]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.76210059],\n\t\t\t\t[163.3748289],\n\t\t\t\t[261.1782343]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_22\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[746.314,0,371.788],\n\t\t\t\t[0,745.992,237.732],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.315167,0.0352154,-0.000828301,0.000312219,0.0891012],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2145858088,0.0004599306573,0.9767050318],\n\t\t\t\t[-0.07749764501,0.9968390076,-0.017495939],\n\t\t\t\t[-0.9736257216,-0.07944672006,-0.2138718611]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-33.0373727],\n\t\t\t\t[146.3668194],\n\t\t\t\t[262.1626174]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_23\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[746.318,0,371.868],\n\t\t\t\t[0,746.096,236.531],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.318459,0.0405311,0.000489761,-0.000285822,0.0876741],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2554085937,0.004734611177,0.9668216142],\n\t\t\t\t[-0.07039835709,0.9972425561,-0.02348096154],\n\t\t\t\t[-0.9642668311,-0.0740598926,-0.25437101]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-17.40671779],\n\t\t\t\t[124.2252344],\n\t\t\t\t[264.0602836]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"20_24\",\n\t\t\t\"type\": \"vga\",\n\t\t\t\"resolution\": [640,480],\n\t\t\t\"panel\": 20,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[745.832,0,382.965],\n\t\t\t\t[0,745.816,231.317],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.320385,0.0446211,0.00028801,0.00167617,0.104376],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2362773498,-0.02089730322,0.9714609188],\n\t\t\t\t[-0.1013714927,0.9948433166,-0.003255144035],\n\t\t\t\t[-0.9663833786,-0.09924756028,-0.2371773332]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.093436327],\n\t\t\t\t[126.6662443],\n\t\t\t\t[260.9183094]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_00\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 0,\n\t\t\t\"K\": [\n\t\t\t\t[1634.03,0,942.792],\n\t\t\t\t[0,1629.73,558.29],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.222445,0.199192,8.73054e-05,0.000982243,0.0238445],\n\t\t\t\"R\": [\n\t\t\t\t[0.1369296663,0.03357591931,-0.9900115778],\n\t\t\t\t[-0.09021094677,0.9956950625,0.02129149064],\n\t\t\t\t[0.9864645212,0.08639444504,0.1393691081]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[20.90028135],\n\t\t\t\t[127.2202879],\n\t\t\t\t[283.1159034]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_01\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[1395.91,0,951.559],\n\t\t\t\t[0,1392.24,561.398],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286227,0.183082,-4.29815e-05,0.000644874,-0.0479635],\n\t\t\t\"R\": [\n\t\t\t\t[0.05337497606,0.02479711619,0.9982666052],\n\t\t\t\t[0.6376765256,0.7684660834,-0.05318390075],\n\t\t\t\t[-0.7684528356,0.6394098699,0.0252043199]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.299256813],\n\t\t\t\t[104.397182],\n\t\t\t\t[363.078698]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_02\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[1397.02,0,939.355],\n\t\t\t\t[0,1394.04,556.611],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.28229,0.173658,-0.000610716,0.000955319,-0.0398628],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9970491806,0.05290586318,-0.05562284625],\n\t\t\t\t[-0.01182874156,0.6100448884,0.792278559],\n\t\t\t\t[0.07584861407,0.7905986364,-0.6076189463]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-16.22360931],\n\t\t\t\t[63.30660163],\n\t\t\t\t[381.0181823]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_03\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[1395.71,0,949.456],\n\t\t\t\t[0,1392.06,566.648],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.281728,0.168097,-0.00021431,1.8072e-05,-0.0371786],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6216465312,-0.0285781748,0.7827763909],\n\t\t\t\t[0.07448493547,0.9926490654,0.09539301533],\n\t\t\t\t[-0.7797484111,0.117605786,-0.6149482047]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-14.50346059],\n\t\t\t\t[117.4297203],\n\t\t\t\t[290.1984382]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_04\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[1633.26,0,949.479],\n\t\t\t\t[0,1629.32,572.374],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.223003,0.185095,-0.000261654,0.00109433,0.0657602],\n\t\t\t\"R\": [\n\t\t\t\t[-0.5292732399,-0.01229259603,0.8483623811],\n\t\t\t\t[0.636650989,0.6551966806,0.4066851706],\n\t\t\t\t[-0.5608434325,0.7553583268,-0.3389519765]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.411400695],\n\t\t\t\t[80.12176746],\n\t\t\t\t[379.8488129]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_05\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[1396.29,0,933.34],\n\t\t\t\t[0,1392.95,560.462],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.28733,0.185523,-0.000225825,-0.000143128,-0.0508452],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9314658579,-0.01073438439,-0.363670357],\n\t\t\t\t[-0.021313424,0.9994579907,0.02508909603],\n\t\t\t\t[0.3632039283,0.03112069687,-0.9311897813]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-6.050515741],\n\t\t\t\t[143.9213951],\n\t\t\t\t[280.3813532]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_06\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[1396.11,0,950.228],\n\t\t\t\t[0,1392.54,548.78],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286481,0.183173,-0.000152555,0.0010664,-0.0482263],\n\t\t\t\"R\": [\n\t\t\t\t[0.9448241112,-0.04876703013,-0.3239277321],\n\t\t\t\t[-0.2141569626,0.6563150135,-0.7234551806],\n\t\t\t\t[0.2478793944,0.7529092773,0.6096584503]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.023614],\n\t\t\t\t[84.45695974],\n\t\t\t\t[376.925635]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_07\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[1395.51,0,947.67],\n\t\t\t\t[0,1392.41,549.081],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286691,0.185163,-6.53256e-05,4.32858e-06,-0.052639],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9419632708,-0.03700247277,0.3336705164],\n\t\t\t\t[0.180351898,0.7825307202,0.5959185052],\n\t\t\t\t[-0.2831578878,0.6215114552,-0.7304417305]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.250326149],\n\t\t\t\t[112.5645453],\n\t\t\t\t[360.2387508]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_08\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[1642.7,0,945.082],\n\t\t\t\t[0,1638.64,562.465],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.22444,0.208938,-0.000569838,0.000484927,0.0287248],\n\t\t\t\"R\": [\n\t\t\t\t[0.9544726119,0.01685383959,-0.2978220632],\n\t\t\t\t[-0.03362017317,0.9981191009,-0.05126347965],\n\t\t\t\t[0.2963979035,0.05894241665,0.9532439742]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.67808464],\n\t\t\t\t[136.6798831],\n\t\t\t\t[282.6801175]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_09\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[1396.79,0,945.482],\n\t\t\t\t[0,1393.03,542.64],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.284259,0.175176,-0.000406823,0.000640552,-0.0406716],\n\t\t\t\"R\": [\n\t\t\t\t[-0.3169419478,-0.08460972789,0.9446634298],\n\t\t\t\t[-0.1243350249,0.9911238917,0.04705563528],\n\t\t\t\t[-0.9402598595,-0.1025408464,-0.3246486894]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[6.780958613],\n\t\t\t\t[147.0057696],\n\t\t\t\t[260.6395044]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_10\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[1393.87,0,944.546],\n\t\t\t\t[0,1390.36,563.199],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.285353,0.177704,-0.000109708,0.000471392,-0.0432146],\n\t\t\t\"R\": [\n\t\t\t\t[0.9503475669,0.04849461332,0.3073886376],\n\t\t\t\t[0.1560494297,0.7803459045,-0.6055648973],\n\t\t\t\t[-0.2692360999,0.6234649483,0.734032275]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[22.71992555],\n\t\t\t\t[112.7759402],\n\t\t\t\t[360.0009328]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_11\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 11,\n\t\t\t\"K\": [\n\t\t\t\t[1492.96,0,934.544],\n\t\t\t\t[0,1489.74,547.466],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.259288,0.190057,-5.50625e-05,0.00031915,-0.0281283],\n\t\t\t\"R\": [\n\t\t\t\t[0.8129763959,0.04080422416,-0.5808652124],\n\t\t\t\t[-0.2848486357,0.8979062573,-0.3355973896],\n\t\t\t\t[0.5078687177,0.4382914196,0.7415996205]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.03199165418],\n\t\t\t\t[105.1487628],\n\t\t\t\t[331.4862369]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_12\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 12,\n\t\t\t\"K\": [\n\t\t\t\t[1395.93,0,964.611],\n\t\t\t\t[0,1392.67,564.875],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.290995,0.19463,-0.000241491,0.000727782,-0.0582663],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9950957343,0.04321912909,-0.08897520145],\n\t\t\t\t[-0.001969290489,0.8906636271,0.454658581],\n\t\t\t\t[0.09889692354,0.4526040326,-0.886210465]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.66653867],\n\t\t\t\t[97.49188585],\n\t\t\t\t[334.8897626]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_13\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 13,\n\t\t\t\"K\": [\n\t\t\t\t[1592.21,0,937.375],\n\t\t\t\t[0,1588.39,560.919],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.239248,0.229218,0.000137317,0.000315934,-0.0358302],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2862766934,0.07452649614,-0.9552441867],\n\t\t\t\t[-0.7557457469,0.5952786327,0.2729317047],\n\t\t\t\t[0.588977097,0.8000557173,-0.1140913162]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.47943966],\n\t\t\t\t[60.20818768],\n\t\t\t\t[381.0821849]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_14\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 14,\n\t\t\t\"K\": [\n\t\t\t\t[1649.51,0,934.882],\n\t\t\t\t[0,1644.85,568.024],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.22365,0.220791,-0.000591343,0.000286172,0.0121962],\n\t\t\t\"R\": [\n\t\t\t\t[0.827339054,-0.07848137689,0.5561930989],\n\t\t\t\t[0.02005408661,0.9936867625,0.110383204],\n\t\t\t\t[-0.5613447456,-0.08017039095,0.8236897383]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-7.23447972],\n\t\t\t\t[142.1657406],\n\t\t\t\t[267.9541185]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_15\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 15,\n\t\t\t\"K\": [\n\t\t\t\t[1430.11,0,948.926],\n\t\t\t\t[0,1426.48,561.705],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.277948,0.185701,0.000192514,0.000149713,-0.0424254],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9997414125,0.006454955712,0.02180462522],\n\t\t\t\t[0.005192647027,0.9983342904,-0.05746025644],\n\t\t\t\t[-0.02213920846,-0.05733217422,-0.9981096519]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[9.642162177],\n\t\t\t\t[134.9258555],\n\t\t\t\t[268.2324221]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_16\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 16,\n\t\t\t\"K\": [\n\t\t\t\t[1427.34,0,949.618],\n\t\t\t\t[0,1423.13,548.132],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.279453,0.188683,-0.000345265,0.000583475,-0.0479414],\n\t\t\t\"R\": [\n\t\t\t\t[0.7694875517,0.002369830201,0.6386574134],\n\t\t\t\t[0.2539259376,0.9164213706,-0.3093436433],\n\t\t\t\t[-0.586012394,0.4002077652,0.7045730755]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.866150988],\n\t\t\t\t[118.1652356],\n\t\t\t\t[330.6340665]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_17\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 17,\n\t\t\t\"K\": [\n\t\t\t\t[1393.35,0,916.395],\n\t\t\t\t[0,1390.34,563.652],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.287138,0.186145,7.50854e-05,0.000557424,-0.0513205],\n\t\t\t\"R\": [\n\t\t\t\t[0.5039250676,0.09465184024,-0.8585456047],\n\t\t\t\t[-0.6050310345,0.7480627966,-0.2726527087],\n\t\t\t\t[0.6164389455,0.6568432701,0.4342348962]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[18.2296155],\n\t\t\t\t[97.71531857],\n\t\t\t\t[361.6667015]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_18\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 18,\n\t\t\t\"K\": [\n\t\t\t\t[1542.2,0,947.567],\n\t\t\t\t[0,1538.02,555.168],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.245751,0.182006,3.81269e-06,0.000651097,0.00472657],\n\t\t\t\"R\": [\n\t\t\t\t[-0.4048875531,-0.001022756131,0.9143659133],\n\t\t\t\t[0.3656410889,0.9163838146,0.1629334173],\n\t\t\t\t[-0.8380767647,0.4002994608,-0.3706584387]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[16.25260358],\n\t\t\t\t[116.7586119],\n\t\t\t\t[329.7529305]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_19\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 19,\n\t\t\t\"K\": [\n\t\t\t\t[1396.57,0,949.242],\n\t\t\t\t[0,1393.19,554.872],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.280864,0.167216,-6.6519e-05,0.000917406,-0.0342733],\n\t\t\t\"R\": [\n\t\t\t\t[0.7360342296,0.009501079563,0.6768776421],\n\t\t\t\t[0.5173282683,0.6370082142,-0.5714822813],\n\t\t\t\t[-0.4366063167,0.7707984591,0.4639446731]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-24.15514071],\n\t\t\t\t[74.04862943],\n\t\t\t\t[379.5076537]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_20\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 20,\n\t\t\t\"K\": [\n\t\t\t\t[1403.46,0,940.386],\n\t\t\t\t[0,1400.1,552.684],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.287177,0.194004,-0.000120001,8.41526e-05,-0.0604614],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6201222217,0.04052054618,-0.7834580496],\n\t\t\t\t[-0.1302964194,0.9794749929,0.1537907063],\n\t\t\t\t[0.773609251,0.1974508131,-0.6021145267]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[24.4496252],\n\t\t\t\t[140.6900046],\n\t\t\t\t[300.8290806]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_21\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 21,\n\t\t\t\"K\": [\n\t\t\t\t[1397.56,0,932.828],\n\t\t\t\t[0,1393.91,562.186],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.28642,0.185674,-0.000229601,1.91211e-05,-0.052608],\n\t\t\t\"R\": [\n\t\t\t\t[-0.2617478675,-0.05032313647,-0.9638234464],\n\t\t\t\t[-0.4532392419,0.8880813121,0.07671878938],\n\t\t\t\t[0.8520928608,0.4569235877,-0.2552618099]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.784671236],\n\t\t\t\t[98.11062797],\n\t\t\t\t[332.9193692]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_22\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 22,\n\t\t\t\"K\": [\n\t\t\t\t[1514.1,0,945.861],\n\t\t\t\t[0,1510.18,558.694],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.260535,0.216046,-0.000156491,0.000677315,-0.0506741],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9239818557,-0.0613765916,0.3774790647],\n\t\t\t\t[0.05486070575,0.9555572213,0.289656175],\n\t\t\t\t[-0.3784809549,0.288345818,-0.8795503715]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-5.224239691],\n\t\t\t\t[110.7456244],\n\t\t\t\t[313.8855054]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_23\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 23,\n\t\t\t\"K\": [\n\t\t\t\t[1572.86,0,941.716],\n\t\t\t\t[0,1568.17,560.048],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.240801,0.195963,-0.000444179,0.000458513,0.00455186],\n\t\t\t\"R\": [\n\t\t\t\t[0.5162966551,0.01335424781,0.856305686],\n\t\t\t\t[0.1418829708,0.9847272537,-0.100903213],\n\t\t\t\t[-0.8445750331,0.173591186,0.506516647]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[2.417701344],\n\t\t\t\t[102.3557555],\n\t\t\t\t[298.3746617]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_24\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 24,\n\t\t\t\"K\": [\n\t\t\t\t[1399.63,0,954.539],\n\t\t\t\t[0,1396.27,546.388],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.288761,0.190789,4.23479e-05,6.78832e-05,-0.0577764],\n\t\t\t\"R\": [\n\t\t\t\t[-0.388991142,-0.05987834367,-0.9192934653],\n\t\t\t\t[0.02928793432,0.9965772059,-0.07730517199],\n\t\t\t\t[0.9207758187,-0.05699523376,-0.3859059924]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.12220678],\n\t\t\t\t[134.1751339],\n\t\t\t\t[265.239245]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_25\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 25,\n\t\t\t\"K\": [\n\t\t\t\t[1397.66,0,935.585],\n\t\t\t\t[0,1394.65,559.251],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.285722,0.183994,-0.000502702,0.000494145,-0.0515729],\n\t\t\t\"R\": [\n\t\t\t\t[0.7926422733,0.00130484237,-0.6096855943],\n\t\t\t\t[0.04487405742,0.9971605675,0.06047414042],\n\t\t\t\t[0.6080333424,-0.07529342651,0.7903330655]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.539475053],\n\t\t\t\t[139.2223569],\n\t\t\t\t[261.6293171]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_26\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 26,\n\t\t\t\"K\": [\n\t\t\t\t[1616.8,0,950.116],\n\t\t\t\t[0,1613.47,551.417],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.223464,0.185279,-0.00090721,0.000127112,0.0351947],\n\t\t\t\"R\": [\n\t\t\t\t[-0.7556190155,-0.04350579001,-0.6535649545],\n\t\t\t\t[0.1389994774,0.9644159151,-0.2249023966],\n\t\t\t\t[0.6400930001,-0.2607857146,-0.7226837222]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.5475419],\n\t\t\t\t[141.1612209],\n\t\t\t\t[240.8579734]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_27\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 27,\n\t\t\t\"K\": [\n\t\t\t\t[1861.86,0,934.556],\n\t\t\t\t[0,1857.26,552.106],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.171511,0.209759,-1.83176e-05,-3.41566e-05,0.211418],\n\t\t\t\"R\": [\n\t\t\t\t[0.9782876177,0.02697940456,0.2054883178],\n\t\t\t\t[0.02691509764,0.9665557486,-0.2550403151],\n\t\t\t\t[-0.2054967507,0.2550335204,0.9448433674]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-0.5131666478],\n\t\t\t\t[123.4498457],\n\t\t\t\t[311.6401591]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_28\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 28,\n\t\t\t\"K\": [\n\t\t\t\t[1395.57,0,953.143],\n\t\t\t\t[0,1392.36,561.982],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.284934,0.181016,0.000127361,0.000271191,-0.0471616],\n\t\t\t\"R\": [\n\t\t\t\t[-0.6310677524,-0.02949081954,-0.775166939],\n\t\t\t\t[-0.5128354354,0.7656140117,0.3883748207],\n\t\t\t\t[0.5820251782,0.6426238999,-0.4982782509]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-8.508070023],\n\t\t\t\t[104.2896072],\n\t\t\t\t[361.3816814]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_29\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 29,\n\t\t\t\"K\": [\n\t\t\t\t[1400.36,0,939.608],\n\t\t\t\t[0,1397.25,572.603],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.286109,0.1878,-0.000309515,0.000886248,-0.0523515],\n\t\t\t\"R\": [\n\t\t\t\t[0.4887300705,-0.07268882749,-0.8694016635],\n\t\t\t\t[-0.08227020668,0.9882426049,-0.1288726774],\n\t\t\t\t[0.8685473685,0.1345098073,0.4770037531]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-20.72850042],\n\t\t\t\t[158.8912224],\n\t\t\t\t[289.281465]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"00_30\",\n\t\t\t\"type\": \"hd\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 0,\n\t\t\t\"node\": 30,\n\t\t\t\"K\": [\n\t\t\t\t[1407.21,0,946.883],\n\t\t\t\t[0,1403.86,563.032],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [-0.285813,0.195568,-0.000394067,0.000468367,-0.0600751],\n\t\t\t\"R\": [\n\t\t\t\t[0.08635045426,0.06174190292,0.9943498059],\n\t\t\t\t[0.2147800801,0.9734543185,-0.07909618832],\n\t\t\t\t[-0.9728376618,0.2203965227,0.07079729175]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[13.79078928],\n\t\t\t\t[132.1300437],\n\t\t\t\t[306.0754676]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_01\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 1,\n\t\t\t\"K\": [\n\t\t\t\t[1053.92,0,947.294],\n\t\t\t\t[0,1054.32,535.405],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0476403,-0.053786,0.000733314,-0.000579648,0.0122759],\n\t\t\t\"R\": [\n\t\t\t\t[0.9095307192,0.0006254166507,-0.4156362348],\n\t\t\t\t[-0.003349684277,0.999977422,-0.0058253781],\n\t\t\t\t[0.4156232073,0.006690610494,0.9095122788]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-15.84850815],\n\t\t\t\t[103.1392168],\n\t\t\t\t[269.3362326]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_02\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 2,\n\t\t\t\"K\": [\n\t\t\t\t[1058.92,0,971.224],\n\t\t\t\t[0,1059.3,541.276],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0485216,-0.0529886,-0.000413578,-0.000171659,0.00909728],\n\t\t\t\"R\": [\n\t\t\t\t[-0.08404700998,-0.006825065684,-0.9964384169],\n\t\t\t\t[-0.04073006897,0.9991643735,-0.003408260769],\n\t\t\t\t[0.9956290281,0.04029855131,-0.08425476347]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-4.246538185],\n\t\t\t\t[93.69672118],\n\t\t\t\t[271.0169727]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_03\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 3,\n\t\t\t\"K\": [\n\t\t\t\t[1050.35,0,971.069],\n\t\t\t\t[0,1050.88,535.343],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0482196,-0.0555053,0.000460862,0.000594278,0.0128034],\n\t\t\t\"R\": [\n\t\t\t\t[-0.9791929995,-0.0009192386581,-0.2029291126],\n\t\t\t\t[0.004325206908,0.9996680429,-0.02539875018],\n\t\t\t\t[0.2028850964,-0.02574798878,-0.9788639736]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-10.71273011],\n\t\t\t\t[112.0293664],\n\t\t\t\t[269.2258843]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_04\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 4,\n\t\t\t\"K\": [\n\t\t\t\t[1053.76,0,952.563],\n\t\t\t\t[0,1053.62,535.073],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0534802,-0.059505,0.000265754,-0.00038559,0.0128987],\n\t\t\t\"R\": [\n\t\t\t\t[-0.4973721867,-0.01252789009,0.8674468052],\n\t\t\t\t[-0.05725964091,0.9981894693,-0.01841512904],\n\t\t\t\t[-0.8656455634,-0.05882886558,-0.4971890215]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.12207689],\n\t\t\t\t[119.639642],\n\t\t\t\t[263.8142799]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_05\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 5,\n\t\t\t\"K\": [\n\t\t\t\t[1061.53,0,963.346],\n\t\t\t\t[0,1061.99,535.689],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0450742,-0.0483577,0.000117724,0.00131017,0.00746483],\n\t\t\t\"R\": [\n\t\t\t\t[0.6332975321,0.02789684006,0.7734054578],\n\t\t\t\t[-0.04440403331,0.9990136015,0.0003253688515],\n\t\t\t\t[-0.772633495,-0.034548377,0.6339115806]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[4.398197962],\n\t\t\t\t[114.449943],\n\t\t\t\t[269.0646085]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_06\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 6,\n\t\t\t\"K\": [\n\t\t\t\t[1053.8,0,975.87],\n\t\t\t\t[0,1054.44,518.546],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0608578,-0.0758877,0.000572907,0.000423304,0.0232485],\n\t\t\t\"R\": [\n\t\t\t\t[0.9936973916,-0.01776547634,0.1106791841],\n\t\t\t\t[0.08238304881,0.7853099766,-0.6135969963],\n\t\t\t\t[-0.07601662453,0.6188478234,0.7818240495]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-23.36095562],\n\t\t\t\t[58.01362542],\n\t\t\t\t[350.0526212]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_07\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 7,\n\t\t\t\"K\": [\n\t\t\t\t[1058.37,0,951.456],\n\t\t\t\t[0,1058.06,537.752],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0510704,-0.0625189,-0.000144014,6.68608e-05,0.016463],\n\t\t\t\"R\": [\n\t\t\t\t[0.4325769754,-0.03234243573,-0.9010167186],\n\t\t\t\t[-0.4868424381,0.832758343,-0.2636247005],\n\t\t\t\t[0.7588554545,0.5526911516,0.344486415]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-19.0385587],\n\t\t\t\t[87.13576568],\n\t\t\t\t[341.2560709]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_08\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 8,\n\t\t\t\"K\": [\n\t\t\t\t[1051.92,0,937.937],\n\t\t\t\t[0,1051.86,554.246],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0499863,-0.0613843,-4.12419e-05,-0.000155211,0.0174279],\n\t\t\t\"R\": [\n\t\t\t\t[-0.7043873056,-0.07078753835,-0.7062773168],\n\t\t\t\t[-0.4398115151,0.8245196459,0.3559960458],\n\t\t\t\t[0.5571394394,0.5613879923,-0.6119143463]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-21.03532832],\n\t\t\t\t[82.26745729],\n\t\t\t\t[344.5100871]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_09\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 9,\n\t\t\t\"K\": [\n\t\t\t\t[1054,0,961.563],\n\t\t\t\t[0,1054.08,544.179],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0446773,-0.0530941,0.000226286,-0.000324258,0.0121913],\n\t\t\t\"R\": [\n\t\t\t\t[-0.8728623151,-0.0989156561,0.4778358211],\n\t\t\t\t[0.2068965126,0.8118396582,0.5459946908],\n\t\t\t\t[-0.4419334927,0.5754407548,-0.6881589393]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-36.30074608],\n\t\t\t\t[73.0041962],\n\t\t\t\t[346.5857858]\n\t\t\t]\n\t\t},\n\t\t{\n\t\t\t\"name\": \"50_10\",\n\t\t\t\"type\": \"kinect-color\",\n\t\t\t\"resolution\": [1920,1080],\n\t\t\t\"panel\": 50,\n\t\t\t\"node\": 10,\n\t\t\t\"K\": [\n\t\t\t\t[1050.04,0,941.59],\n\t\t\t\t[0,1050.6,559.398],\n\t\t\t\t[0,0,1]\n\t\t\t],\n\t\t\t\"distCoef\": [0.0506861,-0.0636966,0.000195295,-6.41025e-06,0.0181857],\n\t\t\t\"R\": [\n\t\t\t\t[0.1849149694,0.002001709126,0.9827524852],\n\t\t\t\t[0.5894867579,0.7998990427,-0.1125472514],\n\t\t\t\t[-0.786328059,0.6001312479,0.146733326]\n\t\t\t],\n\t\t\t\"t\": [\n\t\t\t\t[-12.26435316],\n\t\t\t\t[64.88453925],\n\t\t\t\t[349.5293231]\n\t\t\t]\n\t\t}\n\t]\n}\n"
  },
  {
    "path": "tests/data/panoptic_body3d/160906_band2/hdPose3d_stage1_coco19/body3DScene_00000139.json",
    "content": "{ \"version\": 0.7, \r\n\"univTime\" :47884.218,\r\n\"fpsType\" :\"hd_29_97\",\r\n\"bodies\" :\r\n[\r\n{ \"id\": 0,\r\n\"joints19\": [112.193, -105.597, -63.2943, 0.681274, 98.5895, -126.086, -55.7911, 0.631165, 109.902, -62.3343, -62.7694, 0.434326, 103.926, -106.634, -77.9832, 0.634766, 96.8314, -78.8763, -80.315, 0.630554, 81.2761, -65.6605, -63.3084, 0.521851, 104.519, -62.7352, -72.4198, 0.444824, 65.6156, -49.5546, -67.2074, 0.308655, 54.2865, -10.3131, -52.1117, 0.236267, 120.42, -105.112, -49.3556, 0.60022, 116.189, -76.1983, -41.2718, 0.653992, 92.821, -64.5032, -42.2247, 0.527283, 115.285, -61.9334, -53.119, 0.411194, 85.1507, -47.7375, -27.3165, 0.324036, 68.5293, -8.10239, -40.0008, 0.237915, 99.4248, -129.754, -59.6533, 0.558838, 105.207, -126.2, -67.7812, 0.423035, 102.014, -129.179, -53.6288, 0.597534, 112.005, -124.794, -53.0751, 0.523254]\r\n},\r\n{ \"id\": 1,\r\n\"joints19\": [-75.6724, -98.3814, -40.586, 0.645996, -56.0144, -116.916, -44.6227, 0.601746, -74.2896, -55.1045, -36.5893, 0.251404, -83.9112, -98.0817, -25.7277, 0.517944, -88.2289, -74.2988, -14.0067, 0.396973, -68.2309, -74.1222, -1.47647, 0.329041, -79.1849, -55.0298, -28.0693, 0.249634, -51.5633, -47.6808, -7.04466, 0.285828, -74.7285, -17.5206, -29.2095, 0.225037, -67.3391, -99.4683, -53.6127, 0.477478, -47.0624, -92.1391, -77.8037, 0.564758, -44.4238, -79.2347, -57.8838, 0.42804, -69.3944, -55.1793, -45.1093, 0.227051, -34.6453, -49.6836, -25.2735, 0.309937, -40.5958, -7.8462, -31.1836, 0.256836, -56.8233, -120.322, -40.7627, 0.527283, -62.646, -116.933, -32.5876, 0.487427, -59.8079, -119.867, -46.6254, 0.471802, -69.67, -116.407, -47.7538, 0.328979]\r\n},\r\n{ \"id\": 2,\r\n\"joints19\": [-2.94539, -95.1867, 36.3111, 0.628723, 2.07299, -104.457, 17.1551, 0.454163, -7.05924, -50.5435, 42.1746, 0.244141, 9.71628, -93.5102, 43.4675, 0.522705, 12.0947, -69.463, 41.455, 0.387512, 19.2916, -69.8677, 21.9048, 0.328552, 1.02674, -50.5267, 46.2205, 0.253113, 26.6747, -43.1457, 17.5558, 0.371948, 27.6632, -7.91068, 13.5889, 0.338867, -15.3606, -97.7204, 30.3576, 0.512207, -37.812, -87.1386, 18.9922, 0.449524, -22.3384, -73.7289, 12.8309, 0.288696, -15.1452, -50.5603, 38.1288, 0.238159, 5.46492, -46.765, 4.57304, 0.31604, 4.54105, -11.5529, 11.0104, 0.225098, 5.10417, -106.784, 19.1646, 0.338989, 8.38426, -105.863, 28.9746, 0.374878, -0.147999, -108.49, 17.901, 0.389282, -6.41806, -109.461, 25.684, 0.374512]\r\n}\r\n] }"
  },
  {
    "path": "tests/data/panoptic_body3d/160906_band2/hdPose3d_stage1_coco19/body3DScene_00000140.json",
    "content": "{ \"version\": 0.7, \r\n\"univTime\" :47917.574,\r\n\"fpsType\" :\"hd_29_97\",\r\n\"bodies\" :\r\n[\r\n{ \"id\": 0,\r\n\"joints19\": [112.162, -105.636, -63.2601, 0.683655, 98.6079, -126.096, -55.7691, 0.633362, 109.895, -61.989, -62.8249, 0.434998, 103.92, -106.612, -77.9614, 0.633362, 96.8156, -78.8938, -80.3215, 0.628052, 81.2649, -65.6074, -63.3025, 0.5224, 104.579, -62.7546, -72.4201, 0.444275, 65.7338, -49.5044, -67.2157, 0.308167, 54.3536, -10.2596, -52.2195, 0.234131, 120.391, -105.108, -49.299, 0.603271, 116.181, -76.2786, -41.2666, 0.655334, 92.8451, -64.4865, -42.2389, 0.527039, 115.21, -61.2235, -53.2298, 0.411194, 85.1888, -47.835, -27.3393, 0.316833, 68.6198, -8.08162, -40.0417, 0.240723, 99.4313, -129.72, -59.6381, 0.558228, 105.205, -126.164, -67.7647, 0.423279, 102.011, -129.182, -53.6361, 0.597229, 111.982, -124.783, -53.0672, 0.522705]\r\n},\r\n{ \"id\": 1,\r\n\"joints19\": [-75.6746, -98.3656, -40.5723, 0.641663, -56.0544, -116.939, -44.5928, 0.603577, -74.4415, -55.0317, -36.6536, 0.252808, -83.918, -98.0843, -25.7209, 0.519165, -88.2603, -74.1941, -13.9948, 0.396057, -68.2309, -74.0839, -1.42833, 0.328918, -79.5003, -55.0092, -28.0401, 0.25, -51.5172, -47.7041, -7.04263, 0.294495, -74.7647, -17.5892, -29.1887, 0.228638, -67.361, -99.4319, -53.7077, 0.481934, -47.0466, -92.2037, -77.7492, 0.570923, -44.4639, -79.2762, -57.8438, 0.434448, -69.3827, -55.0541, -45.2672, 0.228271, -34.7812, -49.6926, -25.257, 0.32843, -40.4408, -8.21801, -31.4407, 0.283936, -56.906, -120.336, -40.6846, 0.523743, -62.7131, -116.956, -32.5538, 0.486816, -59.8485, -119.899, -46.5796, 0.469604, -69.74, -116.42, -47.7167, 0.333618]\r\n},\r\n{ \"id\": 2,\r\n\"joints19\": [-2.68829, -95.166, 36.4048, 0.630371, 2.45545, -104.642, 17.3385, 0.4422, -7.03441, -50.7646, 42.0224, 0.242737, 9.85479, -93.5391, 43.7496, 0.508667, 12.1837, -69.2865, 41.4611, 0.386414, 19.4591, -69.7157, 22.0246, 0.327209, 0.906971, -50.8216, 45.9673, 0.251282, 26.7278, -43.1852, 17.6063, 0.375671, 27.6219, -7.85445, 13.6172, 0.336487, -15.0965, -97.8212, 30.3863, 0.518982, -37.313, -87.4077, 18.8649, 0.450623, -22.0828, -73.86, 12.723, 0.291931, -14.9758, -50.7076, 38.0776, 0.235413, 5.50862, -46.8061, 4.64948, 0.321838, 4.38506, -11.3184, 11.4198, 0.237366, 5.50586, -106.921, 19.3049, 0.338745, 8.65006, -105.825, 29.1475, 0.375244, 0.254989, -108.642, 18.0692, 0.389526, -5.97449, -109.525, 25.9132, 0.369568]\r\n}\r\n] }"
  },
  {
    "path": "tests/data/posetrack18/annotations/test_posetrack18_human_detections.json",
    "content": "[\n    {\n        \"bbox\": [\n            1475.2755126953125,\n            2.719658136367798,\n            96.9671630859375,\n            252.88242316246033\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.9290200471878052\n    },\n    {\n        \"bbox\": [\n            279.2542419433594,\n            201.43528747558594,\n            215.51690673828125,\n            277.4363555908203\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.8697755932807922\n    },\n    {\n        \"bbox\": [\n            375.3135070800781,\n            1.6077430248260498,\n            102.83343505859375,\n            205.19831776618958\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.8078259229660034\n    },\n    {\n        \"bbox\": [\n            1372.4200439453125,\n            0.0,\n            105.89013671875,\n            242.61294555664062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.7359948754310608\n    },\n    {\n        \"bbox\": [\n            879.8322143554688,\n            166.1944122314453,\n            129.68414306640625,\n            265.45030212402344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.7012330293655396\n    },\n    {\n        \"bbox\": [\n            1565.218994140625,\n            0.6250243186950684,\n            94.249267578125,\n            251.48860788345337\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.6708132028579712\n    },\n    {\n        \"bbox\": [\n            1625.5699462890625,\n            34.00221633911133,\n            113.07080078125,\n            336.9929618835449\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.6564908027648926\n    },\n    {\n        \"bbox\": [\n            1767.4072265625,\n            0.0,\n            94.924560546875,\n            229.85476684570312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.6467881202697754\n    },\n    {\n        \"bbox\": [\n            956.6194458007812,\n            900.006103515625,\n            149.72381591796875,\n            173.7783203125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.6429733037948608\n    },\n    {\n        \"bbox\": [\n            574.7518310546875,\n            876.6203002929688,\n            133.7698974609375,\n            200.78741455078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.6194133758544922\n    },\n    {\n        \"bbox\": [\n            467.8788146972656,\n            776.9996948242188,\n            108.48025512695312,\n            287.51483154296875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.608767032623291\n    },\n    {\n        \"bbox\": [\n            302.0422058105469,\n            732.33837890625,\n            124.57574462890625,\n            331.01220703125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.5625099539756775\n    },\n    {\n        \"bbox\": [\n            638.8469848632812,\n            743.0866088867188,\n            117.85137939453125,\n            317.97259521484375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.5567368268966675\n    },\n    {\n        \"bbox\": [\n            335.7384948730469,\n            507.2187194824219,\n            145.80545043945312,\n            159.55679321289062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.5184996724128723\n    },\n    {\n        \"bbox\": [\n            1330.8204345703125,\n            838.9266357421875,\n            140.44580078125,\n            240.1510009765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.5148675441741943\n    },\n    {\n        \"bbox\": [\n            720.7056884765625,\n            2.9743223190307617,\n            104.3197021484375,\n            150.11820697784424\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.5129923820495605\n    },\n    {\n        \"bbox\": [\n            196.63421630859375,\n            693.4352416992188,\n            119.49697875976562,\n            362.00836181640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.472736656665802\n    },\n    {\n        \"bbox\": [\n            666.0804443359375,\n            180.66146850585938,\n            95.970458984375,\n            213.87698364257812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.4722053110599518\n    },\n    {\n        \"bbox\": [\n            876.128173828125,\n            339.4115905761719,\n            135.45379638671875,\n            319.6487121582031\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.4647904336452484\n    },\n    {\n        \"bbox\": [\n            667.529296875,\n            415.2683410644531,\n            104.7076416015625,\n            229.71560668945312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.45972582697868347\n    },\n    {\n        \"bbox\": [\n            112.86947631835938,\n            264.6505432128906,\n            144.888671875,\n            191.26544189453125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.45595934987068176\n    },\n    {\n        \"bbox\": [\n            1701.4876708984375,\n            0.0,\n            90.152587890625,\n            221.60284423828125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.45339658856391907\n    },\n    {\n        \"bbox\": [\n            1177.0682373046875,\n            808.5385131835938,\n            118.4273681640625,\n            265.73162841796875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.4308188259601593\n    },\n    {\n        \"bbox\": [\n            1581.5089111328125,\n            773.6590576171875,\n            153.54052734375,\n            289.6710205078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.4269048273563385\n    },\n    {\n        \"bbox\": [\n            531.0040893554688,\n            437.7104187011719,\n            127.3616943359375,\n            280.2588806152344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.42152199149131775\n    },\n    {\n        \"bbox\": [\n            1797.8150634765625,\n            778.5232543945312,\n            102.983642578125,\n            292.46649169921875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.411865234375\n    },\n    {\n        \"bbox\": [\n            1084.093505859375,\n            2.85404109954834,\n            93.6932373046875,\n            210.73848819732666\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.40260007977485657\n    },\n    {\n        \"bbox\": [\n            920.5157470703125,\n            832.7113037109375,\n            94.4918212890625,\n            221.5032958984375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3867260217666626\n    },\n    {\n        \"bbox\": [\n            1115.3507080078125,\n            847.74365234375,\n            109.4945068359375,\n            226.804931640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3844665586948395\n    },\n    {\n        \"bbox\": [\n            1872.486083984375,\n            19.00360679626465,\n            42.8349609375,\n            236.63503456115723\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.37733739614486694\n    },\n    {\n        \"bbox\": [\n            1349.9853515625,\n            210.24911499023438,\n            131.93798828125,\n            167.93081665039062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3761371970176697\n    },\n    {\n        \"bbox\": [\n            766.0445556640625,\n            879.2682495117188,\n            124.82427978515625,\n            201.08441162109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3682442009449005\n    },\n    {\n        \"bbox\": [\n            817.4657592773438,\n            0.0,\n            80.7606201171875,\n            168.49359130859375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3530486524105072\n    },\n    {\n        \"bbox\": [\n            147.0262451171875,\n            1.8125637769699097,\n            79.67684936523438,\n            99.51723968982697\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.31355297565460205\n    },\n    {\n        \"bbox\": [\n            1159.018310546875,\n            750.4727172851562,\n            109.84375,\n            160.12939453125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3134245276451111\n    },\n    {\n        \"bbox\": [\n            201.1594696044922,\n            625.8055419921875,\n            77.64781188964844,\n            134.331787109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3070683181285858\n    },\n    {\n        \"bbox\": [\n            1473.18359375,\n            651.7177124023438,\n            82.4835205078125,\n            130.7080078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.30168840289115906\n    },\n    {\n        \"bbox\": [\n            932.6547241210938,\n            0.0,\n            94.53363037109375,\n            160.51365661621094\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.3008910119533539\n    },\n    {\n        \"bbox\": [\n            1700.9190673828125,\n            828.179931640625,\n            121.2147216796875,\n            245.9788818359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.29163801670074463\n    },\n    {\n        \"bbox\": [\n            1634.7724609375,\n            446.2858581542969,\n            132.4085693359375,\n            209.66311645507812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.291547566652298\n    },\n    {\n        \"bbox\": [\n            1556.4608154296875,\n            473.771728515625,\n            112.165283203125,\n            180.64654541015625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2879399359226227\n    },\n    {\n        \"bbox\": [\n            583.9107055664062,\n            1.929314374923706,\n            73.5870361328125,\n            123.53908467292786\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.28340914845466614\n    },\n    {\n        \"bbox\": [\n            1498.50634765625,\n            698.7794799804688,\n            96.718505859375,\n            314.76446533203125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.28129440546035767\n    },\n    {\n        \"bbox\": [\n            1280.0792236328125,\n            775.8158569335938,\n            76.7454833984375,\n            188.51519775390625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.27848634123802185\n    },\n    {\n        \"bbox\": [\n            1718.6058349609375,\n            226.6940460205078,\n            160.0238037109375,\n            177.1758575439453\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.27552416920661926\n    },\n    {\n        \"bbox\": [\n            756.9520263671875,\n            810.5991821289062,\n            83.45086669921875,\n            189.677001953125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.27519550919532776\n    },\n    {\n        \"bbox\": [\n            1728.245849609375,\n            640.5650024414062,\n            117.093994140625,\n            210.5716552734375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.272867351770401\n    },\n    {\n        \"bbox\": [\n            1772.5546875,\n            525.9481201171875,\n            132.1446533203125,\n            174.74395751953125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2701846957206726\n    },\n    {\n        \"bbox\": [\n            1305.05224609375,\n            209.34393310546875,\n            184.050048828125,\n            414.58587646484375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.26895296573638916\n    },\n    {\n        \"bbox\": [\n            810.69287109375,\n            790.5480346679688,\n            89.7996826171875,\n            185.0943603515625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.26855093240737915\n    },\n    {\n        \"bbox\": [\n            95.97314453125,\n            724.7075805664062,\n            114.75672912597656,\n            298.14398193359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.26742294430732727\n    },\n    {\n        \"bbox\": [\n            1261.4110107421875,\n            909.4841918945312,\n            118.9820556640625,\n            164.47723388671875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2666778564453125\n    },\n    {\n        \"bbox\": [\n            1339.5250244140625,\n            434.0279846191406,\n            87.82666015625,\n            147.42294311523438\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.26228952407836914\n    },\n    {\n        \"bbox\": [\n            63.43070983886719,\n            664.1151733398438,\n            82.15074157714844,\n            128.1494140625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.26013079285621643\n    },\n    {\n        \"bbox\": [\n            1.3776787519454956,\n            679.18505859375,\n            111.62459480762482,\n            224.9747314453125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2587812840938568\n    },\n    {\n        \"bbox\": [\n            1439.8868408203125,\n            816.7938842773438,\n            97.72802734375,\n            256.11944580078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.256550669670105\n    },\n    {\n        \"bbox\": [\n            660.9515380859375,\n            744.8563842773438,\n            94.61444091796875,\n            115.916259765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2563660442829132\n    },\n    {\n        \"bbox\": [\n            556.6321411132812,\n            0.0,\n            31.12762451171875,\n            77.6491470336914\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2539074718952179\n    },\n    {\n        \"bbox\": [\n            414.3009948730469,\n            682.0269165039062,\n            92.76937866210938,\n            310.0914306640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.25366705656051636\n    },\n    {\n        \"bbox\": [\n            1823.6094970703125,\n            520.3126831054688,\n            74.411865234375,\n            80.507080078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2529422640800476\n    },\n    {\n        \"bbox\": [\n            258.0948486328125,\n            2.8098771572113037,\n            73.0369873046875,\n            90.99600052833557\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.25058287382125854\n    },\n    {\n        \"bbox\": [\n            508.9549560546875,\n            714.0374145507812,\n            132.6729736328125,\n            206.59674072265625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.24579626321792603\n    },\n    {\n        \"bbox\": [\n            1647.6907958984375,\n            387.5267639160156,\n            117.0858154296875,\n            134.33120727539062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2425207644701004\n    },\n    {\n        \"bbox\": [\n            1445.354248046875,\n            761.0438842773438,\n            91.1209716796875,\n            122.70550537109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2403791844844818\n    },\n    {\n        \"bbox\": [\n            1028.0394287109375,\n            751.615478515625,\n            101.6038818359375,\n            172.39617919921875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.23425403237342834\n    },\n    {\n        \"bbox\": [\n            10.321240425109863,\n            668.003173828125,\n            92.43458843231201,\n            93.92236328125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.23368315398693085\n    },\n    {\n        \"bbox\": [\n            480.19140625,\n            3.0881388187408447,\n            101.267578125,\n            78.71852469444275\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2329442799091339\n    },\n    {\n        \"bbox\": [\n            1319.99755859375,\n            813.53125,\n            58.90185546875,\n            112.30328369140625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.23115667700767517\n    },\n    {\n        \"bbox\": [\n            0.0,\n            628.298828125,\n            47.96708679199219,\n            120.50457763671875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2270287126302719\n    },\n    {\n        \"bbox\": [\n            298.7027893066406,\n            666.9664306640625,\n            119.76385498046875,\n            144.8203125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2235877364873886\n    },\n    {\n        \"bbox\": [\n            1054.49609375,\n            1.8778526782989502,\n            65.3221435546875,\n            154.7142035961151\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.22313834726810455\n    },\n    {\n        \"bbox\": [\n            296.7391052246094,\n            680.0767822265625,\n            35.053375244140625,\n            69.30267333984375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.21813228726387024\n    },\n    {\n        \"bbox\": [\n            1811.36962890625,\n            285.1565246582031,\n            102.1195068359375,\n            269.7958679199219\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.21760663390159607\n    },\n    {\n        \"bbox\": [\n            114.75823974609375,\n            719.09228515625,\n            74.72804260253906,\n            83.634765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2161155790090561\n    },\n    {\n        \"bbox\": [\n            991.546875,\n            1.210024356842041,\n            59.4659423828125,\n            152.63245916366577\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.2096937894821167\n    },\n    {\n        \"bbox\": [\n            1852.13916015625,\n            519.2532958984375,\n            38.265380859375,\n            43.08807373046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.18011623620986938\n    },\n    {\n        \"bbox\": [\n            316.677978515625,\n            0.0,\n            44.184600830078125,\n            62.04084396362305\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.17839768528938293\n    },\n    {\n        \"bbox\": [\n            1023.7964477539062,\n            0.0,\n            45.53558349609375,\n            87.68540954589844\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.1771439015865326\n    },\n    {\n        \"bbox\": [\n            0.0,\n            690.8153076171875,\n            27.172204971313477,\n            55.42034912109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.17463117837905884\n    },\n    {\n        \"bbox\": [\n            1663.4932861328125,\n            4.420060634613037,\n            65.2760009765625,\n            114.99270486831665\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.1590556651353836\n    },\n    {\n        \"bbox\": [\n            1578.5491943359375,\n            454.1618347167969,\n            74.5714111328125,\n            104.37033081054688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.15501607954502106\n    },\n    {\n        \"bbox\": [\n            544.5846557617188,\n            697.2288208007812,\n            35.70989990234375,\n            26.73150634765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.15327082574367523\n    },\n    {\n        \"bbox\": [\n            534.465087890625,\n            881.8455200195312,\n            78.7249755859375,\n            172.04473876953125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.14815860986709595\n    },\n    {\n        \"bbox\": [\n            1873.2293701171875,\n            834.9508056640625,\n            45.2706298828125,\n            230.974609375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.1479007452726364\n    },\n    {\n        \"bbox\": [\n            146.6645965576172,\n            723.4815673828125,\n            30.512222290039062,\n            41.179443359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.13243095576763153\n    },\n    {\n        \"bbox\": [\n            740.52490234375,\n            10.856040000915527,\n            38.1209716796875,\n            77.29609775543213\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.1309206336736679\n    },\n    {\n        \"bbox\": [\n            1783.414794921875,\n            856.5660400390625,\n            51.0806884765625,\n            216.032958984375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.13079363107681274\n    },\n    {\n        \"bbox\": [\n            1353.722900390625,\n            4.124818801879883,\n            26.04736328125,\n            36.974050521850586\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.12728439271450043\n    },\n    {\n        \"bbox\": [\n            1423.4942626953125,\n            875.3924560546875,\n            16.2568359375,\n            29.398681640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.1250089704990387\n    },\n    {\n        \"bbox\": [\n            1592.7584228515625,\n            1.329086184501648,\n            55.0660400390625,\n            54.82293713092804\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.11483781039714813\n    },\n    {\n        \"bbox\": [\n            1385.247314453125,\n            7.618640422821045,\n            19.5557861328125,\n            37.21356248855591\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.11478649824857712\n    },\n    {\n        \"bbox\": [\n            774.5552978515625,\n            0.0,\n            32.50115966796875,\n            48.10002899169922\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.11244752258062363\n    },\n    {\n        \"bbox\": [\n            1030.501953125,\n            792.454833984375,\n            44.9681396484375,\n            111.78228759765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10898905247449875\n    },\n    {\n        \"bbox\": [\n            302.1847229003906,\n            695.43701171875,\n            20.343109130859375,\n            28.063720703125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10741319507360458\n    },\n    {\n        \"bbox\": [\n            1729.3040771484375,\n            2.0999855995178223,\n            26.806884765625,\n            36.02122259140015\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10721274465322495\n    },\n    {\n        \"bbox\": [\n            1762.438720703125,\n            4.751255989074707,\n            24.288818359375,\n            40.14107036590576\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10624366253614426\n    },\n    {\n        \"bbox\": [\n            211.49954223632812,\n            328.7121887207031,\n            56.994140625,\n            60.76922607421875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10590028017759323\n    },\n    {\n        \"bbox\": [\n            1792.0831298828125,\n            261.65728759765625,\n            92.417236328125,\n            84.54769897460938\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10410129278898239\n    },\n    {\n        \"bbox\": [\n            1547.43359375,\n            4.291971683502197,\n            28.6832275390625,\n            69.40435552597046\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10200422257184982\n    },\n    {\n        \"bbox\": [\n            1335.0888671875,\n            3.258249282836914,\n            23.91845703125,\n            32.369855880737305\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10128340000,\n        \"score\": 0.10069120675325394\n    },\n    {\n        \"bbox\": [\n            1283.4007568359375,\n            6.713701248168945,\n            629.122802734375,\n            1056.8606395721436\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.9853803515434265\n    },\n    {\n        \"bbox\": [\n            288.9501647949219,\n            42.40924835205078,\n            1185.7618713378906,\n            999.2054977416992\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.9629650115966797\n    },\n    {\n        \"bbox\": [\n            649.4730834960938,\n            315.6942138671875,\n            143.35650634765625,\n            229.676513671875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.8901010751724243\n    },\n    {\n        \"bbox\": [\n            1058.3331298828125,\n            258.07269287109375,\n            310.98046875,\n            259.15057373046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.8752242922782898\n    },\n    {\n        \"bbox\": [\n            790.96240234375,\n            182.09800720214844,\n            105.51129150390625,\n            97.01622009277344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.872738242149353\n    },\n    {\n        \"bbox\": [\n            777.576416015625,\n            274.9346618652344,\n            119.44439697265625,\n            178.85000610351562\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.8679455518722534\n    },\n    {\n        \"bbox\": [\n            2.3131344318389893,\n            412.2568054199219,\n            273.67606234550476,\n            235.93026733398438\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.8616952300071716\n    },\n    {\n        \"bbox\": [\n            8.783040046691895,\n            198.89437866210938,\n            196.3238935470581,\n            266.4853515625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.8512702584266663\n    },\n    {\n        \"bbox\": [\n            220.74649047851562,\n            94.02008056640625,\n            98.13226318359375,\n            124.78965759277344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.7501042485237122\n    },\n    {\n        \"bbox\": [\n            164.27354431152344,\n            83.04096984863281,\n            88.21920776367188,\n            127.46699523925781\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.7067092061042786\n    },\n    {\n        \"bbox\": [\n            1087.515625,\n            181.69656372070312,\n            87.4686279296875,\n            72.61752319335938\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.702244758605957\n    },\n    {\n        \"bbox\": [\n            1074.9063720703125,\n            472.5963439941406,\n            124.1480712890625,\n            110.47763061523438\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.628270149230957\n    },\n    {\n        \"bbox\": [\n            343.7706604003906,\n            30.924612045288086,\n            59.412750244140625,\n            86.91977119445801\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.5943357944488525\n    },\n    {\n        \"bbox\": [\n            69.42112731933594,\n            103.34648132324219,\n            112.67413330078125,\n            108.37942504882812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.5710238218307495\n    },\n    {\n        \"bbox\": [\n            79.45482635498047,\n            437.8648376464844,\n            270.02677154541016,\n            180.55715942382812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.40784332156181335\n    },\n    {\n        \"bbox\": [\n            1225.6717529296875,\n            162.2100830078125,\n            78.9639892578125,\n            132.47430419921875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3427259922027588\n    },\n    {\n        \"bbox\": [\n            0.9485000371932983,\n            54.5380973815918,\n            92.79364931583405,\n            115.03351211547852\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.33483877778053284\n    },\n    {\n        \"bbox\": [\n            1105.8240966796875,\n            281.7027282714844,\n            76.47314453125,\n            55.8577880859375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3022329807281494\n    },\n    {\n        \"bbox\": [\n            0.0,\n            258.510498046875,\n            85.2731704711914,\n            205.99591064453125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.277988463640213\n    },\n    {\n        \"bbox\": [\n            1069.812255859375,\n            430.1299133300781,\n            178.785888671875,\n            54.991607666015625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.25947925448417664\n    },\n    {\n        \"bbox\": [\n            681.9738159179688,\n            208.11050415039062,\n            87.06488037109375,\n            76.40863037109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2577346861362457\n    },\n    {\n        \"bbox\": [\n            684.65625,\n            209.45753479003906,\n            65.76763916015625,\n            48.37471008300781\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.25362637639045715\n    },\n    {\n        \"bbox\": [\n            1770.093017578125,\n            45.35274887084961,\n            148.260986328125,\n            1012.7648048400879\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.23887047171592712\n    },\n    {\n        \"bbox\": [\n            167.9042510986328,\n            22.85419273376465,\n            81.45010375976562,\n            74.9856128692627\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.23093517124652863\n    },\n    {\n        \"bbox\": [\n            686.263671875,\n            45.065853118896484,\n            418.443603515625,\n            672.8133583068848\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.22159330546855927\n    },\n    {\n        \"bbox\": [\n            1190.727783203125,\n            260.0331115722656,\n            45.408203125,\n            42.90838623046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2191120684146881\n    },\n    {\n        \"bbox\": [\n            1051.7967529296875,\n            212.4822998046875,\n            37.3897705078125,\n            71.61709594726562\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.13527318835258484\n    },\n    {\n        \"bbox\": [\n            906.1925659179688,\n            454.3064880371094,\n            249.45501708984375,\n            209.19338989257812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.13330410420894623\n    },\n    {\n        \"bbox\": [\n            852.9170532226562,\n            360.49078369140625,\n            25.87530517578125,\n            70.86614990234375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.15234917402267456\n    },\n    {\n        \"bbox\": [\n            609.119140625,\n            295.8336181640625,\n            98.669677734375,\n            86.77999877929688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.8445025086402893\n    },\n    {\n        \"bbox\": [\n            378.2210693359375,\n            156.46856689453125,\n            79.51510620117188,\n            59.65052795410156\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.7748774886131287\n    },\n    {\n        \"bbox\": [\n            198.08822631835938,\n            305.9843444824219,\n            122.8443603515625,\n            100.4822998046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.7065314054489136\n    },\n    {\n        \"bbox\": [\n            135.3995819091797,\n            208.8668670654297,\n            82.15673828125,\n            32.42308044433594\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6814215779304504\n    },\n    {\n        \"bbox\": [\n            535.6635131835938,\n            300.5378112792969,\n            94.14208984375,\n            83.1962890625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6654942035675049\n    },\n    {\n        \"bbox\": [\n            483.58563232421875,\n            197.45590209960938,\n            74.43743896484375,\n            57.176239013671875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6608478426933289\n    },\n    {\n        \"bbox\": [\n            215.0618896484375,\n            210.8956756591797,\n            69.7735595703125,\n            29.752822875976562\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6438001394271851\n    },\n    {\n        \"bbox\": [\n            166.78993225097656,\n            260.73162841796875,\n            81.71955871582031,\n            33.886688232421875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6426426768302917\n    },\n    {\n        \"bbox\": [\n            194.13543701171875,\n            302.4077453613281,\n            132.185302734375,\n            203.56118774414062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.64094477891922\n    },\n    {\n        \"bbox\": [\n            24.686168670654297,\n            160.48495483398438,\n            65.35156631469727,\n            43.957122802734375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6141790747642517\n    },\n    {\n        \"bbox\": [\n            61.93497848510742,\n            206.81692504882812,\n            67.95804214477539,\n            35.73725891113281\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.6034325361251831\n    },\n    {\n        \"bbox\": [\n            684.8605346679688,\n            296.6944274902344,\n            60.11041259765625,\n            79.523681640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.5703861713409424\n    },\n    {\n        \"bbox\": [\n            277.9051818847656,\n            118.02881622314453,\n            75.3424072265625,\n            74.72411346435547\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.5354023575782776\n    },\n    {\n        \"bbox\": [\n            557.520751953125,\n            208.25003051757812,\n            63.16949462890625,\n            47.47157287597656\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.5207008719444275\n    },\n    {\n        \"bbox\": [\n            389.46875,\n            260.3998718261719,\n            95.03842163085938,\n            28.859283447265625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.5194308757781982\n    },\n    {\n        \"bbox\": [\n            246.87026977539062,\n            258.12652587890625,\n            83.399658203125,\n            36.68548583984375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.47507211565971375\n    },\n    {\n        \"bbox\": [\n            230.82713317871094,\n            51.341026306152344,\n            59.52711486816406,\n            42.373046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.4719221889972687\n    },\n    {\n        \"bbox\": [\n            371.5136413574219,\n            302.7303771972656,\n            84.49050903320312,\n            68.41122436523438\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.44887304306030273\n    },\n    {\n        \"bbox\": [\n            449.14666748046875,\n            303.34552001953125,\n            95.31640625,\n            48.94390869140625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.42651283740997314\n    },\n    {\n        \"bbox\": [\n            59.20182800292969,\n            77.63203430175781,\n            69.07972717285156,\n            36.52244567871094\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.42590340971946716\n    },\n    {\n        \"bbox\": [\n            370.47991943359375,\n            210.2904510498047,\n            66.41464233398438,\n            33.1710205078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.4237402677536011\n    },\n    {\n        \"bbox\": [\n            475.22509765625,\n            124.54940032958984,\n            57.011474609375,\n            40.61431121826172\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3908300995826721\n    },\n    {\n        \"bbox\": [\n            467.0397033691406,\n            66.16106414794922,\n            47.917999267578125,\n            27.583763122558594\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.38647398352622986\n    },\n    {\n        \"bbox\": [\n            288.4964904785156,\n            305.16815185546875,\n            99.31219482421875,\n            87.7886962890625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3735053241252899\n    },\n    {\n        \"bbox\": [\n            444.114990234375,\n            90.43252563476562,\n            51.553955078125,\n            31.16741943359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.37254029512405396\n    },\n    {\n        \"bbox\": [\n            99.98625183105469,\n            40.55061340332031,\n            76.22004699707031,\n            65.01245880126953\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3680468797683716\n    },\n    {\n        \"bbox\": [\n            294.51318359375,\n            54.41352844238281,\n            54.0465087890625,\n            41.265953063964844\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3454741835594177\n    },\n    {\n        \"bbox\": [\n            264.3034362792969,\n            83.36378479003906,\n            58.63067626953125,\n            45.3909912109375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.33034616708755493\n    },\n    {\n        \"bbox\": [\n            875.2257690429688,\n            294.2908020019531,\n            63.034912109375,\n            73.73040771484375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.31166598200798035\n    },\n    {\n        \"bbox\": [\n            552.3424072265625,\n            102.28469848632812,\n            53.5325927734375,\n            32.012359619140625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.31135886907577515\n    },\n    {\n        \"bbox\": [\n            447.3630065917969,\n            159.95870971679688,\n            75.57168579101562,\n            79.81913757324219\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3080102503299713\n    },\n    {\n        \"bbox\": [\n            744.2843627929688,\n            170.82386779785156,\n            48.20263671875,\n            32.58000183105469\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.3024618923664093\n    },\n    {\n        \"bbox\": [\n            518.8668823242188,\n            173.53623962402344,\n            57.2681884765625,\n            28.869842529296875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.28725939989089966\n    },\n    {\n        \"bbox\": [\n            578.883056640625,\n            242.28355407714844,\n            105.27862548828125,\n            45.62568664550781\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2870064973831177\n    },\n    {\n        \"bbox\": [\n            620.3238525390625,\n            214.0165557861328,\n            57.0029296875,\n            29.954849243164062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.27958208322525024\n    },\n    {\n        \"bbox\": [\n            346.06988525390625,\n            128.56320190429688,\n            70.56277465820312,\n            74.94837951660156\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2788334786891937\n    },\n    {\n        \"bbox\": [\n            414.5040588378906,\n            125.69651794433594,\n            59.56060791015625,\n            34.760101318359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.27825745940208435\n    },\n    {\n        \"bbox\": [\n            345.8397216796875,\n            258.0870056152344,\n            194.8671875,\n            35.27862548828125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2586188018321991\n    },\n    {\n        \"bbox\": [\n            687.569091796875,\n            163.837158203125,\n            51.50909423828125,\n            39.52703857421875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.24999305605888367\n    },\n    {\n        \"bbox\": [\n            625.0399780273438,\n            392.7872314453125,\n            67.018310546875,\n            72.13482666015625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2429981678724289\n    },\n    {\n        \"bbox\": [\n            498.5255432128906,\n            99.42186737060547,\n            53.512054443359375,\n            31.006126403808594\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.24067141115665436\n    },\n    {\n        \"bbox\": [\n            142.8480224609375,\n            309.98309326171875,\n            82.30924987792969,\n            98.9852294921875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.23763252794742584\n    },\n    {\n        \"bbox\": [\n            536.9259643554688,\n            133.77972412109375,\n            53.9805908203125,\n            43.579833984375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2375190556049347\n    },\n    {\n        \"bbox\": [\n            885.564453125,\n            239.24940490722656,\n            57.38165283203125,\n            37.30012512207031\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.23535390198230743\n    },\n    {\n        \"bbox\": [\n            395.301513671875,\n            92.57003784179688,\n            47.01910400390625,\n            38.36552429199219\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.23471194505691528\n    },\n    {\n        \"bbox\": [\n            409.6800537109375,\n            60.70526123046875,\n            51.487091064453125,\n            32.35259246826172\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.21594807505607605\n    },\n    {\n        \"bbox\": [\n            590.739013671875,\n            132.8422393798828,\n            55.618408203125,\n            34.99034118652344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.21444948017597198\n    },\n    {\n        \"bbox\": [\n            142.70018005371094,\n            14.566540718078613,\n            56.78106689453125,\n            33.07197093963623\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.2036537081003189\n    },\n    {\n        \"bbox\": [\n            320.72296142578125,\n            194.36314392089844,\n            42.888824462890625,\n            34.97528076171875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.20269575715065002\n    },\n    {\n        \"bbox\": [\n            479.15374755859375,\n            264.8033142089844,\n            71.17230224609375,\n            25.205291748046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.1989617943763733\n    },\n    {\n        \"bbox\": [\n            0.3339415192604065,\n            187.03533935546875,\n            50.64700025320053,\n            20.45751953125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.19690930843353271\n    },\n    {\n        \"bbox\": [\n            74.00901794433594,\n            105.07601165771484,\n            66.710693359375,\n            56.327720642089844\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.19045573472976685\n    },\n    {\n        \"bbox\": [\n            347.0372314453125,\n            259.55914306640625,\n            53.66485595703125,\n            32.394195556640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.18698135018348694\n    },\n    {\n        \"bbox\": [\n            67.07357025146484,\n            9.42569351196289,\n            74.41902923583984,\n            62.75996780395508\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.1855248659849167\n    },\n    {\n        \"bbox\": [\n            893.28857421875,\n            213.1145782470703,\n            46.3870849609375,\n            34.87232971191406\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.17870844900608063\n    },\n    {\n        \"bbox\": [\n            611.6231079101562,\n            106.5094223022461,\n            44.85430908203125,\n            29.061744689941406\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.17700931429862976\n    },\n    {\n        \"bbox\": [\n            847.1093139648438,\n            286.3870849609375,\n            56.32452392578125,\n            86.06158447265625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.16932892799377441\n    },\n    {\n        \"bbox\": [\n            445.4731140136719,\n            97.76200103759766,\n            49.56451416015625,\n            45.203514099121094\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.16094166040420532\n    },\n    {\n        \"bbox\": [\n            83.2696304321289,\n            238.672607421875,\n            87.30387115478516,\n            59.288787841796875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.1571291834115982\n    },\n    {\n        \"bbox\": [\n            644.8650512695312,\n            134.5099639892578,\n            52.570556640625,\n            45.77696228027344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.14659520983695984\n    },\n    {\n        \"bbox\": [\n            798.9510498046875,\n            176.64842224121094,\n            34.15826416015625,\n            27.026199340820312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.14340169727802277\n    },\n    {\n        \"bbox\": [\n            289.8072204589844,\n            2.8699655532836914,\n            57.560302734375,\n            31.036349296569824\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.12905792891979218\n    },\n    {\n        \"bbox\": [\n            273.2252502441406,\n            120.26922607421875,\n            33.325103759765625,\n            36.83570861816406\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.12813062965869904\n    },\n    {\n        \"bbox\": [\n            536.1267700195312,\n            301.2402038574219,\n            105.0225830078125,\n            164.69992065429688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.1251327097415924\n    },\n    {\n        \"bbox\": [\n            577.738037109375,\n            167.33460998535156,\n            52.75921630859375,\n            43.77146911621094\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.1169745996594429\n    },\n    {\n        \"bbox\": [\n            10.653980255126953,\n            1.5155118703842163,\n            64.12058639526367,\n            63.142767548561096\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.11120772361755371\n    },\n    {\n        \"bbox\": [\n            290.7361145019531,\n            305.92962646484375,\n            81.94302368164062,\n            186.35324096679688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.10804451256990433\n    },\n    {\n        \"bbox\": [\n            383.0464172363281,\n            33.47468948364258,\n            42.016937255859375,\n            40.26395034790039\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.10608372837305069\n    },\n    {\n        \"bbox\": [\n            373.3436279296875,\n            299.032470703125,\n            162.34857177734375,\n            71.123291015625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.10598088800907135\n    },\n    {\n        \"bbox\": [\n            347.5797424316406,\n            7.471529960632324,\n            51.544647216796875,\n            25.57726001739502\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.10507849603891373\n    },\n    {\n        \"bbox\": [\n            9.35350513458252,\n            944.8892211914062,\n            1300.14759349823,\n            121.89459228515625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10034180000,\n        \"score\": 0.21530765295028687\n    },\n    {\n        \"bbox\": [\n            639.7239379882812,\n            226.8717498779297,\n            344.6689453125,\n            663.6336212158203\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.988675594329834\n    },\n    {\n        \"bbox\": [\n            6.2749924659729,\n            351.6357116699219,\n            243.3602614402771,\n            364.3725280761719\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.956828773021698\n    },\n    {\n        \"bbox\": [\n            461.7480163574219,\n            277.44110107421875,\n            115.16329956054688,\n            186.4822998046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.9538608193397522\n    },\n    {\n        \"bbox\": [\n            1768.55322265625,\n            245.51446533203125,\n            138.985595703125,\n            304.20843505859375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.9133968949317932\n    },\n    {\n        \"bbox\": [\n            1155.5684814453125,\n            359.0439453125,\n            191.2630615234375,\n            272.81744384765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.9098905920982361\n    },\n    {\n        \"bbox\": [\n            1259.7314453125,\n            366.961181640625,\n            90.6544189453125,\n            138.16278076171875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.7968080043792725\n    },\n    {\n        \"bbox\": [\n            480.37066650390625,\n            386.0138854980469,\n            150.568115234375,\n            280.1358337402344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.7637147307395935\n    },\n    {\n        \"bbox\": [\n            263.7475280761719,\n            188.89967346191406,\n            90.03085327148438,\n            113.91123962402344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.7468248605728149\n    },\n    {\n        \"bbox\": [\n            162.36859130859375,\n            187.40757751464844,\n            105.68603515625,\n            143.9015655517578\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.7130147814750671\n    },\n    {\n        \"bbox\": [\n            139.2628936767578,\n            291.9899597167969,\n            106.13040161132812,\n            205.92654418945312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.7115177512168884\n    },\n    {\n        \"bbox\": [\n            1365.2760009765625,\n            246.45489501953125,\n            66.708984375,\n            145.35330200195312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.6987277865409851\n    },\n    {\n        \"bbox\": [\n            1486.121337890625,\n            449.1069641113281,\n            68.625732421875,\n            118.49978637695312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.6513593792915344\n    },\n    {\n        \"bbox\": [\n            1354.540771484375,\n            443.40478515625,\n            147.19580078125,\n            194.12603759765625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.6448480486869812\n    },\n    {\n        \"bbox\": [\n            1363.81591796875,\n            373.9744567871094,\n            81.1202392578125,\n            102.91085815429688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.5243184566497803\n    },\n    {\n        \"bbox\": [\n            1514.0146484375,\n            319.5240783691406,\n            75.83056640625,\n            144.65200805664062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.504604697227478\n    },\n    {\n        \"bbox\": [\n            355.92431640625,\n            377.6044921875,\n            114.5035400390625,\n            120.37677001953125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.4970506429672241\n    },\n    {\n        \"bbox\": [\n            1582.33203125,\n            266.6174621582031,\n            98.7462158203125,\n            264.5225524902344\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.48399269580841064\n    },\n    {\n        \"bbox\": [\n            353.9928283691406,\n            371.8907470703125,\n            121.08633422851562,\n            262.55682373046875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.4818037748336792\n    },\n    {\n        \"bbox\": [\n            362.9367370605469,\n            147.3871612548828,\n            75.418212890625,\n            109.99433898925781\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.4351760447025299\n    },\n    {\n        \"bbox\": [\n            1241.2064208984375,\n            368.8930969238281,\n            127.748291015625,\n            264.2134704589844\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.38909056782722473\n    },\n    {\n        \"bbox\": [\n            1681.270263671875,\n            256.126220703125,\n            83.576416015625,\n            137.42578125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.364656925201416\n    },\n    {\n        \"bbox\": [\n            0.0,\n            167.76327514648438,\n            91.63196563720703,\n            236.555419921875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.35032832622528076\n    },\n    {\n        \"bbox\": [\n            1439.95703125,\n            270.9534606933594,\n            100.35986328125,\n            218.63064575195312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.346635103225708\n    },\n    {\n        \"bbox\": [\n            1318.2305908203125,\n            424.5197448730469,\n            115.10791015625,\n            192.50259399414062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.3269309401512146\n    },\n    {\n        \"bbox\": [\n            1052.64013671875,\n            287.7257385253906,\n            63.3641357421875,\n            172.54461669921875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.24086904525756836\n    },\n    {\n        \"bbox\": [\n            1053.502197265625,\n            331.1842346191406,\n            227.3038330078125,\n            310.5895080566406\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.21309363842010498\n    },\n    {\n        \"bbox\": [\n            1070.9603271484375,\n            360.4552917480469,\n            96.628173828125,\n            133.9866943359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.18517304956912994\n    },\n    {\n        \"bbox\": [\n            1665.9293212890625,\n            255.31796264648438,\n            146.314697265625,\n            291.3702697753906\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.17204511165618896\n    },\n    {\n        \"bbox\": [\n            405.0735778808594,\n            386.8234558105469,\n            190.69692993164062,\n            313.5556945800781\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.15523910522460938\n    },\n    {\n        \"bbox\": [\n            1589.0211181640625,\n            265.5631103515625,\n            84.9398193359375,\n            150.40841674804688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.15313847362995148\n    },\n    {\n        \"bbox\": [\n            0.9758958220481873,\n            422.1836853027344,\n            142.32709795236588,\n            306.2699279785156\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.146592915058136\n    },\n    {\n        \"bbox\": [\n            1419.790283203125,\n            240.48899841308594,\n            55.875,\n            102.48948669433594\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.14388331770896912\n    },\n    {\n        \"bbox\": [\n            1142.052001953125,\n            372.945068359375,\n            375.743896484375,\n            263.99609375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.1362028419971466\n    },\n    {\n        \"bbox\": [\n            1149.924560546875,\n            228.89898681640625,\n            77.2176513671875,\n            141.24282836914062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.13104568421840668\n    },\n    {\n        \"bbox\": [\n            7.145267009735107,\n            362.8689270019531,\n            148.28553438186646,\n            151.63449096679688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.130157008767128\n    },\n    {\n        \"bbox\": [\n            1115.1795654296875,\n            359.9970703125,\n            55.0574951171875,\n            73.02313232421875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.1132773831486702\n    },\n    {\n        \"bbox\": [\n            1797.716552734375,\n            246.42071533203125,\n            108.528076171875,\n            179.66299438476562\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.10333290696144104\n    },\n    {\n        \"bbox\": [\n            1281.1473388671875,\n            254.05291748046875,\n            95.2158203125,\n            128.24417114257812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.09135308116674423\n    },\n    {\n        \"bbox\": [\n            483.60968017578125,\n            383.16656494140625,\n            106.47314453125,\n            105.37130737304688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.08747227489948273\n    },\n    {\n        \"bbox\": [\n            1183.970458984375,\n            248.7894744873047,\n            123.838623046875,\n            133.18003845214844\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.07844730466604233\n    },\n    {\n        \"bbox\": [\n            1157.6649169921875,\n            358.5057678222656,\n            153.3060302734375,\n            142.8681640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.07668760418891907\n    },\n    {\n        \"bbox\": [\n            158.5989532470703,\n            3.899838924407959,\n            94.29812622070312,\n            113.55939722061157\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.0562337264418602\n    },\n    {\n        \"bbox\": [\n            1046.19189453125,\n            303.1739196777344,\n            146.7403564453125,\n            295.9938049316406\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05225243791937828\n    },\n    {\n        \"bbox\": [\n            1075.177490234375,\n            351.35552978515625,\n            187.2501220703125,\n            145.95687866210938\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.052039798349142075\n    },\n    {\n        \"bbox\": [\n            4.226436614990234,\n            596.753662109375,\n            145.0108528137207,\n            141.51971435546875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.44805338978767395\n    },\n    {\n        \"bbox\": [\n            1471.1275634765625,\n            546.7749633789062,\n            409.1026611328125,\n            85.891845703125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.17510481178760529\n    },\n    {\n        \"bbox\": [\n            9.595407485961914,\n            136.05421447753906,\n            273.3134059906006,\n            50.703155517578125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.14366888999938965\n    },\n    {\n        \"bbox\": [\n            921.6530151367188,\n            497.646484375,\n            100.19329833984375,\n            244.272216796875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.41841089725494385\n    },\n    {\n        \"bbox\": [\n            1837.094482421875,\n            311.22064208984375,\n            30.9761962890625,\n            48.001678466796875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.08423541486263275\n    },\n    {\n        \"bbox\": [\n            1839.4462890625,\n            311.10064697265625,\n            37.092529296875,\n            71.60287475585938\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.060598306357860565\n    },\n    {\n        \"bbox\": [\n            332.7347412109375,\n            440.8306579589844,\n            26.84356689453125,\n            49.14508056640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.4217357635498047\n    },\n    {\n        \"bbox\": [\n            1074.7474365234375,\n            455.2643127441406,\n            38.0753173828125,\n            24.68829345703125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.10941091924905777\n    },\n    {\n        \"bbox\": [\n            1034.816162109375,\n            433.4083251953125,\n            37.64892578125,\n            38.33526611328125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05890995264053345\n    },\n    {\n        \"bbox\": [\n            1133.7620849609375,\n            508.0845642089844,\n            70.1640625,\n            130.23025512695312\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.4846752882003784\n    },\n    {\n        \"bbox\": [\n            3.005446195602417,\n            553.9013671875,\n            142.2049114704132,\n            183.9932861328125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.3487741947174072\n    },\n    {\n        \"bbox\": [\n            272.37786865234375,\n            411.44207763671875,\n            81.43817138671875,\n            55.8065185546875\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.21865300834178925\n    },\n    {\n        \"bbox\": [\n            0.24188603460788727,\n            453.31536865234375,\n            148.4058190435171,\n            234.45562744140625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.20409443974494934\n    },\n    {\n        \"bbox\": [\n            30.815982818603516,\n            605.8007202148438,\n            125.22259140014648,\n            55.677490234375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.1920752078294754\n    },\n    {\n        \"bbox\": [\n            1133.945556640625,\n            486.0797424316406,\n            142.3828125,\n            149.95669555664062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.1483757048845291\n    },\n    {\n        \"bbox\": [\n            1113.4261474609375,\n            458.69744873046875,\n            106.506103515625,\n            181.26995849609375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.13916584849357605\n    },\n    {\n        \"bbox\": [\n            436.55487060546875,\n            457.7103576660156,\n            156.08184814453125,\n            253.82962036132812\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.11243928223848343\n    },\n    {\n        \"bbox\": [\n            284.70098876953125,\n            303.1107482910156,\n            85.747802734375,\n            79.47280883789062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.09735624492168427\n    },\n    {\n        \"bbox\": [\n            341.12774658203125,\n            492.6709289550781,\n            93.78155517578125,\n            206.94662475585938\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.08169478923082352\n    },\n    {\n        \"bbox\": [\n            0.0,\n            549.1785278320312,\n            119.3069839477539,\n            111.58819580078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.06240745261311531\n    },\n    {\n        \"bbox\": [\n            7.89318323135376,\n            645.31689453125,\n            136.12907934188843,\n            87.29620361328125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.054731015115976334\n    },\n    {\n        \"bbox\": [\n            213.0941619873047,\n            411.15179443359375,\n            42.60209655761719,\n            32.3763427734375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05244819447398186\n    },\n    {\n        \"bbox\": [\n            130.32546997070312,\n            487.7962951660156,\n            300.62261962890625,\n            236.79757690429688\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.8464512825012207\n    },\n    {\n        \"bbox\": [\n            943.7500610351562,\n            463.9021911621094,\n            207.76824951171875,\n            177.45816040039062\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.6438319087028503\n    },\n    {\n        \"bbox\": [\n            126.81778717041016,\n            458.4678955078125,\n            290.0162582397461,\n            57.33453369140625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.1522291600704193\n    },\n    {\n        \"bbox\": [\n            936.41162109375,\n            449.2172546386719,\n            192.6654052734375,\n            35.686859130859375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.14834310114383698\n    },\n    {\n        \"bbox\": [\n            887.5518798828125,\n            464.12335205078125,\n            357.5780029296875,\n            257.0013427734375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.1072755679488182\n    },\n    {\n        \"bbox\": [\n            7.024689197540283,\n            405.5135498046875,\n            338.4464716911316,\n            278.21929931640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.09115041047334671\n    },\n    {\n        \"bbox\": [\n            161.556884765625,\n            482.5937805175781,\n            242.09451293945312,\n            30.944366455078125\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.06512065976858139\n    },\n    {\n        \"bbox\": [\n            933.17236328125,\n            423.4557800292969,\n            280.425048828125,\n            68.74118041992188\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.06368233263492584\n    },\n    {\n        \"bbox\": [\n            121.80384063720703,\n            488.6224060058594,\n            311.62242889404297,\n            45.982086181640625\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05987454578280449\n    },\n    {\n        \"bbox\": [\n            929.5904541015625,\n            436.67840576171875,\n            381.5384521484375,\n            75.44134521484375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05840197578072548\n    },\n    {\n        \"bbox\": [\n            235.27882385253906,\n            486.3999328613281,\n            136.96372985839844,\n            23.562835693359375\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05732391029596329\n    },\n    {\n        \"bbox\": [\n            69.67058563232422,\n            417.2310485839844,\n            672.0211868286133,\n            311.6492614746094\n        ],\n        \"category_id\": 1,\n        \"image_id\": 10094730000,\n        \"score\": 0.05091623216867447\n    }\n    \n]\n"
  },
  {
    "path": "tests/data/posetrack18/annotations/test_posetrack18_val.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"head_bottom\",\n                \"head_top\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"has_no_densepose\": true,\n            \"is_labeled\": true,\n            \"file_name\": \"images/val/012834_mpii_test/000000.jpg\",\n            \"nframes\": 140,\n            \"frame_id\": 10128340000,\n            \"vid_id\": \"012834\",\n            \"ignore_regions_y\": [\n                [\n                    1079,\n                    615,\n                    612,\n                    674,\n                    660,\n                    664,\n                    678,\n                    713,\n                    704,\n                    667,\n                    665,\n                    678,\n                    700,\n                    729,\n                    753,\n                    740,\n                    695,\n                    668,\n                    646,\n                    623,\n                    624,\n                    659,\n                    676,\n                    685,\n                    695,\n                    678,\n                    675,\n                    673,\n                    663,\n                    693,\n                    703,\n                    732,\n                    719,\n                    690,\n                    669,\n                    660,\n                    660,\n                    663,\n                    689,\n                    697,\n                    691,\n                    697,\n                    713,\n                    736,\n                    721,\n                    703,\n                    698,\n                    708,\n                    741,\n                    758,\n                    778,\n                    795,\n                    780,\n                    757,\n                    745,\n                    737,\n                    745,\n                    782,\n                    809,\n                    850,\n                    881,\n                    835,\n                    810,\n                    806,\n                    782,\n                    782,\n                    806,\n                    832,\n                    863,\n                    897,\n                    940,\n                    931,\n                    957,\n                    976,\n                    1003,\n                    1043,\n                    1045,\n                    1008,\n                    965,\n                    963,\n                    931,\n                    895,\n                    846,\n                    832,\n                    829,\n                    869,\n                    898,\n                    904,\n                    869,\n                    836,\n                    782,\n                    752,\n                    736,\n                    748,\n                    776,\n                    832,\n                    874,\n                    862,\n                    818,\n                    793,\n                    790,\n                    756,\n                    738,\n                    737,\n                    750,\n                    791,\n                    806,\n                    820,\n                    852,\n                    879,\n                    837,\n                    794,\n                    772,\n                    766,\n                    769,\n                    790,\n                    805,\n                    829,\n                    844,\n                    866,\n                    837,\n                    804,\n                    791,\n                    773,\n                    745,\n                    706,\n                    683,\n                    644,\n                    638,\n                    662,\n                    694,\n                    716,\n                    736,\n                    777,\n                    784,\n                    815,\n                    830,\n                    813,\n                    800,\n                    813,\n                    820,\n                    847,\n                    829,\n                    781,\n                    780,\n                    801,\n                    836,\n                    886,\n                    938,\n                    1018,\n                    1029,\n                    1079\n                ],\n                [\n                    0,\n                    21,\n                    43,\n                    60,\n                    90,\n                    95,\n                    95,\n                    43,\n                    40,\n                    84,\n                    104,\n                    104,\n                    74,\n                    6,\n                    4,\n                    71,\n                    69,\n                    0\n                ],\n                [\n                    0,\n                    4,\n                    48,\n                    106,\n                    214,\n                    207,\n                    46,\n                    50,\n                    170,\n                    156,\n                    96,\n                    157,\n                    160,\n                    62,\n                    65,\n                    156,\n                    165,\n                    162,\n                    140,\n                    93,\n                    93,\n                    7,\n                    4,\n                    121,\n                    129,\n                    84,\n                    75,\n                    68\n                ],\n                [\n                    0,\n                    0,\n                    739,\n                    729,\n                    720,\n                    740,\n                    768,\n                    785,\n                    803,\n                    815,\n                    757,\n                    735,\n                    632,\n                    620,\n                    632,\n                    640,\n                    662,\n                    656,\n                    607,\n                    645,\n                    645,\n                    628,\n                    604,\n                    570,\n                    543,\n                    512,\n                    485,\n                    467,\n                    451,\n                    448,\n                    456,\n                    482,\n                    512,\n                    548,\n                    554,\n                    542,\n                    498,\n                    479,\n                    454,\n                    404,\n                    387,\n                    398,\n                    415,\n                    528,\n                    546,\n                    468,\n                    410,\n                    400,\n                    359,\n                    375,\n                    373,\n                    273,\n                    254,\n                    284,\n                    253,\n                    204,\n                    206\n                ]\n            ],\n            \"ignore_regions_x\": [\n                [\n                    3,\n                    0,\n                    30,\n                    44,\n                    74,\n                    99,\n                    106,\n                    102,\n                    115,\n                    121,\n                    141,\n                    156,\n                    165,\n                    187,\n                    200,\n                    211,\n                    196,\n                    198,\n                    210,\n                    226,\n                    252,\n                    266,\n                    263,\n                    271,\n                    291,\n                    299,\n                    326,\n                    339,\n                    360,\n                    399,\n                    412,\n                    424,\n                    437,\n                    432,\n                    439,\n                    461,\n                    489,\n                    510,\n                    534,\n                    548,\n                    559,\n                    567,\n                    587,\n                    593,\n                    604,\n                    612,\n                    633,\n                    652,\n                    645,\n                    638,\n                    649,\n                    650,\n                    661,\n                    654,\n                    662,\n                    685,\n                    713,\n                    727,\n                    733,\n                    752,\n                    762,\n                    769,\n                    785,\n                    812,\n                    841,\n                    863,\n                    869,\n                    877,\n                    899,\n                    909,\n                    918,\n                    906,\n                    902,\n                    909,\n                    917,\n                    900,\n                    932,\n                    932,\n                    941,\n                    919,\n                    926,\n                    935,\n                    950,\n                    957,\n                    983,\n                    1002,\n                    1007,\n                    1032,\n                    1034,\n                    1018,\n                    1018,\n                    1038,\n                    1074,\n                    1106,\n                    1119,\n                    1121,\n                    1130,\n                    1148,\n                    1152,\n                    1172,\n                    1195,\n                    1199,\n                    1209,\n                    1229,\n                    1242,\n                    1240,\n                    1242,\n                    1261,\n                    1264,\n                    1277,\n                    1285,\n                    1286,\n                    1296,\n                    1313,\n                    1336,\n                    1350,\n                    1367,\n                    1403,\n                    1417,\n                    1435,\n                    1459,\n                    1456,\n                    1429,\n                    1420,\n                    1465,\n                    1492,\n                    1496,\n                    1507,\n                    1529,\n                    1553,\n                    1570,\n                    1596,\n                    1609,\n                    1610,\n                    1649,\n                    1671,\n                    1703,\n                    1740,\n                    1763,\n                    1775,\n                    1803,\n                    1809,\n                    1815,\n                    1815,\n                    1857,\n                    1874,\n                    1881,\n                    1897,\n                    1896,\n                    1899,\n                    1888,\n                    1884\n                ],\n                [\n                    378,\n                    381,\n                    365,\n                    359,\n                    334,\n                    292,\n                    257,\n                    262,\n                    231,\n                    236,\n                    219,\n                    193,\n                    196,\n                    183,\n                    154,\n                    159,\n                    140,\n                    121\n                ],\n                [\n                    451,\n                    1173,\n                    1168,\n                    1168,\n                    1170,\n                    1085,\n                    1098,\n                    1070,\n                    1043,\n                    1000,\n                    993,\n                    979,\n                    934,\n                    937,\n                    918,\n                    903,\n                    893,\n                    832,\n                    785,\n                    759,\n                    726,\n                    710,\n                    667,\n                    664,\n                    585,\n                    576,\n                    507,\n                    485\n                ],\n                [\n                    1312,\n                    1918,\n                    1917,\n                    1895,\n                    1867,\n                    1835,\n                    1804,\n                    1779,\n                    1754,\n                    1720,\n                    1726,\n                    1739,\n                    1740,\n                    1735,\n                    1701,\n                    1635,\n                    1587,\n                    1578,\n                    1587,\n                    1564,\n                    1550,\n                    1543,\n                    1562,\n                    1579,\n                    1578,\n                    1581,\n                    1584,\n                    1589,\n                    1601,\n                    1610,\n                    1621,\n                    1637,\n                    1642,\n                    1659,\n                    1673,\n                    1681,\n                    1673,\n                    1671,\n                    1664,\n                    1671,\n                    1681,\n                    1728,\n                    1734,\n                    1789,\n                    1854,\n                    1807,\n                    1820,\n                    1778,\n                    1778,\n                    1717,\n                    1642,\n                    1635,\n                    1600,\n                    1520,\n                    1454,\n                    1415,\n                    1395\n                ]\n            ],\n            \"id\": 10128340000,\n            \"width\": 1920,\n            \"height\": 1080,\n            \"mask_file\": \"mask/val/012834_mpii_test/000000.jpg\"\n        },\n        {\n            \"has_no_densepose\": true,\n            \"is_labeled\": true,\n            \"file_name\": \"images/val/009473_mpii_test/000000.jpg\",\n            \"nframes\": 101,\n            \"frame_id\": 10094730000,\n            \"vid_id\": \"009473\",\n            \"ignore_regions_y\": [\n                [\n                    228,\n                    237,\n                    243,\n                    230,\n                    220,\n                    230,\n                    228,\n                    232,\n                    220,\n                    211,\n                    226,\n                    258,\n                    364,\n                    417,\n                    475,\n                    562,\n                    615,\n                    646,\n                    656,\n                    637,\n                    649,\n                    645,\n                    603,\n                    585,\n                    547\n                ],\n                [\n                    0,\n                    1,\n                    137,\n                    130,\n                    166,\n                    235,\n                    309,\n                    384,\n                    452,\n                    526,\n                    583,\n                    658,\n                    694,\n                    709,\n                    599,\n                    684,\n                    707,\n                    733,\n                    660,\n                    679,\n                    762\n                ]\n            ],\n            \"ignore_regions_x\": [\n                [\n                    1907,\n                    1820,\n                    1758,\n                    1662,\n                    1577,\n                    1492,\n                    1375,\n                    1305,\n                    1250,\n                    1177,\n                    1111,\n                    1033,\n                    1047,\n                    1062,\n                    1056,\n                    1130,\n                    1173,\n                    1232,\n                    1282,\n                    1332,\n                    1416,\n                    1471,\n                    1515,\n                    1541,\n                    1909\n                ],\n                [\n                    0,\n                    257,\n                    284,\n                    407,\n                    450,\n                    505,\n                    562,\n                    592,\n                    613,\n                    626,\n                    639,\n                    639,\n                    594,\n                    454,\n                    371,\n                    343,\n                    269,\n                    152,\n                    88,\n                    35,\n                    3\n                ]\n            ],\n            \"id\": 10094730000,\n            \"width\": 1920,\n            \"height\": 1080,\n            \"mask_file\": \"mask/val/009473_mpii_test/000000.jpg\"\n        },\n        {\n            \"has_no_densepose\": true,\n            \"is_labeled\": true,\n            \"file_name\": \"images/val/003418_mpii_test/000000.jpg\",\n            \"nframes\": 149,\n            \"frame_id\": 10034180000,\n            \"vid_id\": \"003418\",\n            \"ignore_regions_y\": [\n                [\n                    639,\n                    647,\n                    635,\n                    618,\n                    590,\n                    547,\n                    501,\n                    499,\n                    515,\n                    518,\n                    526,\n                    528,\n                    509,\n                    473,\n                    450,\n                    407,\n                    352,\n                    339,\n                    309,\n                    271,\n                    262,\n                    252,\n                    211,\n                    211,\n                    183,\n                    175,\n                    139,\n                    105,\n                    94,\n                    62,\n                    45,\n                    22,\n                    22,\n                    30,\n                    52,\n                    66,\n                    86,\n                    92,\n                    101,\n                    109,\n                    162,\n                    158,\n                    135,\n                    103,\n                    94,\n                    75,\n                    60,\n                    37,\n                    18,\n                    9,\n                    1,\n                    0,\n                    79,\n                    75,\n                    88,\n                    103,\n                    156,\n                    164,\n                    167,\n                    201,\n                    196,\n                    194,\n                    207,\n                    237,\n                    262,\n                    256\n                ],\n                [\n                    94,\n                    71,\n                    62,\n                    41,\n                    28,\n                    30,\n                    43,\n                    64,\n                    88,\n                    96,\n                    120,\n                    115,\n                    98\n                ],\n                [\n                    235,\n                    215,\n                    211,\n                    224,\n                    252,\n                    239,\n                    207,\n                    196,\n                    211,\n                    228,\n                    218,\n                    198,\n                    181,\n                    186,\n                    198,\n                    218,\n                    233,\n                    252,\n                    277,\n                    279,\n                    292,\n                    318,\n                    347,\n                    354,\n                    392,\n                    430,\n                    439,\n                    447,\n                    462,\n                    477,\n                    496,\n                    539,\n                    515,\n                    464,\n                    426,\n                    398,\n                    366,\n                    333,\n                    322,\n                    315,\n                    318,\n                    303,\n                    298,\n                    294,\n                    266,\n                    245\n                ],\n                [\n                    207,\n                    213,\n                    239,\n                    237,\n                    215,\n                    179,\n                    179,\n                    184,\n                    209,\n                    222,\n                    239,\n                    264,\n                    279,\n                    271,\n                    269,\n                    290,\n                    260,\n                    226\n                ],\n                [\n                    194,\n                    175,\n                    160,\n                    164,\n                    179,\n                    167,\n                    160,\n                    216,\n                    266,\n                    262,\n                    266,\n                    269,\n                    281,\n                    298,\n                    309,\n                    318,\n                    332,\n                    341,\n                    345,\n                    345,\n                    290,\n                    262,\n                    226\n                ],\n                [\n                    424,\n                    442,\n                    432,\n                    432,\n                    455,\n                    469,\n                    474,\n                    505,\n                    559,\n                    555,\n                    465,\n                    449,\n                    444\n                ],\n                [\n                    926,\n                    901,\n                    857,\n                    792,\n                    751,\n                    694,\n                    636,\n                    540,\n                    474,\n                    403,\n                    351,\n                    265,\n                    211,\n                    155,\n                    98,\n                    71,\n                    40,\n                    0,\n                    0,\n                    1078,\n                    1078,\n                    1007,\n                    924,\n                    869,\n                    807,\n                    865,\n                    892,\n                    955,\n                    1003,\n                    1057,\n                    1078,\n                    1078,\n                    1030,\n                    961,\n                    926\n                ],\n                [\n                    1050,\n                    1076,\n                    1078,\n                    1057,\n                    1032,\n                    1013,\n                    998,\n                    982,\n                    971,\n                    951,\n                    936,\n                    913,\n                    888,\n                    844,\n                    799,\n                    763,\n                    732,\n                    723,\n                    713,\n                    753,\n                    784,\n                    817,\n                    830,\n                    871,\n                    911,\n                    930\n                ],\n                [\n                    478,\n                    461,\n                    423,\n                    405,\n                    394,\n                    263,\n                    257,\n                    265,\n                    290,\n                    315,\n                    334,\n                    342,\n                    344,\n                    411,\n                    448,\n                    448,\n                    448,\n                    430,\n                    424,\n                    423,\n                    421,\n                    409,\n                    444\n                ]\n            ],\n            \"ignore_regions_x\": [\n                [\n                    0,\n                    1,\n                    198,\n                    258,\n                    307,\n                    337,\n                    343,\n                    335,\n                    320,\n                    290,\n                    273,\n                    260,\n                    232,\n                    190,\n                    196,\n                    183,\n                    171,\n                    162,\n                    149,\n                    132,\n                    105,\n                    77,\n                    69,\n                    322,\n                    324,\n                    303,\n                    279,\n                    273,\n                    247,\n                    224,\n                    226,\n                    215,\n                    203,\n                    190,\n                    192,\n                    181,\n                    169,\n                    167,\n                    154,\n                    139,\n                    99,\n                    86,\n                    81,\n                    56,\n                    60,\n                    62,\n                    60,\n                    49,\n                    35,\n                    15,\n                    9,\n                    3,\n                    0,\n                    11,\n                    13,\n                    0,\n                    1,\n                    9,\n                    90,\n                    64,\n                    49,\n                    33,\n                    18,\n                    13,\n                    15,\n                    0\n                ],\n                [\n                    341,\n                    347,\n                    352,\n                    356,\n                    371,\n                    383,\n                    388,\n                    392,\n                    403,\n                    392,\n                    398,\n                    377,\n                    375\n                ],\n                [\n                    688,\n                    694,\n                    713,\n                    724,\n                    728,\n                    752,\n                    764,\n                    783,\n                    796,\n                    796,\n                    824,\n                    828,\n                    839,\n                    856,\n                    864,\n                    864,\n                    884,\n                    899,\n                    903,\n                    843,\n                    854,\n                    854,\n                    850,\n                    884,\n                    901,\n                    873,\n                    833,\n                    815,\n                    796,\n                    747,\n                    716,\n                    666,\n                    654,\n                    660,\n                    667,\n                    694,\n                    711,\n                    724,\n                    737,\n                    775,\n                    792,\n                    790,\n                    756,\n                    688,\n                    686,\n                    686\n                ],\n                [\n                    1047,\n                    1079,\n                    1079,\n                    1088,\n                    1099,\n                    1103,\n                    1122,\n                    1133,\n                    1141,\n                    1164,\n                    1175,\n                    1164,\n                    1181,\n                    1126,\n                    1092,\n                    1077,\n                    1069,\n                    1047\n                ],\n                [\n                    1252,\n                    1254,\n                    1258,\n                    1277,\n                    1292,\n                    1301,\n                    1322,\n                    1330,\n                    1350,\n                    1322,\n                    1296,\n                    1277,\n                    1256,\n                    1233,\n                    1213,\n                    1198,\n                    1173,\n                    1130,\n                    1098,\n                    1081,\n                    1101,\n                    1198,\n                    1232\n                ],\n                [\n                    1165,\n                    1184,\n                    1226,\n                    1246,\n                    1238,\n                    1226,\n                    1209,\n                    1215,\n                    1180,\n                    1126,\n                    1057,\n                    1053,\n                    1128\n                ],\n                [\n                    1455,\n                    1438,\n                    1438,\n                    1444,\n                    1442,\n                    1423,\n                    1426,\n                    1409,\n                    1399,\n                    1390,\n                    1374,\n                    1349,\n                    1330,\n                    1319,\n                    1307,\n                    1309,\n                    1324,\n                    1330,\n                    1919,\n                    1919,\n                    1884,\n                    1855,\n                    1830,\n                    1828,\n                    1776,\n                    1732,\n                    1734,\n                    1726,\n                    1728,\n                    1707,\n                    1713,\n                    1469,\n                    1461,\n                    1459,\n                    1455\n                ],\n                [\n                    1463,\n                    1411,\n                    1255,\n                    1250,\n                    1246,\n                    1261,\n                    1284,\n                    1280,\n                    1271,\n                    1265,\n                    1275,\n                    1299,\n                    1299,\n                    1296,\n                    1315,\n                    1340,\n                    1365,\n                    1396,\n                    1444,\n                    1428,\n                    1434,\n                    1432,\n                    1446,\n                    1440,\n                    1453,\n                    1455\n                ],\n                [\n                    1246,\n                    1271,\n                    1313,\n                    1344,\n                    1384,\n                    1346,\n                    1307,\n                    1286,\n                    1255,\n                    1203,\n                    1153,\n                    1096,\n                    1078,\n                    1061,\n                    1036,\n                    1090,\n                    1121,\n                    1148,\n                    1169,\n                    1205,\n                    1228,\n                    1265,\n                    1267\n                ]\n            ],\n            \"id\": 10034180000,\n            \"width\": 1920,\n            \"height\": 1080,\n            \"mask_file\": \"mask/val/003418_mpii_test/000000.jpg\"\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox_head\": [\n                378,\n                503,\n                44,\n                53\n            ],\n            \"keypoints\": [\n                401,\n                530,\n                1,\n                409.5254211,\n                555.3547363,\n                1,\n                392.8559265,\n                510.1089478,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                377,\n                560,\n                1,\n                444,\n                556,\n                1,\n                353,\n                605,\n                1,\n                469.5,\n                603.5,\n                1,\n                341.5,\n                653.5,\n                1,\n                463,\n                635,\n                1,\n                389,\n                652,\n                1,\n                442,\n                646,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                322.3,\n                488.60028996999995,\n                166.39999999999998,\n                186.40836786\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000000,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        },\n        {\n            \"bbox_head\": [\n                571,\n                446,\n                42,\n                46\n            ],\n            \"keypoints\": [\n                600.5,\n                475.5,\n                1,\n                590.4649048,\n                493.8685303,\n                1,\n                593.1513062,\n                450.3486023,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                570.5,\n                509.5,\n                1,\n                608.5,\n                509.5,\n                1,\n                539,\n                558.5,\n                1,\n                634,\n                539,\n                1,\n                558.5,\n                584.5,\n                1,\n                624.5,\n                528.5,\n                1,\n                605,\n                595,\n                1,\n                601,\n                593,\n                1,\n                640,\n                634.5,\n                1,\n                598,\n                672,\n                1,\n                616.5,\n                700.5,\n                1,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 1,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                523.85,\n                412.825892645,\n                131.29999999999995,\n                325.19681700999996\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000001,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                159,\n                259,\n                42,\n                47\n            ],\n            \"keypoints\": [\n                201,\n                284.5,\n                1,\n                169.9334106,\n                305.6158752,\n                1,\n                187.549942,\n                265.1630859,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                139.5,\n                307.5,\n                1,\n                193.5,\n                319.5,\n                1,\n                0,\n                0,\n                0,\n                209,\n                371,\n                1,\n                144,\n                365.5,\n                1,\n                231,\n                392,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                222,\n                337,\n                1,\n                241,\n                341.5,\n                1,\n                0,\n                0,\n                0,\n                267,\n                416,\n                1\n            ],\n            \"track_id\": 2,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                120.375,\n                242.53754878499996,\n                165.75,\n                196.08798833000003\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000002,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        },\n        {\n            \"bbox_head\": [\n                372,\n                205,\n                44,\n                44\n            ],\n            \"keypoints\": [\n                410.5,\n                230.5,\n                1,\n                387.8875732,\n                251.1279602,\n                1,\n                398.5843201,\n                208.9040375,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                359.5,\n                262.5,\n                1,\n                409.5,\n                266.5,\n                1,\n                337.5,\n                308.5,\n                1,\n                450,\n                306,\n                1,\n                292,\n                314,\n                1,\n                480,\n                311.5,\n                1,\n                390,\n                339,\n                1,\n                409,\n                339,\n                1,\n                405.5,\n                418.5,\n                1,\n                447.5,\n                366.5,\n                1,\n                391.5,\n                464.5,\n                1,\n                437.5,\n                440.5,\n                1\n            ],\n            \"track_id\": 3,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                263.8,\n                170.56464312499998,\n                244.39999999999998,\n                332.27475125\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000003,\n            \"iscrowd\": false,\n            \"num_keypoints\": 15\n        },\n        {\n            \"bbox_head\": [\n                693,\n                410,\n                44,\n                49\n            ],\n            \"keypoints\": [\n                718.5,\n                440.5,\n                1,\n                717.704834,\n                460.703125,\n                1,\n                712.9713745,\n                414.8476562,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                694.5,\n                474,\n                1,\n                743.5,\n                472.5,\n                1,\n                681.5,\n                530.5,\n                1,\n                757.5,\n                523.5,\n                1,\n                667.5,\n                564.5,\n                1,\n                0,\n                0,\n                0,\n                705.5,\n                563.5,\n                1,\n                737.5,\n                560.5,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                692.5,\n                607.5,\n                1,\n                716.5,\n                603.5,\n                1\n            ],\n            \"track_id\": 4,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                654.0,\n                385.94980463,\n                117.0,\n                250.44804694000004\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000004,\n            \"iscrowd\": false,\n            \"num_keypoints\": 12\n        },\n        {\n            \"bbox_head\": [\n                923,\n                347,\n                46,\n                58\n            ],\n            \"keypoints\": [\n                965.5,\n                382.5,\n                1,\n                933.9436646,\n                403.0452576,\n                1,\n                955.0422363,\n                355.7160645,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                922.5,\n                403.5,\n                1,\n                932.5,\n                431.5,\n                1,\n                0,\n                0,\n                0,\n                960,\n                475.5,\n                1,\n                0,\n                0,\n                0,\n                991.5,\n                462.5,\n                1,\n                934.5,\n                512.5,\n                1,\n                922.5,\n                506.5,\n                1,\n                946.5,\n                567.5,\n                1,\n                964,\n                578,\n                1,\n                900.5,\n                598,\n                1,\n                936,\n                634.5,\n                1\n            ],\n            \"track_id\": 5,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                886.85,\n                313.89847417500005,\n                118.29999999999995,\n                362.4191161499999\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000005,\n            \"iscrowd\": false,\n            \"num_keypoints\": 13\n        },\n        {\n            \"bbox_head\": [\n                691,\n                179,\n                43,\n                52\n            ],\n            \"keypoints\": [\n                708.5,\n                212.5,\n                1,\n                722.6444702,\n                230.0113831,\n                1,\n                704.8916626,\n                186.2414551,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                712,\n                244,\n                1,\n                742,\n                237.5,\n                1,\n                723,\n                293.5,\n                1,\n                745.5,\n                281.5,\n                1,\n                692,\n                319,\n                1,\n                0,\n                0,\n                0,\n                722,\n                323.5,\n                1,\n                748.5,\n                314,\n                1,\n                657.5,\n                301.5,\n                1,\n                668.5,\n                299.5,\n                1,\n                670.5,\n                367.5,\n                1,\n                689.5,\n                362.5,\n                1\n            ],\n            \"track_id\": 6,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                643.85,\n                159.05267336499998,\n                118.29999999999995,\n                235.63610837\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000006,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                927,\n                160,\n                39,\n                52\n            ],\n            \"keypoints\": [\n                952,\n                189,\n                1,\n                946.763916,\n                211.9986572,\n                1,\n                946.302063,\n                166.5010071,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                914.5,\n                234,\n                1,\n                979.5,\n                236.5,\n                1,\n                890.5,\n                270.5,\n                1,\n                998.5,\n                286.5,\n                1,\n                894.5,\n                324,\n                1,\n                0,\n                0,\n                0,\n                932,\n                326.5,\n                1,\n                958.5,\n                327.5,\n                1,\n                1000.5,\n                340.5,\n                1,\n                993.5,\n                372.5,\n                1,\n                955.5,\n                383.5,\n                1,\n                959.5,\n                446.5,\n                1\n            ],\n            \"track_id\": 7,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                874.0,\n                124.50115816500005,\n                143.0,\n                363.99869076999994\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000007,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                1367,\n                427,\n                47,\n                45\n            ],\n            \"keypoints\": [\n                1406,\n                451,\n                1,\n                1379.198608,\n                472.946106,\n                1,\n                1398.976074,\n                431.9154358,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                1375.5,\n                467.5,\n                1,\n                1372,\n                501,\n                1,\n                0,\n                0,\n                0,\n                1343.5,\n                534.5,\n                1,\n                0,\n                0,\n                0,\n                1339.5,\n                573.5,\n                1,\n                1381.5,\n                531.5,\n                1,\n                1376,\n                539.5,\n                1,\n                1452.5,\n                524.5,\n                1,\n                1453.5,\n                535.5,\n                1,\n                1469.5,\n                603.5,\n                1,\n                1466,\n                610,\n                1\n            ],\n            \"track_id\": 8,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                1320.0,\n                405.20275117000006,\n                169.0,\n                231.50993345999996\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000008,\n            \"iscrowd\": false,\n            \"num_keypoints\": 13\n        },\n        {\n            \"bbox_head\": [\n                1378,\n                204,\n                40,\n                44\n            ],\n            \"keypoints\": [\n                1389,\n                234,\n                1,\n                1404.137573,\n                248.9802094,\n                1,\n                1393.396851,\n                208.7648468,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                1375,\n                272,\n                1,\n                1442.5,\n                260.5,\n                1,\n                1374,\n                315,\n                1,\n                1468,\n                303.5,\n                1,\n                1367,\n                340.5,\n                1,\n                1462.5,\n                330.5,\n                1,\n                1407,\n                349.5,\n                1,\n                1439,\n                340.5,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 9,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                1351.85,\n                187.65457382,\n                131.30000000000018,\n                182.95569916\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000009,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        },\n        {\n            \"bbox_head\": [\n                407,\n                -29,\n                35,\n                40\n            ],\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                425.1159668,\n                12.25136662,\n                1,\n                424.0380249,\n                -24.93852425,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                455.5,\n                21.5,\n                1,\n                395.5,\n                29.5,\n                1,\n                474.5,\n                64.5,\n                1,\n                391.5,\n                67,\n                1,\n                474,\n                108,\n                1,\n                379,\n                107,\n                1,\n                446,\n                88,\n                1,\n                426,\n                88,\n                1,\n                424,\n                113,\n                1,\n                403,\n                113,\n                1,\n                430,\n                173,\n                1,\n                415,\n                171,\n                1\n            ],\n            \"track_id\": 10,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                364.675,\n                -54.62930288750002,\n                124.14999999999998,\n                257.32008152500003\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000010,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                648,\n                253,\n                138,\n                103\n            ],\n            \"keypoints\": [\n                750,\n                297.5,\n                1,\n                734.1937256,\n                371.1997375,\n                1,\n                704.1047363,\n                254.4751892,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                697,\n                352.5,\n                1,\n                766,\n                369,\n                1,\n                0,\n                0,\n                0,\n                857,\n                419,\n                1,\n                766,\n                281,\n                1,\n                942,\n                422.5,\n                1,\n                722,\n                525,\n                1,\n                792,\n                544,\n                1,\n                783,\n                697,\n                1,\n                755,\n                699,\n                1,\n                808.5,\n                832.5,\n                1,\n                672,\n                782.5,\n                1\n            ],\n            \"track_id\": 0,\n            \"image_id\": 10094730000,\n            \"bbox\": [\n                631.5,\n                167.77146757999992,\n                351.0,\n                751.4322540400001\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1009473000000,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                878,\n                201,\n                90,\n                125\n            ],\n            \"keypoints\": [\n                900,\n                272,\n                1,\n                905.657959,\n                322.6206665,\n                1,\n                936.0065308,\n                219.1595001,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                950,\n                366,\n                1,\n                852,\n                311,\n                1,\n                1021,\n                428,\n                1,\n                759,\n                303,\n                1,\n                986,\n                422,\n                1,\n                704,\n                374,\n                1,\n                912,\n                516,\n                1,\n                856,\n                524,\n                1,\n                876,\n                663,\n                1,\n                908,\n                680,\n                1,\n                849,\n                828,\n                1,\n                959,\n                804,\n                1\n            ],\n            \"track_id\": 1,\n            \"image_id\": 10094730000,\n            \"bbox\": [\n                656.45,\n                127.83342511500007,\n                412.0999999999999,\n                791.4926498699999\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1009473000001,\n            \"iscrowd\": false,\n            \"num_keypoints\": 15\n        },\n        {\n            \"bbox_head\": [\n                346,\n                337,\n                296,\n                237\n            ],\n            \"keypoints\": [\n                621,\n                471,\n                1,\n                542.2835693,\n                599.2855835,\n                1,\n                457.787323,\n                347.6607971,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                371,\n                737,\n                1,\n                753,\n                579,\n                1,\n                387,\n                981,\n                1,\n                1023,\n                353,\n                1,\n                0,\n                0,\n                0,\n                953,\n                141,\n                1,\n                968,\n                833,\n                1,\n                1152,\n                843,\n                1,\n                0,\n                0,\n                0,\n                1416,\n                429,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 10034180000,\n            \"bbox\": [\n                214.25,\n                15.0,\n                1358.5,\n                1092.0\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1003418000000,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/posetrack18/annotations/val/003418_mpii_test.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"head_bottom\",\n                \"head_top\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"has_no_densepose\": true,\n            \"is_labeled\": true,\n            \"file_name\": \"images/val/003418_mpii_test/000000.jpg\",\n            \"nframes\": 149,\n            \"frame_id\": 10034180000,\n            \"vid_id\": \"003418\",\n            \"ignore_regions_y\": [\n                [\n                    639,\n                    647,\n                    635,\n                    618,\n                    590,\n                    547,\n                    501,\n                    499,\n                    515,\n                    518,\n                    526,\n                    528,\n                    509,\n                    473,\n                    450,\n                    407,\n                    352,\n                    339,\n                    309,\n                    271,\n                    262,\n                    252,\n                    211,\n                    211,\n                    183,\n                    175,\n                    139,\n                    105,\n                    94,\n                    62,\n                    45,\n                    22,\n                    22,\n                    30,\n                    52,\n                    66,\n                    86,\n                    92,\n                    101,\n                    109,\n                    162,\n                    158,\n                    135,\n                    103,\n                    94,\n                    75,\n                    60,\n                    37,\n                    18,\n                    9,\n                    1,\n                    0,\n                    79,\n                    75,\n                    88,\n                    103,\n                    156,\n                    164,\n                    167,\n                    201,\n                    196,\n                    194,\n                    207,\n                    237,\n                    262,\n                    256\n                ],\n                [\n                    94,\n                    71,\n                    62,\n                    41,\n                    28,\n                    30,\n                    43,\n                    64,\n                    88,\n                    96,\n                    120,\n                    115,\n                    98\n                ],\n                [\n                    235,\n                    215,\n                    211,\n                    224,\n                    252,\n                    239,\n                    207,\n                    196,\n                    211,\n                    228,\n                    218,\n                    198,\n                    181,\n                    186,\n                    198,\n                    218,\n                    233,\n                    252,\n                    277,\n                    279,\n                    292,\n                    318,\n                    347,\n                    354,\n                    392,\n                    430,\n                    439,\n                    447,\n                    462,\n                    477,\n                    496,\n                    539,\n                    515,\n                    464,\n                    426,\n                    398,\n                    366,\n                    333,\n                    322,\n                    315,\n                    318,\n                    303,\n                    298,\n                    294,\n                    266,\n                    245\n                ],\n                [\n                    207,\n                    213,\n                    239,\n                    237,\n                    215,\n                    179,\n                    179,\n                    184,\n                    209,\n                    222,\n                    239,\n                    264,\n                    279,\n                    271,\n                    269,\n                    290,\n                    260,\n                    226\n                ],\n                [\n                    194,\n                    175,\n                    160,\n                    164,\n                    179,\n                    167,\n                    160,\n                    216,\n                    266,\n                    262,\n                    266,\n                    269,\n                    281,\n                    298,\n                    309,\n                    318,\n                    332,\n                    341,\n                    345,\n                    345,\n                    290,\n                    262,\n                    226\n                ],\n                [\n                    424,\n                    442,\n                    432,\n                    432,\n                    455,\n                    469,\n                    474,\n                    505,\n                    559,\n                    555,\n                    465,\n                    449,\n                    444\n                ],\n                [\n                    926,\n                    901,\n                    857,\n                    792,\n                    751,\n                    694,\n                    636,\n                    540,\n                    474,\n                    403,\n                    351,\n                    265,\n                    211,\n                    155,\n                    98,\n                    71,\n                    40,\n                    0,\n                    0,\n                    1078,\n                    1078,\n                    1007,\n                    924,\n                    869,\n                    807,\n                    865,\n                    892,\n                    955,\n                    1003,\n                    1057,\n                    1078,\n                    1078,\n                    1030,\n                    961,\n                    926\n                ],\n                [\n                    1050,\n                    1076,\n                    1078,\n                    1057,\n                    1032,\n                    1013,\n                    998,\n                    982,\n                    971,\n                    951,\n                    936,\n                    913,\n                    888,\n                    844,\n                    799,\n                    763,\n                    732,\n                    723,\n                    713,\n                    753,\n                    784,\n                    817,\n                    830,\n                    871,\n                    911,\n                    930\n                ],\n                [\n                    478,\n                    461,\n                    423,\n                    405,\n                    394,\n                    263,\n                    257,\n                    265,\n                    290,\n                    315,\n                    334,\n                    342,\n                    344,\n                    411,\n                    448,\n                    448,\n                    448,\n                    430,\n                    424,\n                    423,\n                    421,\n                    409,\n                    444\n                ]\n            ],\n            \"ignore_regions_x\": [\n                [\n                    0,\n                    1,\n                    198,\n                    258,\n                    307,\n                    337,\n                    343,\n                    335,\n                    320,\n                    290,\n                    273,\n                    260,\n                    232,\n                    190,\n                    196,\n                    183,\n                    171,\n                    162,\n                    149,\n                    132,\n                    105,\n                    77,\n                    69,\n                    322,\n                    324,\n                    303,\n                    279,\n                    273,\n                    247,\n                    224,\n                    226,\n                    215,\n                    203,\n                    190,\n                    192,\n                    181,\n                    169,\n                    167,\n                    154,\n                    139,\n                    99,\n                    86,\n                    81,\n                    56,\n                    60,\n                    62,\n                    60,\n                    49,\n                    35,\n                    15,\n                    9,\n                    3,\n                    0,\n                    11,\n                    13,\n                    0,\n                    1,\n                    9,\n                    90,\n                    64,\n                    49,\n                    33,\n                    18,\n                    13,\n                    15,\n                    0\n                ],\n                [\n                    341,\n                    347,\n                    352,\n                    356,\n                    371,\n                    383,\n                    388,\n                    392,\n                    403,\n                    392,\n                    398,\n                    377,\n                    375\n                ],\n                [\n                    688,\n                    694,\n                    713,\n                    724,\n                    728,\n                    752,\n                    764,\n                    783,\n                    796,\n                    796,\n                    824,\n                    828,\n                    839,\n                    856,\n                    864,\n                    864,\n                    884,\n                    899,\n                    903,\n                    843,\n                    854,\n                    854,\n                    850,\n                    884,\n                    901,\n                    873,\n                    833,\n                    815,\n                    796,\n                    747,\n                    716,\n                    666,\n                    654,\n                    660,\n                    667,\n                    694,\n                    711,\n                    724,\n                    737,\n                    775,\n                    792,\n                    790,\n                    756,\n                    688,\n                    686,\n                    686\n                ],\n                [\n                    1047,\n                    1079,\n                    1079,\n                    1088,\n                    1099,\n                    1103,\n                    1122,\n                    1133,\n                    1141,\n                    1164,\n                    1175,\n                    1164,\n                    1181,\n                    1126,\n                    1092,\n                    1077,\n                    1069,\n                    1047\n                ],\n                [\n                    1252,\n                    1254,\n                    1258,\n                    1277,\n                    1292,\n                    1301,\n                    1322,\n                    1330,\n                    1350,\n                    1322,\n                    1296,\n                    1277,\n                    1256,\n                    1233,\n                    1213,\n                    1198,\n                    1173,\n                    1130,\n                    1098,\n                    1081,\n                    1101,\n                    1198,\n                    1232\n                ],\n                [\n                    1165,\n                    1184,\n                    1226,\n                    1246,\n                    1238,\n                    1226,\n                    1209,\n                    1215,\n                    1180,\n                    1126,\n                    1057,\n                    1053,\n                    1128\n                ],\n                [\n                    1455,\n                    1438,\n                    1438,\n                    1444,\n                    1442,\n                    1423,\n                    1426,\n                    1409,\n                    1399,\n                    1390,\n                    1374,\n                    1349,\n                    1330,\n                    1319,\n                    1307,\n                    1309,\n                    1324,\n                    1330,\n                    1919,\n                    1919,\n                    1884,\n                    1855,\n                    1830,\n                    1828,\n                    1776,\n                    1732,\n                    1734,\n                    1726,\n                    1728,\n                    1707,\n                    1713,\n                    1469,\n                    1461,\n                    1459,\n                    1455\n                ],\n                [\n                    1463,\n                    1411,\n                    1255,\n                    1250,\n                    1246,\n                    1261,\n                    1284,\n                    1280,\n                    1271,\n                    1265,\n                    1275,\n                    1299,\n                    1299,\n                    1296,\n                    1315,\n                    1340,\n                    1365,\n                    1396,\n                    1444,\n                    1428,\n                    1434,\n                    1432,\n                    1446,\n                    1440,\n                    1453,\n                    1455\n                ],\n                [\n                    1246,\n                    1271,\n                    1313,\n                    1344,\n                    1384,\n                    1346,\n                    1307,\n                    1286,\n                    1255,\n                    1203,\n                    1153,\n                    1096,\n                    1078,\n                    1061,\n                    1036,\n                    1090,\n                    1121,\n                    1148,\n                    1169,\n                    1205,\n                    1228,\n                    1265,\n                    1267\n                ]\n            ],\n            \"id\": 10034180000,\n            \"width\": 1920,\n            \"height\": 1080,\n            \"mask_file\": \"mask/val/003418_mpii_test/000000.jpg\"\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox_head\": [\n                346,\n                337,\n                296,\n                237\n            ],\n            \"keypoints\": [\n                621,\n                471,\n                1,\n                542.2835693,\n                599.2855835,\n                1,\n                457.787323,\n                347.6607971,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                371,\n                737,\n                1,\n                753,\n                579,\n                1,\n                387,\n                981,\n                1,\n                1023,\n                353,\n                1,\n                0,\n                0,\n                0,\n                953,\n                141,\n                1,\n                968,\n                833,\n                1,\n                1152,\n                843,\n                1,\n                0,\n                0,\n                0,\n                1416,\n                429,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 10034180000,\n            \"bbox\": [\n                214.25,\n                15.0,\n                1358.5,\n                1092.0\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1003418000000,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/posetrack18/annotations/val/009473_mpii_test.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"head_bottom\",\n                \"head_top\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"has_no_densepose\": true,\n            \"is_labeled\": true,\n            \"file_name\": \"images/val/009473_mpii_test/000000.jpg\",\n            \"nframes\": 101,\n            \"frame_id\": 10094730000,\n            \"vid_id\": \"009473\",\n            \"ignore_regions_y\": [\n                [\n                    228,\n                    237,\n                    243,\n                    230,\n                    220,\n                    230,\n                    228,\n                    232,\n                    220,\n                    211,\n                    226,\n                    258,\n                    364,\n                    417,\n                    475,\n                    562,\n                    615,\n                    646,\n                    656,\n                    637,\n                    649,\n                    645,\n                    603,\n                    585,\n                    547\n                ],\n                [\n                    0,\n                    1,\n                    137,\n                    130,\n                    166,\n                    235,\n                    309,\n                    384,\n                    452,\n                    526,\n                    583,\n                    658,\n                    694,\n                    709,\n                    599,\n                    684,\n                    707,\n                    733,\n                    660,\n                    679,\n                    762\n                ]\n            ],\n            \"ignore_regions_x\": [\n                [\n                    1907,\n                    1820,\n                    1758,\n                    1662,\n                    1577,\n                    1492,\n                    1375,\n                    1305,\n                    1250,\n                    1177,\n                    1111,\n                    1033,\n                    1047,\n                    1062,\n                    1056,\n                    1130,\n                    1173,\n                    1232,\n                    1282,\n                    1332,\n                    1416,\n                    1471,\n                    1515,\n                    1541,\n                    1909\n                ],\n                [\n                    0,\n                    257,\n                    284,\n                    407,\n                    450,\n                    505,\n                    562,\n                    592,\n                    613,\n                    626,\n                    639,\n                    639,\n                    594,\n                    454,\n                    371,\n                    343,\n                    269,\n                    152,\n                    88,\n                    35,\n                    3\n                ]\n            ],\n            \"id\": 10094730000,\n            \"width\": 1920,\n            \"height\": 1080,\n            \"mask_file\": \"mask/val/009473_mpii_test/000000.jpg\"\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox_head\": [\n                648,\n                253,\n                138,\n                103\n            ],\n            \"keypoints\": [\n                750,\n                297.5,\n                1,\n                734.1937256,\n                371.1997375,\n                1,\n                704.1047363,\n                254.4751892,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                697,\n                352.5,\n                1,\n                766,\n                369,\n                1,\n                0,\n                0,\n                0,\n                857,\n                419,\n                1,\n                766,\n                281,\n                1,\n                942,\n                422.5,\n                1,\n                722,\n                525,\n                1,\n                792,\n                544,\n                1,\n                783,\n                697,\n                1,\n                755,\n                699,\n                1,\n                808.5,\n                832.5,\n                1,\n                672,\n                782.5,\n                1\n            ],\n            \"track_id\": 0,\n            \"image_id\": 10094730000,\n            \"bbox\": [\n                631.5,\n                167.77146757999992,\n                351.0,\n                751.4322540400001\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1009473000000,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                878,\n                201,\n                90,\n                125\n            ],\n            \"keypoints\": [\n                900,\n                272,\n                1,\n                905.657959,\n                322.6206665,\n                1,\n                936.0065308,\n                219.1595001,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                950,\n                366,\n                1,\n                852,\n                311,\n                1,\n                1021,\n                428,\n                1,\n                759,\n                303,\n                1,\n                986,\n                422,\n                1,\n                704,\n                374,\n                1,\n                912,\n                516,\n                1,\n                856,\n                524,\n                1,\n                876,\n                663,\n                1,\n                908,\n                680,\n                1,\n                849,\n                828,\n                1,\n                959,\n                804,\n                1\n            ],\n            \"track_id\": 1,\n            \"image_id\": 10094730000,\n            \"bbox\": [\n                656.45,\n                127.83342511500007,\n                412.0999999999999,\n                791.4926498699999\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1009473000001,\n            \"iscrowd\": false,\n            \"num_keypoints\": 15\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/posetrack18/annotations/val/012834_mpii_test.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"person\",\n            \"keypoints\": [\n                \"nose\",\n                \"head_bottom\",\n                \"head_top\",\n                \"left_ear\",\n                \"right_ear\",\n                \"left_shoulder\",\n                \"right_shoulder\",\n                \"left_elbow\",\n                \"right_elbow\",\n                \"left_wrist\",\n                \"right_wrist\",\n                \"left_hip\",\n                \"right_hip\",\n                \"left_knee\",\n                \"right_knee\",\n                \"left_ankle\",\n                \"right_ankle\"\n            ],\n            \"skeleton\": [\n                [\n                    16,\n                    14\n                ],\n                [\n                    14,\n                    12\n                ],\n                [\n                    17,\n                    15\n                ],\n                [\n                    15,\n                    13\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    6,\n                    12\n                ],\n                [\n                    7,\n                    13\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    9\n                ],\n                [\n                    8,\n                    10\n                ],\n                [\n                    9,\n                    11\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    1,\n                    2\n                ],\n                [\n                    1,\n                    3\n                ],\n                [\n                    2,\n                    4\n                ],\n                [\n                    3,\n                    5\n                ],\n                [\n                    4,\n                    6\n                ],\n                [\n                    5,\n                    7\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"has_no_densepose\": true,\n            \"is_labeled\": true,\n            \"file_name\": \"images/val/012834_mpii_test/000000.jpg\",\n            \"nframes\": 140,\n            \"frame_id\": 10128340000,\n            \"vid_id\": \"012834\",\n            \"ignore_regions_y\": [\n                [\n                    1079,\n                    615,\n                    612,\n                    674,\n                    660,\n                    664,\n                    678,\n                    713,\n                    704,\n                    667,\n                    665,\n                    678,\n                    700,\n                    729,\n                    753,\n                    740,\n                    695,\n                    668,\n                    646,\n                    623,\n                    624,\n                    659,\n                    676,\n                    685,\n                    695,\n                    678,\n                    675,\n                    673,\n                    663,\n                    693,\n                    703,\n                    732,\n                    719,\n                    690,\n                    669,\n                    660,\n                    660,\n                    663,\n                    689,\n                    697,\n                    691,\n                    697,\n                    713,\n                    736,\n                    721,\n                    703,\n                    698,\n                    708,\n                    741,\n                    758,\n                    778,\n                    795,\n                    780,\n                    757,\n                    745,\n                    737,\n                    745,\n                    782,\n                    809,\n                    850,\n                    881,\n                    835,\n                    810,\n                    806,\n                    782,\n                    782,\n                    806,\n                    832,\n                    863,\n                    897,\n                    940,\n                    931,\n                    957,\n                    976,\n                    1003,\n                    1043,\n                    1045,\n                    1008,\n                    965,\n                    963,\n                    931,\n                    895,\n                    846,\n                    832,\n                    829,\n                    869,\n                    898,\n                    904,\n                    869,\n                    836,\n                    782,\n                    752,\n                    736,\n                    748,\n                    776,\n                    832,\n                    874,\n                    862,\n                    818,\n                    793,\n                    790,\n                    756,\n                    738,\n                    737,\n                    750,\n                    791,\n                    806,\n                    820,\n                    852,\n                    879,\n                    837,\n                    794,\n                    772,\n                    766,\n                    769,\n                    790,\n                    805,\n                    829,\n                    844,\n                    866,\n                    837,\n                    804,\n                    791,\n                    773,\n                    745,\n                    706,\n                    683,\n                    644,\n                    638,\n                    662,\n                    694,\n                    716,\n                    736,\n                    777,\n                    784,\n                    815,\n                    830,\n                    813,\n                    800,\n                    813,\n                    820,\n                    847,\n                    829,\n                    781,\n                    780,\n                    801,\n                    836,\n                    886,\n                    938,\n                    1018,\n                    1029,\n                    1079\n                ],\n                [\n                    0,\n                    21,\n                    43,\n                    60,\n                    90,\n                    95,\n                    95,\n                    43,\n                    40,\n                    84,\n                    104,\n                    104,\n                    74,\n                    6,\n                    4,\n                    71,\n                    69,\n                    0\n                ],\n                [\n                    0,\n                    4,\n                    48,\n                    106,\n                    214,\n                    207,\n                    46,\n                    50,\n                    170,\n                    156,\n                    96,\n                    157,\n                    160,\n                    62,\n                    65,\n                    156,\n                    165,\n                    162,\n                    140,\n                    93,\n                    93,\n                    7,\n                    4,\n                    121,\n                    129,\n                    84,\n                    75,\n                    68\n                ],\n                [\n                    0,\n                    0,\n                    739,\n                    729,\n                    720,\n                    740,\n                    768,\n                    785,\n                    803,\n                    815,\n                    757,\n                    735,\n                    632,\n                    620,\n                    632,\n                    640,\n                    662,\n                    656,\n                    607,\n                    645,\n                    645,\n                    628,\n                    604,\n                    570,\n                    543,\n                    512,\n                    485,\n                    467,\n                    451,\n                    448,\n                    456,\n                    482,\n                    512,\n                    548,\n                    554,\n                    542,\n                    498,\n                    479,\n                    454,\n                    404,\n                    387,\n                    398,\n                    415,\n                    528,\n                    546,\n                    468,\n                    410,\n                    400,\n                    359,\n                    375,\n                    373,\n                    273,\n                    254,\n                    284,\n                    253,\n                    204,\n                    206\n                ]\n            ],\n            \"ignore_regions_x\": [\n                [\n                    3,\n                    0,\n                    30,\n                    44,\n                    74,\n                    99,\n                    106,\n                    102,\n                    115,\n                    121,\n                    141,\n                    156,\n                    165,\n                    187,\n                    200,\n                    211,\n                    196,\n                    198,\n                    210,\n                    226,\n                    252,\n                    266,\n                    263,\n                    271,\n                    291,\n                    299,\n                    326,\n                    339,\n                    360,\n                    399,\n                    412,\n                    424,\n                    437,\n                    432,\n                    439,\n                    461,\n                    489,\n                    510,\n                    534,\n                    548,\n                    559,\n                    567,\n                    587,\n                    593,\n                    604,\n                    612,\n                    633,\n                    652,\n                    645,\n                    638,\n                    649,\n                    650,\n                    661,\n                    654,\n                    662,\n                    685,\n                    713,\n                    727,\n                    733,\n                    752,\n                    762,\n                    769,\n                    785,\n                    812,\n                    841,\n                    863,\n                    869,\n                    877,\n                    899,\n                    909,\n                    918,\n                    906,\n                    902,\n                    909,\n                    917,\n                    900,\n                    932,\n                    932,\n                    941,\n                    919,\n                    926,\n                    935,\n                    950,\n                    957,\n                    983,\n                    1002,\n                    1007,\n                    1032,\n                    1034,\n                    1018,\n                    1018,\n                    1038,\n                    1074,\n                    1106,\n                    1119,\n                    1121,\n                    1130,\n                    1148,\n                    1152,\n                    1172,\n                    1195,\n                    1199,\n                    1209,\n                    1229,\n                    1242,\n                    1240,\n                    1242,\n                    1261,\n                    1264,\n                    1277,\n                    1285,\n                    1286,\n                    1296,\n                    1313,\n                    1336,\n                    1350,\n                    1367,\n                    1403,\n                    1417,\n                    1435,\n                    1459,\n                    1456,\n                    1429,\n                    1420,\n                    1465,\n                    1492,\n                    1496,\n                    1507,\n                    1529,\n                    1553,\n                    1570,\n                    1596,\n                    1609,\n                    1610,\n                    1649,\n                    1671,\n                    1703,\n                    1740,\n                    1763,\n                    1775,\n                    1803,\n                    1809,\n                    1815,\n                    1815,\n                    1857,\n                    1874,\n                    1881,\n                    1897,\n                    1896,\n                    1899,\n                    1888,\n                    1884\n                ],\n                [\n                    378,\n                    381,\n                    365,\n                    359,\n                    334,\n                    292,\n                    257,\n                    262,\n                    231,\n                    236,\n                    219,\n                    193,\n                    196,\n                    183,\n                    154,\n                    159,\n                    140,\n                    121\n                ],\n                [\n                    451,\n                    1173,\n                    1168,\n                    1168,\n                    1170,\n                    1085,\n                    1098,\n                    1070,\n                    1043,\n                    1000,\n                    993,\n                    979,\n                    934,\n                    937,\n                    918,\n                    903,\n                    893,\n                    832,\n                    785,\n                    759,\n                    726,\n                    710,\n                    667,\n                    664,\n                    585,\n                    576,\n                    507,\n                    485\n                ],\n                [\n                    1312,\n                    1918,\n                    1917,\n                    1895,\n                    1867,\n                    1835,\n                    1804,\n                    1779,\n                    1754,\n                    1720,\n                    1726,\n                    1739,\n                    1740,\n                    1735,\n                    1701,\n                    1635,\n                    1587,\n                    1578,\n                    1587,\n                    1564,\n                    1550,\n                    1543,\n                    1562,\n                    1579,\n                    1578,\n                    1581,\n                    1584,\n                    1589,\n                    1601,\n                    1610,\n                    1621,\n                    1637,\n                    1642,\n                    1659,\n                    1673,\n                    1681,\n                    1673,\n                    1671,\n                    1664,\n                    1671,\n                    1681,\n                    1728,\n                    1734,\n                    1789,\n                    1854,\n                    1807,\n                    1820,\n                    1778,\n                    1778,\n                    1717,\n                    1642,\n                    1635,\n                    1600,\n                    1520,\n                    1454,\n                    1415,\n                    1395\n                ]\n            ],\n            \"id\": 10128340000,\n            \"width\": 1920,\n            \"height\": 1080,\n            \"mask_file\": \"mask/val/012834_mpii_test/000000.jpg\"\n        }\n    ],\n    \"annotations\": [\n        {\n            \"bbox_head\": [\n                378,\n                503,\n                44,\n                53\n            ],\n            \"keypoints\": [\n                401,\n                530,\n                1,\n                409.5254211,\n                555.3547363,\n                1,\n                392.8559265,\n                510.1089478,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                377,\n                560,\n                1,\n                444,\n                556,\n                1,\n                353,\n                605,\n                1,\n                469.5,\n                603.5,\n                1,\n                341.5,\n                653.5,\n                1,\n                463,\n                635,\n                1,\n                389,\n                652,\n                1,\n                442,\n                646,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 0,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                322.3,\n                488.60028996999995,\n                166.39999999999998,\n                186.40836786\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000000,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        },\n        {\n            \"bbox_head\": [\n                571,\n                446,\n                42,\n                46\n            ],\n            \"keypoints\": [\n                600.5,\n                475.5,\n                1,\n                590.4649048,\n                493.8685303,\n                1,\n                593.1513062,\n                450.3486023,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                570.5,\n                509.5,\n                1,\n                608.5,\n                509.5,\n                1,\n                539,\n                558.5,\n                1,\n                634,\n                539,\n                1,\n                558.5,\n                584.5,\n                1,\n                624.5,\n                528.5,\n                1,\n                605,\n                595,\n                1,\n                601,\n                593,\n                1,\n                640,\n                634.5,\n                1,\n                598,\n                672,\n                1,\n                616.5,\n                700.5,\n                1,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 1,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                523.85,\n                412.825892645,\n                131.29999999999995,\n                325.19681700999996\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000001,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                159,\n                259,\n                42,\n                47\n            ],\n            \"keypoints\": [\n                201,\n                284.5,\n                1,\n                169.9334106,\n                305.6158752,\n                1,\n                187.549942,\n                265.1630859,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                139.5,\n                307.5,\n                1,\n                193.5,\n                319.5,\n                1,\n                0,\n                0,\n                0,\n                209,\n                371,\n                1,\n                144,\n                365.5,\n                1,\n                231,\n                392,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                222,\n                337,\n                1,\n                241,\n                341.5,\n                1,\n                0,\n                0,\n                0,\n                267,\n                416,\n                1\n            ],\n            \"track_id\": 2,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                120.375,\n                242.53754878499996,\n                165.75,\n                196.08798833000003\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000002,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        },\n        {\n            \"bbox_head\": [\n                372,\n                205,\n                44,\n                44\n            ],\n            \"keypoints\": [\n                410.5,\n                230.5,\n                1,\n                387.8875732,\n                251.1279602,\n                1,\n                398.5843201,\n                208.9040375,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                359.5,\n                262.5,\n                1,\n                409.5,\n                266.5,\n                1,\n                337.5,\n                308.5,\n                1,\n                450,\n                306,\n                1,\n                292,\n                314,\n                1,\n                480,\n                311.5,\n                1,\n                390,\n                339,\n                1,\n                409,\n                339,\n                1,\n                405.5,\n                418.5,\n                1,\n                447.5,\n                366.5,\n                1,\n                391.5,\n                464.5,\n                1,\n                437.5,\n                440.5,\n                1\n            ],\n            \"track_id\": 3,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                263.8,\n                170.56464312499998,\n                244.39999999999998,\n                332.27475125\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000003,\n            \"iscrowd\": false,\n            \"num_keypoints\": 15\n        },\n        {\n            \"bbox_head\": [\n                693,\n                410,\n                44,\n                49\n            ],\n            \"keypoints\": [\n                718.5,\n                440.5,\n                1,\n                717.704834,\n                460.703125,\n                1,\n                712.9713745,\n                414.8476562,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                694.5,\n                474,\n                1,\n                743.5,\n                472.5,\n                1,\n                681.5,\n                530.5,\n                1,\n                757.5,\n                523.5,\n                1,\n                667.5,\n                564.5,\n                1,\n                0,\n                0,\n                0,\n                705.5,\n                563.5,\n                1,\n                737.5,\n                560.5,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                692.5,\n                607.5,\n                1,\n                716.5,\n                603.5,\n                1\n            ],\n            \"track_id\": 4,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                654.0,\n                385.94980463,\n                117.0,\n                250.44804694000004\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000004,\n            \"iscrowd\": false,\n            \"num_keypoints\": 12\n        },\n        {\n            \"bbox_head\": [\n                923,\n                347,\n                46,\n                58\n            ],\n            \"keypoints\": [\n                965.5,\n                382.5,\n                1,\n                933.9436646,\n                403.0452576,\n                1,\n                955.0422363,\n                355.7160645,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                922.5,\n                403.5,\n                1,\n                932.5,\n                431.5,\n                1,\n                0,\n                0,\n                0,\n                960,\n                475.5,\n                1,\n                0,\n                0,\n                0,\n                991.5,\n                462.5,\n                1,\n                934.5,\n                512.5,\n                1,\n                922.5,\n                506.5,\n                1,\n                946.5,\n                567.5,\n                1,\n                964,\n                578,\n                1,\n                900.5,\n                598,\n                1,\n                936,\n                634.5,\n                1\n            ],\n            \"track_id\": 5,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                886.85,\n                313.89847417500005,\n                118.29999999999995,\n                362.4191161499999\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000005,\n            \"iscrowd\": false,\n            \"num_keypoints\": 13\n        },\n        {\n            \"bbox_head\": [\n                691,\n                179,\n                43,\n                52\n            ],\n            \"keypoints\": [\n                708.5,\n                212.5,\n                1,\n                722.6444702,\n                230.0113831,\n                1,\n                704.8916626,\n                186.2414551,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                712,\n                244,\n                1,\n                742,\n                237.5,\n                1,\n                723,\n                293.5,\n                1,\n                745.5,\n                281.5,\n                1,\n                692,\n                319,\n                1,\n                0,\n                0,\n                0,\n                722,\n                323.5,\n                1,\n                748.5,\n                314,\n                1,\n                657.5,\n                301.5,\n                1,\n                668.5,\n                299.5,\n                1,\n                670.5,\n                367.5,\n                1,\n                689.5,\n                362.5,\n                1\n            ],\n            \"track_id\": 6,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                643.85,\n                159.05267336499998,\n                118.29999999999995,\n                235.63610837\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000006,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                927,\n                160,\n                39,\n                52\n            ],\n            \"keypoints\": [\n                952,\n                189,\n                1,\n                946.763916,\n                211.9986572,\n                1,\n                946.302063,\n                166.5010071,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                914.5,\n                234,\n                1,\n                979.5,\n                236.5,\n                1,\n                890.5,\n                270.5,\n                1,\n                998.5,\n                286.5,\n                1,\n                894.5,\n                324,\n                1,\n                0,\n                0,\n                0,\n                932,\n                326.5,\n                1,\n                958.5,\n                327.5,\n                1,\n                1000.5,\n                340.5,\n                1,\n                993.5,\n                372.5,\n                1,\n                955.5,\n                383.5,\n                1,\n                959.5,\n                446.5,\n                1\n            ],\n            \"track_id\": 7,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                874.0,\n                124.50115816500005,\n                143.0,\n                363.99869076999994\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000007,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        },\n        {\n            \"bbox_head\": [\n                1367,\n                427,\n                47,\n                45\n            ],\n            \"keypoints\": [\n                1406,\n                451,\n                1,\n                1379.198608,\n                472.946106,\n                1,\n                1398.976074,\n                431.9154358,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                1375.5,\n                467.5,\n                1,\n                1372,\n                501,\n                1,\n                0,\n                0,\n                0,\n                1343.5,\n                534.5,\n                1,\n                0,\n                0,\n                0,\n                1339.5,\n                573.5,\n                1,\n                1381.5,\n                531.5,\n                1,\n                1376,\n                539.5,\n                1,\n                1452.5,\n                524.5,\n                1,\n                1453.5,\n                535.5,\n                1,\n                1469.5,\n                603.5,\n                1,\n                1466,\n                610,\n                1\n            ],\n            \"track_id\": 8,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                1320.0,\n                405.20275117000006,\n                169.0,\n                231.50993345999996\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000008,\n            \"iscrowd\": false,\n            \"num_keypoints\": 13\n        },\n        {\n            \"bbox_head\": [\n                1378,\n                204,\n                40,\n                44\n            ],\n            \"keypoints\": [\n                1389,\n                234,\n                1,\n                1404.137573,\n                248.9802094,\n                1,\n                1393.396851,\n                208.7648468,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                1375,\n                272,\n                1,\n                1442.5,\n                260.5,\n                1,\n                1374,\n                315,\n                1,\n                1468,\n                303.5,\n                1,\n                1367,\n                340.5,\n                1,\n                1462.5,\n                330.5,\n                1,\n                1407,\n                349.5,\n                1,\n                1439,\n                340.5,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0\n            ],\n            \"track_id\": 9,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                1351.85,\n                187.65457382,\n                131.30000000000018,\n                182.95569916\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000009,\n            \"iscrowd\": false,\n            \"num_keypoints\": 11\n        },\n        {\n            \"bbox_head\": [\n                407,\n                -29,\n                35,\n                40\n            ],\n            \"keypoints\": [\n                0,\n                0,\n                0,\n                425.1159668,\n                12.25136662,\n                1,\n                424.0380249,\n                -24.93852425,\n                1,\n                0,\n                0,\n                0,\n                0,\n                0,\n                0,\n                455.5,\n                21.5,\n                1,\n                395.5,\n                29.5,\n                1,\n                474.5,\n                64.5,\n                1,\n                391.5,\n                67,\n                1,\n                474,\n                108,\n                1,\n                379,\n                107,\n                1,\n                446,\n                88,\n                1,\n                426,\n                88,\n                1,\n                424,\n                113,\n                1,\n                403,\n                113,\n                1,\n                430,\n                173,\n                1,\n                415,\n                171,\n                1\n            ],\n            \"track_id\": 10,\n            \"image_id\": 10128340000,\n            \"bbox\": [\n                364.675,\n                -54.62930288750002,\n                124.14999999999998,\n                257.32008152500003\n            ],\n            \"scores\": [],\n            \"category_id\": 1,\n            \"id\": 1012834000010,\n            \"iscrowd\": false,\n            \"num_keypoints\": 14\n        }\n    ]\n}\n"
  },
  {
    "path": "tests/data/rhd/test_rhd.json",
    "content": "{\n    \"info\": {\n        \"description\": \"RHD\",\n        \"version\": \"1.1\",\n        \"year\": \"2021\",\n        \"date_created\": \"2021/03/13\"\n    },\n    \"licenses\": \"\",\n    \"images\": [\n        {\n            \"file_name\": \"00111.png\",\n            \"height\": 320,\n            \"width\": 320,\n            \"id\": 111,\n            \"cam_param\": {\n                \"focal\": [\n                    299.0,\n                    299.0\n                ],\n                \"princpt\": [\n                    160.0,\n                    160.0\n                ]\n            }\n        },\n        {\n            \"file_name\": \"01111.png\",\n            \"height\": 320,\n            \"width\": 320,\n            \"id\": 1111,\n            \"cam_param\": {\n                \"focal\": [\n                    305.8999938964844,\n                    305.8999938964844\n                ],\n                \"princpt\": [\n                    160.0,\n                    160.0\n                ]\n            }\n        },\n        {\n            \"file_name\": \"11111.png\",\n            \"height\": 320,\n            \"width\": 320,\n            \"id\": 11111,\n            \"cam_param\": {\n                \"focal\": [\n                    263.20001220703125,\n                    263.20001220703125\n                ],\n                \"princpt\": [\n                    160.0,\n                    160.0\n                ]\n            }\n        }\n    ],\n    \"annotations\": [\n        {\n            \"id\": 111,\n            \"image_id\": 111,\n            \"category_id\": 1,\n            \"iscrowd\": 0,\n            \"bbox\": [\n                162.5699920654297,\n                63.858001708984375,\n                93.96000671386719,\n                121.4639892578125\n            ],\n            \"area\": 11412.757246157154,\n            \"keypoints\": [\n                [\n                    245.8000030517578,\n                    73.9800033569336,\n                    1\n                ],\n                [\n                    170.39999389648438,\n                    115.0,\n                    1\n                ],\n                [\n                    180.39999389648438,\n                    103.69999694824219,\n                    1\n                ],\n                [\n                    194.10000610351562,\n                    89.16999816894531,\n                    1\n                ],\n                [\n                    220.0,\n                    82.51000213623047,\n                    1\n                ],\n                [\n                    193.0,\n                    163.60000610351562,\n                    1\n                ],\n                [\n                    194.5,\n                    154.1999969482422,\n                    1\n                ],\n                [\n                    196.6999969482422,\n                    144.39999389648438,\n                    1\n                ],\n                [\n                    202.39999389648438,\n                    123.69999694824219,\n                    1\n                ],\n                [\n                    208.39999389648438,\n                    175.1999969482422,\n                    1\n                ],\n                [\n                    210.6999969482422,\n                    164.3000030517578,\n                    1\n                ],\n                [\n                    211.60000610351562,\n                    152.10000610351562,\n                    1\n                ],\n                [\n                    215.60000610351562,\n                    131.5,\n                    1\n                ],\n                [\n                    228.10000610351562,\n                    167.1999969482422,\n                    1\n                ],\n                [\n                    228.6999969482422,\n                    159.0,\n                    1\n                ],\n                [\n                    228.1999969482422,\n                    151.10000610351562,\n                    1\n                ],\n                [\n                    228.6999969482422,\n                    132.1999969482422,\n                    1\n                ],\n                [\n                    248.6999969482422,\n                    143.6999969482422,\n                    1\n                ],\n                [\n                    247.6999969482422,\n                    148.3000030517578,\n                    1\n                ],\n                [\n                    246.39999389648438,\n                    148.10000610351562,\n                    1\n                ],\n                [\n                    244.39999389648438,\n                    129.1999969482422,\n                    1\n                ]\n            ],\n            \"joint_cam\": [\n                [\n                    117.9000015258789,\n                    -118.19999694824219,\n                    411.0\n                ],\n                [\n                    17.09000015258789,\n                    -73.70999908447266,\n                    489.5\n                ],\n                [\n                    32.540000915527344,\n                    -89.88999938964844,\n                    477.20001220703125\n                ],\n                [\n                    52.959999084472656,\n                    -110.0,\n                    464.3999938964844\n                ],\n                [\n                    87.95999908447266,\n                    -113.70000457763672,\n                    438.6999816894531\n                ],\n                [\n                    56.71000289916992,\n                    6.140999794006348,\n                    514.1000366210938\n                ],\n                [\n                    56.7599983215332,\n                    -9.583000183105469,\n                    492.1000061035156\n                ],\n                [\n                    57.97999954223633,\n                    -24.700000762939453,\n                    472.79998779296875\n                ],\n                [\n                    64.52000427246094,\n                    -55.34000015258789,\n                    455.5\n                ],\n                [\n                    81.20000457763672,\n                    25.459999084472656,\n                    501.6999816894531\n                ],\n                [\n                    81.8800048828125,\n                    6.9070000648498535,\n                    483.3999938964844\n                ],\n                [\n                    80.05999755859375,\n                    -12.220000267028809,\n                    464.1000061035156\n                ],\n                [\n                    83.37000274658203,\n                    -42.70000076293945,\n                    448.0\n                ],\n                [\n                    113.20000457763672,\n                    11.960000038146973,\n                    496.6999816894531\n                ],\n                [\n                    109.0999984741211,\n                    -1.5170000791549683,\n                    475.20001220703125\n                ],\n                [\n                    103.20000457763672,\n                    -13.480000495910645,\n                    452.6999816894531\n                ],\n                [\n                    102.0,\n                    -41.32999801635742,\n                    443.79998779296875\n                ],\n                [\n                    143.09999084472656,\n                    -26.25,\n                    482.3000183105469\n                ],\n                [\n                    137.0,\n                    -18.23000144958496,\n                    467.29998779296875\n                ],\n                [\n                    130.60000610351562,\n                    -18.049999237060547,\n                    452.0\n                ],\n                [\n                    124.9000015258789,\n                    -45.51000213623047,\n                    442.0999755859375\n                ]\n            ],\n            \"hand_type\": \"left\"\n        },\n        {\n            \"id\": 1111,\n            \"image_id\": 1111,\n            \"category_id\": 1,\n            \"iscrowd\": 0,\n            \"bbox\": [\n                163.91000366210938,\n                92.3900146484375,\n                59.88001251220703,\n                118.91999053955078\n            ],\n            \"area\": 7120.930521459843,\n            \"keypoints\": [\n                [\n                    218.8000030517578,\n                    201.39999389648438,\n                    1\n                ],\n                [\n                    168.89999389648438,\n                    147.89999389648438,\n                    1\n                ],\n                [\n                    171.5,\n                    161.6999969482422,\n                    1\n                ],\n                [\n                    182.3000030517578,\n                    178.0,\n                    1\n                ],\n                [\n                    202.60000610351562,\n                    191.10000610351562,\n                    1\n                ],\n                [\n                    184.6999969482422,\n                    174.1999969482422,\n                    1\n                ],\n                [\n                    175.6999969482422,\n                    162.39999389648438,\n                    1\n                ],\n                [\n                    180.60000610351562,\n                    148.10000610351562,\n                    1\n                ],\n                [\n                    200.5,\n                    153.3000030517578,\n                    1\n                ],\n                [\n                    181.5,\n                    173.89999389648438,\n                    1\n                ],\n                [\n                    180.0,\n                    156.5,\n                    1\n                ],\n                [\n                    185.10000610351562,\n                    140.89999389648438,\n                    1\n                ],\n                [\n                    205.6999969482422,\n                    146.6999969482422,\n                    1\n                ],\n                [\n                    175.39999389648438,\n                    160.3000030517578,\n                    1\n                ],\n                [\n                    183.60000610351562,\n                    145.3000030517578,\n                    1\n                ],\n                [\n                    194.89999389648438,\n                    132.6999969482422,\n                    1\n                ],\n                [\n                    208.8000030517578,\n                    145.6999969482422,\n                    1\n                ],\n                [\n                    199.39999389648438,\n                    102.30000305175781,\n                    1\n                ],\n                [\n                    201.89999389648438,\n                    116.19999694824219,\n                    1\n                ],\n                [\n                    208.10000610351562,\n                    127.4000015258789,\n                    1\n                ],\n                [\n                    210.60000610351562,\n                    148.5,\n                    1\n                ]\n            ],\n            \"joint_cam\": [\n                [\n                    96.12000274658203,\n                    67.63999938964844,\n                    499.70001220703125\n                ],\n                [\n                    15.380000114440918,\n                    -20.969999313354492,\n                    528.0\n                ],\n                [\n                    20.209999084472656,\n                    3.059999942779541,\n                    536.0999755859375\n                ],\n                [\n                    38.869998931884766,\n                    31.470001220703125,\n                    533.2999877929688\n                ],\n                [\n                    73.62000274658203,\n                    53.81999969482422,\n                    529.2000122070312\n                ],\n                [\n                    42.380001068115234,\n                    24.42999839782715,\n                    524.7999877929688\n                ],\n                [\n                    27.260000228881836,\n                    4.211999893188477,\n                    529.7999877929688\n                ],\n                [\n                    36.38999938964844,\n                    -21.010000228881836,\n                    540.0999755859375\n                ],\n                [\n                    71.79000091552734,\n                    -11.949999809265137,\n                    542.7000122070312\n                ],\n                [\n                    35.5,\n                    22.989999771118164,\n                    505.5999755859375\n                ],\n                [\n                    33.540000915527344,\n                    -5.878000259399414,\n                    512.9000244140625\n                ],\n                [\n                    42.69000244140625,\n                    -32.55999755859375,\n                    521.0999755859375\n                ],\n                [\n                    78.16999816894531,\n                    -22.75,\n                    522.8999633789062\n                ],\n                [\n                    24.560001373291016,\n                    0.47450000047683716,\n                    487.79998779296875\n                ],\n                [\n                    38.18000030517578,\n                    -23.760000228881836,\n                    494.1000061035156\n                ],\n                [\n                    57.27000045776367,\n                    -44.72999954223633,\n                    501.3999938964844\n                ],\n                [\n                    80.33000183105469,\n                    -23.520000457763672,\n                    503.8999938964844\n                ],\n                [\n                    58.06999969482422,\n                    -85.06999969482422,\n                    450.8999938964844\n                ],\n                [\n                    62.619998931884766,\n                    -65.56999969482422,\n                    457.5\n                ],\n                [\n                    73.29999542236328,\n                    -49.72999954223633,\n                    466.3999938964844\n                ],\n                [\n                    79.80000305175781,\n                    -18.200000762939453,\n                    482.3000183105469\n                ]\n            ],\n            \"hand_type\": \"left\"\n        },\n        {\n            \"id\": 11111,\n            \"image_id\": 11111,\n            \"category_id\": 1,\n            \"iscrowd\": 0,\n            \"bbox\": [\n                162.8300018310547,\n                135.88999938964844,\n                59.63999557495117,\n                48.1200065612793\n            ],\n            \"area\": 2869.8769783813186,\n            \"keypoints\": [\n                [\n                    167.8000030517578,\n                    154.10000610351562,\n                    1\n                ],\n                [\n                    217.5,\n                    146.60000610351562,\n                    1\n                ],\n                [\n                    207.8000030517578,\n                    146.39999389648438,\n                    1\n                ],\n                [\n                    197.10000610351562,\n                    144.8000030517578,\n                    1\n                ],\n                [\n                    181.5,\n                    148.0,\n                    1\n                ],\n                [\n                    206.8000030517578,\n                    167.1999969482422,\n                    1\n                ],\n                [\n                    206.5,\n                    160.1999969482422,\n                    1\n                ],\n                [\n                    202.10000610351562,\n                    150.89999389648438,\n                    1\n                ],\n                [\n                    191.39999389648438,\n                    139.89999389648438,\n                    1\n                ],\n                [\n                    200.0,\n                    170.0,\n                    1\n                ],\n                [\n                    200.39999389648438,\n                    163.6999969482422,\n                    1\n                ],\n                [\n                    198.0,\n                    155.6999969482422,\n                    1\n                ],\n                [\n                    186.39999389648438,\n                    145.10000610351562,\n                    1\n                ],\n                [\n                    194.6999969482422,\n                    172.39999389648438,\n                    1\n                ],\n                [\n                    195.1999969482422,\n                    168.10000610351562,\n                    1\n                ],\n                [\n                    191.8000030517578,\n                    160.89999389648438,\n                    1\n                ],\n                [\n                    182.0,\n                    151.6999969482422,\n                    1\n                ],\n                [\n                    198.1999969482422,\n                    180.0,\n                    1\n                ],\n                [\n                    195.0,\n                    176.3000030517578,\n                    1\n                ],\n                [\n                    189.10000610351562,\n                    170.39999389648438,\n                    1\n                ],\n                [\n                    177.3000030517578,\n                    160.1999969482422,\n                    1\n                ]\n            ],\n            \"joint_cam\": [\n                [\n                    20.479999542236328,\n                    -15.470000267028809,\n                    693.2999877929688\n                ],\n                [\n                    138.40000915527344,\n                    -32.17000198364258,\n                    633.2000122070312\n                ],\n                [\n                    118.0,\n                    -33.62999725341797,\n                    649.2000122070312\n                ],\n                [\n                    94.87999725341797,\n                    -38.78999710083008,\n                    673.699951171875\n                ],\n                [\n                    56.01000213623047,\n                    -31.309999465942383,\n                    686.2999877929688\n                ],\n                [\n                    116.80000305175781,\n                    18.049999237060547,\n                    656.7999877929688\n                ],\n                [\n                    112.80000305175781,\n                    0.48660001158714294,\n                    638.2999877929688\n                ],\n                [\n                    99.94000244140625,\n                    -21.559999465942383,\n                    625.199951171875\n                ],\n                [\n                    74.3699951171875,\n                    -47.75,\n                    623.7999877929688\n                ],\n                [\n                    99.95999908447266,\n                    24.979999542236328,\n                    658.5\n                ],\n                [\n                    97.34000396728516,\n                    9.000999450683594,\n                    633.4000244140625\n                ],\n                [\n                    88.5199966430664,\n                    -9.983000755310059,\n                    612.7999877929688\n                ],\n                [\n                    61.19000244140625,\n                    -34.4900016784668,\n                    609.6000366210938\n                ],\n                [\n                    86.45000457763672,\n                    31.0,\n                    655.6000366210938\n                ],\n                [\n                    84.11000061035156,\n                    19.43000030517578,\n                    629.7000122070312\n                ],\n                [\n                    73.44000244140625,\n                    2.186999797821045,\n                    608.6000366210938\n                ],\n                [\n                    50.53000259399414,\n                    -19.139999389648438,\n                    605.7000122070312\n                ],\n                [\n                    91.06999969482422,\n                    47.60000228881836,\n                    626.6000366210938\n                ],\n                [\n                    81.22000122070312,\n                    37.78000259399414,\n                    610.800048828125\n                ],\n                [\n                    66.75,\n                    23.989999771118164,\n                    604.0999755859375\n                ],\n                [\n                    39.94999694824219,\n                    0.4115999937057495,\n                    607.7999877929688\n                ]\n            ],\n            \"hand_type\": \"right\"\n        }\n    ],\n    \"categories\": [\n        {\n            \"id\": 1,\n            \"name\": \"hand\",\n            \"supercategory\": \"hand\",\n            \"keypoints\": [\n                \"wrist\",\n                \"thumb1\",\n                \"thumb2\",\n                \"thumb3\",\n                \"thumb4\",\n                \"forefinger1\",\n                \"forefinger2\",\n                \"forefinger3\",\n                \"forefinger4\",\n                \"middle_finger1\",\n                \"middle_finger2\",\n                \"middle_finger3\",\n                \"middle_finger4\",\n                \"ring_finger1\",\n                \"ring_finger2\",\n                \"ring_finger3\",\n                \"ring_finger4\",\n                \"pinky_finger1\",\n                \"pinky_finger2\",\n                \"pinky_finger3\",\n                \"pinky_finger4\"\n            ],\n            \"skeleton\": [\n                [\n                    1,\n                    2\n                ],\n                [\n                    2,\n                    3\n                ],\n                [\n                    3,\n                    4\n                ],\n                [\n                    4,\n                    5\n                ],\n                [\n                    1,\n                    6\n                ],\n                [\n                    6,\n                    7\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    8,\n                    9\n                ],\n                [\n                    1,\n                    10\n                ],\n                [\n                    10,\n                    11\n                ],\n                [\n                    11,\n                    12\n                ],\n                [\n                    12,\n                    13\n                ],\n                [\n                    1,\n                    14\n                ],\n                [\n                    14,\n                    15\n                ],\n                [\n                    15,\n                    16\n                ],\n                [\n                    16,\n                    17\n                ],\n                [\n                    1,\n                    18\n                ],\n                [\n                    18,\n                    19\n                ],\n                [\n                    19,\n                    20\n                ],\n                [\n                    20,\n                    21\n                ]\n            ]\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/shelf/calibration_shelf.json",
    "content": "{\n  \"0\": {\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"R\": [\n      [\n        0.650977,\n        -0.758717,\n        0.024027\n      ],\n      [\n        -0.018862,\n        -0.04781,\n        -0.998678\n      ],\n      [\n        0.758863,\n        0.649664,\n        -0.045434\n      ]\n    ],\n    \"T\": [\n      [\n        -1586.4496077989998\n      ],\n      [\n        -2109.46905869\n      ],\n      [\n        1104.209800652\n      ]\n    ],\n    \"fx\": 1063.512085,\n    \"fy\": 1071.863647,\n    \"cx\": 511.738251,\n    \"cy\": 350.088287\n  },\n  \"1\": {\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"R\": [\n      [\n        -0.016771,\n        -0.999835,\n        0.006926\n      ],\n      [\n        -0.029435,\n        -0.006431,\n        -0.999546\n      ],\n      [\n        0.999426,\n        -0.016967,\n        -0.029322\n      ]\n    ],\n    \"T\": [\n      [\n        -3512.391424833\n      ],\n      [\n        311.47771461800005\n      ],\n      [\n        964.5481307480001\n      ]\n    ],\n    \"fx\": 1097.697754,\n    \"fy\": 1086.668457,\n    \"cx\": 521.652161,\n    \"cy\": 376.587067\n  },\n  \"2\": {\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"R\": [\n      [\n        -0.789986,\n        -0.610527,\n        0.05638\n      ],\n      [\n        -0.370413,\n        0.401962,\n        -0.837389\n      ],\n      [\n        0.488586,\n        -0.68241,\n        -0.543691\n      ]\n    ],\n    \"T\": [\n      [\n        -1420.944211509\n      ],\n      [\n        2546.574076866\n      ],\n      [\n        2688.8728944060003\n      ]\n    ],\n    \"fx\": 1130.065552,\n    \"fy\": 1112.470337,\n    \"cx\": 566.884338,\n    \"cy\": 375.212708\n  },\n  \"3\": {\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"R\": [\n      [\n        -0.970568,\n        0.235647,\n        -0.049676\n      ],\n      [\n        0.09763,\n        0.196438,\n        -0.975644\n      ],\n      [\n        -0.22015,\n        -0.951779,\n        -0.213663\n      ]\n    ],\n    \"T\": [\n      [\n        963.489306486\n      ],\n      [\n        3408.674914882\n      ],\n      [\n        1422.035001899\n      ]\n    ],\n    \"fx\": 1056.162598,\n    \"fy\": 1059.639648,\n    \"cx\": 552.43573,\n    \"cy\": 393.180389\n  },\n  \"4\": {\n    \"k\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"p\": [\n      [\n        0.0\n      ],\n      [\n        0.0\n      ]\n    ],\n    \"R\": [\n      [\n        -0.194109,\n        0.980554,\n        -0.028888\n      ],\n      [\n        0.233045,\n        0.017488,\n        -0.972309\n      ],\n      [\n        -0.952896,\n        -0.195466,\n        -0.231908\n      ]\n    ],\n    \"T\": [\n      [\n        3832.020978729\n      ],\n      [\n        273.55271850000014\n      ],\n      [\n        1439.4616998990002\n      ]\n    ],\n    \"fx\": 1089.654175,\n    \"fy\": 1080.99939,\n    \"cx\": 498.32962,\n    \"cy\": 359.514832\n  }\n}"
  },
  {
    "path": "tests/data/ubody3d/ubody3d_train.json",
    "content": "{\"images\": [{\"id\": 15, \"height\": 720, \"width\": 1280, \"file_name\": \"Magic_show/Magic_show_S1_Trim1/Magic_show_S1_Trim1/000016.png\"}], \"annotations\": [{\"id\": 0, \"image_id\": 15, \"bbox\": [74.55498504638672, 8.571063995361328, 1062.4967727661133, 701.8491630554199], \"segmentation\": [[]], \"area\": 0, \"iscrowd\": 0, \"category_id\": 1, \"score\": 1, \"person_id\": 0, \"hand_box1\": [336.4236145019531, 321.40362548828125, 473.6637268066406, 452.62567138671875], \"hand_box2\": [699.218994140625, 50.335018157958984, 533.58251953125, 621.6577186584473], \"keypoints\": [[252.16543579101562, 2132.398681640625], [793.895263671875, 2988.90771484375], [232.56475830078125, 2939.503173828125], [588.2872314453125, 570.474365234375], [862.1456298828125, 514.33837890625], [373.89849853515625, 519.60888671875], [1073.739990234375, 765.0070190429688], [89.8785400390625, 775.919921875], [1000.2418212890625, 635.8955688476562], [189.44015502929688, 567.993408203125], [891.81298828125, 2948.2041015625], [1013.4824829101562, 3015.250732421875], [819.24658203125, 3122.821533203125], [172.14041137695312, 2868.272705078125], [31.46063232421875, 2937.01025390625], [244.37692260742188, 3111.135009765625], [760.2764282226562, 235.35623168945312], [469.04644775390625, 237.359130859375], [672.689453125, 216.68638610839844], [536.8645629882812, 215.08010864257812], [594.4747924804688, 302.86590576171875], [937.543212890625, 563.2012939453125], [877.2040405273438, 564.7064819335938], [826.8228759765625, 548.8115234375], [768.3922729492188, 532.2924194335938], [945.0330810546875, 433.25579833984375], [887.2977905273438, 411.39129638671875], [854.9716796875, 409.1885986328125], [812.5216064453125, 409.8503112792969], [993.1986083984375, 415.13519287109375], [983.431640625, 352.09503173828125], [976.8125610351562, 306.58990478515625], [967.6991577148438, 251.8966064453125], [1042.6788330078125, 439.2115783691406], [1061.695068359375, 382.62310791015625], [1078.3428955078125, 336.8554382324219], [1089.8707275390625, 288.113037109375], [1077.3145751953125, 467.8497009277344], [1113.5694580078125, 449.51904296875], [1147.91796875, 434.2681884765625], [1184.372314453125, 406.7205505371094], [262.0787048339844, 512.4108276367188], [314.8291320800781, 495.84429931640625], [355.2375183105469, 463.73870849609375], [400.5841064453125, 429.6348876953125], [290.11627197265625, 385.6371765136719], [334.016357421875, 356.7796325683594], [352.326904296875, 347.6751403808594], [379.92449951171875, 336.6559143066406], [248.99337768554688, 355.2509460449219], [270.441162109375, 294.56085205078125], [283.58990478515625, 247.07943725585938], [298.6072692871094, 191.95077514648438], [194.588623046875, 364.1822509765625], [197.89288330078125, 304.9277038574219], [198.94699096679688, 255.0223846435547], [207.83172607421875, 206.8009490966797], [152.69793701171875, 380.91925048828125], [126.07894897460938, 349.861083984375], [99.02603149414062, 320.67138671875], [75.35498046875, 280.7127380371094], [605.5189819335938, 258.36474609375], [636.6569213867188, 261.03448486328125], [672.689453125, 216.68638610839844], [536.8645629882812, 215.08010864257812], [480.609130859375, 193.2221221923828], [498.7352294921875, 169.0961151123047], [527.0252075195312, 168.48736572265625], [556.564453125, 174.32501220703125], [582.2213134765625, 183.7449188232422], [619.771728515625, 185.09783935546875], [646.1015625, 177.27572631835938], [678.3016357421875, 172.73214721679688], [709.5665283203125, 174.52818298339844], [730.6221313476562, 199.52928161621094], [600.2632446289062, 215.79234313964844], [598.0828247070312, 240.45635986328125], [596.2218627929688, 264.4862976074219], [594.4674072265625, 287.62481689453125], [572.7188110351562, 305.8975830078125], [583.9725341796875, 311.3199157714844], [596.401123046875, 315.5985107421875], [609.6165771484375, 311.5094909667969], [622.2186279296875, 306.6711120605469], [512.6423950195312, 211.75982666015625], [528.5633544921875, 204.07089233398438], [548.4610595703125, 205.9830780029297], [565.9568481445312, 217.66900634765625], [548.8089599609375, 222.94613647460938], [530.2134399414062, 222.75762939453125], [639.6070556640625, 219.82444763183594], [655.8860473632812, 209.6044158935547], [676.3201904296875, 208.3985595703125], [694.9487915039062, 217.1615753173828], [674.3418579101562, 226.85595703125], [655.4156494140625, 225.6745147705078], [551.7490234375, 353.2354736328125], [564.1500244140625, 346.4883728027344], [583.2034912109375, 344.99609375], [595.4065551757812, 347.21868896484375], [607.8397216796875, 345.721435546875], [629.6182250976562, 348.2886047363281], [648.6402587890625, 353.0809631347656], [634.0433349609375, 361.12738037109375], [612.543212890625, 365.1044921875], [598.9017333984375, 366.5699768066406], [585.4385375976562, 366.0231018066406], [566.12353515625, 362.2437744140625], [553.4495239257812, 352.7164001464844], [583.9151000976562, 355.8670654296875], [596.3876342773438, 356.340576171875], [608.99560546875, 356.22100830078125], [648.081787109375, 352.85076904296875], [612.7412719726562, 351.5333251953125], [598.9871215820312, 351.8242492675781], [585.3312377929688, 352.4969482421875], [464.1539001464844, 202.29954528808594], [465.8164978027344, 244.8143768310547], [469.96026611328125, 282.73333740234375], [474.998779296875, 318.5062255859375], [485.900390625, 354.82257080078125], [503.9440002441406, 389.1557922363281], [533.9607543945312, 420.1808776855469], [569.1990356445312, 439.69488525390625], [604.7715454101562, 445.1242370605469], [641.609130859375, 438.5807189941406], [677.1731567382812, 419.1774597167969], [709.558349609375, 390.3476867675781], [728.9358520507812, 358.6229553222656], [743.6824951171875, 323.7010192871094], [752.355224609375, 286.009033203125], [756.031494140625, 248.0742645263672], [756.6275634765625, 206.8378448486328]], \"foot_kpts\": [1166.72314453125, 38.096336364746094, 0, 1002.4937744140625, 109.48077392578125, 0, 1049.140869140625, 663.1453857421875, 0, 317.3815002441406, 32.0361328125, 0, 402.523681640625, 303.2774963378906, 0, 177.21731567382812, 665.190673828125, 0], \"face_kpts\": [482.1813659667969, 206.51531982421875, 0, 474.4501037597656, 248.23251342773438, 1, 482.5657043457031, 282.5651550292969, 1, 490.3671569824219, 326.8166198730469, 1, 498.9546813964844, 355.2204895019531, 1, 519.25634765625, 390.5085754394531, 1, 543.9222412109375, 417.4048156738281, 1, 574.4150390625, 437.6228332519531, 1, 614.6944580078125, 442.5209045410156, 1, 648.99267578125, 436.2539978027344, 1, 682.6341552734375, 416.4512023925781, 1, 702.5023193359375, 392.0824279785156, 1, 725.9093017578125, 358.3260803222656, 1, 739.4346923828125, 328.9374084472656, 1, 746.7598876953125, 285.0207824707031, 1, 748.8603515625, 251.59585571289062, 1, 755.915771484375, 212.4534149169922, 0, 496.4743957519531, 188.47494506835938, 1, 514.8231201171875, 177.99856567382812, 1, 535.214111328125, 176.0469970703125, 1, 556.4619140625, 177.9375, 1, 576.8843994140625, 183.35317993164062, 1, 631.4595947265625, 183.65673828125, 1, 652.4815673828125, 180.27340698242188, 1, 676.221923828125, 180.07711791992188, 1, 698.4794921875, 184.41073608398438, 1, 718.5443115234375, 196.21084594726562, 1, 604.396484375, 218.71194458007812, 1, 602.6702880859375, 245.68115234375, 1, 600.9422607421875, 271.4402770996094, 1, 599.4947509765625, 297.5359802246094, 1, 571.33203125, 313.3100891113281, 1, 586.1724853515625, 317.1542663574219, 1, 601.4893798828125, 320.0868835449219, 1, 617.738525390625, 316.9916687011719, 1, 632.822509765625, 313.9440002441406, 1, 524.906005859375, 216.0177001953125, 1, 542.880859375, 206.15841674804688, 1, 563.9365234375, 208.03213500976562, 1, 578.5321044921875, 222.44454956054688, 1, 559.7491455078125, 226.11843872070312, 1, 541.22607421875, 225.11203002929688, 1, 636.491943359375, 223.62353515625, 1, 652.7271728515625, 210.68789672851562, 1, 674.761474609375, 209.86370849609375, 1, 692.972900390625, 221.53323364257812, 1, 674.9864501953125, 228.75543212890625, 1, 656.0750732421875, 229.04306030273438, 1, 560.0743408203125, 351.4398498535156, 1, 577.081787109375, 347.0306091308594, 1, 594.04638671875, 345.2702941894531, 1, 604.1793212890625, 346.1555480957031, 1, 614.151611328125, 344.8525695800781, 1, 634.447509765625, 345.7118225097656, 1, 656.1597900390625, 347.9260559082031, 1, 640.6773681640625, 358.7562561035156, 1, 624.00732421875, 366.7438049316406, 1, 605.445556640625, 369.8896789550781, 1, 588.646484375, 367.5843811035156, 1, 573.5023193359375, 360.9281921386719, 1, 565.385498046875, 352.2278137207031, 1, 585.1085205078125, 353.1212463378906, 1, 604.616943359375, 355.0426330566406, 1, 626.8272705078125, 351.8833312988281, 1, 650.2919921875, 349.2644958496094, 1, 627.5924072265625, 353.0104675292969, 1, 604.7803955078125, 355.8074645996094, 1, 584.6986083984375, 354.2829284667969, 1], \"lefthand_kpts\": [942.7679443359375, 607.469482421875, 1, 888.291259765625, 539.277587890625, 1, 832.873291015625, 483.5708923339844, 1, 787.126953125, 436.6972351074219, 1, 710.735107421875, 413.7229309082031, 1, 888.9903564453125, 319.5710754394531, 1, 868.0140380859375, 280.7148742675781, 1, 830.3096923828125, 266.0387268066406, 1, 778.9337158203125, 271.2351379394531, 1, 962.7294921875, 272.7072448730469, 1, 955.781005859375, 187.65567016601562, 1, 953.9222412109375, 103.62838745117188, 1, 959.151611328125, 29.267608642578125, 1, 1047.009033203125, 294.3193664550781, 1, 1056.5989990234375, 215.84146118164062, 1, 1066.36865234375, 147.68014526367188, 1, 1081.0699462890625, 65.11972045898438, 1, 1107.0172119140625, 358.7002258300781, 1, 1159.4434814453125, 319.2156677246094, 1, 1206.9718017578125, 272.8797912597656, 1, 1261.1082763671875, 224.43637084960938, 1], \"righthand_kpts\": [233.142822265625, 582.3209228515625, 1, 300.6414794921875, 508.47479248046875, 1, 362.43896484375, 455.85186767578125, 1, 377.3603515625, 404.19744873046875, 1, 446.76416015625, 377.29241943359375, 1, 342.8802490234375, 310.6497802734375, 1, 368.6904296875, 284.673095703125, 1, 381.802734375, 251.73486328125, 1, 421.5467529296875, 225.363525390625, 1, 283.64288330078125, 254.122802734375, 1, 304.9996337890625, 170.8004150390625, 1, 320.6651611328125, 98.6851806640625, 1, 335.6553955078125, 28.2318115234375, 1, 199.05755615234375, 256.80859375, 1, 206.0360107421875, 177.01025390625, 1, 215.68804931640625, 106.7457275390625, 1, 224.53521728515625, 32.276611328125, 1, 128.827392578125, 294.99359130859375, 1, 99.0606689453125, 239.12982177734375, 1, 65.53125, 189.2431640625, 1, 37.63360595703125, 116.657958984375, 1], \"center\": [605.8033447265625, 359.4956359863281], \"scale\": [6.6406049728393555, 8.854140281677246], \"keypoints_score\": [0.972457766532898, 0.866172194480896, 0.8760361671447754, 0.3526427149772644, 0.3903506398200989, 0.921836793422699, 0.9433825016021729, 0.20496317744255066, 0.2460474669933319, 0.20729553699493408, 0.17142903804779053, 0.18208564817905426, 0.22269707918167114], \"face_kpts_score\": [0.3680439293384552, 0.5355573892593384, 0.6418813467025757, 0.6644495725631714, 0.7590401768684387, 0.5538617372512817, 0.5907169580459595, 0.5878690481185913, 0.6348617076873779, 0.7361799478530884, 0.6556291580200195, 0.618322491645813, 0.6537319421768188, 0.5892513394355774, 0.7059171199798584, 0.645734429359436, 0.4574907422065735, 0.9639992713928223, 0.9263820648193359, 0.8876979351043701, 0.9284569621086121, 0.9739065170288086, 0.9502178430557251, 0.9174821376800537, 0.918608546257019, 0.9061530232429504, 0.862210750579834, 0.9776759147644043, 0.973875105381012, 0.974762499332428, 0.9565852880477905, 0.9716235399246216, 1.0059518814086914, 0.946382999420166, 0.9594531059265137, 0.9658107757568359, 1.0158061981201172, 0.9708306789398193, 0.9969902634620667, 0.9845597743988037, 0.9349627494812012, 0.9380444288253784, 0.9717998504638672, 0.9871775507926941, 0.9774664640426636, 0.9537898898124695, 0.9465979933738708, 0.9661000967025757, 0.9713011980056763, 0.9717509746551514, 0.956028938293457, 1.000832438468933, 0.9808722734451294, 0.9960898160934448, 0.9364079236984253, 1.0011546611785889, 0.9167187213897705, 0.9541155099868774, 0.9244742393493652, 0.988551139831543, 0.9954862594604492, 0.9832127094268799, 0.978826642036438, 0.9751479625701904, 0.956895112991333, 0.9974040985107422, 0.9864891767501831, 0.9898920655250549], \"foot_kpts_score\": [0.24755269289016724, 0.1599443256855011, 0.25949808955192566, 0.2688680589199066, 0.14811083674430847, 0.23364056646823883], \"lefthand_kpts_score\": [0.603957986831665, 0.46176729202270506, 0.5001004695892334, 0.6286116600036621, 0.7983541250228882, 0.7467568874359131, 0.7094749569892883, 0.7889106035232544, 0.8908322811126709, 0.8638974189758301, 1.0441084861755372, 0.9282500505447387, 0.9102095127105713, 0.7738837957382202, 0.94963458776474, 0.8981462478637695, 0.9926700949668884, 0.7828058958053589, 0.9498528003692627, 0.9387582302093506, 0.8471795082092285], \"righthand_kpts_score\": [0.6722876787185669, 0.60037282705307, 0.5398626983165741, 0.7077780723571777, 0.7050052642822265, 0.6411999225616455, 0.725990629196167, 0.758279001712799, 0.8829087972640991, 0.889958119392395, 0.9569337129592895, 0.9145335912704468, 0.9213766813278198, 0.8925279140472412, 0.9955486416816711, 1.0033048152923585, 1.0014301896095277, 0.9033888339996338, 0.9002806305885315, 0.8902452945709228, 0.888652241230011], \"face_box\": [445.3220458984375, 145.05938720703125, 348.63178710937495, 332.0302734375], \"face_valid\": true, \"leftfoot_valid\": false, \"rightfoot_valid\": false, \"lefthand_valid\": true, \"righthand_valid\": true, \"lefthand_box\": [699.218994140625, 50.335018157958984, 533.58251953125, 621.6577186584473], \"righthand_box\": [81.47227172851564, -7.12115478515625, 398.4362548828125, 664.060546875], \"lefthand_update\": true, \"righthand_update\": true, \"lefthand_kpts_vitposehand\": [942.7679443359375, 607.469482421875, 1, 888.291259765625, 539.277587890625, 1, 832.873291015625, 483.5708923339844, 1, 787.126953125, 436.6972351074219, 1, 710.735107421875, 413.7229309082031, 1, 888.9903564453125, 319.5710754394531, 1, 868.0140380859375, 280.7148742675781, 1, 830.3096923828125, 266.0387268066406, 1, 778.9337158203125, 271.2351379394531, 1, 962.7294921875, 272.7072448730469, 1, 955.781005859375, 187.65567016601562, 1, 953.9222412109375, 103.62838745117188, 1, 959.151611328125, 29.267608642578125, 1, 1047.009033203125, 294.3193664550781, 1, 1056.5989990234375, 215.84146118164062, 1, 1066.36865234375, 147.68014526367188, 1, 1081.0699462890625, 65.11972045898438, 1, 1107.0172119140625, 358.7002258300781, 1, 1159.4434814453125, 319.2156677246094, 1, 1206.9718017578125, 272.8797912597656, 1, 1261.1082763671875, 224.43637084960938, 1], \"righthand_kpts_vitposehand\": [233.142822265625, 582.3209228515625, 1, 300.6414794921875, 508.47479248046875, 1, 362.43896484375, 455.85186767578125, 1, 377.3603515625, 404.19744873046875, 1, 446.76416015625, 377.29241943359375, 1, 342.8802490234375, 310.6497802734375, 1, 368.6904296875, 284.673095703125, 1, 381.802734375, 251.73486328125, 1, 421.5467529296875, 225.363525390625, 1, 283.64288330078125, 254.122802734375, 1, 304.9996337890625, 170.8004150390625, 1, 320.6651611328125, 98.6851806640625, 1, 335.6553955078125, 28.2318115234375, 1, 199.05755615234375, 256.80859375, 1, 206.0360107421875, 177.01025390625, 1, 215.68804931640625, 106.7457275390625, 1, 224.53521728515625, 32.276611328125, 1, 128.827392578125, 294.99359130859375, 1, 99.0606689453125, 239.12982177734375, 1, 65.53125, 189.2431640625, 1, 37.63360595703125, 116.657958984375, 1], \"num_keypoints\": 9, \"full_body\": false, \"valid_label\": 2,  \"keypoints_3d\": [[252.16543579101562, 2132.398681640625, 5.6501007080078125], [793.895263671875, 2988.90771484375, 4.6084747314453125], [232.56475830078125, 2939.503173828125, 4.28839111328125], [588.2872314453125, 570.474365234375, 9.544265747070312], [862.1456298828125, 514.33837890625, 8.8726806640625], [373.89849853515625, 519.60888671875, 9.171127319335938], [1073.739990234375, 765.0070190429688, 7.1384735107421875], [89.8785400390625, 775.919921875, 7.5379791259765625], [1000.2418212890625, 635.8955688476562, 5.19927978515625], [189.44015502929688, 567.993408203125, 5.757049560546875], [891.81298828125, 2948.2041015625, 3.0384368896484375], [1013.4824829101562, 3015.250732421875, 3.43035888671875], [819.24658203125, 3122.821533203125, 4.943603515625], [172.14041137695312, 2868.272705078125, 2.809112548828125], [31.46063232421875, 2937.01025390625, 3.1867828369140625], [244.37692260742188, 3111.135009765625, 4.5428619384765625], [760.2764282226562, 235.35623168945312, 9.170547485351562], [469.04644775390625, 237.359130859375, 9.270904541015625], [672.689453125, 216.68638610839844, 8.436477661132812], [536.8645629882812, 215.08010864257812, 8.477508544921875], [594.4747924804688, 302.86590576171875, 8.231826782226562], [937.543212890625, 563.2012939453125, 7.81884765625], [877.2040405273438, 564.7064819335938, 7.746490478515625], [826.8228759765625, 548.8115234375, 7.6898651123046875], [768.3922729492188, 532.2924194335938, 7.540069580078125], [945.0330810546875, 433.25579833984375, 7.78143310546875], [887.2977905273438, 411.39129638671875, 7.68023681640625], [854.9716796875, 409.1885986328125, 7.548248291015625], [812.5216064453125, 409.8503112792969, 7.41748046875], [993.1986083984375, 415.13519287109375, 7.762298583984375], [983.431640625, 352.09503173828125, 7.7212677001953125], [976.8125610351562, 306.58990478515625, 7.644317626953125], [967.6991577148438, 251.8966064453125, 7.58074951171875], [1042.6788330078125, 439.2115783691406, 7.7346954345703125], [1061.695068359375, 382.62310791015625, 7.7144622802734375], [1078.3428955078125, 336.8554382324219, 7.6671142578125], [1089.8707275390625, 288.113037109375, 7.64324951171875], [1077.3145751953125, 467.8497009277344, 7.6988525390625], [1113.5694580078125, 449.51904296875, 7.6714019775390625], [1147.91796875, 434.2681884765625, 7.6133880615234375], [1184.372314453125, 406.7205505371094, 7.566802978515625], [262.0787048339844, 512.4108276367188, 7.7939453125], [314.8291320800781, 495.84429931640625, 7.6787109375], [355.2375183105469, 463.73870849609375, 7.6097564697265625], [400.5841064453125, 429.6348876953125, 7.4446563720703125], [290.11627197265625, 385.6371765136719, 7.82208251953125], [334.016357421875, 356.7796325683594, 7.663116455078125], [352.326904296875, 347.6751403808594, 7.499725341796875], [379.92449951171875, 336.6559143066406, 7.330535888671875], [248.99337768554688, 355.2509460449219, 7.84161376953125], [270.441162109375, 294.56085205078125, 7.848602294921875], [283.58990478515625, 247.07943725585938, 7.8173370361328125], [298.6072692871094, 191.95077514648438, 7.8151092529296875], [194.588623046875, 364.1822509765625, 7.8341217041015625], [197.89288330078125, 304.9277038574219, 7.8556976318359375], [198.94699096679688, 255.0223846435547, 7.8529815673828125], [207.83172607421875, 206.8009490966797, 7.8715667724609375], [152.69793701171875, 380.91925048828125, 7.8072052001953125], [126.07894897460938, 349.861083984375, 7.8142547607421875], [99.02603149414062, 320.67138671875, 7.79296875], [75.35498046875, 280.7127380371094, 7.79833984375], [605.5189819335938, 258.36474609375, 7.6539459228515625], [636.6569213867188, 261.03448486328125, 7.6003265380859375], [672.689453125, 216.68638610839844, 6.8922119140625], [536.8645629882812, 215.08010864257812, 6.9332427978515625], [480.609130859375, 193.2221221923828, 7.156890869140625], [498.7352294921875, 169.0961151123047, 7.0008087158203125], [527.0252075195312, 168.48736572265625, 6.879364013671875], [556.564453125, 174.32501220703125, 6.8116912841796875], [582.2213134765625, 183.7449188232422, 6.796417236328125], [619.771728515625, 185.09783935546875, 6.7884368896484375], [646.1015625, 177.27572631835938, 6.788299560546875], [678.3016357421875, 172.73214721679688, 6.8334197998046875], [709.5665283203125, 174.52818298339844, 6.94036865234375], [730.6221313476562, 199.52928161621094, 7.08001708984375], [600.2632446289062, 215.79234313964844, 6.797698974609375], [598.0828247070312, 240.45635986328125, 6.753753662109375], [596.2218627929688, 264.4862976074219, 6.70782470703125], [594.4674072265625, 287.62481689453125, 6.66571044921875], [572.7188110351562, 305.8975830078125, 6.8535308837890625], [583.9725341796875, 311.3199157714844, 6.8229217529296875], [596.401123046875, 315.5985107421875, 6.804962158203125], [609.6165771484375, 311.5094909667969, 6.8159027099609375], [622.2186279296875, 306.6711120605469, 6.8405303955078125], [512.6423950195312, 211.75982666015625, 7.02471923828125], [528.5633544921875, 204.07089233398438, 6.9400634765625], [548.4610595703125, 205.9830780029297, 6.92816162109375], [565.9568481445312, 217.66900634765625, 6.9529266357421875], [548.8089599609375, 222.94613647460938, 6.9491424560546875], [530.2134399414062, 222.75762939453125, 6.9624176025390625], [639.6070556640625, 219.82444763183594, 6.930755615234375], [655.8860473632812, 209.6044158935547, 6.8970184326171875], [676.3201904296875, 208.3985595703125, 6.8957061767578125], [694.9487915039062, 217.1615753173828, 6.9696502685546875], [674.3418579101562, 226.85595703125, 6.9189300537109375], [655.4156494140625, 225.6745147705078, 6.91705322265625], [551.7490234375, 353.2354736328125, 6.971923828125], [564.1500244140625, 346.4883728027344, 6.88177490234375], [583.2034912109375, 344.99609375, 6.8333587646484375], [595.4065551757812, 347.21868896484375, 6.8253173828125], [607.8397216796875, 345.721435546875, 6.82666015625], [629.6182250976562, 348.2886047363281, 6.8668060302734375], [648.6402587890625, 353.0809631347656, 6.940582275390625], [634.0433349609375, 361.12738037109375, 6.8939056396484375], [612.543212890625, 365.1044921875, 6.8557891845703125], [598.9017333984375, 366.5699768066406, 6.8533477783203125], [585.4385375976562, 366.0231018066406, 6.8624725341796875], [566.12353515625, 362.2437744140625, 6.9132232666015625], [553.4495239257812, 352.7164001464844, 6.97503662109375], [583.9151000976562, 355.8670654296875, 6.8811187744140625], [596.3876342773438, 356.340576171875, 6.8712615966796875], [608.99560546875, 356.22100830078125, 6.8746795654296875], [648.081787109375, 352.85076904296875, 6.94110107421875], [612.7412719726562, 351.5333251953125, 6.865570068359375], [598.9871215820312, 351.8242492675781, 6.8616485595703125], [585.3312377929688, 352.4969482421875, 6.87408447265625], [464.1539001464844, 202.29954528808594, 7.4058380126953125], [465.8164978027344, 244.8143768310547, 7.313018798828125], [469.96026611328125, 282.73333740234375, 7.331451416015625], [474.998779296875, 318.5062255859375, 7.377685546875], [485.900390625, 354.82257080078125, 7.34814453125], [503.9440002441406, 389.1557922363281, 7.29644775390625], [533.9607543945312, 420.1808776855469, 7.2111968994140625], [569.1990356445312, 439.69488525390625, 7.0761260986328125], [604.7715454101562, 445.1242370605469, 7.0256805419921875], [641.609130859375, 438.5807189941406, 7.05670166015625], [677.1731567382812, 419.1774597167969, 7.1628265380859375], [709.558349609375, 390.3476867675781, 7.262908935546875], [728.9358520507812, 358.6229553222656, 7.3195648193359375], [743.6824951171875, 323.7010192871094, 7.3823699951171875], [752.355224609375, 286.009033203125, 7.3757171630859375], [756.031494140625, 248.0742645263672, 7.3575439453125], [756.6275634765625, 206.8378448486328, 7.39019775390625]], \"keypoints_valid\": [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1], \"camera_param\": {\"focal\": [34553.93155415853, 34553.93075942993], \"princpt\": [605.3033752441406, 358.99560546875]}}], \"categories\": [{\"supercategory\": \"person\", \"id\": 1, \"name\": \"person\"}]}"
  },
  {
    "path": "tests/data/wflw/test_wflw.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"person\",\n            \"id\": 1,\n            \"name\": \"face\",\n            \"keypoints\": [],\n            \"skeleton\": []\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 2,\n            \"file_name\": \"36_Football_americanfootball_ball_36_415.jpg\",\n            \"height\": 661,\n            \"width\": 1024\n        },\n        {\n            \"id\": 12,\n            \"file_name\": \"7_Cheering_Cheering_7_16.jpg\",\n            \"height\": 1024,\n            \"width\": 1024\n        }\n    ],\n    \"annotations\": [\n        {\n            \"image_id\": 2,\n            \"id\": 2,\n            \"keypoints\": [\n                440.696106,\n                132.732559,\n                1,\n                441.125309,\n                138.20883600000002,\n                1,\n                441.775067,\n                143.662576,\n                1,\n                442.838757,\n                149.050135,\n                1,\n                444.330483,\n                154.335484,\n                1,\n                446.199104,\n                159.499988,\n                1,\n                448.359594,\n                164.549883,\n                1,\n                450.707972,\n                169.515574,\n                1,\n                453.152313,\n                174.43489,\n                1,\n                455.663647,\n                179.320327,\n                1,\n                458.272826,\n                184.154116,\n                1,\n                461.018412,\n                188.911642,\n                1,\n                463.94567,\n                193.559255,\n                1,\n                467.22343,\n                197.963659,\n                1,\n                471.117738,\n                201.826457,\n                1,\n                475.751887,\n                204.749145,\n                1,\n                480.989902,\n                206.343046,\n                1,\n                487.065598,\n                206.402104,\n                1,\n                492.947114,\n                204.866338,\n                1,\n                498.297161,\n                201.969714,\n                1,\n                503.013751,\n                198.11849,\n                1,\n                507.157957,\n                193.652851,\n                1,\n                510.843251,\n                188.799396,\n                1,\n                514.1297,\n                183.667342,\n                1,\n                516.955071,\n                178.26847800000004,\n                1,\n                519.2164700000002,\n                172.61085,\n                1,\n                520.848493,\n                166.740574,\n                1,\n                521.9502669999998,\n                160.74653700000005,\n                1,\n                522.708073,\n                154.698484,\n                1,\n                523.292433,\n                148.630853,\n                1,\n                523.782152,\n                142.554803,\n                1,\n                524.208992,\n                136.47398700000002,\n                1,\n                524.604004,\n                130.391006,\n                1,\n                448.863007,\n                130.600006,\n                1,\n                454.970001,\n                126.268997,\n                1,\n                460.80896,\n                127.033981,\n                1,\n                466.639008,\n                127.488991,\n                1,\n                471.871002,\n                128.024002,\n                1,\n                471.839966,\n                131.30699199999998,\n                1,\n                466.7300110000001,\n                130.602005,\n                1,\n                460.683014,\n                129.84198,\n                1,\n                455.03299,\n                128.447983,\n                1,\n                484.471008,\n                126.532997,\n                1,\n                491.312988,\n                124.467003,\n                1,\n                497.66098,\n                122.172989,\n                1,\n                504.834991,\n                123.182007,\n                1,\n                510.877014,\n                127.14801,\n                1,\n                504.89801,\n                125.372993,\n                1,\n                497.656982,\n                124.851997,\n                1,\n                491.562012,\n                127.464005,\n                1,\n                484.731995,\n                129.934998,\n                1,\n                478.60199000000006,\n                137.615005,\n                1,\n                478.797445,\n                144.648194,\n                1,\n                478.710781,\n                151.672784,\n                1,\n                479.648263,\n                158.477047,\n                1,\n                472.342987,\n                162.587006,\n                1,\n                476.080474,\n                163.443556,\n                1,\n                479.895523,\n                163.767872,\n                1,\n                484.256557,\n                162.987089,\n                1,\n                488.335907,\n                161.220047,\n                1,\n                454.908997,\n                139.330002,\n                1,\n                457.994713,\n                139.25393799999998,\n                1,\n                461.081185,\n                139.258667,\n                1,\n                465.0926280000001,\n                138.585731,\n                1,\n                469.109314,\n                137.906326,\n                1,\n                465.638515,\n                140.893484,\n                1,\n                461.276336,\n                142.038503,\n                1,\n                457.94384,\n                141.053913,\n                1,\n                488.993011,\n                136.03999299999998,\n                1,\n                492.80749,\n                136.399268,\n                1,\n                496.59449000000006,\n                136.98136499999998,\n                1,\n                500.786029,\n                137.41671000000002,\n                1,\n                504.984009,\n                137.048096,\n                1,\n                501.171214,\n                139.364812,\n                1,\n                496.775512,\n                139.941385,\n                1,\n                492.595083,\n                138.593753,\n                1,\n                468.338989,\n                177.639496,\n                1,\n                472.57608,\n                175.232479,\n                1,\n                477.20692,\n                173.776125,\n                1,\n                480.569762,\n                173.825898,\n                1,\n                483.565578,\n                174.109503,\n                1,\n                490.367366,\n                175.431598,\n                1,\n                496.381042,\n                178.96504199999995,\n                1,\n                491.802489,\n                182.339998,\n                1,\n                486.685901,\n                184.599911,\n                1,\n                481.033928,\n                184.016885,\n                1,\n                476.397867,\n                182.850118,\n                1,\n                472.60944400000005,\n                179.86823,\n                1,\n                469.541992,\n                177.462006,\n                1,\n                474.959022,\n                175.385376,\n                1,\n                480.747386,\n                175.48909799999996,\n                1,\n                488.63756500000005,\n                175.736854,\n                1,\n                495.716522,\n                179.02507,\n                1,\n                488.642736,\n                177.62467,\n                1,\n                481.422413,\n                177.62252,\n                1,\n                475.491142,\n                176.514907,\n                1,\n                461.279777,\n                140.890199,\n                1,\n                496.453474,\n                137.763648,\n                1\n            ],\n            \"num_keypoints\": 98,\n            \"bbox\": [\n                432.3053162,\n                113.7500775,\n                100.68947760000003,\n                101.074938\n            ],\n            \"iscrowd\": 0,\n            \"area\": 10177.182705672392,\n            \"category_id\": 1,\n            \"center\": [\n                482.5,\n                164.5\n            ],\n            \"scale\": 0.425\n        },\n        {\n            \"image_id\": 12,\n            \"id\": 12,\n            \"keypoints\": [\n                737.310974,\n                302.2290040000001,\n                1,\n                735.612565,\n                307.91392,\n                1,\n                733.935549,\n                313.605176,\n                1,\n                732.301247,\n                319.308828,\n                1,\n                730.746049,\n                325.034488,\n                1,\n                729.333061,\n                330.796748,\n                1,\n                728.130165,\n                336.606254,\n                1,\n                727.2343940000002,\n                342.470465,\n                1,\n                726.769826,\n                348.383693,\n                1,\n                726.8573719999998,\n                354.313744,\n                1,\n                727.578398,\n                360.199602,\n                1,\n                729.013058,\n                365.95307,\n                1,\n                731.013678,\n                371.537441,\n                1,\n                733.2071559999998,\n                377.050279,\n                1,\n                735.47649,\n                382.530816,\n                1,\n                738.714025,\n                387.475552,\n                1,\n                743.5621620000002,\n                390.822643,\n                1,\n                749.412371,\n                392.269205,\n                1,\n                755.438439,\n                391.936151,\n                1,\n                761.2417849999998,\n                390.247929,\n                1,\n                766.732837,\n                387.708216,\n                1,\n                772.008913,\n                384.743038,\n                1,\n                777.11136,\n                381.48808,\n                1,\n                782.0033440000002,\n                377.925076,\n                1,\n                786.614896,\n                374.007594,\n                1,\n                790.746727,\n                369.589677,\n                1,\n                794.345917,\n                364.72535,\n                1,\n                797.705108,\n                359.69007,\n                1,\n                800.979223,\n                354.59913,\n                1,\n                804.030756,\n                349.372408,\n                1,\n                806.796596,\n                343.988855,\n                1,\n                809.360701,\n                338.505917,\n                1,\n                811.822571,\n                332.976135,\n                1,\n                738.142029,\n                316.583008,\n                1,\n                745.198975,\n                314.119995,\n                1,\n                749.843933,\n                315.911957,\n                1,\n                754.8779910000002,\n                317.789001,\n                1,\n                759.728943,\n                321.003967,\n                1,\n                758.924988,\n                323.009979,\n                1,\n                753.684021,\n                320.766998,\n                1,\n                748.650024,\n                318.889984,\n                1,\n                743.77301,\n                317.5,\n                1,\n                776.567993,\n                325.3989870000001,\n                1,\n                783.789917,\n                325.703003,\n                1,\n                791.1229860000002,\n                326.806976,\n                1,\n                797.598999,\n                328.432007,\n                1,\n                802.210022,\n                335.786987,\n                1,\n                796.032959,\n                331.798981,\n                1,\n                789.445007,\n                330.45401,\n                1,\n                782.429016,\n                328.828003,\n                1,\n                775.448975,\n                328.189972,\n                1,\n                766.489014,\n                330.141998,\n                1,\n                763.441048,\n                338.395354,\n                1,\n                760.1896519999998,\n                346.556714,\n                1,\n                758.378882,\n                354.899379,\n                1,\n                749.651978,\n                347.691986,\n                1,\n                752.802228,\n                352.909886,\n                1,\n                757.095133,\n                357.015939,\n                1,\n                762.194149,\n                356.25881,\n                1,\n                767.192932,\n                354.72403,\n                1,\n                743.380371,\n                322.295288,\n                1,\n                746.923719,\n                321.313264,\n                1,\n                750.553004,\n                321.784633,\n                1,\n                754.640226,\n                323.780582,\n                1,\n                756.981018,\n                327.664001,\n                1,\n                752.689438,\n                328.511655,\n                1,\n                748.3559,\n                328.079052,\n                1,\n                744.9315429999998,\n                326.014911,\n                1,\n                778.2459719999998,\n                334.537994,\n                1,\n                782.672983,\n                333.246396,\n                1,\n                787.060109,\n                334.610516,\n                1,\n                790.163963,\n                337.265647,\n                1,\n                792.42627,\n                340.685699,\n                1,\n                788.630666,\n                341.780179,\n                1,\n                784.70712,\n                341.598866,\n                1,\n                780.419418,\n                339.058276,\n                1,\n                740.483521,\n                361.065002,\n                1,\n                746.374246,\n                362.133178,\n                1,\n                751.741875,\n                364.488928,\n                1,\n                753.4344530000002,\n                365.103217,\n                1,\n                755.192267,\n                365.240915,\n                1,\n                759.601523,\n                366.89777,\n                1,\n                763.757446,\n                369.269043,\n                1,\n                759.467306,\n                371.294422,\n                1,\n                755.0135389999998,\n                372.896933,\n                1,\n                750.305609,\n                372.79702,\n                1,\n                745.439744,\n                370.475123,\n                1,\n                742.098872,\n                366.24297,\n                1,\n                742.159546,\n                363.090027,\n                1,\n                747.630617,\n                364.064427,\n                1,\n                752.565978,\n                366.666498,\n                1,\n                757.357922,\n                367.478878,\n                1,\n                761.918091,\n                369.147156,\n                1,\n                756.790297,\n                369.722393,\n                1,\n                751.666194,\n                369.277424,\n                1,\n                746.561781,\n                366.750798,\n                1,\n                749.141667,\n                325.096875,\n                1,\n                785.415625,\n                337.221875,\n                1\n            ],\n            \"num_keypoints\": 98,\n            \"bbox\": [\n                718.2645514999999,\n                293.2249839000001,\n                102.06329400000016,\n                108.0482411999999\n            ],\n            \"iscrowd\": 0,\n            \"area\": 11027.759407778518,\n            \"category_id\": 1,\n            \"center\": [\n                769.0,\n                347.5\n            ],\n            \"scale\": 0.455\n        },\n        {\n            \"image_id\": 12,\n            \"id\": 40,\n            \"keypoints\": [\n                744.762024,\n                731.096985,\n                1,\n                742.708957,\n                737.737215,\n                1,\n                740.7710030000002,\n                744.411776,\n                1,\n                739.0626599999998,\n                751.148374,\n                1,\n                737.733779,\n                757.96915,\n                1,\n                736.981188,\n                764.875717,\n                1,\n                737.0235700000002,\n                771.821884,\n                1,\n                737.765315,\n                778.7307400000002,\n                1,\n                738.86145,\n                785.593963,\n                1,\n                740.013747,\n                792.448173,\n                1,\n                741.1454200000002,\n                799.305824,\n                1,\n                742.3103629999998,\n                806.157846,\n                1,\n                743.6804400000002,\n                812.971502,\n                1,\n                744.630958,\n                819.850678,\n                1,\n                745.515035,\n                826.73686,\n                1,\n                748.690323,\n                832.821804,\n                1,\n                754.099426,\n                837.1631169999998,\n                1,\n                760.77823,\n                840.673624,\n                1,\n                768.147343,\n                842.162887,\n                1,\n                775.328568,\n                840.156231,\n                1,\n                781.549446,\n                835.8637679999998,\n                1,\n                787.79765,\n                831.6084860000002,\n                1,\n                794.115317,\n                827.4566940000002,\n                1,\n                800.175629,\n                822.943352,\n                1,\n                805.771167,\n                817.8629549999998,\n                1,\n                811.103558,\n                812.504673,\n                1,\n                816.124275,\n                806.855559,\n                1,\n                820.577538,\n                800.750585,\n                1,\n                824.5104719999998,\n                794.29608,\n                1,\n                828.03107,\n                787.6072519999999,\n                1,\n                831.192861,\n                780.74112,\n                1,\n                834.09596,\n                773.761204,\n                1,\n                836.867371,\n                766.727722,\n                1,\n                747.40802,\n                744.338989,\n                1,\n                756.8099980000002,\n                739.810974,\n                1,\n                762.8229980000001,\n                742.584961,\n                1,\n                769.116028,\n                746.8430179999998,\n                1,\n                774.4959719999998,\n                750.2109379999998,\n                1,\n                772.661011,\n                755.225037,\n                1,\n                766.9570309999998,\n                751.564026,\n                1,\n                760.413025,\n                748.731018,\n                1,\n                754.565979,\n                745.8809809999998,\n                1,\n                794.039978,\n                759.955017,\n                1,\n                802.140991,\n                759.838989,\n                1,\n                809.362976,\n                760.9539179999998,\n                1,\n                817.004089,\n                762.0819700000002,\n                1,\n                822.989014,\n                770.3709719999998,\n                1,\n                814.904053,\n                767.382935,\n                1,\n                807.603088,\n                766.098022,\n                1,\n                800.3809809999998,\n                764.984009,\n                1,\n                792.616028,\n                763.8099980000002,\n                1,\n                781.869995,\n                762.830994,\n                1,\n                777.671572,\n                775.3052809999998,\n                1,\n                773.599147,\n                787.815521,\n                1,\n                768.793789,\n                799.963975,\n                1,\n                759.9530639999998,\n                790.217224,\n                1,\n                763.438017,\n                796.8758799999998,\n                1,\n                768.200237,\n                802.5832889999998,\n                1,\n                776.714431,\n                800.940712,\n                1,\n                784.7540280000002,\n                796.731995,\n                1,\n                752.452454,\n                752.677429,\n                1,\n                758.142965,\n                751.832449,\n                1,\n                763.787095,\n                752.7987400000002,\n                1,\n                768.450332,\n                755.789755,\n                1,\n                771.7440190000002,\n                760.278992,\n                1,\n                766.108723,\n                761.570158,\n                1,\n                760.4538719999998,\n                760.565587,\n                1,\n                755.866811,\n                757.23883,\n                1,\n                791.400024,\n                769.619995,\n                1,\n                797.455167,\n                766.7197309999998,\n                1,\n                804.060133,\n                768.1290280000002,\n                1,\n                808.641021,\n                770.830526,\n                1,\n                812.1015620000002,\n                774.896179,\n                1,\n                807.2036360000002,\n                776.0263259999998,\n                1,\n                802.194302,\n                776.233114,\n                1,\n                796.1303330000002,\n                774.055774,\n                1,\n                756.312012,\n                806.9689940000002,\n                1,\n                761.152525,\n                807.042413,\n                1,\n                765.388771,\n                809.286819,\n                1,\n                766.746996,\n                810.379537,\n                1,\n                768.3692599999998,\n                811.051278,\n                1,\n                774.090223,\n                811.996037,\n                1,\n                779.304504,\n                814.633972,\n                1,\n                774.153851,\n                817.59002,\n                1,\n                768.453259,\n                819.044276,\n                1,\n                762.763688,\n                817.53634,\n                1,\n                759.5313259999998,\n                814.798765,\n                1,\n                757.4994230000002,\n                811.065074,\n                1,\n                758.089478,\n                808.210449,\n                1,\n                762.1575849999998,\n                809.557143,\n                1,\n                765.7118929999998,\n                811.955629,\n                1,\n                771.596042,\n                812.993758,\n                1,\n                777.41687,\n                814.616699,\n                1,\n                770.648339,\n                816.4749009999998,\n                1,\n                763.8826849999998,\n                815.569504,\n                1,\n                760.502713,\n                812.2854629999998,\n                1,\n                762.746584,\n                755.108075,\n                1,\n                802.488199,\n                770.511801,\n                1\n            ],\n            \"num_keypoints\": 98,\n            \"bbox\": [\n                726.9925697,\n                719.9903948,\n                119.86341960000004,\n                48.00960520000001\n            ],\n            \"iscrowd\": 0,\n            \"area\": 5754.595452917945,\n            \"category_id\": 1,\n            \"center\": [\n                786.5,\n                787.0\n            ],\n            \"scale\": 0.56\n        },\n        {\n            \"image_id\": 12,\n            \"id\": 1169,\n            \"keypoints\": [\n                473.170593,\n                353.335999,\n                1,\n                472.454142,\n                358.228909,\n                1,\n                471.788643,\n                363.128975,\n                1,\n                471.219892,\n                368.041068,\n                1,\n                470.94488600000005,\n                372.975959,\n                1,\n                471.550405,\n                377.8716,\n                1,\n                473.340887,\n                382.473922,\n                1,\n                475.160443,\n                387.069845,\n                1,\n                476.591016,\n                391.802996,\n                1,\n                478.183709,\n                396.482262,\n                1,\n                480.41786,\n                400.887374,\n                1,\n                483.28217300000006,\n                404.915875,\n                1,\n                485.94821,\n                409.072889,\n                1,\n                487.708742,\n                413.688483,\n                1,\n                490.510995,\n                417.693684,\n                1,\n                494.524824,\n                420.571949,\n                1,\n                498.905613,\n                422.85572,\n                1,\n                504.011519,\n                423.758231,\n                1,\n                508.98311500000005,\n                422.289137,\n                1,\n                512.9631360000002,\n                418.935051,\n                1,\n                516.483537,\n                415.068495,\n                1,\n                520.4627019999998,\n                411.682146,\n                1,\n                524.5683650000002,\n                408.443837,\n                1,\n                528.2940480000002,\n                404.779843,\n                1,\n                531.408005,\n                400.585369,\n                1,\n                533.7782599999998,\n                395.929292,\n                1,\n                535.604259,\n                391.029695,\n                1,\n                537.2263849999998,\n                386.057698,\n                1,\n                538.779161,\n                381.063564,\n                1,\n                540.257309,\n                376.04686,\n                1,\n                541.658462,\n                371.008091,\n                1,\n                543.005638,\n                365.954595,\n                1,\n                544.3259889999998,\n                360.894012,\n                1,\n                476.626984,\n                359.039978,\n                1,\n                481.548981,\n                356.339966,\n                1,\n                485.91098,\n                357.414032,\n                1,\n                489.883972,\n                359.63501,\n                1,\n                494.381958,\n                363.002014,\n                1,\n                494.093964,\n                365.890961,\n                1,\n                489.495972,\n                362.60498,\n                1,\n                485.306,\n                360.726959,\n                1,\n                481.214996,\n                359.679962,\n                1,\n                506.893005,\n                361.631012,\n                1,\n                512.028931,\n                360.1489870000001,\n                1,\n                518.090027,\n                359.3940120000001,\n                1,\n                524.357971,\n                359.295013,\n                1,\n                529.7819820000002,\n                363.101013,\n                1,\n                523.89093,\n                362.149994,\n                1,\n                517.776001,\n                362.536987,\n                1,\n                511.72399900000005,\n                363.200958,\n                1,\n                506.344971,\n                365.294006,\n                1,\n                501.347992,\n                367.559998,\n                1,\n                500.189242,\n                376.773265,\n                1,\n                498.956651,\n                385.973584,\n                1,\n                498.187578,\n                395.168944,\n                1,\n                491.300049,\n                391.111084,\n                1,\n                494.141522,\n                394.808003,\n                1,\n                498.40839000000005,\n                396.494433,\n                1,\n                502.755472,\n                394.932757,\n                1,\n                506.338013,\n                391.92099,\n                1,\n                478.184326,\n                363.812805,\n                1,\n                482.723986,\n                362.820035,\n                1,\n                487.304845,\n                363.425472,\n                1,\n                490.813411,\n                365.581369,\n                1,\n                493.446991,\n                368.773987,\n                1,\n                489.161792,\n                369.81081,\n                1,\n                484.775209,\n                369.488891,\n                1,\n                480.564629,\n                367.719005,\n                1,\n                507.460999,\n                371.890991,\n                1,\n                511.778055,\n                367.477709,\n                1,\n                517.9155969999998,\n                366.674784,\n                1,\n                522.678173,\n                367.724831,\n                1,\n                527.087158,\n                369.840698,\n                1,\n                522.757581,\n                373.347413,\n                1,\n                517.304023,\n                374.436933,\n                1,\n                512.204885,\n                373.876232,\n                1,\n                488.688477,\n                399.221008,\n                1,\n                493.442718,\n                400.217365,\n                1,\n                498.155821,\n                401.379151,\n                1,\n                499.542691,\n                401.500691,\n                1,\n                501.246774,\n                401.519773,\n                1,\n                506.836522,\n                401.478986,\n                1,\n                512.330994,\n                402.490967,\n                1,\n                508.472018,\n                405.699605,\n                1,\n                504.486124,\n                408.714805,\n                1,\n                499.5658360000001,\n                409.33235,\n                1,\n                494.571667,\n                407.645284,\n                1,\n                490.657115,\n                404.125086,\n                1,\n                489.64199800000006,\n                400.294006,\n                1,\n                494.17166900000007,\n                403.631745,\n                1,\n                499.518763,\n                405.267957,\n                1,\n                505.461418,\n                404.415617,\n                1,\n                511.249969,\n                402.717072,\n                1,\n                505.450159,\n                404.418683,\n                1,\n                499.495484,\n                405.266308,\n                1,\n                494.161436,\n                403.626137,\n                1,\n                486.570186,\n                366.549068,\n                1,\n                517.171429,\n                369.798758,\n                1\n            ],\n            \"num_keypoints\": 98,\n            \"bbox\": [\n                463.60677570000007,\n                346.2937758,\n                88.05732359999968,\n                84.50667840000006\n            ],\n            \"iscrowd\": 0,\n            \"area\": 7441.431926229908,\n            \"category_id\": 1,\n            \"center\": [\n                507.5,\n                388.5\n            ],\n            \"scale\": 0.375\n        }\n    ]\n}"
  },
  {
    "path": "tests/data/zebra/test_zebra.json",
    "content": "{\n    \"categories\": [\n        {\n            \"supercategory\": \"animal\",\n            \"id\": 1,\n            \"name\": \"zebra\",\n            \"keypoints\": [\n                \"snout\",\n                \"head\",\n                \"neck\",\n                \"forelegL1\",\n                \"forelegR1\",\n                \"hindlegL1\",\n                \"hindlegR1\",\n                \"tailbase\",\n                \"tailtip\"\n            ],\n            \"skeleton\": [\n                [\n                    2,\n                    1\n                ],\n                [\n                    3,\n                    2\n                ],\n                [\n                    4,\n                    3\n                ],\n                [\n                    5,\n                    3\n                ],\n                [\n                    6,\n                    8\n                ],\n                [\n                    7,\n                    8\n                ],\n                [\n                    8,\n                    3\n                ],\n                [\n                    9,\n                    8\n                ]\n            ]\n        }\n    ],\n    \"images\": [\n        {\n            \"id\": 810,\n            \"file_name\": \"810.jpg\",\n            \"height\": 160,\n            \"width\": 160\n        },\n        {\n            \"id\": 850,\n            \"file_name\": \"850.jpg\",\n            \"height\": 160,\n            \"width\": 160\n        }\n    ],\n    \"annotations\": [\n        {\n            \"keypoints\": [\n                121.13823384782104,\n                64.42827920259212,\n                2.0,\n                117.9981442098391,\n                70.81295036652858,\n                2.0,\n                101.74729396479975,\n                80.0,\n                2.0,\n                95.57905809119656,\n                75.75733930455307,\n                2.0,\n                95.2128993293075,\n                82.7116929245571,\n                2.0,\n                62.78126573755127,\n                75.8747890881429,\n                2.0,\n                62.31104503893799,\n                83.86685797031176,\n                2.0,\n                58.25270603520024,\n                80.0,\n                2.0,\n                53.31206457278393,\n                85.52060239198866,\n                2.0\n            ],\n            \"image_id\": 810,\n            \"id\": 810,\n            \"num_keypoints\": 9,\n            \"bbox\": [\n                53.31206457278393,\n                64.42827920259212,\n                68.8261692750371,\n                22.092323189396538\n            ],\n            \"iscrowd\": 0,\n            \"area\": 1520.5299755122337,\n            \"category_id\": 1\n        },\n        {\n            \"keypoints\": [\n                122.31461535908949,\n                89.25315845576364,\n                2.0,\n                117.81536523827128,\n                87.97006030862022,\n                2.0,\n                101.66067429997881,\n                80.0,\n                2.0,\n                97.88660503356242,\n                74.70007144842482,\n                2.0,\n                96.6342743993913,\n                81.95450979316085,\n                2.0,\n                62.9768902919959,\n                75.51961961159495,\n                2.0,\n                63.64287080847072,\n                83.46692756256179,\n                2.0,\n                58.3393257000212,\n                80.0,\n                2.0,\n                55.41273077187657,\n                77.94207820202976,\n                2.0\n            ],\n            \"image_id\": 850,\n            \"id\": 850,\n            \"num_keypoints\": 9,\n            \"bbox\": [\n                55.41273077187657,\n                74.70007144842482,\n                67.90188458721292,\n                15.553087007338817\n            ],\n            \"iscrowd\": 0,\n            \"area\": 1056.083918947201,\n            \"category_id\": 1\n        }\n    ]\n}"
  },
  {
    "path": "tests/test_apis/test_inference.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom pathlib import Path\nfrom tempfile import TemporaryDirectory\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nfrom mmcv.image import imread, imwrite\nfrom mmengine.utils import is_list_of\nfrom parameterized import parameterized\n\nfrom mmpose.apis import inference_bottomup, inference_topdown, init_model\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.testing._utils import _rand_bboxes, get_config_file, get_repo_dir\nfrom mmpose.utils import register_all_modules\n\n\nclass TestInference(TestCase):\n\n    def setUp(self) -> None:\n        register_all_modules()\n\n    @parameterized.expand([(('configs/body_2d_keypoint/topdown_heatmap/coco/'\n                             'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py'),\n                            ('cpu', 'cuda'))])\n    def test_init_model(self, config, devices):\n        config_file = get_config_file(config)\n\n        for device in devices:\n            if device == 'cuda' and not torch.cuda.is_available():\n                # Skip the test if cuda is required but unavailable\n                continue\n\n            # test init_model with str path\n            _ = init_model(config_file, device=device)\n\n            # test init_model with :obj:`Path`\n            _ = init_model(Path(config_file), device=device)\n\n            # test init_detector with undesirable type\n            with self.assertRaisesRegex(\n                    TypeError, 'config must be a filename or Config object'):\n                config_list = [config_file]\n                _ = init_model(config_list)\n\n    @parameterized.expand([(('configs/body_2d_keypoint/topdown_heatmap/coco/'\n                             'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py'),\n                            ('cpu', 'cuda'))])\n    def test_inference_topdown(self, config, devices):\n        project_dir = osp.abspath(osp.dirname(osp.dirname(__file__)))\n        project_dir = osp.join(project_dir, '..')\n        config_file = osp.join(project_dir, config)\n\n        rng = np.random.RandomState(0)\n        img_w = img_h = 100\n        img = rng.randint(0, 255, (img_h, img_w, 3), dtype=np.uint8)\n        bboxes = _rand_bboxes(rng, 2, img_w, img_h)\n\n        for device in devices:\n            if device == 'cuda' and not torch.cuda.is_available():\n                # Skip the test if cuda is required but unavailable\n                continue\n            model = init_model(config_file, device=device)\n\n            # test inference with bboxes\n            results = inference_topdown(model, img, bboxes, bbox_format='xywh')\n            self.assertTrue(is_list_of(results, PoseDataSample))\n            self.assertEqual(len(results), 2)\n            self.assertTrue(results[0].pred_instances.keypoints.shape,\n                            (1, 17, 2))\n\n            # test inference without bbox\n            results = inference_topdown(model, img)\n            self.assertTrue(is_list_of(results, PoseDataSample))\n            self.assertEqual(len(results), 1)\n            self.assertTrue(results[0].pred_instances.keypoints.shape,\n                            (1, 17, 2))\n\n            # test inference from image file\n            with TemporaryDirectory() as tmp_dir:\n                img_path = osp.join(tmp_dir, 'img.jpg')\n                imwrite(img, img_path)\n\n                results = inference_topdown(model, img_path)\n                self.assertTrue(is_list_of(results, PoseDataSample))\n                self.assertEqual(len(results), 1)\n                self.assertTrue(results[0].pred_instances.keypoints.shape,\n                                (1, 17, 2))\n\n    @parameterized.expand([(('configs/body_2d_keypoint/'\n                             'associative_embedding/coco/'\n                             'ae_hrnet-w32_8xb24-300e_coco-512x512.py'),\n                            ('cpu', 'cuda'))])\n    def test_inference_bottomup(self, config, devices):\n        config_file = get_config_file(config)\n        img = osp.join(get_repo_dir(), 'tests/data/coco/000000000785.jpg')\n\n        for device in devices:\n            if device == 'cuda' and not torch.cuda.is_available():\n                # Skip the test if cuda is required but unavailable\n                continue\n            model = init_model(config_file, device=device)\n\n            # test inference from image\n            results = inference_bottomup(model, img=imread(img))\n            self.assertTrue(is_list_of(results, PoseDataSample))\n            self.assertEqual(len(results), 1)\n            self.assertTrue(results[0].pred_instances.keypoints.shape,\n                            (1, 17, 2))\n\n            # test inference from file\n            results = inference_bottomup(model, img=img)\n            self.assertTrue(is_list_of(results, PoseDataSample))\n            self.assertEqual(len(results), 1)\n            self.assertTrue(results[0].pred_instances.keypoints.shape,\n                            (1, 17, 2))\n"
  },
  {
    "path": "tests/test_apis/test_inferencers/test_hand3d_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nfrom collections import defaultdict\nfrom tempfile import TemporaryDirectory\nfrom unittest import TestCase\n\nimport mmcv\nimport torch\n\nfrom mmpose.apis.inferencers import Hand3DInferencer\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.utils import register_all_modules\n\n\nclass TestHand3DInferencer(TestCase):\n\n    def tearDown(self) -> None:\n        register_all_modules(init_default_scope=True)\n        return super().tearDown()\n\n    def test_init(self):\n\n        inferencer = Hand3DInferencer(model='hand3d')\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n\n    def test_call(self):\n\n        inferencer = Hand3DInferencer(model='hand3d')\n\n        img_path = 'tests/data/interhand2.6m/image29590.jpg'\n        img = mmcv.imread(img_path)\n\n        # `inputs` is path to an image\n        inputs = img_path\n        results1 = next(inferencer(inputs, return_vis=True))\n        self.assertIn('visualization', results1)\n        self.assertIn('predictions', results1)\n        self.assertIn('keypoints', results1['predictions'][0][0])\n        self.assertEqual(len(results1['predictions'][0][0]['keypoints']), 42)\n\n        # `inputs` is an image array\n        inputs = img\n        results2 = next(inferencer(inputs))\n        self.assertEqual(\n            len(results1['predictions'][0]), len(results2['predictions'][0]))\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results2['predictions'][0][0]['keypoints'])\n        results2 = next(inferencer(inputs, return_datasamples=True))\n        self.assertIsInstance(results2['predictions'][0], PoseDataSample)\n\n        # `inputs` is path to a directory\n        inputs = osp.dirname(img_path)\n\n        with TemporaryDirectory() as tmp_dir:\n            # only save visualizations\n            for res in inferencer(inputs, vis_out_dir=tmp_dir):\n                pass\n            self.assertEqual(len(os.listdir(tmp_dir)), 4)\n            # save both visualizations and predictions\n            results3 = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results3[key].extend(res[key])\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/visualizations')), 4)\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/predictions')), 4)\n        self.assertEqual(len(results3['predictions']), 4)\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results3['predictions'][1][0]['keypoints'])\n"
  },
  {
    "path": "tests/test_apis/test_inferencers/test_mmpose_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport platform\nimport unittest\nfrom collections import defaultdict\nfrom tempfile import TemporaryDirectory\nfrom unittest import TestCase\n\nimport mmcv\n\nfrom mmpose.apis.inferencers import MMPoseInferencer\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.utils import register_all_modules\n\n\nclass TestMMPoseInferencer(TestCase):\n\n    def tearDown(self) -> None:\n        register_all_modules(init_default_scope=True)\n        return super().tearDown()\n\n    def test_pose2d_call(self):\n        try:\n            from mmdet.apis.det_inferencer import DetInferencer  # noqa: F401\n        except (ImportError, ModuleNotFoundError):\n            return unittest.skip('mmdet is not installed')\n\n        # top-down model\n        if platform.system().lower() == 'windows':\n            # the default human pose estimator utilizes rtmdet-m detector\n            # through alias, which seems not compatible with windows\n            det_model = 'demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py'\n            det_weights = 'https://download.openmmlab.com/mmdetection/v2.0/' \\\n                          'faster_rcnn/faster_rcnn_r50_fpn_1x_coco/' \\\n                          'faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'\n        else:\n            det_model, det_weights = None, None\n        inferencer = MMPoseInferencer(\n            'human', det_model=det_model, det_weights=det_weights)\n\n        img_path = 'tests/data/coco/000000197388.jpg'\n        img = mmcv.imread(img_path)\n\n        # `inputs` is path to an image\n        inputs = img_path\n        results1 = next(inferencer(inputs, return_vis=True))\n        self.assertIn('visualization', results1)\n        self.assertSequenceEqual(results1['visualization'][0].shape, img.shape)\n        self.assertIn('predictions', results1)\n        self.assertIn('keypoints', results1['predictions'][0][0])\n        self.assertEqual(len(results1['predictions'][0][0]['keypoints']), 17)\n\n        # `inputs` is an image array\n        inputs = img\n        results2 = next(inferencer(inputs))\n        self.assertEqual(\n            len(results1['predictions'][0]), len(results2['predictions'][0]))\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results2['predictions'][0][0]['keypoints'])\n        results2 = next(inferencer(inputs, return_datasamples=True))\n        self.assertIsInstance(results2['predictions'][0], PoseDataSample)\n\n        # `inputs` is path to a directory\n        inputs = osp.dirname(img_path)\n        with TemporaryDirectory() as tmp_dir:\n            # only save visualizations\n            for res in inferencer(inputs, vis_out_dir=tmp_dir):\n                pass\n            self.assertEqual(len(os.listdir(tmp_dir)), 4)\n            # save both visualizations and predictions\n            results3 = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results3[key].extend(res[key])\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/visualizations')), 4)\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/predictions')), 4)\n        self.assertEqual(len(results3['predictions']), 4)\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results3['predictions'][3][0]['keypoints'])\n\n        # `inputs` is path to a video\n        inputs = 'tests/data/posetrack18/videos/000001_mpiinew_test/' \\\n                 '000001_mpiinew_test.mp4'\n        with TemporaryDirectory() as tmp_dir:\n            results = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results[key].extend(res[key])\n            self.assertIn('000001_mpiinew_test.mp4',\n                          os.listdir(f'{tmp_dir}/visualizations'))\n            self.assertIn('000001_mpiinew_test.json',\n                          os.listdir(f'{tmp_dir}/predictions'))\n        self.assertTrue(inferencer._video_input)\n        self.assertIn(len(results['predictions']), (4, 5))\n\n    def test_pose3d_call(self):\n        try:\n            from mmdet.apis.det_inferencer import DetInferencer  # noqa: F401\n        except (ImportError, ModuleNotFoundError):\n            return unittest.skip('mmdet is not installed')\n\n        # top-down model\n        if platform.system().lower() == 'windows':\n            # the default human pose estimator utilizes rtmdet-m detector\n            # through alias, which seems not compatible with windows\n            det_model = 'demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py'\n            det_weights = 'https://download.openmmlab.com/mmdetection/v2.0/' \\\n                          'faster_rcnn/faster_rcnn_r50_fpn_1x_coco/' \\\n                          'faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'\n        else:\n            det_model, det_weights = None, None\n        inferencer = MMPoseInferencer(\n            pose3d='human3d', det_model=det_model, det_weights=det_weights)\n\n        # `inputs` is path to a video\n        inputs = 'https://user-images.githubusercontent.com/87690686/' \\\n            '164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.mp4'\n        with TemporaryDirectory() as tmp_dir:\n            results = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results[key].extend(res[key])\n            self.assertIn('164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.mp4',\n                          os.listdir(f'{tmp_dir}/visualizations'))\n            self.assertIn(\n                '164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.json',\n                os.listdir(f'{tmp_dir}/predictions'))\n        self.assertTrue(inferencer._video_input)\n\n    def test_hand3d_call(self):\n\n        inferencer = MMPoseInferencer(pose3d='hand3d')\n\n        # `inputs` is path to a video\n        inputs = 'tests/data/interhand2.6m/image29590.jpg'\n        results1 = next(inferencer(inputs, return_vis=True))\n        self.assertIn('visualization', results1)\n        self.assertIn('predictions', results1)\n        self.assertIn('keypoints', results1['predictions'][0][0])\n        self.assertEqual(len(results1['predictions'][0][0]['keypoints']), 42)\n"
  },
  {
    "path": "tests/test_apis/test_inferencers/test_pose2d_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport platform\nimport unittest\nfrom collections import defaultdict\nfrom tempfile import TemporaryDirectory\nfrom unittest import TestCase\n\nimport mmcv\nimport torch\nfrom mmengine.infer.infer import BaseInferencer\n\nfrom mmpose.apis.inferencers import Pose2DInferencer\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.utils import register_all_modules\n\n\nclass TestPose2DInferencer(TestCase):\n\n    def tearDown(self) -> None:\n        register_all_modules(init_default_scope=True)\n        return super().tearDown()\n\n    def _get_det_model_weights(self):\n        if platform.system().lower() == 'windows':\n            # the default human/animal pose estimator utilizes rtmdet-m\n            # detector through alias, which seems not compatible with windows\n            det_model = 'demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py'\n            det_weights = 'https://download.openmmlab.com/mmdetection/v2.0/' \\\n                          'faster_rcnn/faster_rcnn_r50_fpn_1x_coco/' \\\n                          'faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'\n        else:\n            det_model, det_weights = None, None\n\n        return det_model, det_weights\n\n    def test_init(self):\n\n        try:\n            from mmdet.apis.det_inferencer import DetInferencer  # noqa: F401\n        except (ImportError, ModuleNotFoundError):\n            return unittest.skip('mmdet is not installed')\n\n        det_model, det_weights = self._get_det_model_weights()\n\n        # 1. init with config path and checkpoint\n        inferencer = Pose2DInferencer(\n            model='configs/body_2d_keypoint/simcc/coco/'\n            'simcc_res50_8xb64-210e_coco-256x192.py',\n            weights='https://download.openmmlab.com/mmpose/'\n            'v1/body_2d_keypoint/simcc/coco/'\n            'simcc_res50_8xb64-210e_coco-256x192-8e0f5b59_20220919.pth',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=0 if det_model else None)\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertIsInstance(inferencer.detector, BaseInferencer)\n        self.assertSequenceEqual(inferencer.det_cat_ids, (0, ))\n\n        # 2. init with config name\n        inferencer = Pose2DInferencer(\n            model='td-hm_res50_8xb32-210e_onehand10k-256x256',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=0 if det_model else None)\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertIsInstance(inferencer.detector, BaseInferencer)\n        self.assertSequenceEqual(inferencer.det_cat_ids, (0, ))\n\n        # 3. init with alias\n        inferencer = Pose2DInferencer(\n            model='animal',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=(15, 16, 17, 18, 19, 20, 21, 22,\n                         23) if det_model else None)\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertIsInstance(inferencer.detector, BaseInferencer)\n        self.assertSequenceEqual(inferencer.det_cat_ids,\n                                 (15, 16, 17, 18, 19, 20, 21, 22, 23))\n\n        # 4. init with bottom-up model\n        inferencer = Pose2DInferencer(\n            model='configs/body_2d_keypoint/dekr/coco/'\n            'dekr_hrnet-w32_8xb10-140e_coco-512x512.py',\n            weights='https://download.openmmlab.com/mmpose/v1/'\n            'body_2d_keypoint/dekr/coco/'\n            'dekr_hrnet-w32_8xb10-140e_coco-512x512_ac7c17bf-20221228.pth',\n        )\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertFalse(hasattr(inferencer, 'detector'))\n\n    def test_call(self):\n\n        try:\n            from mmdet.apis.det_inferencer import DetInferencer  # noqa: F401\n        except (ImportError, ModuleNotFoundError):\n            return unittest.skip('mmdet is not installed')\n\n        # top-down model\n        det_model, det_weights = self._get_det_model_weights()\n        inferencer = Pose2DInferencer(\n            'human', det_model=det_model, det_weights=det_weights)\n\n        img_path = 'tests/data/coco/000000197388.jpg'\n        img = mmcv.imread(img_path)\n\n        # `inputs` is path to an image\n        inputs = img_path\n        results1 = next(inferencer(inputs, return_vis=True))\n        self.assertIn('visualization', results1)\n        self.assertSequenceEqual(results1['visualization'][0].shape, img.shape)\n        self.assertIn('predictions', results1)\n        self.assertIn('keypoints', results1['predictions'][0][0])\n        self.assertEqual(len(results1['predictions'][0][0]['keypoints']), 17)\n\n        # `inputs` is an image array\n        inputs = img\n        results2 = next(inferencer(inputs))\n        self.assertEqual(\n            len(results1['predictions'][0]), len(results2['predictions'][0]))\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results2['predictions'][0][0]['keypoints'])\n        results2 = next(inferencer(inputs, return_datasamples=True))\n        self.assertIsInstance(results2['predictions'][0], PoseDataSample)\n\n        # `inputs` is path to a directory\n        inputs = osp.dirname(img_path)\n\n        with TemporaryDirectory() as tmp_dir:\n            # only save visualizations\n            for res in inferencer(inputs, vis_out_dir=tmp_dir):\n                pass\n            self.assertEqual(len(os.listdir(tmp_dir)), 4)\n            # save both visualizations and predictions\n            results3 = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results3[key].extend(res[key])\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/visualizations')), 4)\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/predictions')), 4)\n        self.assertEqual(len(results3['predictions']), 4)\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results3['predictions'][3][0]['keypoints'])\n\n        with self.assertRaises(AssertionError):\n            for res in inferencer(inputs, vis_out_dir=f'{tmp_dir}/1.jpg'):\n                pass\n\n        # `inputs` is path to a video\n        inputs = 'tests/data/posetrack18/videos/000001_mpiinew_test/' \\\n                 '000001_mpiinew_test.mp4'\n        with TemporaryDirectory() as tmp_dir:\n            results = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results[key].extend(res[key])\n            self.assertIn('000001_mpiinew_test.mp4',\n                          os.listdir(f'{tmp_dir}/visualizations'))\n            self.assertIn('000001_mpiinew_test.json',\n                          os.listdir(f'{tmp_dir}/predictions'))\n        self.assertTrue(inferencer._video_input)\n        self.assertIn(len(results['predictions']), (4, 5))\n"
  },
  {
    "path": "tests/test_apis/test_inferencers/test_pose3d_inferencer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport platform\nimport unittest\nfrom collections import defaultdict\nfrom tempfile import TemporaryDirectory\nfrom unittest import TestCase\n\nimport mmcv\nimport torch\n\nfrom mmpose.apis.inferencers import Pose2DInferencer, Pose3DInferencer\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.utils import register_all_modules\n\n\nclass TestPose3DInferencer(TestCase):\n\n    def tearDown(self) -> None:\n        register_all_modules(init_default_scope=True)\n        return super().tearDown()\n\n    def _get_det_model_weights(self):\n        if platform.system().lower() == 'windows':\n            # the default human/animal pose estimator utilizes rtmdet-m\n            # detector through alias, which seems not compatible with windows\n            det_model = 'demo/mmdetection_cfg/faster_rcnn_r50_fpn_coco.py'\n            det_weights = 'https://download.openmmlab.com/mmdetection/v2.0/' \\\n                          'faster_rcnn/faster_rcnn_r50_fpn_1x_coco/' \\\n                          'faster_rcnn_r50_fpn_1x_coco_20200130-047c8118.pth'\n        else:\n            det_model, det_weights = None, None\n\n        return det_model, det_weights\n\n    def test_init(self):\n\n        try:\n            from mmdet.apis.det_inferencer import DetInferencer  # noqa: F401\n        except (ImportError, ModuleNotFoundError):\n            return unittest.skip('mmdet is not installed')\n\n        det_model, det_weights = self._get_det_model_weights()\n\n        # 1. init with config path and checkpoint\n        inferencer = Pose3DInferencer(\n            model=  # noqa\n            'configs/body_3d_keypoint/video_pose_lift/h36m/video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py',  # noqa\n            weights=  # noqa\n            'https://download.openmmlab.com/mmpose/body3d/videopose/videopose_h36m_243frames_fullconv_supervised_cpn_ft-88f5abbb_20210527.pth',  # noqa\n            pose2d_model='configs/body_2d_keypoint/simcc/coco/'\n            'simcc_res50_8xb64-210e_coco-256x192.py',\n            pose2d_weights='https://download.openmmlab.com/mmpose/'\n            'v1/body_2d_keypoint/simcc/coco/'\n            'simcc_res50_8xb64-210e_coco-256x192-8e0f5b59_20220919.pth',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=0 if det_model else None)\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertIsInstance(inferencer.pose2d_model, Pose2DInferencer)\n\n        # 2. init with config name\n        inferencer = Pose3DInferencer(\n            model='configs/body_3d_keypoint/video_pose_lift/h36m/'\n            'video-pose-lift_tcn-243frm-supv-cpn-ft_8xb128-200e_h36m.py',\n            pose2d_model='configs/body_2d_keypoint/simcc/coco/'\n            'simcc_res50_8xb64-210e_coco-256x192.py',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=0 if det_model else None)\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertIsInstance(inferencer.pose2d_model, Pose2DInferencer)\n\n        # 3. init with alias\n        inferencer = Pose3DInferencer(\n            model='human3d',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=0 if det_model else None)\n        self.assertIsInstance(inferencer.model, torch.nn.Module)\n        self.assertIsInstance(inferencer.pose2d_model, Pose2DInferencer)\n\n    def test_call(self):\n\n        try:\n            from mmdet.apis.det_inferencer import DetInferencer  # noqa: F401\n        except (ImportError, ModuleNotFoundError):\n            return unittest.skip('mmdet is not installed')\n\n        # top-down model\n        det_model, det_weights = self._get_det_model_weights()\n        inferencer = Pose3DInferencer(\n            model='human3d',\n            det_model=det_model,\n            det_weights=det_weights,\n            det_cat_ids=0 if det_model else None)\n\n        img_path = 'tests/data/coco/000000197388.jpg'\n        img = mmcv.imread(img_path)\n\n        # `inputs` is path to an image\n        inputs = img_path\n        results1 = next(inferencer(inputs, return_vis=True))\n        self.assertIn('visualization', results1)\n        self.assertIn('predictions', results1)\n        self.assertIn('keypoints', results1['predictions'][0][0])\n        self.assertEqual(len(results1['predictions'][0][0]['keypoints']), 17)\n\n        # `inputs` is an image array\n        inputs = img\n        results2 = next(inferencer(inputs))\n        self.assertEqual(\n            len(results1['predictions'][0]), len(results2['predictions'][0]))\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results2['predictions'][0][0]['keypoints'])\n        results2 = next(inferencer(inputs, return_datasamples=True))\n        self.assertIsInstance(results2['predictions'][0], PoseDataSample)\n\n        # `inputs` is path to a directory\n        inputs = osp.dirname(img_path)\n\n        with TemporaryDirectory() as tmp_dir:\n            # only save visualizations\n            for res in inferencer(inputs, vis_out_dir=tmp_dir):\n                pass\n            self.assertEqual(len(os.listdir(tmp_dir)), 4)\n            # save both visualizations and predictions\n            results3 = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results3[key].extend(res[key])\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/visualizations')), 4)\n            self.assertEqual(len(os.listdir(f'{tmp_dir}/predictions')), 4)\n        self.assertEqual(len(results3['predictions']), 4)\n        self.assertSequenceEqual(results1['predictions'][0][0]['keypoints'],\n                                 results3['predictions'][3][0]['keypoints'])\n\n        # `inputs` is path to a video\n        inputs = 'https://user-images.githubusercontent.com/87690686/' \\\n            '164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.mp4'\n        with TemporaryDirectory() as tmp_dir:\n            results = defaultdict(list)\n            for res in inferencer(inputs, out_dir=tmp_dir):\n                for key in res:\n                    results[key].extend(res[key])\n            self.assertIn('164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.mp4',\n                          os.listdir(f'{tmp_dir}/visualizations'))\n            self.assertIn(\n                '164970135-b14e424c-765a-4180-9bc8-fa8d6abc5510.json',\n                os.listdir(f'{tmp_dir}/predictions'))\n        self.assertTrue(inferencer._video_input)\n"
  },
  {
    "path": "tests/test_codecs/test_annotation_processors.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import YOLOXPoseAnnotationProcessor\n\n\nclass TestYOLOXPoseAnnotationProcessor(TestCase):\n\n    def test_encode(self):\n        processor = YOLOXPoseAnnotationProcessor(expand_bbox=True)\n\n        keypoints = np.array([[[0, 1], [2, 6], [4, 5]], [[5, 6], [7, 8],\n                                                         [8, 9]]])\n        keypoints_visible = np.array([[1, 1, 0], [1, 0, 1]])\n        bbox = np.array([[0, 1, 3, 4], [1, 2, 5, 6]])\n        category_id = [1, 2]\n\n        encoded = processor.encode(keypoints, keypoints_visible, bbox,\n                                   category_id)\n\n        self.assertTrue('bbox' in encoded)\n        self.assertTrue('bbox_labels' in encoded)\n        self.assertTrue(\n            np.array_equal(encoded['bbox'],\n                           np.array([[0., 1., 3., 6.], [1., 2., 8., 9.]])))\n        self.assertTrue(\n            np.array_equal(encoded['bbox_labels'], np.array([0, 1])))\n\n    def test_decode(self):\n        # make sure the `decode` method has been defined\n        processor = YOLOXPoseAnnotationProcessor()\n        _ = processor.decode(dict())\n"
  },
  {
    "path": "tests/test_codecs/test_associative_embedding.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nfrom munkres import Munkres\n\nfrom mmpose.codecs import AssociativeEmbedding\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom mmpose.testing import get_coco_sample\n\n\nclass TestAssociativeEmbedding(TestCase):\n\n    def setUp(self) -> None:\n        self.decode_keypoint_order = [\n            0, 1, 2, 3, 4, 5, 6, 11, 12, 7, 8, 9, 10, 13, 14, 15, 16\n        ]\n\n    def test_build(self):\n        cfg = dict(\n            type='AssociativeEmbedding',\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=False,\n            decode_keypoint_order=self.decode_keypoint_order,\n        )\n        codec = KEYPOINT_CODECS.build(cfg)\n        self.assertIsInstance(codec, AssociativeEmbedding)\n\n    def test_encode(self):\n        data = get_coco_sample(img_shape=(256, 256), num_instances=1)\n\n        # w/o UDP\n        codec = AssociativeEmbedding(\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=False,\n            decode_keypoint_order=self.decode_keypoint_order)\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n        keypoint_weights = encoded['keypoint_weights']\n\n        self.assertEqual(heatmaps.shape, (17, 64, 64))\n        self.assertEqual(keypoint_indices.shape, (1, 17, 2))\n        self.assertEqual(keypoint_weights.shape, (1, 17))\n\n        for k in range(heatmaps.shape[0]):\n            index_expected = np.argmax(heatmaps[k])\n            index_encoded = keypoint_indices[0, k, 0]\n            self.assertEqual(index_expected, index_encoded)\n\n        # w/ UDP\n        codec = AssociativeEmbedding(\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=True,\n            decode_keypoint_order=self.decode_keypoint_order)\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n        keypoint_weights = encoded['keypoint_weights']\n\n        self.assertEqual(heatmaps.shape, (17, 64, 64))\n        self.assertEqual(keypoint_indices.shape, (1, 17, 2))\n        self.assertEqual(keypoint_weights.shape, (1, 17))\n\n        for k in range(heatmaps.shape[0]):\n            index_expected = np.argmax(heatmaps[k])\n            index_encoded = keypoint_indices[0, k, 0]\n            self.assertEqual(index_expected, index_encoded)\n\n    def _get_tags(self,\n                  heatmaps,\n                  keypoint_indices,\n                  tag_per_keypoint: bool,\n                  tag_dim: int = 1):\n\n        K, H, W = heatmaps.shape\n        N = keypoint_indices.shape[0]\n\n        if tag_per_keypoint:\n            tags = np.zeros((K * tag_dim, H, W), dtype=np.float32)\n        else:\n            tags = np.zeros((tag_dim, H, W), dtype=np.float32)\n\n        for n, k in product(range(N), range(K)):\n            y, x = np.unravel_index(keypoint_indices[n, k, 0], (H, W))\n            if tag_per_keypoint:\n                tags[k::K, y, x] = n\n            else:\n                tags[:, y, x] = n\n\n        return tags\n\n    def _sort_preds(self, keypoints_pred, scores_pred, keypoints_gt):\n        \"\"\"Sort multi-instance predictions to best match the ground-truth.\n\n        Args:\n            keypoints_pred (np.ndarray): predictions in shape (N, K, D)\n            scores (np.ndarray): predictions in shape (N, K)\n            keypoints_gt (np.ndarray): ground-truth in shape (N, K, D)\n\n        Returns:\n            np.ndarray: Sorted predictions\n        \"\"\"\n        assert keypoints_gt.shape == keypoints_pred.shape\n        costs = np.linalg.norm(\n            keypoints_gt[None] - keypoints_pred[:, None], ord=2,\n            axis=3).mean(axis=2)\n        match = Munkres().compute(costs)\n        keypoints_pred_sorted = np.zeros_like(keypoints_pred)\n        scores_pred_sorted = np.zeros_like(scores_pred)\n        for i, j in match:\n            keypoints_pred_sorted[i] = keypoints_pred[j]\n            scores_pred_sorted[i] = scores_pred[j]\n\n        return keypoints_pred_sorted, scores_pred_sorted\n\n    def test_decode(self):\n        data = get_coco_sample(\n            img_shape=(256, 256), num_instances=2, non_occlusion=True)\n\n        # w/o UDP\n        codec = AssociativeEmbedding(\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=False,\n            decode_keypoint_order=self.decode_keypoint_order)\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n\n        tags = self._get_tags(\n            heatmaps, keypoint_indices, tag_per_keypoint=True)\n\n        # to Tensor\n        batch_heatmaps = torch.from_numpy(heatmaps[None])\n        batch_tags = torch.from_numpy(tags[None])\n\n        batch_keypoints, batch_keypoint_scores, batch_instance_scores = \\\n            codec.batch_decode(batch_heatmaps, batch_tags)\n\n        self.assertIsInstance(batch_keypoints, list)\n        self.assertIsInstance(batch_keypoint_scores, list)\n        self.assertEqual(len(batch_keypoints), 1)\n        self.assertEqual(len(batch_keypoint_scores), 1)\n\n        keypoints, scores = self._sort_preds(batch_keypoints[0],\n                                             batch_keypoint_scores[0],\n                                             data['keypoints'])\n\n        self.assertIsInstance(keypoints, np.ndarray)\n        self.assertIsInstance(scores, np.ndarray)\n        self.assertEqual(keypoints.shape, (2, 17, 2))\n        self.assertEqual(scores.shape, (2, 17))\n\n        self.assertTrue(np.allclose(keypoints, data['keypoints'], atol=4.0))\n\n        # w/o UDP, tag_imd=2\n        codec = AssociativeEmbedding(\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=False,\n            decode_keypoint_order=self.decode_keypoint_order)\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n\n        tags = self._get_tags(\n            heatmaps, keypoint_indices, tag_per_keypoint=True, tag_dim=2)\n\n        # to Tensor\n        batch_heatmaps = torch.from_numpy(heatmaps[None])\n        batch_tags = torch.from_numpy(tags[None])\n\n        batch_keypoints, batch_keypoint_scores, batch_instance_scores = \\\n            codec.batch_decode(batch_heatmaps, batch_tags)\n\n        self.assertIsInstance(batch_keypoints, list)\n        self.assertIsInstance(batch_keypoint_scores, list)\n        self.assertEqual(len(batch_keypoints), 1)\n        self.assertEqual(len(batch_keypoint_scores), 1)\n\n        keypoints, scores = self._sort_preds(batch_keypoints[0],\n                                             batch_keypoint_scores[0],\n                                             data['keypoints'])\n\n        self.assertIsInstance(keypoints, np.ndarray)\n        self.assertIsInstance(scores, np.ndarray)\n        self.assertEqual(keypoints.shape, (2, 17, 2))\n        self.assertEqual(scores.shape, (2, 17))\n\n        self.assertTrue(np.allclose(keypoints, data['keypoints'], atol=4.0))\n\n        # w/ UDP\n        codec = AssociativeEmbedding(\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=True,\n            decode_keypoint_order=self.decode_keypoint_order)\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n\n        tags = self._get_tags(\n            heatmaps, keypoint_indices, tag_per_keypoint=True)\n\n        # to Tensor\n        batch_heatmaps = torch.from_numpy(heatmaps[None])\n        batch_tags = torch.from_numpy(tags[None])\n\n        batch_keypoints, batch_keypoint_scores, batch_instance_scores = \\\n            codec.batch_decode(batch_heatmaps, batch_tags)\n\n        self.assertIsInstance(batch_keypoints, list)\n        self.assertIsInstance(batch_keypoint_scores, list)\n        self.assertEqual(len(batch_keypoints), 1)\n        self.assertEqual(len(batch_keypoint_scores), 1)\n\n        keypoints, scores = self._sort_preds(batch_keypoints[0],\n                                             batch_keypoint_scores[0],\n                                             data['keypoints'])\n\n        self.assertIsInstance(keypoints, np.ndarray)\n        self.assertIsInstance(scores, np.ndarray)\n        self.assertEqual(keypoints.shape, (2, 17, 2))\n        self.assertEqual(scores.shape, (2, 17))\n\n        self.assertTrue(np.allclose(keypoints, data['keypoints'], atol=4.0))\n"
  },
  {
    "path": "tests/test_codecs/test_decoupled_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import DecoupledHeatmap\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom mmpose.testing import get_coco_sample\n\n\nclass TestDecoupledHeatmap(TestCase):\n\n    def setUp(self) -> None:\n        pass\n\n    def _make_multi_instance_data(self, data):\n        bbox = data['bbox'].reshape(-1, 2, 2)\n        keypoints = data['keypoints']\n        keypoints_visible = data['keypoints_visible']\n\n        keypoints_visible[..., 0] = 0\n\n        offset = keypoints.max(axis=1, keepdims=True)\n        bbox_outside = bbox - offset\n        keypoints_outside = keypoints - offset\n        keypoints_outside_visible = np.zeros(keypoints_visible.shape)\n\n        bbox_overlap = bbox.mean(\n            axis=1, keepdims=True) + 0.8 * (\n                bbox - bbox.mean(axis=1, keepdims=True))\n        keypoint_overlap = keypoints.mean(\n            axis=1, keepdims=True) + 0.8 * (\n                keypoints - keypoints.mean(axis=1, keepdims=True))\n        keypoint_overlap_visible = keypoints_visible\n\n        data['bbox'] = np.concatenate((bbox, bbox_outside, bbox_overlap),\n                                      axis=0)\n        data['keypoints'] = np.concatenate(\n            (keypoints, keypoints_outside, keypoint_overlap), axis=0)\n        data['keypoints_visible'] = np.concatenate(\n            (keypoints_visible, keypoints_outside_visible,\n             keypoint_overlap_visible),\n            axis=0)\n\n        return data\n\n    def test_build(self):\n        cfg = dict(\n            type='DecoupledHeatmap',\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n        )\n        codec = KEYPOINT_CODECS.build(cfg)\n        self.assertIsInstance(codec, DecoupledHeatmap)\n\n    def test_encode(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n        data['bbox'] = np.tile(data['bbox'], 2).reshape(-1, 4, 2)\n        data['bbox'][:, 1:3, 0] = data['bbox'][:, 0:2, 0]\n        data = self._make_multi_instance_data(data)\n\n        codec = DecoupledHeatmap(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n        )\n\n        print(data['bbox'].shape)\n        encoded = codec.encode(\n            data['keypoints'], data['keypoints_visible'], bbox=data['bbox'])\n\n        heatmaps = encoded['heatmaps']\n        instance_heatmaps = encoded['instance_heatmaps']\n        keypoint_weights = encoded['keypoint_weights']\n        instance_coords = encoded['instance_coords']\n\n        self.assertEqual(heatmaps.shape, (18, 128, 128))\n        self.assertEqual(keypoint_weights.shape, (2, 17))\n        self.assertEqual(instance_heatmaps.shape, (34, 128, 128))\n        self.assertEqual(instance_coords.shape, (2, 2))\n\n        # without bbox\n        encoded = codec.encode(\n            data['keypoints'], data['keypoints_visible'], bbox=None)\n\n        heatmaps = encoded['heatmaps']\n        instance_heatmaps = encoded['instance_heatmaps']\n        keypoint_weights = encoded['keypoint_weights']\n        instance_coords = encoded['instance_coords']\n\n        self.assertEqual(heatmaps.shape, (18, 128, 128))\n        self.assertEqual(keypoint_weights.shape, (2, 17))\n        self.assertEqual(instance_heatmaps.shape, (34, 128, 128))\n        self.assertEqual(instance_coords.shape, (2, 2))\n\n        # root_type\n        with self.assertRaises(ValueError):\n            codec = DecoupledHeatmap(\n                input_size=(512, 512),\n                heatmap_size=(128, 128),\n                root_type='box_center',\n            )\n            encoded = codec.encode(\n                data['keypoints'],\n                data['keypoints_visible'],\n                bbox=data['bbox'])\n\n        codec = DecoupledHeatmap(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            root_type='bbox_center',\n        )\n\n        encoded = codec.encode(\n            data['keypoints'], data['keypoints_visible'], bbox=data['bbox'])\n\n        heatmaps = encoded['heatmaps']\n        instance_heatmaps = encoded['instance_heatmaps']\n        keypoint_weights = encoded['keypoint_weights']\n        instance_coords = encoded['instance_coords']\n\n        self.assertEqual(heatmaps.shape, (18, 128, 128))\n        self.assertEqual(keypoint_weights.shape, (2, 17))\n        self.assertEqual(instance_heatmaps.shape, (34, 128, 128))\n        self.assertEqual(instance_coords.shape, (2, 2))\n\n    def test_decode(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=2)\n        data['bbox'] = np.tile(data['bbox'], 2).reshape(-1, 4, 2)\n        data['bbox'][:, 1:3, 0] = data['bbox'][:, 0:2, 0]\n\n        codec = DecoupledHeatmap(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n        )\n\n        encoded = codec.encode(\n            data['keypoints'], data['keypoints_visible'], bbox=data['bbox'])\n        instance_heatmaps = encoded['instance_heatmaps'].reshape(\n            encoded['instance_coords'].shape[0], -1,\n            *encoded['instance_heatmaps'].shape[-2:])\n        instance_scores = np.ones(encoded['instance_coords'].shape[0])\n        decoded = codec.decode(instance_heatmaps, instance_scores[:, None])\n        keypoints, keypoint_scores = decoded\n\n        self.assertEqual(keypoints.shape, (2, 17, 2))\n        self.assertEqual(keypoint_scores.shape, (2, 17))\n\n    def test_cicular_verification(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n        data['bbox'] = np.tile(data['bbox'], 2).reshape(-1, 4, 2)\n        data['bbox'][:, 1:3, 0] = data['bbox'][:, 0:2, 0]\n\n        codec = DecoupledHeatmap(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n        )\n\n        encoded = codec.encode(\n            data['keypoints'], data['keypoints_visible'], bbox=data['bbox'])\n        instance_heatmaps = encoded['instance_heatmaps'].reshape(\n            encoded['instance_coords'].shape[0], -1,\n            *encoded['instance_heatmaps'].shape[-2:])\n        instance_scores = np.ones(encoded['instance_coords'].shape[0])\n        decoded = codec.decode(instance_heatmaps, instance_scores[:, None])\n        keypoints, _ = decoded\n        keypoints += 1.5\n\n        self.assertTrue(np.allclose(keypoints, data['keypoints'], atol=5.))\n"
  },
  {
    "path": "tests/test_codecs/test_edpose_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import EDPoseLabel\n\n\nclass TestEDPoseLabel(TestCase):\n\n    def setUp(self):\n        self.encoder = EDPoseLabel(num_select=2, num_keypoints=2)\n        self.img_shape = (640, 480)\n        self.keypoints = np.array([[[100, 50], [200, 50]],\n                                   [[300, 400], [100, 200]]])\n        self.area = np.array([5000, 8000])\n\n    def test_encode(self):\n        # Test encoding\n        encoded_data = self.encoder.encode(\n            img_shape=self.img_shape, keypoints=self.keypoints, area=self.area)\n\n        self.assertEqual(encoded_data['keypoints'].shape, self.keypoints.shape)\n        self.assertEqual(encoded_data['area'].shape, self.area.shape)\n\n        # Check if the keypoints were normalized correctly\n        expected_keypoints = self.keypoints / np.array(\n            self.img_shape, dtype=np.float32)\n        np.testing.assert_array_almost_equal(encoded_data['keypoints'],\n                                             expected_keypoints)\n\n        # Check if the area was normalized correctly\n        expected_area = self.area / float(\n            self.img_shape[0] * self.img_shape[1])\n        np.testing.assert_array_almost_equal(encoded_data['area'],\n                                             expected_area)\n\n    def test_decode(self):\n        # Dummy predictions for logits, boxes, and keypoints\n        pred_logits = np.array([0.7, 0.6]).reshape(2, 1)\n        pred_boxes = np.array([[0.1, 0.1, 0.5, 0.5], [0.6, 0.6, 0.8, 0.8]])\n        pred_keypoints = np.array([[0.2, 0.3, 1, 0.3, 0.4, 1],\n                                   [0.6, 0.7, 1, 0.7, 0.8, 1]])\n        input_shapes = np.array(self.img_shape)\n\n        # Test decoding\n        boxes, keypoints, scores = self.encoder.decode(\n            input_shapes=input_shapes,\n            pred_logits=pred_logits,\n            pred_boxes=pred_boxes,\n            pred_keypoints=pred_keypoints)\n\n        self.assertEqual(boxes.shape, pred_boxes.shape)\n        self.assertEqual(keypoints.shape, (self.encoder.num_select,\n                                           self.encoder.num_keypoints, 2))\n        self.assertEqual(scores.shape,\n                         (self.encoder.num_select, self.encoder.num_keypoints))\n"
  },
  {
    "path": "tests/test_codecs/test_hand_3d_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestHand3DHeatmap(TestCase):\n\n    def build_hand_3d_heatmap(self, **kwargs):\n        cfg = dict(type='Hand3DHeatmap')\n        cfg.update(kwargs)\n        return KEYPOINT_CODECS.build(cfg)\n\n    def setUp(self) -> None:\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 42, 3))\n        keypoints[..., :2] = keypoints[..., :2] * [256, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.ones((\n            1,\n            42,\n        ), dtype=np.float32)\n        heatmaps = np.random.rand(42, 64, 64, 64).astype(np.float32)\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            heatmaps=heatmaps)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        # test default settings\n        codec = self.build_hand_3d_heatmap()\n\n        encoded = codec.encode(\n            keypoints,\n            keypoints_visible,\n            dataset_keypoint_weights=np.ones(42, ),\n            rel_root_depth=np.float32(1.),\n            rel_root_valid=0.,\n            hand_type=np.array([[1, 0]]),\n            hand_type_valid=np.array([1]),\n            focal=np.array([1000., 1000.]),\n            principal_pt=np.array([200., 200.]))\n\n        self.assertEqual(encoded['heatmaps'].shape, (42 * 64, 64, 64))\n        self.assertEqual(encoded['keypoint_weights'].shape, (\n            1,\n            42,\n        ))\n\n        # test with different joint weights\n        codec = self.build_hand_3d_heatmap(use_different_joint_weights=True)\n\n        encoded = codec.encode(\n            keypoints,\n            keypoints_visible,\n            dataset_keypoint_weights=np.ones(42, ),\n            rel_root_depth=np.float32(1.),\n            rel_root_valid=0.,\n            hand_type=np.array([[1, 0]]),\n            hand_type_valid=np.array([1]),\n            focal=np.array([1000., 1000.]),\n            principal_pt=np.array([200., 200.]))\n\n        self.assertEqual(encoded['heatmaps'].shape, (42 * 64, 64, 64))\n        self.assertEqual(encoded['keypoint_weights'].shape, (\n            1,\n            42,\n        ))\n\n        # test joint_indices\n        codec = self.build_hand_3d_heatmap(joint_indices=[0, 8, 16])\n        encoded = codec.encode(\n            keypoints,\n            keypoints_visible,\n            dataset_keypoint_weights=np.ones(42, ),\n            rel_root_depth=np.float32(1.),\n            rel_root_valid=0.,\n            hand_type=np.array([[1, 0]]),\n            hand_type_valid=np.array([1]),\n            focal=np.array([1000., 1000.]),\n            principal_pt=np.array([200., 200.]))\n        self.assertEqual(encoded['heatmaps'].shape, (3 * 64, 64, 64))\n        self.assertEqual(encoded['keypoint_weights'].shape, (\n            1,\n            3,\n        ))\n\n    def test_decode(self):\n        heatmaps = self.data['heatmaps']\n\n        # test default settings\n        codec = self.build_hand_3d_heatmap()\n\n        keypoints, scores, _, _ = codec.decode(heatmaps, np.ones((1, )),\n                                               np.ones((1, 2)))\n\n        self.assertEqual(keypoints.shape, (1, 42, 3))\n        self.assertEqual(scores.shape, (1, 42))\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        codec = self.build_hand_3d_heatmap()\n\n        encoded = codec.encode(\n            keypoints,\n            keypoints_visible,\n            dataset_keypoint_weights=np.ones(42, ),\n            rel_root_depth=np.float32(1.),\n            rel_root_valid=0.,\n            hand_type=np.array([[1, 0]]),\n            hand_type_valid=np.array([1]),\n            focal=np.array([1000., 1000.]),\n            principal_pt=np.array([200., 200.]))\n        _keypoints, _, _, _ = codec.decode(\n            encoded['heatmaps'].reshape(42, 64, 64, 64), np.ones((1, )),\n            np.ones((1, 2)))\n\n        self.assertTrue(\n            np.allclose(keypoints[..., :2], _keypoints[..., :2], atol=5.))\n"
  },
  {
    "path": "tests/test_codecs/test_image_pose_lifting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import ImagePoseLifting\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestImagePoseLifting(TestCase):\n\n    def setUp(self) -> None:\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.random.randint(2, size=(1, 17))\n        lifting_target = (0.1 + 0.8 * np.random.rand(1, 17, 3))\n        lifting_target_visible = np.random.randint(\n            2, size=(\n                1,\n                17,\n            ))\n        encoded_wo_sigma = np.random.rand(1, 17, 3)\n\n        self.keypoints_mean = np.random.rand(17, 2).astype(np.float32)\n        self.keypoints_std = np.random.rand(17, 2).astype(np.float32) + 1e-6\n        self.target_mean = np.random.rand(1, 17, 3).astype(np.float32)\n        self.target_std = np.random.rand(1, 17, 3).astype(np.float32) + 1e-6\n\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            lifting_target=lifting_target,\n            lifting_target_visible=lifting_target_visible,\n            encoded_wo_sigma=encoded_wo_sigma)\n\n    def build_pose_lifting_label(self, **kwargs):\n        cfg = dict(\n            type='ImagePoseLifting',\n            num_keypoints=17,\n            root_index=0,\n            reshape_keypoints=False)\n        cfg.update(kwargs)\n        return KEYPOINT_CODECS.build(cfg)\n\n    def test_build(self):\n        codec = self.build_pose_lifting_label()\n        self.assertIsInstance(codec, ImagePoseLifting)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n        lifting_target = self.data['lifting_target']\n        lifting_target_visible = self.data['lifting_target_visible']\n\n        # test default settings\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(encoded['trajectory_weights'].shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(encoded['target_root'].shape, (\n            1,\n            3,\n        ))\n\n        # test removing root\n        codec = self.build_pose_lifting_label(\n            remove_root=True, save_index=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible)\n\n        self.assertTrue('target_root_removed' in encoded\n                        and 'target_root_index' in encoded)\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            16,\n        ))\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 16, 3))\n        self.assertEqual(encoded['target_root'].shape, (\n            1,\n            3,\n        ))\n\n        # test normalization\n        codec = self.build_pose_lifting_label(\n            keypoints_mean=self.keypoints_mean,\n            keypoints_std=self.keypoints_std,\n            target_mean=self.target_mean,\n            target_std=self.target_std)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n\n    def test_decode(self):\n        lifting_target = self.data['lifting_target']\n        encoded_wo_sigma = self.data['encoded_wo_sigma']\n\n        codec = self.build_pose_lifting_label()\n\n        decoded, scores = codec.decode(\n            encoded_wo_sigma, target_root=lifting_target[..., 0, :])\n\n        self.assertEqual(decoded.shape, (1, 17, 3))\n        self.assertEqual(scores.shape, (1, 17))\n\n        codec = self.build_pose_lifting_label(remove_root=True)\n\n        decoded, scores = codec.decode(\n            encoded_wo_sigma, target_root=lifting_target[..., 0, :])\n\n        self.assertEqual(decoded.shape, (1, 18, 3))\n        self.assertEqual(scores.shape, (1, 18))\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n        lifting_target = self.data['lifting_target']\n        lifting_target_visible = self.data['lifting_target_visible']\n\n        # test default settings\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible)\n\n        _keypoints, _ = codec.decode(\n            encoded['lifting_target_label'],\n            target_root=lifting_target[..., 0, :])\n\n        self.assertTrue(np.allclose(lifting_target, _keypoints, atol=5.))\n\n        # test removing root\n        codec = self.build_pose_lifting_label(remove_root=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible)\n\n        _keypoints, _ = codec.decode(\n            encoded['lifting_target_label'],\n            target_root=lifting_target[..., 0, :])\n\n        self.assertTrue(np.allclose(lifting_target, _keypoints, atol=5.))\n\n        # test normalization\n        codec = self.build_pose_lifting_label(\n            keypoints_mean=self.keypoints_mean,\n            keypoints_std=self.keypoints_std,\n            target_mean=self.target_mean,\n            target_std=self.target_std)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible)\n\n        _keypoints, _ = codec.decode(\n            encoded['lifting_target_label'],\n            target_root=lifting_target[..., 0, :])\n\n        self.assertTrue(np.allclose(lifting_target, _keypoints, atol=5.))\n"
  },
  {
    "path": "tests/test_codecs/test_integral_regression_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import IntegralRegressionLabel  # noqa: F401\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestRegressionLabel(TestCase):\n\n    # name and configs of all test cases\n    def setUp(self) -> None:\n        self.configs = [\n            (\n                'ipr',\n                dict(\n                    type='IntegralRegressionLabel',\n                    input_size=(192, 256),\n                    heatmap_size=(48, 64),\n                    sigma=2),\n            ),\n        ]\n\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        heatmaps = np.random.rand(17, 64, 48).astype(np.float32)\n        encoded_wo_sigma = np.random.rand(1, 17, 2)\n        keypoints_visible = np.ones((1, 17), dtype=np.float32)\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            heatmaps=heatmaps,\n            encoded_wo_sigma=encoded_wo_sigma)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n            heatmaps = encoded['heatmaps']\n            keypoint_labels = encoded['keypoint_labels']\n            keypoint_weights = encoded['keypoint_weights']\n\n            self.assertEqual(heatmaps.shape, (17, 64, 48),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(keypoint_labels.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(keypoint_weights.shape, (1, 17),\n                             f'Failed case: \"{name}\"')\n\n    def test_decode(self):\n        encoded_wo_sigma = self.data['encoded_wo_sigma']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            keypoints, scores = codec.decode(encoded_wo_sigma)\n\n            self.assertEqual(keypoints.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores.shape, (1, 17), f'Failed case: \"{name}\"')\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n            keypoint_labels = encoded['keypoint_labels']\n\n            _keypoints, _ = codec.decode(keypoint_labels)\n\n            self.assertTrue(\n                np.allclose(keypoints, _keypoints, atol=5.),\n                f'Failed case: \"{name}\"')\n"
  },
  {
    "path": "tests/test_codecs/test_megvii_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import MegviiHeatmap\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestMegviiHeatmap(TestCase):\n\n    def setUp(self) -> None:\n        # name and configs of all test cases\n        self.configs = [\n            (\n                'megvii',\n                dict(\n                    type='MegviiHeatmap',\n                    input_size=(192, 256),\n                    heatmap_size=(48, 64),\n                    kernel_size=11),\n            ),\n        ]\n\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.ones((1, 17), dtype=np.float32)\n        heatmaps = np.random.rand(17, 64, 48).astype(np.float32)\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            heatmaps=heatmaps)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n\n            self.assertEqual(encoded['heatmaps'].shape, (17, 64, 48),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(encoded['keypoint_weights'].shape,\n                             (1, 17)), f'Failed case: \"{name}\"'\n\n    def test_decode(self):\n        heatmaps = self.data['heatmaps']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            keypoints, scores = codec.decode(heatmaps)\n\n            self.assertEqual(keypoints.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores.shape, (1, 17), f'Failed case: \"{name}\"')\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n            _keypoints, _ = codec.decode(encoded['heatmaps'])\n\n            self.assertTrue(\n                np.allclose(keypoints, _keypoints, atol=5.),\n                f'Failed case: \"{name}\"')\n\n    def test_errors(self):\n        # multiple instance\n        codec = MegviiHeatmap(\n            input_size=(192, 256), heatmap_size=(48, 64), kernel_size=11)\n        keypoints = np.random.rand(2, 17, 2)\n        keypoints_visible = np.random.rand(2, 17)\n\n        with self.assertRaisesRegex(AssertionError,\n                                    'only support single-instance'):\n            codec.encode(keypoints, keypoints_visible)\n"
  },
  {
    "path": "tests/test_codecs/test_motionbert_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import load\n\nfrom mmpose.codecs import MotionBERTLabel\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestMotionBERTLabel(TestCase):\n\n    def get_camera_param(self, imgname, camera_param) -> dict:\n        \"\"\"Get camera parameters of a frame by its image name.\"\"\"\n        subj, rest = osp.basename(imgname).split('_', 1)\n        action, rest = rest.split('.', 1)\n        camera, rest = rest.split('_', 1)\n        return camera_param[(subj, camera)]\n\n    def build_pose_lifting_label(self, **kwargs):\n        cfg = dict(type='MotionBERTLabel', num_keypoints=17)\n        cfg.update(kwargs)\n        return KEYPOINT_CODECS.build(cfg)\n\n    def setUp(self) -> None:\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [1000, 1002]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.random.randint(2, size=(1, 17))\n        lifting_target = (0.1 + 0.8 * np.random.rand(1, 17, 3))\n        lifting_target_visible = np.random.randint(\n            2, size=(\n                1,\n                17,\n            ))\n        encoded_wo_sigma = np.random.rand(1, 17, 3)\n\n        camera_param = load('tests/data/h36m/cameras.pkl')\n        camera_param = self.get_camera_param(\n            'S1/S1_Directions_1.54138969/S1_Directions_1.54138969_000001.jpg',\n            camera_param)\n        factor = 0.1 + 5 * np.random.rand(1, )\n\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            lifting_target=lifting_target,\n            lifting_target_visible=lifting_target_visible,\n            camera_param=camera_param,\n            factor=factor,\n            encoded_wo_sigma=encoded_wo_sigma)\n\n    def test_build(self):\n        codec = self.build_pose_lifting_label()\n        self.assertIsInstance(codec, MotionBERTLabel)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n        lifting_target = self.data['lifting_target']\n        lifting_target_visible = self.data['lifting_target_visible']\n        camera_param = self.data['camera_param']\n        factor = self.data['factor']\n\n        # test default settings\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param, factor)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            17,\n        ))\n\n        # test concatenating visibility\n        codec = self.build_pose_lifting_label(concat_vis=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param, factor)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 3))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n\n    def test_decode(self):\n        encoded_wo_sigma = self.data['encoded_wo_sigma']\n        camera_param = self.data['camera_param']\n\n        # test default settings\n        codec = self.build_pose_lifting_label()\n\n        decoded, scores = codec.decode(encoded_wo_sigma)\n\n        self.assertEqual(decoded.shape, (1, 17, 3))\n        self.assertEqual(scores.shape, (1, 17))\n\n        # test denormalize according to image shape\n        codec = self.build_pose_lifting_label()\n\n        decoded, scores = codec.decode(\n            encoded_wo_sigma,\n            w=np.array([camera_param['w']]),\n            h=np.array([camera_param['h']]))\n\n        self.assertEqual(decoded.shape, (1, 17, 3))\n        self.assertEqual(scores.shape, (1, 17))\n\n        # test with factor\n        codec = self.build_pose_lifting_label()\n\n        decoded, scores = codec.decode(\n            encoded_wo_sigma, factor=np.array([0.23]))\n\n        self.assertEqual(decoded.shape, (1, 17, 3))\n        self.assertEqual(scores.shape, (1, 17))\n\n    def test_cicular_verification(self):\n        keypoints_visible = self.data['keypoints_visible']\n        lifting_target = self.data['lifting_target']\n        lifting_target_visible = self.data['lifting_target_visible']\n        camera_param = self.data['camera_param']\n\n        # test denormalize according to image shape\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 3))\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        _keypoints, _ = codec.decode(\n            encoded['keypoint_labels'],\n            w=np.array([camera_param['w']]),\n            h=np.array([camera_param['h']]))\n\n        keypoints[..., :, :] = keypoints[..., :, :] - keypoints[..., 0, :]\n\n        self.assertTrue(\n            np.allclose(keypoints[..., :2] / 1000, _keypoints[..., :2]))\n\n        # test with factor\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 3))\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        _keypoints, _ = codec.decode(\n            encoded['keypoint_labels'],\n            w=np.array([camera_param['w']]),\n            h=np.array([camera_param['h']]),\n            factor=encoded['factor'])\n\n        keypoints *= encoded['factor']\n        keypoints[..., :, :] = keypoints[..., :, :] - keypoints[..., 0, :]\n\n        self.assertTrue(\n            np.allclose(keypoints[..., :2] / 1000, _keypoints[..., :2]))\n"
  },
  {
    "path": "tests/test_codecs/test_msra_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import MSRAHeatmap\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestMSRAHeatmap(TestCase):\n\n    def setUp(self) -> None:\n        # name and configs of all test cases\n        self.configs = [\n            (\n                'msra',\n                dict(\n                    type='MSRAHeatmap',\n                    input_size=(192, 256),\n                    heatmap_size=(48, 64),\n                    sigma=2.0),\n            ),\n            (\n                'msra+dark',\n                dict(\n                    type='MSRAHeatmap',\n                    input_size=(192, 256),\n                    heatmap_size=(48, 64),\n                    sigma=2.0,\n                    unbiased=True),\n            ),\n        ]\n\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.ones((1, 17), dtype=np.float32)\n        heatmaps = np.random.rand(17, 64, 48).astype(np.float32)\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            heatmaps=heatmaps)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n\n            self.assertEqual(encoded['heatmaps'].shape, (17, 64, 48),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(encoded['keypoint_weights'].shape,\n                             (1, 17)), f'Failed case: \"{name}\"'\n\n    def test_decode(self):\n        heatmaps = self.data['heatmaps']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            keypoints, scores = codec.decode(heatmaps)\n\n            self.assertEqual(keypoints.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores.shape, (1, 17), f'Failed case: \"{name}\"')\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n            _keypoints, _ = codec.decode(encoded['heatmaps'])\n\n            self.assertTrue(\n                np.allclose(keypoints, _keypoints, atol=5.),\n                f'Failed case: \"{name}\"')\n\n    def test_errors(self):\n        # multiple instance\n        codec = MSRAHeatmap(\n            input_size=(192, 256), heatmap_size=(48, 64), sigma=2.0)\n        keypoints = np.random.rand(2, 17, 2)\n        keypoints_visible = np.random.rand(2, 17)\n\n        with self.assertRaisesRegex(AssertionError,\n                                    'only support single-instance'):\n            codec.encode(keypoints, keypoints_visible)\n"
  },
  {
    "path": "tests/test_codecs/test_regression_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import RegressionLabel  # noqa: F401\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestRegressionLabel(TestCase):\n\n    # name and configs of all test cases\n    def setUp(self) -> None:\n        self.configs = [\n            (\n                'regression',\n                dict(\n                    type='RegressionLabel',\n                    input_size=(192, 256),\n                ),\n            ),\n        ]\n\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        encoded_with_sigma = np.random.rand(1, 17, 4)\n        encoded_wo_sigma = np.random.rand(1, 17, 2)\n        keypoints_visible = np.ones((1, 17), dtype=np.float32)\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            encoded_with_sigma=encoded_with_sigma,\n            encoded_wo_sigma=encoded_wo_sigma)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n\n            self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(encoded['keypoint_weights'].shape, (1, 17),\n                             f'Failed case: \"{name}\"')\n\n    def test_decode(self):\n        encoded_with_sigma = self.data['encoded_with_sigma']\n        encoded_wo_sigma = self.data['encoded_wo_sigma']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            keypoints1, scores1 = codec.decode(encoded_with_sigma)\n            keypoints2, scores2 = codec.decode(encoded_wo_sigma)\n\n            self.assertEqual(keypoints1.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores1.shape, (1, 17), f'Failed case: \"{name}\"')\n            self.assertEqual(keypoints2.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores2.shape, (1, 17), f'Failed case: \"{name}\"')\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n\n            _keypoints, _ = codec.decode(encoded['keypoint_labels'])\n\n            self.assertTrue(\n                np.allclose(keypoints, _keypoints, atol=5.),\n                f'Failed case: \"{name}\"')\n"
  },
  {
    "path": "tests/test_codecs/test_simcc_label.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import SimCCLabel  # noqa: F401\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestSimCCLabel(TestCase):\n\n    # name and configs of all test cases\n    def setUp(self) -> None:\n        self.configs = [\n            (\n                'simcc gaussian',\n                dict(\n                    type='SimCCLabel',\n                    input_size=(192, 256),\n                    smoothing_type='gaussian',\n                    sigma=6.0,\n                    simcc_split_ratio=2.0),\n            ),\n            (\n                'simcc smoothing',\n                dict(\n                    type='SimCCLabel',\n                    input_size=(192, 256),\n                    smoothing_type='standard',\n                    sigma=5.0,\n                    simcc_split_ratio=3.0,\n                    label_smooth_weight=0.1),\n            ),\n            (\n                'simcc one-hot',\n                dict(\n                    type='SimCCLabel',\n                    input_size=(192, 256),\n                    smoothing_type='standard',\n                    sigma=5.0,\n                    simcc_split_ratio=3.0),\n            ),\n            (\n                'simcc dark',\n                dict(\n                    type='SimCCLabel',\n                    input_size=(192, 256),\n                    smoothing_type='gaussian',\n                    sigma=6.0,\n                    simcc_split_ratio=2.0,\n                    use_dark=True),\n            ),\n            (\n                'simcc separated sigmas',\n                dict(\n                    type='SimCCLabel',\n                    input_size=(192, 256),\n                    smoothing_type='gaussian',\n                    sigma=(4.9, 5.66),\n                    simcc_split_ratio=2.0),\n            ),\n        ]\n\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.ones((1, 17), dtype=np.float32)\n        self.data = dict(\n            keypoints=keypoints, keypoints_visible=keypoints_visible)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n\n            self.assertEqual(encoded['keypoint_x_labels'].shape,\n                             (1, 17, int(192 * codec.simcc_split_ratio)),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(encoded['keypoint_y_labels'].shape,\n                             (1, 17, int(256 * codec.simcc_split_ratio)),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(encoded['keypoint_weights'].shape, (1, 17),\n                             f'Failed case: \"{name}\"')\n\n    def test_decode(self):\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            simcc_x = np.random.rand(1, 17, int(192 * codec.simcc_split_ratio))\n            simcc_y = np.random.rand(1, 17, int(256 * codec.simcc_split_ratio))\n\n            keypoints, scores = codec.decode(simcc_x, simcc_y)\n\n            self.assertEqual(keypoints.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores.shape, (1, 17), f'Failed case: \"{name}\"')\n\n        # test decode_visibility\n        cfg = cfg.copy()\n        cfg['decode_visibility'] = True\n        codec = KEYPOINT_CODECS.build(cfg)\n\n        simcc_x = np.random.rand(1, 17, int(\n            192 * codec.simcc_split_ratio)) * 10\n        simcc_y = np.random.rand(1, 17, int(\n            256 * codec.simcc_split_ratio)) * 10\n        keypoints, scores = codec.decode(simcc_x, simcc_y)\n\n        self.assertEqual(len(scores), 2)\n        self.assertEqual(scores[0].shape, (1, 17), f'Failed case: \"{name}\"')\n        self.assertEqual(scores[1].shape, (1, 17), f'Failed case: \"{name}\"')\n        self.assertGreaterEqual(scores[1].min(), 0.0)\n        self.assertLessEqual(scores[1].max(), 1.0)\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n            keypoint_x_labels = encoded['keypoint_x_labels']\n            keypoint_y_labels = encoded['keypoint_y_labels']\n\n            _keypoints, _ = codec.decode(keypoint_x_labels, keypoint_y_labels)\n\n            self.assertTrue(\n                np.allclose(keypoints, _keypoints, atol=5.),\n                f'Failed case: \"{name}\"')\n\n    def test_errors(self):\n        cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='uniform',\n            sigma=1.0,\n            simcc_split_ratio=2.0)\n\n        with self.assertRaisesRegex(ValueError,\n                                    'got invalid `smoothing_type`'):\n            _ = KEYPOINT_CODECS.build(cfg)\n\n        # invalid label_smooth_weight in smoothing\n        cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='standard',\n            sigma=1.0,\n            simcc_split_ratio=2.0,\n            label_smooth_weight=1.1)\n\n        with self.assertRaisesRegex(ValueError,\n                                    '`label_smooth_weight` should be'):\n            _ = KEYPOINT_CODECS.build(cfg)\n\n        # invalid label_smooth_weight for gaussian\n        cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=1.0,\n            simcc_split_ratio=2.0,\n            label_smooth_weight=0.1)\n\n        with self.assertRaisesRegex(ValueError,\n                                    'is only used for `standard` mode.'):\n            _ = KEYPOINT_CODECS.build(cfg)\n"
  },
  {
    "path": "tests/test_codecs/test_spr.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import SPR\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom mmpose.testing import get_coco_sample\nfrom mmpose.utils.tensor_utils import to_numpy, to_tensor\n\n\nclass TestSPR(TestCase):\n\n    def setUp(self) -> None:\n        pass\n\n    def _make_multi_instance_data(self, data):\n        keypoints = data['keypoints']\n        keypoints_visible = data['keypoints_visible']\n\n        keypoints_visible[..., 0] = 0\n\n        keypoints_outside = keypoints - keypoints.max(axis=-1, keepdims=True)\n        keypoints_outside_visible = np.zeros(keypoints_visible.shape)\n\n        keypoint_overlap = keypoints.mean(\n            axis=-1, keepdims=True) + 0.8 * (\n                keypoints - keypoints.mean(axis=-1, keepdims=True))\n        keypoint_overlap_visible = keypoints_visible\n\n        data['keypoints'] = np.concatenate(\n            (keypoints, keypoints_outside, keypoint_overlap), axis=0)\n        data['keypoints_visible'] = np.concatenate(\n            (keypoints_visible, keypoints_outside_visible,\n             keypoint_overlap_visible),\n            axis=0)\n\n        return data\n\n    def test_build(self):\n        cfg = dict(\n            type='SPR',\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=4,\n        )\n        codec = KEYPOINT_CODECS.build(cfg)\n        self.assertIsInstance(codec, SPR)\n\n    def test_encode(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n        data = self._make_multi_instance_data(data)\n\n        # w/o keypoint heatmaps\n        codec = SPR(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=4,\n        )\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        displacements = encoded['displacements']\n        heatmap_weights = encoded['heatmap_weights']\n        displacement_weights = encoded['displacement_weights']\n\n        self.assertEqual(heatmaps.shape, (1, 128, 128))\n        self.assertEqual(heatmap_weights.shape, (1, 128, 128))\n        self.assertEqual(displacements.shape, (34, 128, 128))\n        self.assertEqual(displacement_weights.shape, (34, 128, 128))\n\n        # w/ keypoint heatmaps\n        with self.assertRaises(AssertionError):\n            codec = SPR(\n                input_size=(512, 512),\n                heatmap_size=(128, 128),\n                sigma=4,\n                generate_keypoint_heatmaps=True,\n            )\n\n        codec = SPR(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, 2),\n            generate_keypoint_heatmaps=True,\n        )\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        displacements = encoded['displacements']\n        heatmap_weights = encoded['heatmap_weights']\n        displacement_weights = encoded['displacement_weights']\n\n        self.assertEqual(heatmaps.shape, (18, 128, 128))\n        self.assertEqual(heatmap_weights.shape, (18, 128, 128))\n        self.assertEqual(displacements.shape, (34, 128, 128))\n        self.assertEqual(displacement_weights.shape, (34, 128, 128))\n\n        # root_type\n        with self.assertRaises(ValueError):\n            codec = SPR(\n                input_size=(512, 512),\n                heatmap_size=(128, 128),\n                sigma=(4, ),\n                root_type='box_center',\n            )\n            encoded = codec.encode(data['keypoints'],\n                                   data['keypoints_visible'])\n\n        codec = SPR(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, ),\n            root_type='bbox_center',\n        )\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n\n        heatmaps = encoded['heatmaps']\n        displacements = encoded['displacements']\n        heatmap_weights = encoded['heatmap_weights']\n        displacement_weights = encoded['displacement_weights']\n\n        self.assertEqual(heatmaps.shape, (1, 128, 128))\n        self.assertEqual(heatmap_weights.shape, (1, 128, 128))\n        self.assertEqual(displacements.shape, (34, 128, 128))\n        self.assertEqual(displacement_weights.shape, (34, 128, 128))\n\n    def test_decode(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n\n        # decode w/o keypoint heatmaps\n        codec = SPR(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, ),\n            generate_keypoint_heatmaps=False,\n        )\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n        decoded = codec.decode(\n            to_tensor(encoded['heatmaps']),\n            to_tensor(encoded['displacements']))\n\n        keypoints, (root_scores, keypoint_scores) = decoded\n        self.assertIsNone(keypoint_scores)\n        self.assertEqual(keypoints.shape, data['keypoints'].shape)\n        self.assertEqual(root_scores.shape, data['keypoints'].shape[:1])\n\n        # decode w/ keypoint heatmaps\n        codec = SPR(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, 2),\n            generate_keypoint_heatmaps=True,\n        )\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n        decoded = codec.decode(\n            to_tensor(encoded['heatmaps']),\n            to_tensor(encoded['displacements']))\n\n        keypoints, (root_scores, keypoint_scores) = decoded\n        self.assertIsNotNone(keypoint_scores)\n        self.assertEqual(keypoints.shape, data['keypoints'].shape)\n        self.assertEqual(root_scores.shape, data['keypoints'].shape[:1])\n        self.assertEqual(keypoint_scores.shape, data['keypoints'].shape[:2])\n\n    def test_cicular_verification(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n\n        codec = SPR(\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, ),\n            generate_keypoint_heatmaps=False,\n        )\n\n        encoded = codec.encode(data['keypoints'], data['keypoints_visible'])\n        decoded = codec.decode(\n            to_tensor(encoded['heatmaps']),\n            to_tensor(encoded['displacements']))\n\n        keypoints, _ = decoded\n        self.assertTrue(\n            np.allclose(to_numpy(keypoints), data['keypoints'], atol=5.))\n"
  },
  {
    "path": "tests/test_codecs/test_udp_heatmap.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.codecs import UDPHeatmap\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestUDPHeatmap(TestCase):\n\n    def setUp(self) -> None:\n        # name and configs of all test cases\n        self.configs = [\n            (\n                'udp gaussian',\n                dict(\n                    type='UDPHeatmap',\n                    input_size=(192, 256),\n                    heatmap_size=(48, 64),\n                    heatmap_type='gaussian',\n                ),\n            ),\n            (\n                'udp combined',\n                dict(\n                    type='UDPHeatmap',\n                    input_size=(192, 256),\n                    heatmap_size=(48, 64),\n                    heatmap_type='combined'),\n            ),\n        ]\n\n        # The bbox is usually padded so the keypoint will not be near the\n        # boundary\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.ones((1, 17), dtype=np.float32)\n        self.data = dict(\n            keypoints=keypoints, keypoints_visible=keypoints_visible)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n\n            if codec.heatmap_type == 'combined':\n                channel_per_kpt = 3\n            else:\n                channel_per_kpt = 1\n\n            self.assertEqual(encoded['heatmaps'].shape,\n                             (channel_per_kpt * 17, 64, 48),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(encoded['keypoint_weights'].shape,\n                             (1, 17)), f'Failed case: \"{name}\"'\n\n    def test_decode(self):\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n            if codec.heatmap_type == 'combined':\n                channel_per_kpt = 3\n            else:\n                channel_per_kpt = 1\n\n            heatmaps = np.random.rand(channel_per_kpt * 17, 64,\n                                      48).astype(np.float32)\n\n            keypoints, scores = codec.decode(heatmaps)\n\n            self.assertEqual(keypoints.shape, (1, 17, 2),\n                             f'Failed case: \"{name}\"')\n            self.assertEqual(scores.shape, (1, 17), f'Failed case: \"{name}\"')\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n\n        for name, cfg in self.configs:\n            codec = KEYPOINT_CODECS.build(cfg)\n\n            encoded = codec.encode(keypoints, keypoints_visible)\n            _keypoints, _ = codec.decode(encoded['heatmaps'])\n\n            self.assertTrue(\n                np.allclose(keypoints, _keypoints, atol=10.),\n                f'Failed case: \"{name}\",{abs(keypoints - _keypoints) < 5.} ')\n\n    def test_errors(self):\n        # invalid heatmap type\n        with self.assertRaisesRegex(ValueError, 'invalid `heatmap_type`'):\n            _ = UDPHeatmap(\n                input_size=(192, 256),\n                heatmap_size=(48, 64),\n                heatmap_type='invalid')\n\n        # multiple instance\n        codec = UDPHeatmap(input_size=(192, 256), heatmap_size=(48, 64))\n        keypoints = np.random.rand(2, 17, 2)\n        keypoints_visible = np.random.rand(2, 17)\n\n        with self.assertRaisesRegex(AssertionError,\n                                    'only support single-instance'):\n            codec.encode(keypoints, keypoints_visible)\n"
  },
  {
    "path": "tests/test_codecs/test_video_pose_lifting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import load\n\nfrom mmpose.codecs import VideoPoseLifting\nfrom mmpose.registry import KEYPOINT_CODECS\n\n\nclass TestVideoPoseLifting(TestCase):\n\n    def get_camera_param(self, imgname, camera_param) -> dict:\n        \"\"\"Get camera parameters of a frame by its image name.\"\"\"\n        subj, rest = osp.basename(imgname).split('_', 1)\n        action, rest = rest.split('.', 1)\n        camera, rest = rest.split('_', 1)\n        return camera_param[(subj, camera)]\n\n    def build_pose_lifting_label(self, **kwargs):\n        cfg = dict(\n            type='VideoPoseLifting', num_keypoints=17, reshape_keypoints=False)\n        cfg.update(kwargs)\n        return KEYPOINT_CODECS.build(cfg)\n\n    def setUp(self) -> None:\n        keypoints = (0.1 + 0.8 * np.random.rand(1, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.random.randint(2, size=(1, 17))\n        lifting_target = (0.1 + 0.8 * np.random.rand(1, 17, 3))\n        lifting_target_visible = np.random.randint(\n            2, size=(\n                1,\n                17,\n            ))\n        encoded_wo_sigma = np.random.rand(1, 17, 3)\n\n        camera_param = load('tests/data/h36m/cameras.pkl')\n        camera_param = self.get_camera_param(\n            'S1/S1_Directions_1.54138969/S1_Directions_1.54138969_000001.jpg',\n            camera_param)\n\n        self.data = dict(\n            keypoints=keypoints,\n            keypoints_visible=keypoints_visible,\n            lifting_target=lifting_target,\n            lifting_target_visible=lifting_target_visible,\n            camera_param=camera_param,\n            encoded_wo_sigma=encoded_wo_sigma)\n\n    def test_build(self):\n        codec = self.build_pose_lifting_label()\n        self.assertIsInstance(codec, VideoPoseLifting)\n\n    def test_encode(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n        lifting_target = self.data['lifting_target']\n        lifting_target_visible = self.data['lifting_target_visible']\n        camera_param = self.data['camera_param']\n\n        # test default settings\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(encoded['trajectory_weights'].shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(encoded['target_root'].shape, (\n            1,\n            3,\n        ))\n\n        # test not zero-centering\n        codec = self.build_pose_lifting_label(zero_center=False)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(encoded['trajectory_weights'].shape, (\n            1,\n            17,\n        ))\n\n        # test reshape_keypoints\n        codec = self.build_pose_lifting_label(reshape_keypoints=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (34, 1))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 17, 3))\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(encoded['trajectory_weights'].shape, (\n            1,\n            17,\n        ))\n\n        # test removing root\n        codec = self.build_pose_lifting_label(\n            remove_root=True, save_index=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        self.assertTrue('target_root_removed' in encoded\n                        and 'target_root_index' in encoded)\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            1,\n            16,\n        ))\n        self.assertEqual(encoded['keypoint_labels'].shape, (1, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (1, 16, 3))\n        self.assertEqual(encoded['target_root'].shape, (\n            1,\n            3,\n        ))\n\n        # test normalizing camera\n        codec = self.build_pose_lifting_label(normalize_camera=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        self.assertTrue('camera_param' in encoded)\n        scale = np.array(0.5 * camera_param['w'], dtype=np.float32)\n        self.assertTrue(\n            np.allclose(\n                camera_param['f'] / scale,\n                encoded['camera_param']['f'],\n                atol=4.))\n\n        # test with multiple targets\n        keypoints = (0.1 + 0.8 * np.random.rand(2, 17, 2)) * [192, 256]\n        keypoints = np.round(keypoints).astype(np.float32)\n        keypoints_visible = np.random.randint(2, size=(2, 17))\n        lifting_target = (0.1 + 0.8 * np.random.rand(2, 17, 3))\n        lifting_target_visible = np.random.randint(\n            2, size=(\n                2,\n                17,\n            ))\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        self.assertEqual(encoded['keypoint_labels'].shape, (2, 17, 2))\n        self.assertEqual(encoded['lifting_target_label'].shape, (2, 17, 3))\n        self.assertEqual(encoded['lifting_target_weight'].shape, (\n            2,\n            17,\n        ))\n        self.assertEqual(encoded['trajectory_weights'].shape, (\n            2,\n            17,\n        ))\n        self.assertEqual(encoded['target_root'].shape, (\n            2,\n            3,\n        ))\n\n    def test_decode(self):\n        lifting_target = self.data['lifting_target']\n        encoded_wo_sigma = self.data['encoded_wo_sigma']\n\n        codec = self.build_pose_lifting_label()\n\n        decoded, scores = codec.decode(\n            encoded_wo_sigma, target_root=lifting_target[..., 0, :])\n\n        self.assertEqual(decoded.shape, (1, 17, 3))\n        self.assertEqual(scores.shape, (1, 17))\n\n        codec = self.build_pose_lifting_label(remove_root=True)\n\n        decoded, scores = codec.decode(\n            encoded_wo_sigma, target_root=lifting_target[..., 0, :])\n\n        self.assertEqual(decoded.shape, (1, 18, 3))\n        self.assertEqual(scores.shape, (1, 18))\n\n    def test_cicular_verification(self):\n        keypoints = self.data['keypoints']\n        keypoints_visible = self.data['keypoints_visible']\n        lifting_target = self.data['lifting_target']\n        lifting_target_visible = self.data['lifting_target_visible']\n        camera_param = self.data['camera_param']\n\n        # test default settings\n        codec = self.build_pose_lifting_label()\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        _keypoints, _ = codec.decode(\n            encoded['lifting_target_label'],\n            target_root=lifting_target[..., 0, :])\n\n        self.assertTrue(np.allclose(lifting_target, _keypoints, atol=5.))\n\n        # test removing root\n        codec = self.build_pose_lifting_label(remove_root=True)\n        encoded = codec.encode(keypoints, keypoints_visible, lifting_target,\n                               lifting_target_visible, camera_param)\n\n        _keypoints, _ = codec.decode(\n            encoded['lifting_target_label'],\n            target_root=lifting_target[..., 0, :])\n\n        self.assertTrue(np.allclose(lifting_target, _keypoints, atol=5.))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_animalkingdom_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import AnimalKingdomDataset\n\n\nclass TestAnimalKingdomDataset(TestCase):\n\n    def build_ak_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_animalkingdom.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/ak',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return AnimalKingdomDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_ak_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'Animal Kingdom')\n\n        # test number of keypoints\n        num_keypoints = 23\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_ak_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_ak_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_ak_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_ak_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_ak_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_ak_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_ak_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_ak_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_animalpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import AnimalPoseDataset\n\n\nclass TestAnimalPoseDataset(TestCase):\n\n    def build_animalpose_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_animalpose.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/animalpose',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return AnimalPoseDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_animalpose_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'animalpose')\n\n        # test number of keypoints\n        num_keypoints = 20\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_animalpose_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_animalpose_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_animalpose_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_animalpose_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_animalpose_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_animalpose_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_animalpose_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_animalpose_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_ap10k_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import AP10KDataset\n\n\nclass TestAP10KDataset(TestCase):\n\n    def build_ap10k_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_ap10k.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/ap10k',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return AP10KDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_ap10k_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'ap10k')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_ap10k_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_ap10k_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.test_mode, True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_ap10k_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_ap10k_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_ap10k_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_ap10k_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_ap10k_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_ap10k_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_atrw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import ATRWDataset\n\n\nclass TestATRWDataset(TestCase):\n\n    def build_atrw_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_atrw.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/atrw',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return ATRWDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_atrw_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'atrw')\n\n        # test number of keypoints\n        num_keypoints = 15\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_atrw_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_atrw_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_atrw_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_atrw_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_atrw_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_atrw_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_atrw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_atrw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_fly_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import FlyDataset\n\n\nclass TestFlyDataset(TestCase):\n\n    def build_fly_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_fly.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/fly',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return FlyDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_fly_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'fly')\n\n        # test number of keypoints\n        num_keypoints = 32\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_fly_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_fly_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_fly_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_fly_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_fly_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_fly_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_fly_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_fly_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_horse10_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import Horse10Dataset\n\n\nclass TestHorse10Dataset(TestCase):\n\n    def build_horse10_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_horse10.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/horse10',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return Horse10Dataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_horse10_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'horse10')\n\n        # test number of keypoints\n        num_keypoints = 22\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_horse10_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_horse10_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_horse10_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_horse10_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_horse10_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_horse10_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_horse10_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_horse10_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_locust_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import LocustDataset\n\n\nclass TestLocustDataset(TestCase):\n\n    def build_locust_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_locust.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/locust',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return LocustDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_locust_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'locust')\n\n        # test number of keypoints\n        num_keypoints = 35\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_locust_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_locust_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_locust_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_locust_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_locust_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_locust_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_locust_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_locust_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_macaque_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import MacaqueDataset\n\n\nclass TestMacaqueDataset(TestCase):\n\n    def build_macaque_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_macaque.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/macaque',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return MacaqueDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_macaque_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'macaque')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_macaque_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_macaque_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_macaque_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_macaque_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_macaque_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_macaque_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_macaque_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_macaque_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_animal_datasets/test_zebra_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.animal import ZebraDataset\n\n\nclass TestZebraDataset(TestCase):\n\n    def build_zebra_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_zebra.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/zebra',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return ZebraDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_zebra_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'zebra')\n\n        # test number of keypoints\n        num_keypoints = 9\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_zebra_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_zebra_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_zebra_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_zebra_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_zebra_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_zebra_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_zebra_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_zebra_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_aic_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import AicDataset\n\n\nclass TestAicDataset(TestCase):\n\n    def build_aic_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_aic.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/aic',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return AicDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_aic_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'aic')\n\n        # test number of keypoints\n        num_keypoints = 14\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_aic_dataset(data_mode='topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 9)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_aic_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 9)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_aic_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_aic_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_aic_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_aic_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_aic_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_aic_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_coco_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import CocoDataset\n\n\nclass TestCocoDataset(TestCase):\n\n    def build_coco_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_coco.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/coco',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return CocoDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_coco_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'coco')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_coco_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 12)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_coco_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 12)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with bbox file\n        dataset = self.build_coco_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n        self.assertEqual(len(dataset), 118)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with filter config\n        dataset = self.build_coco_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/coco/test_coco_det_AP_H_56.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(len(dataset), 33)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_coco_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_coco_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_coco_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_coco_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_coco_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_coco_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_crowdpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import CrowdPoseDataset\n\n\nclass TestCrowdPoseDataset(TestCase):\n\n    def build_crowdpose_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_crowdpose.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/crowdpose',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return CrowdPoseDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_crowdpose_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'crowdpose')\n\n        # test number of keypoints\n        num_keypoints = 14\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_crowdpose_dataset(data_mode='topdown')\n        # filter an invalid instance due to num_keypoints = 0\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_crowdpose_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with bbox file\n        dataset = self.build_crowdpose_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/crowdpose/test_crowdpose_det_AP_40.json')\n        self.assertEqual(len(dataset), 6)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with filter config\n        # filter one instance due to bbox_score < bbox_score_thr\n        dataset = self.build_crowdpose_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/crowdpose/test_crowdpose_det_AP_40.json',\n            filter_cfg=dict(bbox_score_thr=0.97))\n        self.assertEqual(len(dataset), 5)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_crowdpose_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_crowdpose_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_crowdpose_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_crowdpose_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/crowdpose/test_crowdpose_det_AP_40.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_crowdpose_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/crowdpose/test_crowdpose_det_AP_40.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_crowdpose_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.97))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_exlpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import ExlposeDataset\n\n\nclass TestExlposeDataset(TestCase):\n\n    def build_exlpose_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_exlpose.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/exlpose',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return ExlposeDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_exlpose_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'exlpose')\n\n        # test number of keypoints\n        num_keypoints = 14\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_exlpose_dataset(data_mode='topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 6)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_exlpose_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 6)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_exlpose_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_exlpose_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_exlpose_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_exlpose_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_exlpose_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_exlpose_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_h36m_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body3d import Human36mDataset\n\n\nclass TestH36MDataset(TestCase):\n\n    def build_h36m_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_h36m_body3d.npz',\n            data_mode='topdown',\n            data_root='tests/data/h36m',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return Human36mDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_ids=list,\n                img_paths=list,\n                keypoints=np.ndarray,\n                keypoints_3d=np.ndarray,\n                scale=np.float32,\n                center=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_ids=list,\n                img_paths=list,\n                keypoints=np.ndarray,\n                keypoints_3d=np.ndarray,\n                scale=list,\n                center=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_h36m_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'h36m')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_h36m_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_h36m_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown training with camera file\n        dataset = self.build_h36m_dataset(\n            data_mode='topdown', camera_param_file='cameras.pkl')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown training with sequence config\n        dataset = self.build_h36m_dataset(\n            data_mode='topdown',\n            seq_len=27,\n            seq_step=1,\n            causal=False,\n            pad_video_seq=True,\n            camera_param_file='cameras.pkl')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        dataset = self.build_h36m_dataset(\n            data_mode='topdown',\n            seq_len=1,\n            seq_step=1,\n            multiple_target=1,\n            causal=False,\n            pad_video_seq=True,\n            camera_param_file='cameras.pkl')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with 2d keypoint detection file and\n        # sequence config\n        dataset = self.build_h36m_dataset(\n            data_mode='topdown',\n            seq_len=27,\n            seq_step=1,\n            causal=False,\n            pad_video_seq=True,\n            test_mode=True,\n            keypoint_2d_src='detection',\n            keypoint_2d_det_file='test_h36m_2d_detection.npy')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_h36m_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup training\n        dataset = self.build_h36m_dataset(\n            data_mode='bottomup',\n            seq_len=27,\n            seq_step=1,\n            causal=False,\n            pad_video_seq=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_h36m_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_h36m_dataset(data_mode='invalid')\n\n        SUPPORTED_keypoint_2d_src = {'gt', 'detection', 'pipeline'}\n        with self.assertRaisesRegex(\n                ValueError, 'Unsupported `keypoint_2d_src` \"invalid\". '\n                f'Supported options are {SUPPORTED_keypoint_2d_src}'):\n            _ = self.build_h36m_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                keypoint_2d_src='invalid')\n\n        with self.assertRaisesRegex(AssertionError,\n                                    'Annotation file `(.+?)` does not exist'):\n            _ = self.build_h36m_dataset(\n                data_mode='topdown', test_mode=False, ann_file='invalid')\n\n        with self.assertRaisesRegex(AssertionError,\n                                    'Unsupported `subset_frac` 2.'):\n            _ = self.build_h36m_dataset(data_mode='topdown', subset_frac=2)\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_humanart21_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import HumanArt21Dataset\n\n\nclass TestHumanart21Dataset(TestCase):\n\n    def build_humanart_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_humanart.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/humanart',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return HumanArt21Dataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_humanart_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'Human-Art')\n\n        # test number of keypoints\n        num_keypoints = 21\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_humanart_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_humanart_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with bbox file\n        dataset = self.build_humanart_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json')\n        self.assertEqual(len(dataset), 13)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with filter config\n        dataset = self.build_humanart_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(len(dataset), 8)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_humanart_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_humanart_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_humanart_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_humanart_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_humanart_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_humanart_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_humanart_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import HumanArtDataset\n\n\nclass TestHumanartDataset(TestCase):\n\n    def build_humanart_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_humanart.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/humanart',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return HumanArtDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_humanart_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'Human-Art')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_humanart_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_humanart_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with bbox file\n        dataset = self.build_humanart_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json')\n        self.assertEqual(len(dataset), 13)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with filter config\n        dataset = self.build_humanart_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(len(dataset), 8)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_humanart_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_humanart_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_humanart_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_humanart_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_humanart_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/humanart/test_humanart_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_humanart_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_jhmdb_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import JhmdbDataset\n\n\nclass TestJhmdbDataset(TestCase):\n\n    def build_jhmdb_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_jhmdb_sub1.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/jhmdb',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return JhmdbDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_jhmdb_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'jhmdb')\n\n        # test number of keypoints\n        num_keypoints = 15\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_jhmdb_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_jhmdb_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_jhmdb_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_jhmdb_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_jhmdb_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_jhmdb_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_jhmdb_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_jhmdb_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_mhp_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import MhpDataset\n\n\nclass TestMhpDataset(TestCase):\n\n    def build_mhp_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_mhp.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/mhp',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return MhpDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                num_keypoints=int,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                iscrowd=int,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                num_keypoints=list,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_mhp_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'mhp')\n\n        # test number of keypoints\n        num_keypoints = 16\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_mhp_dataset(data_mode='topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_mhp_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_mhp_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_mhp_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_mhp_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_mhp_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_mhp_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_mhp_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_mpii_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import MpiiDataset\n\n\nclass TestMpiiDataset(TestCase):\n\n    def build_mpii_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_mpii.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/mpii',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return MpiiDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_mpii_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'mpii')\n\n        # test number of keypoints\n        num_keypoints = 16\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_mpii_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_mpii_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_mpii_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_mpii_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_mpii_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_mpii_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_mpii_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_mpii_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_mpii_trb_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import MpiiTrbDataset\n\n\nclass TestMpiiTrbDataset(TestCase):\n\n    def build_mpii_trb_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_mpii_trb.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/mpii',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return MpiiTrbDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_mpii_trb_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'mpii_trb')\n\n        # test number of keypoints\n        num_keypoints = 40\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_mpii_trb_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_mpii_trb_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_mpii_trb_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_mpii_trb_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_mpii_trb_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_mpii_trb_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_mpii_trb_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_mpii_trb_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_ochuman_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import OCHumanDataset\n\n\nclass TestOCHumanDataset(TestCase):\n\n    def build_ochuman_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_ochuman.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/ochuman',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return OCHumanDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_ochuman_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'ochuman')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_ochuman_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_ochuman_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 5)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_ochuman_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_ochuman_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_ochuman_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_ochuman_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_ochuman_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_ochuman_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_posetrack18_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import PoseTrack18Dataset\n\n\nclass TestPoseTrack18Dataset(TestCase):\n\n    def build_posetrack18_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='annotations/test_posetrack18_val.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/posetrack18',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return PoseTrack18Dataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                area=(list, np.ndarray),\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_posetrack18_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'posetrack18')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_posetrack18_dataset(data_mode='topdown')\n        self.assertEqual(len(dataset), 14)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_posetrack18_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 14)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with bbox file\n        dataset = self.build_posetrack18_dataset(\n            test_mode=True,\n            bbox_file='tests/data/posetrack18/annotations/'\n            'test_posetrack18_human_detections.json')\n        self.assertEqual(len(dataset), 278)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with filter config\n        dataset = self.build_posetrack18_dataset(\n            test_mode=True,\n            bbox_file='tests/data/posetrack18/annotations/'\n            'test_posetrack18_human_detections.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(len(dataset), 119)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_posetrack18_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_posetrack18_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_posetrack18_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_posetrack18_dataset(\n                test_mode=False,\n                bbox_file='tests/data/posetrack18/annotations/'\n                'test_posetrack18_human_detections.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_posetrack18_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/posetrack18/annotations/'\n                'test_posetrack18_human_detections.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_posetrack18_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_body_datasets/test_posetrack18_video_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.body import PoseTrack18VideoDataset\n\n\nclass TestPoseTrack18VideoDataset(TestCase):\n\n    def build_posetrack18_video_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='annotations/test_posetrack18_val.json',\n            bbox_file=None,\n            data_mode='topdown',\n            frame_weights=[0.0, 1.0],\n            frame_sampler_mode='random',\n            frame_range=[-2, 2],\n            num_sampled_frame=1,\n            frame_indices=[-2, -1, 0, 1, 2],\n            ph_fill_len=6,\n            data_root='tests/data/posetrack18',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return PoseTrack18VideoDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                # mind this difference: img_path is a list\n                img_path=list,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                # mind this difference\n                frame_weights=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=list,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                frame_weights=np.ndarray,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_posetrack18_video_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'posetrack18')\n\n        # test number of keypoints\n        num_keypoints = 17\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training, frame_sampler_mode = 'random'\n        dataset = self.build_posetrack18_video_dataset(\n            data_mode='topdown', frame_sampler_mode='random')\n        self.assertEqual(len(dataset), 14)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown training, frame_sampler_mode = 'fixed'\n        dataset = self.build_posetrack18_video_dataset(\n            data_mode='topdown',\n            frame_sampler_mode='fixed',\n            frame_weights=[0.0, 1.0],\n            frame_indices=[-1, 0])\n        self.assertEqual(len(dataset), 14)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing, frame_sampler_mode = 'random'\n        dataset = self.build_posetrack18_video_dataset(\n            data_mode='topdown', test_mode=True, frame_sampler_mode='random')\n        self.assertEqual(len(dataset), 14)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing, frame_sampler_mode = 'fixed'\n        dataset = self.build_posetrack18_video_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            frame_sampler_mode='fixed',\n            frame_weights=(0.3, 0.1, 0.25, 0.25, 0.1),\n            frame_indices=[-2, -1, 0, 1, 2])\n        self.assertEqual(len(dataset), 14)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with bbox file, frame_sampler_mode = 'random'\n        dataset = self.build_posetrack18_video_dataset(\n            test_mode=True,\n            frame_sampler_mode='random',\n            bbox_file='tests/data/posetrack18/annotations/'\n            'test_posetrack18_human_detections.json')\n        self.assertEqual(len(dataset), 278)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with bbox file, frame_sampler_mode = 'fixed'\n        dataset = self.build_posetrack18_video_dataset(\n            test_mode=True,\n            frame_sampler_mode='fixed',\n            frame_weights=(0.3, 0.1, 0.25, 0.25, 0.1),\n            frame_indices=[-2, -1, 0, 1, 2],\n            bbox_file='tests/data/posetrack18/annotations/'\n            'test_posetrack18_human_detections.json')\n        self.assertEqual(len(dataset), 278)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with filter config\n        dataset = self.build_posetrack18_video_dataset(\n            test_mode=True,\n            frame_sampler_mode='fixed',\n            frame_weights=(0.3, 0.1, 0.25, 0.25, 0.1),\n            frame_indices=[-2, -1, 0, 1, 2],\n            bbox_file='tests/data/posetrack18/annotations/'\n            'test_posetrack18_human_detections.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(len(dataset), 119)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_posetrack18_video_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_posetrack18_video_dataset(\n            data_mode='bottomup',\n            test_mode=True,\n            frame_sampler_mode='fixed',\n            frame_indices=[-2, -1, 0, 1, 2],\n            frame_weights=(0.3, 0.1, 0.25, 0.25, 0.1))\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n        # test invalid frame_weights\n        with self.assertRaisesRegex(AssertionError,\n                                    'Invalid `frame_weights`:'):\n            _ = self.build_posetrack18_video_dataset(frame_weights=[0])\n\n        with self.assertRaisesRegex(AssertionError, 'should sum to 1.0'):\n            _ = self.build_posetrack18_video_dataset(frame_weights=[0.2, 0.3])\n        with self.assertRaisesRegex(\n                AssertionError, 'frame_weight can not be a negative value'):\n            _ = self.build_posetrack18_video_dataset(frame_weights=[-0.2, 1.2])\n\n        # test invalid frame_sampler_mode\n        with self.assertRaisesRegex(ValueError,\n                                    'got invalid frame_sampler_mode'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='invalid')\n\n        # test invalid argument when `frame_sampler_mode = 'random'`\n        with self.assertRaisesRegex(AssertionError,\n                                    'please specify the `frame_range`'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_range=None,\n            )\n        with self.assertRaisesRegex(AssertionError,\n                                    'frame_range can not be a negative value'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_range=-2,\n            )\n        # correct usage\n        _ = self.build_posetrack18_video_dataset(\n            frame_sampler_mode='random',\n            frame_range=2,\n        )\n        with self.assertRaisesRegex(AssertionError, 'The length must be 2'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_range=[3],\n            )\n        with self.assertRaisesRegex(AssertionError, 'Invalid `frame_range`'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_range=[3, -3],\n            )\n        with self.assertRaisesRegex(AssertionError,\n                                    'Each element must be int'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_range=[-2, 5.5],\n            )\n        with self.assertRaisesRegex(\n                TypeError,\n                'The type of `frame_range` must be int or Sequence'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_range=dict(low=-2, high=2),\n            )\n\n        # test valid number of frames\n        with self.assertRaisesRegex(AssertionError,\n                                    'please specify `num_sampled_frame`'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                num_sampled_frame=None,\n            )\n        with self.assertRaisesRegex(\n                AssertionError,\n                'does not match the number of sampled adjacent frames'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='random',\n                frame_weights=[0.2, 0.3, 0.5],\n                num_sampled_frame=1,\n            )\n\n        # test invalid argument when `frame_sampler_mode = 'fixed'`\n        with self.assertRaisesRegex(AssertionError,\n                                    'please specify the `frame_indices`'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='fixed',\n                frame_indices=None,\n            )\n        with self.assertRaisesRegex(\n                AssertionError, 'does not match the length of frame_indices'):\n            _ = self.build_posetrack18_video_dataset(\n                frame_sampler_mode='fixed',\n                frame_weights=[0.5, 0.3, 0.2],\n                frame_indices=[-2, -1, 0, 1, 2],\n            )\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_posetrack18_video_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_posetrack18_video_dataset(\n                test_mode=False,\n                bbox_file='tests/data/posetrack18/annotations/'\n                'test_posetrack18_human_detections.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_posetrack18_video_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/posetrack18/annotations/'\n                'test_posetrack18_human_detections.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_posetrack18_video_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_dataset_wrappers/test_combined_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.dataset_wrappers import CombinedDataset\n\n\nclass TestCombinedDataset(TestCase):\n\n    def build_combined_dataset(self, **kwargs):\n\n        coco_cfg = dict(\n            type='CocoDataset',\n            ann_file='test_coco.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/coco',\n            pipeline=[],\n            test_mode=False)\n\n        aic_cfg = dict(\n            type='AicDataset',\n            ann_file='test_aic.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/aic',\n            pipeline=[],\n            test_mode=False)\n\n        cfg = dict(\n            metainfo=dict(from_file='configs/_base_/datasets/coco.py'),\n            datasets=[coco_cfg, aic_cfg],\n            pipeline=[])\n        cfg.update(kwargs)\n        return CombinedDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def test_get_subset_index(self):\n        dataset = self.build_combined_dataset()\n        lens = dataset._lens\n\n        with self.assertRaises(ValueError):\n            subset_idx, sample_idx = dataset._get_subset_index(sum(lens))\n\n        index = lens[0]\n        subset_idx, sample_idx = dataset._get_subset_index(index)\n        self.assertEqual(subset_idx, 1)\n        self.assertEqual(sample_idx, 0)\n\n        index = -lens[1] - 1\n        subset_idx, sample_idx = dataset._get_subset_index(index)\n        self.assertEqual(subset_idx, 0)\n        self.assertEqual(sample_idx, lens[0] - 1)\n\n        # combiend dataset with resampling ratio\n        dataset = self.build_combined_dataset(sample_ratio_factor=[1, 0.3])\n        self.assertEqual(\n            len(dataset),\n            len(dataset.datasets[0]) + round(0.3 * len(dataset.datasets[1])))\n        lens = dataset._lens\n\n        index = lens[0]\n        subset_idx, sample_idx = dataset._get_subset_index(index)\n        self.assertEqual(subset_idx, 1)\n        self.assertIn(sample_idx, (0, 1, 2))\n\n        index = -lens[1] - 1\n        subset_idx, sample_idx = dataset._get_subset_index(index)\n        self.assertEqual(subset_idx, 0)\n        self.assertEqual(sample_idx, lens[0] - 1)\n\n        with self.assertRaises(AssertionError):\n            _ = self.build_combined_dataset(sample_ratio_factor=[1, 0.3, 0.1])\n\n        with self.assertRaises(AssertionError):\n            _ = self.build_combined_dataset(sample_ratio_factor=[1, -0.3])\n\n    def test_prepare_data(self):\n        dataset = self.build_combined_dataset()\n        lens = dataset._lens\n\n        data_info = dataset[lens[0]]\n        self.check_data_info_keys(data_info)\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_aflw_dataset.py",
    "content": "# Copyright (c) build_aflw_datasetOpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import AFLWDataset\n\n\nclass TestAFLWDataset(TestCase):\n\n    def build_aflw_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_aflw.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/aflw',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return AFLWDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_aflw_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'aflw')\n\n        # test number of keypoints\n        num_keypoints = 19\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_aflw_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_aflw_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_aflw_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_aflw_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_aflw_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_aflw_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_aflw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_aflw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_coco_wholebody_face_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import CocoWholeBodyFaceDataset\n\n\nclass TestCocoWholeBodyFaceDataset(TestCase):\n\n    def build_coco_wholebody_face_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_coco_wholebody.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/coco',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return CocoWholeBodyFaceDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_coco_wholebody_face_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'],\n                         'coco_wholebody_face')\n\n        # test number of keypoints\n        num_keypoints = 68\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_coco_wholebody_face_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        # filter invalid insances due to face_valid = false\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_coco_wholebody_face_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_coco_wholebody_face_dataset(data_mode='bottomup')\n        # filter one invalid instance due to face_valid = false\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_coco_wholebody_face_dataset(\n            data_mode='bottomup', test_mode=True)\n        # all images are used for evaluation\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_coco_wholebody_face_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_coco_wholebody_face_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_coco_wholebody_face_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_coco_wholebody_face_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_cofw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import COFWDataset\n\n\nclass TestCOFWDataset(TestCase):\n\n    def build_cofw_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_cofw.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/cofw',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return COFWDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_cofw_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'cofw')\n\n        # test number of keypoints\n        num_keypoints = 29\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_cofw_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_cofw_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_cofw_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_cofw_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_cofw_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_cofw_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_cofw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_cofw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_face_300vw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import Face300VWDataset\n\n\nclass TestFace300VWDataset(TestCase):\n\n    def build_face_300vw_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='anno_300vw.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/300vw',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return Face300VWDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_face_300vw_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], '300vw')\n\n        # test number of keypoints\n        num_keypoints = 68\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_face_300vw_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_face_300vw_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_face_300vw_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_face_300vw_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_face_300vw_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_face_300vw_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_face_300vw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_face_300vw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_face_300w_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import Face300WDataset\n\n\nclass TestFace300WDataset(TestCase):\n\n    def build_face_300w_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_300w.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/300w',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return Face300WDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_face_300w_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], '300w')\n\n        # test number of keypoints\n        num_keypoints = 68\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_face_300w_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_face_300w_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_face_300w_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_face_300w_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_face_300w_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_face_300w_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_face_300w_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_face_300w_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_face_300wlp_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import Face300WLPDataset\n\n\nclass TestFace300WLPDataset(TestCase):\n\n    def build_face_300wlp_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_300wlp.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/300wlp',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return Face300WLPDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_face_300wlp_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], '300wlp')\n\n        # test number of keypoints\n        num_keypoints = 68\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_face_300wlp_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_face_300wlp_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_face_300wlp_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_face_300wlp_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_face_300wlp_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_face_300wlp_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_face_300wlp_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_face_300wlp_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_lapa_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import LapaDataset\n\n\nclass TestLaPaDataset(TestCase):\n\n    def build_lapa_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_lapa.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/lapa',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return LapaDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_lapa_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'lapa')\n\n        # test number of keypoints\n        num_keypoints = 106\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), 0)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_lapa_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        # filter invalid insances due to face_valid = false\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_lapa_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_face_datasets/test_wflw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.face import WFLWDataset\n\n\nclass TestWFLWDataset(TestCase):\n\n    def build_wflw_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_wflw.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/wflw',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return WFLWDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox_center=np.ndarray,\n                bbox_scale=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_wflw_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'wflw')\n\n        # test number of keypoints\n        num_keypoints = 98\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_wflw_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_wflw_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_wflw_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_wflw_dataset(data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_wflw_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_wflw_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_wflw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_wflw_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_fashion_datasets/test_deepfashion_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.fashion import DeepFashionDataset\n\n\nclass TestDeepFashionDataset(TestCase):\n\n    def build_deepfashion_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_fld.json',\n            subset='',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/fld',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return DeepFashionDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        # test subset = 'full'\n        dataset = self.build_deepfashion_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'deepfashion_full')\n\n        # test number of keypoints\n        num_keypoints = 8\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test subset = 'upper'\n        dataset = self.build_deepfashion_dataset(subset='upper')\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'deepfashion_upper')\n        # test number of keypoints\n        num_keypoints = 6\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test subset = 'upper'\n        dataset = self.build_deepfashion_dataset(subset='lower')\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'deepfashion_lower')\n        # test number of keypoints\n        num_keypoints = 4\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n    def test_topdown(self):\n        # test subset = 'full' topdown training\n        dataset = self.build_deepfashion_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n        # test subset = 'full' topdown testing\n        dataset = self.build_deepfashion_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test subset = 'full' bottomup training\n        dataset = self.build_deepfashion_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test subset = 'full' bottomup testing\n        dataset = self.build_deepfashion_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 2)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_deepfashion_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(ValueError, 'got invalid subset'):\n            _ = self.build_deepfashion_dataset(subset='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_deepfashion_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_deepfashion_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_deepfashion_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_coco_wholebody_hand_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand import CocoWholeBodyHandDataset\n\n\nclass TestCocoWholeBodyHandDataset(TestCase):\n\n    def build_coco_wholebody_hand_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_coco_wholebody.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/coco',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return CocoWholeBodyHandDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_coco_wholebody_hand_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'],\n                         'coco_wholebody_hand')\n\n        # test number of keypoints\n        num_keypoints = 21\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_coco_wholebody_hand_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        # filter invalid instances according to ``lefthand_valid``\n        # and ``righthand_valid``\n        self.assertEqual(len(dataset), 10)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_coco_wholebody_hand_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 10)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_coco_wholebody_hand_dataset(data_mode='bottomup')\n        # filter repeated images\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_coco_wholebody_hand_dataset(\n            data_mode='bottomup', test_mode=True)\n        # filter repeated images\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_coco_wholebody_hand_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_coco_wholebody_hand_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_coco_wholebody_hand_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_coco_wholebody_hand_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_freihand_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand import FreiHandDataset\n\n\nclass TestFreiHandDataset(TestCase):\n\n    def build_freihand_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_freihand.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/freihand',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return FreiHandDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_freihand_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'freihand')\n\n        # test number of keypoints\n        num_keypoints = 21\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_freihand_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 8)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_freihand_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 8)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_freihand_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 8)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_freihand_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 8)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_freihand_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_freihand_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_freihand_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_freihand_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_interhand2d_double_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand import InterHand2DDoubleDataset\n\n\nclass TestInterHand2DDoubleDataset(TestCase):\n\n    def build_interhand2d_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_interhand2.6m_data.json',\n            camera_param_file='test_interhand2.6m_camera.json',\n            joint_file='test_interhand2.6m_joint_3d.json',\n            data_mode='topdown',\n            data_root='tests/data/interhand2.6m',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return InterHand2DDoubleDataset(**cfg)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                hand_type=np.ndarray,\n                hand_type_valid=np.ndarray,\n                num_keypoints=int,\n                iscrowd=bool,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                hand_type=np.ndarray,\n                hand_type_valid=np.ndarray,\n                num_keypoints=list,\n                iscrowd=list,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_interhand2d_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'interhand3d')\n\n        # test number of keypoints\n        num_keypoints = 42\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_interhand2d_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_interhand2d_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_interhand2d_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_interhand2d_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_interhand2d_dataset(data_mode='invalid')\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_interhand3d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand3d import InterHand3DDataset\n\n\nclass TestInterHand3DDataset(TestCase):\n\n    def build_interhand3d_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_interhand2.6m_data.json',\n            camera_param_file='test_interhand2.6m_camera.json',\n            joint_file='test_interhand2.6m_joint_3d.json',\n            data_mode='topdown',\n            data_root='tests/data/interhand2.6m',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return InterHand3DDataset(**cfg)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                rotation=int,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                hand_type=np.ndarray,\n                hand_type_valid=np.ndarray,\n                rel_root_depth=np.float32,\n                rel_root_valid=np.float32,\n                abs_depth=list,\n                focal=np.ndarray,\n                principal_pt=np.ndarray,\n                num_keypoints=int,\n                iscrowd=bool,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                rotation=list,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                hand_type=np.ndarray,\n                hand_type_valid=np.ndarray,\n                rel_root_depth=list,\n                rel_root_valid=list,\n                abs_depth=list,\n                focal=np.ndarray,\n                principal_pt=np.ndarray,\n                num_keypoints=list,\n                iscrowd=list,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_interhand3d_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'interhand3d')\n\n        # test number of keypoints\n        num_keypoints = 42\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_interhand3d_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_interhand3d_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_interhand3d_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_interhand3d_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_interhand3d_dataset(data_mode='invalid')\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_onehand10k_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand import OneHand10KDataset\n\n\nclass TestOneHand10KDataset(TestCase):\n\n    def build_onehand10k_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_onehand10k.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/onehand10k',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return OneHand10KDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_onehand10k_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'onehand10k')\n\n        # test number of keypoints\n        num_keypoints = 21\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_onehand10k_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_onehand10k_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_onehand10k_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_onehand10k_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_onehand10k_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_onehand10k_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_onehand10k_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_onehand10k_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_panoptic_hand2d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand import PanopticHand2DDataset\n\n\nclass TestPanopticHand2DDataset(TestCase):\n\n    def build_panoptic_hand2d_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_panoptic.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/panoptic',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return PanopticHand2DDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                num_keypoints=int,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                iscrowd=int,\n                segmentation=list,\n                head_size=float,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                num_keypoints=list,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_panoptic_hand2d_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'panoptic_hand2d')\n\n        # test number of keypoints\n        num_keypoints = 21\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_panoptic_hand2d_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_panoptic_hand2d_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_panoptic_hand2d_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_panoptic_hand2d_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_panoptic_hand2d_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_panoptic_hand2d_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_panoptic_hand2d_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_panoptic_hand2d_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_hand_datasets/test_rhd2d_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.hand import Rhd2DDataset\n\n\nclass TestRhd2DDataset(TestCase):\n\n    def build_rhd2d_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_rhd.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/rhd',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return Rhd2DDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_rhd2d_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'rhd2d')\n\n        # test number of keypoints\n        num_keypoints = 21\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_rhd2d_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_rhd2d_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(dataset.bbox_file, None)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0])\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_rhd2d_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_rhd2d_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 3)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_rhd2d_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_rhd2d_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_rhd2d_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='temp_bbox_file.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_rhd2d_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_wholebody_datasets/test_coco_wholebody_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.wholebody import CocoWholeBodyDataset\n\n\nclass TestCocoWholeBodyDataset(TestCase):\n\n    def build_coco_wholebody_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='test_coco_wholebody.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/coco',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return CocoWholeBodyDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_coco_wholebody_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'coco_wholebody')\n\n        # test number of keypoints\n        num_keypoints = 133\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_coco_wholebody_dataset(data_mode='topdown')\n        # filter two invalid instances due to num_keypoints = 0\n        self.assertEqual(len(dataset), 12)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_coco_wholebody_dataset(\n            data_mode='topdown', test_mode=True)\n        self.assertEqual(len(dataset), 12)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with bbox file\n        dataset = self.build_coco_wholebody_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n        self.assertEqual(len(dataset), 118)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with filter config\n        dataset = self.build_coco_wholebody_dataset(\n            data_mode='topdown',\n            test_mode=True,\n            bbox_file='tests/data/coco/test_coco_det_AP_H_56.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(len(dataset), 33)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_coco_wholebody_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_coco_wholebody_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_coco_wholebody_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_coco_wholebody_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_coco_wholebody_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_coco_wholebody_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_wholebody_datasets/test_h3wb_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.wholebody3d import H36MWholeBodyDataset\n\n\nclass TestH36MWholeBodyDataset(TestCase):\n\n    def build_h3wb_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='h3wb_train_bbox_subset.npz',\n            data_mode='topdown',\n            data_root='tests/data/h3wb',\n            pipeline=[])\n\n        cfg.update(kwargs)\n        return H36MWholeBodyDataset(**cfg)\n\n    def check_data_info_keys(self, data_info: dict):\n        expected_keys = dict(\n            img_paths=list,\n            keypoints=np.ndarray,\n            keypoints_3d=np.ndarray,\n            scale=np.ndarray,\n            center=np.ndarray,\n            id=int)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_h3wb_dataset()\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'h3wb')\n\n        # test number of keypoints\n        num_keypoints = 133\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_h3wb_dataset(data_mode='topdown')\n        dataset.full_init()\n        self.assertEqual(len(dataset), 1)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown training with sequence config\n        dataset = self.build_h3wb_dataset(\n            data_mode='topdown',\n            seq_len=1,\n            seq_step=1,\n            causal=False,\n            pad_video_seq=True)\n        dataset.full_init()\n        self.assertEqual(len(dataset), 1)\n        self.check_data_info_keys(dataset[0])\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_wholebody_datasets/test_halpe_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.wholebody import HalpeDataset\n\n\nclass TestHalpeDataset(TestCase):\n\n    def build_halpe_dataset(self, **kwargs):\n        cfg = dict(\n            ann_file='test_halpe.json',\n            bbox_file=None,\n            data_mode='topdown',\n            data_root='tests/data/halpe',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return HalpeDataset(**cfg)\n\n    def check_data_info_keys(self,\n                             data_info: dict,\n                             data_mode: str = 'topdown'):\n        if data_mode == 'topdown':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                id=int)\n        elif data_mode == 'bottomup':\n            expected_keys = dict(\n                img_id=int,\n                img_path=str,\n                bbox=np.ndarray,\n                bbox_score=np.ndarray,\n                keypoints=np.ndarray,\n                keypoints_visible=np.ndarray,\n                invalid_segs=list,\n                id=list)\n        else:\n            raise ValueError(f'Invalid data_mode {data_mode}')\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def check_metainfo_keys(self, metainfo: dict):\n        expected_keys = dict(\n            dataset_name=str,\n            num_keypoints=int,\n            keypoint_id2name=dict,\n            keypoint_name2id=dict,\n            upper_body_ids=list,\n            lower_body_ids=list,\n            flip_indices=list,\n            flip_pairs=list,\n            keypoint_colors=np.ndarray,\n            num_skeleton_links=int,\n            skeleton_links=list,\n            skeleton_link_colors=np.ndarray,\n            dataset_keypoint_weights=np.ndarray)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, metainfo)\n            self.assertIsInstance(metainfo[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_halpe_dataset()\n        self.check_metainfo_keys(dataset.metainfo)\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'halpe')\n\n        # test number of keypoints\n        num_keypoints = 136\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n        # note that len(sigmas) may be zero if dataset.metainfo['sigmas'] = []\n        self.assertEqual(len(dataset.metainfo['sigmas']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_halpe_dataset(data_mode='topdown')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        # filter two invalid instance due to num_keypoints = 0\n        self.assertEqual(len(dataset), 12)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing\n        dataset = self.build_halpe_dataset(data_mode='topdown', test_mode=True)\n        self.assertEqual(dataset.data_mode, 'topdown')\n        # filter two invalid instance due to num_keypoints = 0\n        self.assertEqual(len(dataset), 12)\n        self.check_data_info_keys(dataset[0], data_mode='topdown')\n\n        # test topdown testing with bbox file\n        dataset = self.build_halpe_dataset(\n            test_mode=True,\n            bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(len(dataset), 118)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing with filter config\n        dataset = self.build_halpe_dataset(\n            test_mode=True,\n            bbox_file='tests/data/coco/test_coco_det_AP_H_56.json',\n            filter_cfg=dict(bbox_score_thr=0.3))\n        self.assertEqual(dataset.data_mode, 'topdown')\n        self.assertEqual(len(dataset), 33)\n\n    def test_bottomup(self):\n        # test bottomup training\n        dataset = self.build_halpe_dataset(data_mode='bottomup')\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n        # test bottomup testing\n        dataset = self.build_halpe_dataset(\n            data_mode='bottomup', test_mode=True)\n        self.assertEqual(len(dataset), 4)\n        self.check_data_info_keys(dataset[0], data_mode='bottomup')\n\n    def test_exceptions_and_warnings(self):\n\n        with self.assertRaisesRegex(ValueError, 'got invalid data_mode'):\n            _ = self.build_halpe_dataset(data_mode='invalid')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_file\" is only supported when `test_mode==True`'):\n            _ = self.build_halpe_dataset(\n                data_mode='topdown',\n                test_mode=False,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError, '\"bbox_file\" is only supported in topdown mode'):\n            _ = self.build_halpe_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                bbox_file='tests/data/coco/test_coco_det_AP_H_56.json')\n\n        with self.assertRaisesRegex(\n                ValueError,\n                '\"bbox_score_thr\" is only supported in topdown mode'):\n            _ = self.build_halpe_dataset(\n                data_mode='bottomup',\n                test_mode=True,\n                filter_cfg=dict(bbox_score_thr=0.3))\n"
  },
  {
    "path": "tests/test_datasets/test_datasets/test_wholebody_datasets/test_ubody_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.datasets.wholebody3d import UBody3dDataset\n\n\nclass TestUBody3dDataset(TestCase):\n\n    def build_ubody3d_dataset(self, **kwargs):\n\n        cfg = dict(\n            ann_file='ubody3d_train.json',\n            data_mode='topdown',\n            data_root='tests/data/ubody3d',\n            pipeline=[],\n            test_mode=False)\n\n        cfg.update(kwargs)\n        return UBody3dDataset(**cfg)\n\n    def check_data_info_keys(self, data_info: dict):\n        expected_keys = dict(\n            img_paths=list,\n            keypoints=np.ndarray,\n            keypoints_3d=np.ndarray,\n            scale=np.ndarray,\n            center=np.ndarray,\n            id=int)\n\n        for key, type_ in expected_keys.items():\n            self.assertIn(key, data_info)\n            self.assertIsInstance(data_info[key], type_, key)\n\n    def test_metainfo(self):\n        dataset = self.build_ubody3d_dataset()\n        # test dataset_name\n        self.assertEqual(dataset.metainfo['dataset_name'], 'ubody3d')\n\n        # test number of keypoints\n        num_keypoints = 137\n        self.assertEqual(dataset.metainfo['num_keypoints'], num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['keypoint_colors']), num_keypoints)\n        self.assertEqual(\n            len(dataset.metainfo['dataset_keypoint_weights']), num_keypoints)\n\n        # test some extra metainfo\n        self.assertEqual(\n            len(dataset.metainfo['skeleton_links']),\n            len(dataset.metainfo['skeleton_link_colors']))\n\n    def test_topdown(self):\n        # test topdown training\n        dataset = self.build_ubody3d_dataset(data_mode='topdown')\n        dataset.full_init()\n        self.assertEqual(len(dataset), 1)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown testing\n        dataset = self.build_ubody3d_dataset(\n            data_mode='topdown', test_mode=True)\n        dataset.full_init()\n        self.assertEqual(len(dataset), 1)\n        self.check_data_info_keys(dataset[0])\n\n        # test topdown training with sequence config\n        dataset = self.build_ubody3d_dataset(\n            data_mode='topdown',\n            seq_len=1,\n            seq_step=1,\n            causal=False,\n            pad_video_seq=True)\n        dataset.full_init()\n        self.assertEqual(len(dataset), 1)\n        self.check_data_info_keys(dataset[0])\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_bottomup_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmcv.transforms import Compose\n\nfrom mmpose.datasets.transforms import (BottomupGetHeatmapMask,\n                                        BottomupRandomAffine,\n                                        BottomupRandomChoiceResize,\n                                        BottomupRandomCrop, BottomupResize,\n                                        RandomFlip)\nfrom mmpose.testing import get_coco_sample\n\n\nclass TestBottomupRandomAffine(TestCase):\n\n    def setUp(self):\n        # prepare dummy bottom-up data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(240, 320), num_instances=4, with_bbox_cs=True)\n\n    def test_transform(self):\n\n        # without UDP\n        transform = BottomupRandomAffine(input_size=(512, 512), use_udp=False)\n        results = transform(deepcopy(self.data_info))\n\n        self.assertEqual(results['img'].shape, (512, 512, 3))\n        self.assertEqual(results['input_size'], (512, 512))\n        self.assertIn('warp_mat', results)\n\n        # with UDP\n        transform = BottomupRandomAffine(input_size=(512, 512), use_udp=True)\n        results = transform(deepcopy(self.data_info))\n\n        self.assertEqual(results['img'].shape, (512, 512, 3))\n        self.assertEqual(results['input_size'], (512, 512))\n        self.assertIn('warp_mat', results)\n\n\nclass TestBottomupGetHeatmapMask(TestCase):\n\n    def setUp(self):\n        # prepare dummy bottom-up data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(240, 320), num_instances=4, with_bbox_cs=True)\n\n    def test_transform(self):\n\n        # single-scale heatmap mask\n        pipeline = Compose([\n            BottomupRandomAffine(input_size=(512, 512)),\n            RandomFlip(prob=1.0, direction='horizontal'),\n            BottomupGetHeatmapMask()\n        ])\n\n        results = deepcopy(self.data_info)\n        results['heatmaps'] = np.random.rand(17, 64, 64).astype(np.float32)\n        results = pipeline(results)\n\n        self.assertEqual(results['heatmap_mask'].shape, (64, 64))\n        self.assertTrue(results['heatmap_mask'].dtype, np.uint8)\n\n        # multi-scale heatmap mask\n        pipeline = Compose([\n            BottomupRandomAffine(input_size=(512, 512)),\n            RandomFlip(prob=1.0, direction='horizontal'),\n            BottomupGetHeatmapMask()\n        ])\n\n        results = deepcopy(self.data_info)\n        heatmap_sizes = [(64, 64), (32, 32)]\n        results['heatmaps'] = [\n            np.random.rand(17, h, w).astype(np.float32)\n            for w, h in heatmap_sizes\n        ]\n        results = pipeline(results)\n\n        self.assertIsInstance(results['heatmap_mask'], list)\n        for i, sizes in enumerate(heatmap_sizes):\n            mask = results['heatmap_mask'][i]\n            self.assertEqual(mask.shape, sizes)\n            self.assertTrue(mask.dtype, np.uint8)\n\n        # no heatmap\n        pipeline = Compose([\n            BottomupRandomAffine(input_size=(512, 512)),\n            RandomFlip(prob=1.0, direction='horizontal'),\n            BottomupGetHeatmapMask()\n        ])\n\n        results = deepcopy(self.data_info)\n        results = pipeline(results)\n\n        self.assertEqual(results['heatmap_mask'].shape, (512, 512))\n        self.assertTrue(results['heatmap_mask'].dtype, np.uint8)\n\n\nclass TestBottomupResize(TestCase):\n\n    def setUp(self):\n        # prepare dummy bottom-up data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(240, 480),\n            img_fill=255,\n            num_instances=4,\n            with_bbox_cs=True)\n\n    def test_transform(self):\n\n        # single-scale, fit\n        transform = BottomupResize(input_size=(256, 256), resize_mode='fit')\n        results = transform(deepcopy(self.data_info))\n        # the middle section of the image is the resized content, while the\n        # top and bottom are padded with zeros\n        self.assertEqual(results['img'].shape, (256, 256, 3))\n        self.assertTrue(\n            np.allclose(results['input_scale'], np.array([480., 480.])))\n        self.assertTrue(\n            np.allclose(results['input_center'], np.array([240., 120.])))\n        self.assertTrue(np.all(results['img'][64:192] > 0))\n        self.assertTrue(np.all(results['img'][:64] == 0))\n        self.assertTrue(np.all(results['img'][192:] == 0))\n\n        # single-scale, expand\n        transform = BottomupResize(input_size=(256, 256), resize_mode='expand')\n        results = transform(deepcopy(self.data_info))\n        # the actual input size is expanded to (512, 256) according to the\n        # original image shape\n        self.assertEqual(results['img'].shape, (256, 512, 3))\n        self.assertTrue(np.all(results['img'] > 0))\n\n        # single-scale, expand, size_factor=100\n        transform = BottomupResize(\n            input_size=(256, 256), resize_mode='expand', size_factor=100)\n        results = transform(deepcopy(self.data_info))\n        # input size is ceiled from (512, 256) to (600, 300)\n        self.assertEqual(results['img'].shape, (300, 600, 3))\n\n        # multi-scale\n        transform = BottomupResize(\n            input_size=(256, 256), aug_scales=[1.5], resize_mode='fit')\n        results = transform(deepcopy(self.data_info))\n        self.assertIsInstance(results['img'], list)\n        self.assertIsInstance(results['input_center'], np.ndarray)\n        self.assertIsInstance(results['input_scale'], np.ndarray)\n        self.assertEqual(results['img'][0].shape, (256, 256, 3))\n        self.assertEqual(results['img'][1].shape, (384, 384, 3))\n\n\nclass TestBottomupRandomCrop(TestCase):\n\n    def setUp(self):\n        # test invalid crop_type\n        with self.assertRaisesRegex(ValueError, 'Invalid crop_type'):\n            BottomupRandomCrop(crop_size=(10, 10), crop_type='unknown')\n\n        crop_type_list = ['absolute', 'absolute_range']\n        for crop_type in crop_type_list:\n            # test h > 0 and w > 0\n            for crop_size in [(0, 0), (0, 1), (1, 0)]:\n                with self.assertRaises(AssertionError):\n                    BottomupRandomCrop(\n                        crop_size=crop_size, crop_type=crop_type)\n            # test type(h) = int and type(w) = int\n            for crop_size in [(1.0, 1), (1, 1.0), (1.0, 1.0)]:\n                with self.assertRaises(AssertionError):\n                    BottomupRandomCrop(\n                        crop_size=crop_size, crop_type=crop_type)\n\n        # test crop_size[0] <= crop_size[1]\n        with self.assertRaises(AssertionError):\n            BottomupRandomCrop(crop_size=(10, 5), crop_type='absolute_range')\n\n        # test h in (0, 1] and w in (0, 1]\n        crop_type_list = ['relative_range', 'relative']\n        for crop_type in crop_type_list:\n            for crop_size in [(0, 1), (1, 0), (1.1, 0.5), (0.5, 1.1)]:\n                with self.assertRaises(AssertionError):\n                    BottomupRandomCrop(\n                        crop_size=crop_size, crop_type=crop_type)\n\n        self.data_info = get_coco_sample(img_shape=(24, 32))\n\n    def test_transform(self):\n        # test relative and absolute crop\n        src_results = self.data_info\n        target_shape = (12, 16)\n        for crop_type, crop_size in zip(['relative', 'absolute'], [(0.5, 0.5),\n                                                                   (16, 12)]):\n            transform = BottomupRandomCrop(\n                crop_size=crop_size, crop_type=crop_type)\n            results = transform(deepcopy(src_results))\n            self.assertEqual(results['img'].shape[:2], target_shape)\n\n        # test absolute_range crop\n        transform = BottomupRandomCrop(\n            crop_size=(10, 20), crop_type='absolute_range')\n        results = transform(deepcopy(src_results))\n        h, w = results['img'].shape[:2]\n        self.assertTrue(10 <= w <= 20)\n        self.assertTrue(10 <= h <= 20)\n        self.assertEqual(results['img_shape'], results['img'].shape[:2])\n        # test relative_range crop\n        transform = BottomupRandomCrop(\n            crop_size=(0.5, 0.5), crop_type='relative_range')\n        results = transform(deepcopy(src_results))\n        h, w = results['img'].shape[:2]\n        self.assertTrue(16 <= w <= 32)\n        self.assertTrue(12 <= h <= 24)\n        self.assertEqual(results['img_shape'], results['img'].shape[:2])\n\n        # test with keypoints, bbox, segmentation\n        src_results = get_coco_sample(img_shape=(10, 10), num_instances=2)\n        segmentation = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)\n        keypoints = np.ones_like(src_results['keypoints']) * 5\n        src_results['segmentation'] = segmentation\n        src_results['keypoints'] = keypoints\n        transform = BottomupRandomCrop(\n            crop_size=(7, 5),\n            allow_negative_crop=False,\n            recompute_bbox=False,\n            bbox_clip_border=True)\n        results = transform(deepcopy(src_results))\n        h, w = results['img'].shape[:2]\n        self.assertEqual(h, 5)\n        self.assertEqual(w, 7)\n        self.assertEqual(results['bbox'].shape[0], 2)\n        self.assertTrue(results['keypoints_visible'].all())\n        self.assertTupleEqual(results['segmentation'].shape[:2], (5, 7))\n        self.assertEqual(results['img_shape'], results['img'].shape[:2])\n\n        # test bbox_clip_border = False\n        transform = BottomupRandomCrop(\n            crop_size=(10, 11),\n            allow_negative_crop=False,\n            recompute_bbox=True,\n            bbox_clip_border=False)\n        results = transform(deepcopy(src_results))\n        self.assertTrue((results['bbox'] == src_results['bbox']).all())\n\n        # test the crop does not contain any gt-bbox\n        # allow_negative_crop = False\n        img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)\n        bbox = np.zeros((0, 4), dtype=np.float32)\n        src_results = {'img': img, 'bbox': bbox}\n        transform = BottomupRandomCrop(\n            crop_size=(5, 3), allow_negative_crop=False)\n        results = transform(deepcopy(src_results))\n        self.assertIsNone(results)\n\n        # allow_negative_crop = True\n        img = np.random.randint(0, 255, size=(10, 10), dtype=np.uint8)\n        bbox = np.zeros((0, 4), dtype=np.float32)\n        src_results = {'img': img, 'bbox': bbox}\n        transform = BottomupRandomCrop(\n            crop_size=(5, 3), allow_negative_crop=True)\n        results = transform(deepcopy(src_results))\n        self.assertTrue(isinstance(results, dict))\n\n\nclass TestBottomupRandomChoiceResize(TestCase):\n\n    def setUp(self):\n        self.data_info = get_coco_sample(img_shape=(300, 400))\n\n    def test_transform(self):\n        results = dict()\n        # test with one scale\n        transform = BottomupRandomChoiceResize(scales=[(1333, 800)])\n        results = deepcopy(self.data_info)\n        results = transform(results)\n        self.assertEqual(results['img'].shape, (800, 1333, 3))\n\n        # test with multi scales\n        _scale_choice = [(1333, 800), (1333, 600)]\n        transform = BottomupRandomChoiceResize(scales=_scale_choice)\n        results = deepcopy(self.data_info)\n        results = transform(results)\n        self.assertIn((results['img'].shape[1], results['img'].shape[0]),\n                      _scale_choice)\n\n        # test keep_ratio\n        transform = BottomupRandomChoiceResize(\n            scales=[(900, 600)], resize_type='Resize', keep_ratio=True)\n        results = deepcopy(self.data_info)\n        _input_ratio = results['img'].shape[0] / results['img'].shape[1]\n        results = transform(results)\n        _output_ratio = results['img'].shape[0] / results['img'].shape[1]\n        self.assertLess(abs(_input_ratio - _output_ratio), 1.5 * 1e-3)\n\n        # test clip_object_border\n        bbox = [[200, 150, 600, 450]]\n        transform = BottomupRandomChoiceResize(\n            scales=[(200, 150)], resize_type='Resize', clip_object_border=True)\n        results = deepcopy(self.data_info)\n        results['bbox'] = np.array(bbox)\n        results = transform(results)\n        self.assertEqual(results['img'].shape, (150, 200, 3))\n        self.assertTrue((results['bbox'] == np.array([[100, 75, 200,\n                                                       150]])).all())\n\n        transform = BottomupRandomChoiceResize(\n            scales=[(200, 150)],\n            resize_type='Resize',\n            clip_object_border=False)\n        results = self.data_info\n        results['bbox'] = np.array(bbox)\n        results = transform(results)\n        assert results['img'].shape == (150, 200, 3)\n        assert np.equal(results['bbox'], np.array([[100, 75, 300, 225]])).all()\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_common_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport os.path as osp\nfrom copy import deepcopy\nfrom unittest import TestCase\n\nimport mmcv\nimport numpy as np\nfrom mmcv.transforms import Compose, LoadImageFromFile\nfrom mmengine.utils import is_list_of\n\nfrom mmpose.datasets.transforms import (Albumentation, FilterAnnotations,\n                                        GenerateTarget, GetBBoxCenterScale,\n                                        PhotometricDistortion,\n                                        RandomBBoxTransform, RandomFlip,\n                                        RandomHalfBody, TopdownAffine,\n                                        YOLOXHSVRandomAug)\nfrom mmpose.testing import get_coco_sample\n\n\nclass TestGetBBoxCenterScale(TestCase):\n\n    def setUp(self):\n\n        # prepare dummy top-down data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(480, 640),\n            num_instances=1,\n            with_bbox_cs=True,\n            with_img_mask=True,\n            random_keypoints_visible=True)\n\n    def test_transform(self):\n        # test converting bbox to center and scale\n        padding = 1.25\n\n        transform = GetBBoxCenterScale(padding=padding)\n        results = deepcopy(self.data_info)\n        results = transform(results)\n\n        center = (results['bbox'][:, :2] + results['bbox'][:, 2:4]) * 0.5\n        scale = (results['bbox'][:, 2:4] - results['bbox'][:, :2]) * padding\n\n        self.assertTrue(np.allclose(results['bbox_center'], center))\n        self.assertTrue(np.allclose(results['bbox_scale'], scale))\n\n        # test using existing bbox center and scale\n        results = deepcopy(self.data_info)\n        center = np.random.rand(1, 2).astype(np.float32)\n        scale = np.random.rand(1, 2).astype(np.float32)\n        results.update(bbox_center=center, bbox_scale=scale)\n        results = transform(results)\n        self.assertTrue(np.allclose(results['bbox_center'], center))\n        self.assertTrue(np.allclose(results['bbox_scale'], scale * padding))\n\n    def test_repr(self):\n        transform = GetBBoxCenterScale(padding=1.25)\n        self.assertEqual(repr(transform), 'GetBBoxCenterScale(padding=1.25)')\n\n\nclass TestRandomFlip(TestCase):\n\n    def setUp(self):\n        # prepare dummy top-down data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(480, 640),\n            num_instances=1,\n            with_bbox_cs=True,\n            with_img_mask=True,\n            random_keypoints_visible=True)\n\n    def test_init(self):\n        # prob: float, direction: str\n        _ = RandomFlip(prob=0.5, direction='horizontal')\n\n        # prob: float, direction: list\n        _ = RandomFlip(prob=0.5, direction=['horizontal', 'vertical'])\n\n        # prob: list, direction: list\n        _ = RandomFlip(prob=[0.3, 0.3], direction=['horizontal', 'vertical'])\n\n    def test_transform(self):\n        # test horizontal flip\n        transform = RandomFlip(prob=1., direction='horizontal')\n        results = deepcopy(self.data_info)\n        results = transform(results)\n\n        ids1, ids2 = zip(*(self.data_info['flip_pairs']))\n        kpts1 = self.data_info['keypoints'][:, ids1]\n        kpts1_vis = self.data_info['keypoints_visible'][:, ids1]\n        kpts2 = results['keypoints'][:, ids2]\n        kpts2_vis = results['keypoints_visible'][:, ids2]\n        bbox_center_flipped = self.data_info['bbox_center'].copy()\n        bbox_center_flipped[:, 0] = 640 - 1 - bbox_center_flipped[:, 0]\n\n        self.assertTrue(\n            np.allclose(results['img'], self.data_info['img'][:, ::-1]))\n        self.assertTrue(\n            np.allclose(results['img_mask'],\n                        self.data_info['img_mask'][:, ::-1]))\n        self.assertTrue(\n            np.allclose(results['bbox_center'], bbox_center_flipped))\n        self.assertTrue(np.allclose(kpts1[..., 0], 640 - kpts2[..., 0] - 1))\n        self.assertTrue(np.allclose(kpts1[..., 1], kpts2[..., 1]))\n        self.assertTrue(np.allclose(kpts1_vis, kpts2_vis))\n\n        # test vertical flip\n        transform = RandomFlip(prob=1., direction='vertical')\n        results = deepcopy(self.data_info)\n        results = transform(results)\n\n        ids1, ids2 = zip(*(self.data_info['flip_pairs']))\n        kpts1 = self.data_info['keypoints'][:, ids1]\n        kpts1_vis = self.data_info['keypoints_visible'][:, ids1]\n        kpts2 = results['keypoints'][:, ids2]\n        kpts2_vis = results['keypoints_visible'][:, ids2]\n        bbox_center_flipped = self.data_info['bbox_center'].copy()\n        bbox_center_flipped[:, 1] = 480 - 1 - bbox_center_flipped[:, 1]\n\n        self.assertTrue(\n            np.allclose(results['img'], self.data_info['img'][::-1]))\n        self.assertTrue(\n            np.allclose(results['img_mask'], self.data_info['img_mask'][::-1]))\n        self.assertTrue(\n            np.allclose(results['bbox_center'], bbox_center_flipped))\n        self.assertTrue(np.allclose(kpts1[..., 0], kpts2[..., 0]))\n        self.assertTrue(np.allclose(kpts1[..., 1], 480 - kpts2[..., 1] - 1))\n        self.assertTrue(np.allclose(kpts1_vis, kpts2_vis))\n\n        # test diagonal flip\n        transform = RandomFlip(prob=1., direction='diagonal')\n        results = deepcopy(self.data_info)\n        results = transform(results)\n\n        kpts1 = self.data_info['keypoints']\n        kpts1_vis = self.data_info['keypoints_visible']\n        kpts2 = results['keypoints']\n        kpts2_vis = results['keypoints_visible']\n        bbox_center_flipped = self.data_info['bbox_center'].copy()\n        bbox_center_flipped[:, 0] = 640 - 1 - bbox_center_flipped[:, 0]\n        bbox_center_flipped[:, 1] = 480 - 1 - bbox_center_flipped[:, 1]\n\n        self.assertTrue(\n            np.allclose(results['img'], self.data_info['img'][::-1, ::-1]))\n        self.assertTrue(\n            np.allclose(results['img_mask'],\n                        self.data_info['img_mask'][::-1, ::-1]))\n        self.assertTrue(\n            np.allclose(results['bbox_center'], bbox_center_flipped))\n        self.assertTrue(np.allclose(kpts1[..., 0], 640 - kpts2[..., 0] - 1))\n        self.assertTrue(np.allclose(kpts1[..., 1], 480 - kpts2[..., 1] - 1))\n        self.assertTrue(np.allclose(kpts1_vis, kpts2_vis))\n\n    def test_errors(self):\n        # invalid arguments\n        with self.assertRaisesRegex(ValueError,\n                                    'probs must be float or list of float'):\n            _ = RandomFlip(prob=None)\n\n        with self.assertRaisesRegex(\n                ValueError, 'direction must be either str or list of str'):\n            _ = RandomFlip(direction=None)\n\n        with self.assertRaises(AssertionError):\n            _ = RandomFlip(prob=2.0)\n\n        with self.assertRaises(AssertionError):\n            _ = RandomFlip(direction='invalid_direction')\n\n    def test_repr(self):\n        transform = RandomFlip(prob=0.5, direction='horizontal')\n        self.assertEqual(\n            repr(transform), 'RandomFlip(prob=0.5, direction=horizontal)')\n\n\nclass TestRandomHalfBody(TestCase):\n\n    def setUp(self):\n        # prepare dummy top-down data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(480, 640),\n            num_instances=1,\n            with_bbox_cs=True,\n            with_img_mask=True)\n\n    def test_transform(self):\n        padding = 1.5\n\n        # keep upper body\n        transform = RandomHalfBody(\n            prob=1.,\n            min_total_keypoints=8,\n            min_upper_keypoints=2,\n            min_lower_keypoints=2)\n        results = deepcopy(self.data_info)\n        results['keypoints_visible'][:, results['lower_body_ids']] = 0\n        results = transform(results)\n\n        kpts = self.data_info['keypoints'][:, self.data_info['upper_body_ids']]\n        self.assertTrue(np.allclose(results['bbox_center'], kpts.mean(axis=1)))\n        self.assertTrue(\n            np.allclose(results['bbox_scale'],\n                        (kpts.max(axis=1) - kpts.min(axis=1)) * padding))\n\n        # keep lower body\n        transform = RandomHalfBody(\n            prob=1.,\n            min_total_keypoints=6,\n            min_upper_keypoints=4,\n            min_lower_keypoints=4)\n        results = deepcopy(self.data_info)\n        results['keypoints_visible'][:, results['upper_body_ids']] = 0\n        results = transform(results)\n\n        kpts = self.data_info['keypoints'][:, self.data_info['lower_body_ids']]\n        self.assertTrue(np.allclose(results['bbox_center'], kpts.mean(axis=1)))\n        self.assertTrue(\n            np.allclose(results['bbox_scale'],\n                        (kpts.max(axis=1) - kpts.min(axis=1)) * padding))\n\n        # no transform due to prob\n        transform = RandomHalfBody(prob=0.)\n        results = transform(deepcopy(self.data_info))\n\n        self.assertTrue(\n            np.allclose(results['bbox_center'], self.data_info['bbox_center']))\n        self.assertTrue(\n            np.allclose(results['bbox_scale'], self.data_info['bbox_scale']))\n\n        # no transform due to insufficient valid total keypoints\n        transform = RandomHalfBody(\n            prob=1.,\n            min_total_keypoints=8,\n            min_upper_keypoints=2,\n            min_lower_keypoints=2)\n        results = deepcopy(self.data_info)\n        results['keypoints_visible'].fill(0)\n        results = transform(results)\n\n        self.assertTrue(\n            np.allclose(results['bbox_center'], self.data_info['bbox_center']))\n        self.assertTrue(\n            np.allclose(results['bbox_scale'], self.data_info['bbox_scale']))\n\n        # no transform due to insufficient valid half-body keypoints\n        transform = RandomHalfBody(\n            prob=1.,\n            min_total_keypoints=4,\n            min_upper_keypoints=3,\n            min_lower_keypoints=3)\n        results = deepcopy(self.data_info)\n        results['keypoints_visible'][:, results['upper_body_ids'][2:]] = 0\n        results['keypoints_visible'][:, results['lower_body_ids'][2:]] = 0\n        results = transform(results)\n\n        self.assertTrue(\n            np.allclose(results['bbox_center'], self.data_info['bbox_center']))\n        self.assertTrue(\n            np.allclose(results['bbox_scale'], self.data_info['bbox_scale']))\n\n    def test_repr(self):\n        transform = RandomHalfBody(\n            min_total_keypoints=8,\n            min_upper_keypoints=2,\n            min_lower_keypoints=2,\n            padding=1.5,\n            prob=0.3,\n            upper_prioritized_prob=0.7)\n        self.assertEqual(\n            repr(transform),\n            'RandomHalfBody(min_total_keypoints=8, min_upper_keypoints=2, '\n            'min_lower_keypoints=2, padding=1.5, prob=0.3, '\n            'upper_prioritized_prob=0.7)')\n\n\nclass TestRandomBBoxTransform(TestCase):\n\n    def setUp(self):\n        # prepare dummy top-down data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(480, 640),\n            num_instances=1,\n            with_bbox_cs=True,\n            with_img_mask=True)\n\n    def test_transform(self):\n        shfit_factor = 0.16\n        scale_factor = (0.5, 1.5)\n        rotate_factor = 90.\n\n        # test random shift\n        transform = RandomBBoxTransform(\n            shift_factor=shfit_factor,\n            shift_prob=1.0,\n            scale_prob=0.0,\n            rotate_prob=0.0)\n        results = transform(deepcopy(self.data_info))\n\n        center = self.data_info['bbox_center']\n        scale = self.data_info['bbox_scale']\n        center_range = [\n            center - scale * shfit_factor,\n            center + scale * shfit_factor,\n        ]\n\n        self.assertFalse(np.allclose(results['bbox_center'], center))\n        self.assertTrue(((results['bbox_center'] > center_range[0]) &\n                         (results['bbox_center'] < center_range[1])).all())\n        self.assertTrue(np.allclose(results['bbox_scale'], scale))\n        self.assertTrue(\n            np.allclose(results['bbox_rotation'], np.zeros((1, 17))))\n\n        # test random resizing\n        transform = RandomBBoxTransform(\n            scale_factor=scale_factor,\n            shift_prob=0.0,\n            scale_prob=1.0,\n            rotate_prob=0.0)\n\n        results = transform(deepcopy(self.data_info))\n        center = self.data_info['bbox_center']\n        scale = self.data_info['bbox_scale']\n        scale_range = [scale * scale_factor[0], scale * scale_factor[1]]\n\n        self.assertTrue(np.allclose(results['bbox_center'], center))\n        self.assertFalse(np.allclose(results['bbox_scale'], scale))\n        self.assertTrue(((results['bbox_scale'] > scale_range[0]) &\n                         (results['bbox_scale'] < scale_range[1])).all())\n        self.assertTrue(\n            np.allclose(results['bbox_rotation'], np.zeros((1, 17))))\n\n        # test random rotation\n        transform = RandomBBoxTransform(\n            rotate_factor=rotate_factor,\n            shift_prob=0.0,\n            scale_prob=0.0,\n            rotate_prob=1.0)\n\n        results = transform(deepcopy(self.data_info))\n        rotation_range = [-rotate_factor, rotate_factor]\n        bbox_rotation_min = np.full((1, 17), rotation_range[0])\n        bbox_rotation_max = np.full((1, 17), rotation_range[1])\n\n        self.assertTrue(\n            np.allclose(results['bbox_center'], self.data_info['bbox_center']))\n        self.assertTrue(\n            np.allclose(results['bbox_scale'], self.data_info['bbox_scale']))\n        self.assertFalse(np.allclose(results['bbox_rotation'], 0))\n        self.assertTrue(((results['bbox_rotation'] > bbox_rotation_min) &\n                         (results['bbox_rotation'] < bbox_rotation_max)).all())\n\n        # test hybrid transform\n        transform = RandomBBoxTransform(\n            shift_factor=shfit_factor,\n            scale_factor=scale_factor,\n            rotate_factor=rotate_factor,\n            shift_prob=1.0,\n            scale_prob=1.0,\n            rotate_prob=1.0)\n\n        results = transform(deepcopy(self.data_info))\n        center = self.data_info['bbox_center']\n        scale = self.data_info['bbox_scale']\n\n        center_range = [\n            center - scale * shfit_factor,\n            center + scale * shfit_factor,\n        ]\n        scale_range = [scale * scale_factor[0], scale * scale_factor[1]]\n        rotation_range = [-rotate_factor, rotate_factor]\n\n        self.assertFalse(np.allclose(results['bbox_center'], center))\n        self.assertTrue(((results['bbox_center'] > center_range[0]) &\n                         (results['bbox_center'] < center_range[1])).all())\n        self.assertFalse(np.allclose(results['bbox_scale'], scale))\n        self.assertTrue(((results['bbox_scale'] > scale_range[0]) &\n                         (results['bbox_scale'] < scale_range[1])).all())\n        self.assertFalse(np.allclose(results['bbox_rotation'], 0))\n        self.assertTrue(((results['bbox_rotation'] > rotation_range[0]) &\n                         (results['bbox_rotation'] < rotation_range[1])).all())\n\n    def test_repr(self):\n        transform = RandomBBoxTransform(\n            shift_factor=0.16,\n            shift_prob=0.3,\n            scale_factor=0.5,\n            scale_prob=1.0,\n            rotate_factor=40.0,\n            rotate_prob=0.6)\n\n        self.assertEqual(\n            repr(transform),\n            'RandomBBoxTransform(shift_prob=0.3, shift_factor=0.16, '\n            'scale_prob=1.0, scale_factor=0.5, rotate_prob=0.6, '\n            'rotate_factor=40.0)')\n\n\nclass TestAlbumentation(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup the valiables which are used in each test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        data_prefix = 'tests/data/coco'\n        results = dict(img_path=osp.join(data_prefix, '000000000785.jpg'))\n        load = LoadImageFromFile()\n        self.results = load(copy.deepcopy(results))\n\n    def test_transform(self):\n        # test when ``keymap`` is None\n        transform = Albumentation(transforms=[\n            dict(type='RandomBrightnessContrast', p=0.2),\n            dict(type='ToFloat')\n        ])\n        results_update = transform(copy.deepcopy(self.results))\n        self.assertEqual(results_update['img'].dtype, np.float32)\n\n    def test_repr(self):\n        # test when ``keymap`` is not None\n        transforms = [\n            dict(type='RandomBrightnessContrast', p=0.2),\n            dict(type='ToFloat')\n        ]\n        transform = Albumentation(\n            transforms=transforms, keymap={'img': 'image'})\n        self.assertEqual(\n            repr(transform), f'Albumentation(transforms={transforms})')\n\n\nclass TestPhotometricDistortion(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup the valiables which are used in each test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        data_prefix = 'tests/data/coco'\n        results = dict(img_path=osp.join(data_prefix, '000000000785.jpg'))\n        load = LoadImageFromFile()\n        self.results = load(copy.deepcopy(results))\n\n    def test_transform(self):\n        transform = PhotometricDistortion()\n        results_update = transform(copy.deepcopy(self.results))\n        self.assertEqual(results_update['img'].dtype, np.uint8)\n\n    def test_repr(self):\n        transform = PhotometricDistortion()\n        self.assertEqual(\n            repr(transform), ('PhotometricDistortion'\n                              '(brightness_delta=32, '\n                              'contrast_range=(0.5, 1.5), '\n                              'saturation_range=(0.5, 1.5), '\n                              'hue_delta=18)'))\n\n\nclass TestGenerateTarget(TestCase):\n\n    def setUp(self):\n        # prepare dummy top-down data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(480, 640),\n            num_instances=1,\n            with_bbox_cs=True,\n            with_img_mask=True)\n\n    def test_generate_single_target(self):\n        encoder = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n\n        # generate heatmap\n        pipeline = Compose([\n            TopdownAffine(input_size=(192, 256)),\n            GenerateTarget(encoder=encoder)\n        ])\n        results = pipeline(deepcopy(self.data_info))\n\n        self.assertEqual(results['heatmaps'].shape, (17, 64, 48))\n        self.assertTrue(\n            np.allclose(results['keypoint_weights'], np.ones((1, 17))))\n\n        # generate heatmap and use meta keypoint weights\n        pipeline = Compose([\n            TopdownAffine(input_size=(192, 256)),\n            GenerateTarget(\n                encoder=encoder,\n                use_dataset_keypoint_weights=True,\n            )\n        ])\n        results = pipeline(deepcopy(self.data_info))\n\n        self.assertEqual(results['heatmaps'].shape, (17, 64, 48))\n        self.assertEqual(results['keypoint_weights'].shape, (1, 17))\n        self.assertTrue(\n            np.allclose(results['keypoint_weights'],\n                        self.data_info['dataset_keypoint_weights'][None]))\n\n    def test_generate_multilevel_target(self):\n        encoder_0 = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n        encoder_1 = dict(encoder_0, heatmap_size=(24, 32))\n\n        # generate multilevel heatmap\n        pipeline = Compose([\n            TopdownAffine(input_size=(192, 256)),\n            GenerateTarget(\n                encoder=[encoder_0, encoder_1],\n                multilevel=True,\n                use_dataset_keypoint_weights=True)\n        ])\n        results = pipeline(deepcopy(self.data_info))\n\n        self.assertTrue(is_list_of(results['heatmaps'], np.ndarray))\n        self.assertTrue(is_list_of(results['keypoint_weights'], np.ndarray))\n        self.assertEqual(results['heatmaps'][0].shape, (17, 64, 48))\n        self.assertEqual(results['heatmaps'][1].shape, (17, 32, 24))\n        self.assertEqual(results['keypoint_weights'][0].shape, (1, 17))\n\n    def test_generate_combined_target(self):\n        encoder_0 = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n        encoder_1 = dict(type='RegressionLabel', input_size=(192, 256))\n        # generate multilevel heatmap\n        pipeline = Compose([\n            TopdownAffine(input_size=(192, 256)),\n            GenerateTarget(\n                encoder=[encoder_0, encoder_1],\n                multilevel=False,\n                use_dataset_keypoint_weights=True)\n        ])\n\n        results = pipeline(deepcopy(self.data_info))\n\n        self.assertEqual(results['heatmaps'].shape, (17, 64, 48))\n        self.assertEqual(results['keypoint_labels'].shape, (1, 17, 2))\n        self.assertIsInstance(results['keypoint_weights'], list)\n        self.assertEqual(results['keypoint_weights'][0].shape, (1, 17))\n\n    def test_errors(self):\n\n        # single encoder with `multilevel=True`\n        encoder = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n\n        with self.assertRaisesRegex(AssertionError,\n                                    'Need multiple encoder configs'):\n            _ = GenerateTarget(encoder=encoder, multilevel=True)\n\n        # diverse keys in multilevel encoding\n        encoder_0 = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n\n        encoder_1 = dict(type='RegressionLabel', input_size=(192, 256))\n        pipeline = Compose([\n            TopdownAffine(input_size=(192, 256)),\n            GenerateTarget(encoder=[encoder_0, encoder_1], multilevel=True)\n        ])\n\n        with self.assertRaisesRegex(ValueError, 'have the same keys'):\n            _ = pipeline(deepcopy(self.data_info))\n\n        # overlapping keys in combined encoding\n        encoder = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n\n        pipeline = Compose([\n            TopdownAffine(input_size=(192, 256)),\n            GenerateTarget(encoder=[encoder, encoder], multilevel=False)\n        ])\n\n        with self.assertRaisesRegex(ValueError, 'Overlapping item'):\n            _ = pipeline(deepcopy(self.data_info))\n\n        # deprecated argument `target_type` is given\n        encoder = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.0)\n\n        with self.assertWarnsRegex(DeprecationWarning,\n                                   '`target_type` is deprecated'):\n            _ = GenerateTarget(encoder=encoder, target_type='heatmap')\n\n\nclass TestFilterAnnotations(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup the model and optimizer which are used in every test\n        method.\"\"\"\n        self.results = {\n            'img':\n            np.random.random((224, 224, 3)),\n            'img_shape': (224, 224),\n            'bbox':\n            np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]]),\n            'bbox_score':\n            np.array([0.9, 0.8, 0.7]),\n            'category_id':\n            np.array([1, 2, 3]),\n            'keypoints':\n            np.array([[15, 15, 1], [25, 25, 1], [45, 45, 1]]),\n            'keypoints_visible':\n            np.array([[1, 1, 0], [1, 1, 1], [1, 1, 1]]),\n            'area':\n            np.array([300, 600, 1200]),\n        }\n\n    def test_transform(self):\n        # Test keep_empty = True\n        transform = FilterAnnotations(\n            min_gt_bbox_wh=(50, 50),\n            keep_empty=True,\n            by_box=True,\n        )\n        results = transform(copy.deepcopy(self.results))\n        self.assertIsNone(results)\n\n        # Test keep_empty = False\n        transform = FilterAnnotations(\n            min_gt_bbox_wh=(50, 50),\n            keep_empty=False,\n        )\n        results = transform(copy.deepcopy(self.results))\n        self.assertTrue(isinstance(results, dict))\n\n        # Test filter annotations by bbox\n        transform = FilterAnnotations(min_gt_bbox_wh=(15, 15), by_box=True)\n        results = transform(copy.deepcopy(self.results))\n        print((results['bbox'] == np.array([[20, 20, 40, 40], [40, 40, 80,\n                                                               80]])).all())\n        self.assertTrue((results['bbox'] == np.array([[20, 20, 40, 40],\n                                                      [40, 40, 80,\n                                                       80]])).all())\n        self.assertTrue((results['bbox_score'] == np.array([0.8, 0.7])).all())\n        self.assertTrue((results['category_id'] == np.array([2, 3])).all())\n        self.assertTrue((results['keypoints'] == np.array([[25, 25, 1],\n                                                           [45, 45,\n                                                            1]])).all())\n        self.assertTrue(\n            (results['keypoints_visible'] == np.array([[1, 1, 1], [1, 1,\n                                                                   1]])).all())\n        self.assertTrue((results['area'] == np.array([600, 1200])).all())\n\n        # Test filter annotations by area\n        transform = FilterAnnotations(min_gt_area=1000, by_area=True)\n        results = transform(copy.deepcopy(self.results))\n        self.assertIsInstance(results, dict)\n        self.assertTrue((results['bbox'] == np.array([[40, 40, 80,\n                                                       80]])).all())\n        self.assertTrue((results['bbox_score'] == np.array([0.7])).all())\n        self.assertTrue((results['category_id'] == np.array([3])).all())\n        self.assertTrue((results['keypoints'] == np.array([[45, 45,\n                                                            1]])).all())\n        self.assertTrue(\n            (results['keypoints_visible'] == np.array([[1, 1, 1]])).all())\n        self.assertTrue((results['area'] == np.array([1200])).all())\n\n        # Test filter annotations by keypoints visibility\n        transform = FilterAnnotations(min_kpt_vis=3, by_kpt=True)\n        results = transform(copy.deepcopy(self.results))\n        self.assertIsInstance(results, dict)\n        self.assertTrue((results['bbox'] == np.array([[20, 20, 40, 40],\n                                                      [40, 40, 80,\n                                                       80]])).all())\n        self.assertTrue((results['bbox_score'] == np.array([0.8, 0.7])).all())\n        self.assertTrue((results['category_id'] == np.array([2, 3])).all())\n        self.assertTrue((results['keypoints'] == np.array([[25, 25, 1],\n                                                           [45, 45,\n                                                            1]])).all())\n        self.assertTrue(\n            (results['keypoints_visible'] == np.array([[1, 1, 1], [1, 1,\n                                                                   1]])).all())\n        self.assertTrue((results['area'] == np.array([600, 1200])).all())\n\n\nclass TestYOLOXHSVRandomAug(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup the model and optimizer which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        img = mmcv.imread(\n            osp.join(\n                osp.dirname(__file__), '../../data/coco/000000000785.jpg'),\n            'color')\n        self.results = {\n            'img':\n            img,\n            'img_shape': (640, 425),\n            'category_id':\n            np.array([1, 2, 3], dtype=np.int64),\n            'bbox':\n            np.array([[10, 10, 20, 20], [20, 20, 40, 40], [40, 40, 80, 80]],\n                     dtype=np.float32),\n        }\n\n    def test_transform(self):\n        transform = YOLOXHSVRandomAug()\n        results = transform(copy.deepcopy(self.results))\n        self.assertTrue(\n            results['img'].shape[:2] == self.results['img'].shape[:2])\n        self.assertTrue(\n            results['category_id'].shape[0] == results['bbox'].shape[0])\n        self.assertTrue(results['bbox'].dtype == np.float32)\n\n    def test_repr(self):\n        transform = YOLOXHSVRandomAug()\n        self.assertEqual(\n            repr(transform), ('YOLOXHSVRandomAug(hue_delta=5, '\n                              'saturation_delta=30, '\n                              'value_delta=30)'))\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_converting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.transforms import KeypointConverter\nfrom mmpose.testing import get_coco_sample\n\n\nclass TestKeypointConverter(TestCase):\n\n    def setUp(self):\n        # prepare dummy bottom-up data sample with COCO metainfo\n        self.data_info = get_coco_sample(\n            img_shape=(240, 320), num_instances=4, with_bbox_cs=True)\n\n    def test_transform(self):\n        # 1-to-1 mapping\n        mapping = [(3, 0), (6, 1), (16, 2), (5, 3)]\n        transform = KeypointConverter(num_keypoints=5, mapping=mapping)\n        results = transform(self.data_info.copy())\n\n        # check shape\n        self.assertEqual(results['keypoints'].shape[0],\n                         self.data_info['keypoints'].shape[0])\n        self.assertEqual(results['keypoints'].shape[1], 5)\n        self.assertEqual(results['keypoints'].shape[2], 2)\n        self.assertEqual(results['keypoints_visible'].shape[0],\n                         self.data_info['keypoints_visible'].shape[0])\n        self.assertEqual(results['keypoints_visible'].shape[1], 5)\n\n        # check value\n        for source_index, target_index in mapping:\n            self.assertTrue((results['keypoints'][:, target_index] ==\n                             self.data_info['keypoints'][:,\n                                                         source_index]).all())\n            self.assertEqual(results['keypoints_visible'].ndim, 3)\n            self.assertEqual(results['keypoints_visible'].shape[2], 2)\n            self.assertTrue(\n                (results['keypoints_visible'][:, target_index, 0] ==\n                 self.data_info['keypoints_visible'][:, source_index]).all())\n\n        # 2-to-1 mapping\n        mapping = [((3, 5), 0), (6, 1), (16, 2), (5, 3)]\n        transform = KeypointConverter(num_keypoints=5, mapping=mapping)\n        results = transform(self.data_info.copy())\n\n        # check shape\n        self.assertEqual(results['keypoints'].shape[0],\n                         self.data_info['keypoints'].shape[0])\n        self.assertEqual(results['keypoints'].shape[1], 5)\n        self.assertEqual(results['keypoints'].shape[2], 2)\n        self.assertEqual(results['keypoints_visible'].shape[0],\n                         self.data_info['keypoints_visible'].shape[0])\n        self.assertEqual(results['keypoints_visible'].shape[1], 5)\n\n        # check value\n        for source_index, target_index in mapping:\n            if isinstance(source_index, tuple):\n                source_index, source_index2 = source_index\n                self.assertTrue(\n                    (results['keypoints'][:, target_index] == 0.5 *\n                     (self.data_info['keypoints'][:, source_index] +\n                      self.data_info['keypoints'][:, source_index2])).all())\n                self.assertEqual(results['keypoints_visible'].ndim, 3)\n                self.assertEqual(results['keypoints_visible'].shape[2], 2)\n                self.assertTrue(\n                    (results['keypoints_visible'][:, target_index, 0] ==\n                     self.data_info['keypoints_visible'][:, source_index] *\n                     self.data_info['keypoints_visible'][:,\n                                                         source_index2]).all())\n            else:\n                self.assertTrue(\n                    (results['keypoints'][:, target_index] ==\n                     self.data_info['keypoints'][:, source_index]).all())\n                self.assertEqual(results['keypoints_visible'].ndim, 3)\n                self.assertEqual(results['keypoints_visible'].shape[2], 2)\n                self.assertTrue(\n                    (results['keypoints_visible'][:, target_index, 0] ==\n                     self.data_info['keypoints_visible'][:,\n                                                         source_index]).all())\n\n        # check 3d keypoint\n        self.data_info['keypoints_3d'] = np.random.random((4, 17, 3))\n        self.data_info['target_idx'] = [-1]\n        mapping = [(3, 0), (6, 1), (16, 2), (5, 3)]\n        transform = KeypointConverter(num_keypoints=5, mapping=mapping)\n        results = transform(self.data_info.copy())\n\n        # check shape\n        self.assertEqual(results['keypoints_3d'].shape[0],\n                         self.data_info['keypoints_3d'].shape[0])\n        self.assertEqual(results['keypoints_3d'].shape[1], 5)\n        self.assertEqual(results['keypoints_3d'].shape[2], 3)\n        self.assertEqual(results['keypoints_visible'].shape[0],\n                         self.data_info['keypoints_visible'].shape[0])\n        self.assertEqual(results['keypoints_visible'].shape[1], 5)\n\n        # check value\n        for source_index, target_index in mapping:\n            self.assertTrue(\n                (results['keypoints_3d'][:, target_index] ==\n                 self.data_info['keypoints_3d'][:, source_index]).all())\n            self.assertEqual(results['keypoints_visible'].ndim, 3)\n            self.assertEqual(results['keypoints_visible'].shape[2], 2)\n            self.assertTrue(\n                (results['keypoints_visible'][:, target_index, 0] ==\n                 self.data_info['keypoints_visible'][:, source_index]).all())\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_formatting.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.datasets.transforms import PackPoseInputs\nfrom mmpose.structures import PoseDataSample\n\n\nclass TestPackPoseInputs(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        # prepare dummy top-down data sample with COCO metainfo\n        self.results_topdown = {\n            'img_id':\n            1,\n            'img_path':\n            'tests/data/coco/000000000785.jpg',\n            'id':\n            1,\n            'ori_shape': (425, 640),\n            'img_shape': (425, 640, 3),\n            'scale_factor':\n            2.0,\n            'flip':\n            False,\n            'flip_direction':\n            None,\n            'img':\n            np.zeros((425, 640, 3), dtype=np.uint8),\n            'bbox':\n            np.array([[0, 0, 100, 100]], dtype=np.float32),\n            'bbox_center':\n            np.array([[50, 50]], dtype=np.float32),\n            'bbox_scale':\n            np.array([[125, 125]], dtype=np.float32),\n            'bbox_rotation':\n            np.array([45], dtype=np.float32),\n            'bbox_score':\n            np.ones(1, dtype=np.float32),\n            'keypoints':\n            np.random.randint(0, 100, (1, 17, 2)).astype(np.float32),\n            'keypoints_visible':\n            np.full((1, 17), 1).astype(np.float32),\n            'keypoint_weights':\n            np.full((1, 17), 1).astype(np.float32),\n            'heatmaps':\n            np.random.random((17, 64, 48)).astype(np.float32),\n            'keypoint_labels':\n            np.random.randint(0, 100, (1, 17, 2)).astype(np.float32),\n            'keypoint_x_labels':\n            np.random.randint(0, 100, (1, 17, 2)).astype(np.float32),\n            'keypoint_y_labels':\n            np.random.randint(0, 100, (1, 17, 2)).astype(np.float32),\n            'transformed_keypoints':\n            np.random.randint(0, 100, (1, 17, 2)).astype(np.float32),\n        }\n        self.meta_keys = ('img_id', 'img_path', 'ori_shape', 'img_shape',\n                          'scale_factor', 'flip', 'flip_direction')\n\n    def test_transform(self):\n        transform = PackPoseInputs(\n            meta_keys=self.meta_keys, pack_transformed=True)\n        results = transform(copy.deepcopy(self.results_topdown))\n        self.assertIn('transformed_keypoints',\n                      results['data_samples'].gt_instances)\n\n        transform = PackPoseInputs(meta_keys=self.meta_keys)\n        results = transform(copy.deepcopy(self.results_topdown))\n        self.assertIn('inputs', results)\n        self.assertIsInstance(results['inputs'], torch.Tensor)\n        self.assertEqual(results['inputs'].shape, (3, 425, 640))\n        self.assertIn('data_samples', results)\n        self.assertIsInstance(results['data_samples'], PoseDataSample)\n        self.assertIsInstance(results['data_samples'].gt_instances,\n                              InstanceData)\n        self.assertIsInstance(results['data_samples'].gt_fields, PixelData)\n        self.assertEqual(len(results['data_samples'].gt_instances), 1)\n        self.assertIsInstance(results['data_samples'].gt_fields.heatmaps,\n                              torch.Tensor)\n        self.assertNotIn('transformed_keypoints',\n                         results['data_samples'].gt_instances)\n\n        # test when results['img'] is sequence of frames\n        results = copy.deepcopy(self.results_topdown)\n        len_seq = 5\n        results['img'] = [\n            np.random.randint(0, 255, (425, 640, 3), dtype=np.uint8)\n            for _ in range(len_seq)\n        ]\n        results = transform(results)\n        self.assertIn('inputs', results)\n        self.assertIsInstance(results['inputs'], torch.Tensor)\n        # translate into 4-dim tensor: [len_seq, c, h, w]\n        self.assertEqual(results['inputs'].shape, (len_seq, 3, 425, 640))\n\n    def test_repr(self):\n        transform = PackPoseInputs(meta_keys=self.meta_keys)\n        self.assertEqual(\n            repr(transform), f'PackPoseInputs(meta_keys={self.meta_keys}, '\n            f'pack_transformed={transform.pack_transformed})')\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_loading.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmcv import imread\n\nfrom mmpose.datasets.transforms.loading import LoadImage\n\n\nclass TestLoadImage(TestCase):\n\n    def test_load_image(self):\n\n        transform = LoadImage()\n        results = dict(img_path='tests/data/coco/000000000785.jpg')\n\n        results = transform(results)\n\n        self.assertIsInstance(results['img'], np.ndarray)\n\n    def test_with_input_image(self):\n        transform = LoadImage(to_float32=True)\n\n        img_path = 'tests/data/coco/000000000785.jpg'\n        results = dict(\n            img_path=img_path, img=imread(img_path).astype(np.uint8))\n\n        results = transform(results)\n\n        self.assertIsInstance(results['img'], np.ndarray)\n        self.assertTrue(results['img'].dtype, np.float32)\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_mix_img_transform.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\n\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.datasets.transforms import Mosaic, YOLOXMixUp\n\n\nclass TestMosaic(TestCase):\n\n    def setUp(self):\n        # Create a sample data dictionary for testing\n        sample_data = {\n            'img':\n            np.random.randint(0, 255, size=(480, 640, 3), dtype=np.uint8),\n            'bbox': np.random.rand(2, 4),\n            'bbox_score': np.random.rand(2, ),\n            'category_id': [1, 2],\n            'keypoints': np.random.rand(2, 3, 2),\n            'keypoints_visible': np.random.rand(2, 3),\n            'area': np.random.rand(2, )\n        }\n        mixed_data_list = [sample_data.copy() for _ in range(3)]\n        sample_data.update({'mixed_data_list': mixed_data_list})\n\n        self.sample_data = sample_data\n\n    def test_apply_mix(self):\n        mosaic = Mosaic()\n        transformed_data = mosaic.apply_mix(self.sample_data)\n\n        # Check if the transformed data has the expected keys\n        self.assertTrue('img' in transformed_data)\n        self.assertTrue('img_shape' in transformed_data)\n        self.assertTrue('bbox' in transformed_data)\n        self.assertTrue('category_id' in transformed_data)\n        self.assertTrue('bbox_score' in transformed_data)\n        self.assertTrue('keypoints' in transformed_data)\n        self.assertTrue('keypoints_visible' in transformed_data)\n        self.assertTrue('area' in transformed_data)\n\n    def test_create_mosaic_image(self):\n        mosaic = Mosaic()\n        mosaic_img, annos = mosaic._create_mosaic_image(\n            self.sample_data, self.sample_data['mixed_data_list'])\n\n        # Check if the mosaic image and annotations are generated correctly\n        self.assertEqual(mosaic_img.shape, (1280, 1280, 3))\n        self.assertTrue('bboxes' in annos)\n        self.assertTrue('bbox_scores' in annos)\n        self.assertTrue('category_id' in annos)\n        self.assertTrue('keypoints' in annos)\n        self.assertTrue('keypoints_visible' in annos)\n        self.assertTrue('area' in annos)\n\n    def test_mosaic_combine(self):\n        mosaic = Mosaic()\n        center = (320, 240)\n        img_shape = (480, 640)\n        paste_coord, crop_coord = mosaic._mosaic_combine(\n            'top_left', center, img_shape)\n\n        # Check if the coordinates are calculated correctly\n        self.assertEqual(paste_coord, (0, 0, 320, 240))\n        self.assertEqual(crop_coord, (160, 400, 480, 640))\n\n\nclass TestYOLOXMixUp(TestCase):\n\n    def setUp(self):\n        # Create a sample data dictionary for testing\n        sample_data = {\n            'img':\n            np.random.randint(0, 255, size=(480, 640, 3), dtype=np.uint8),\n            'bbox': np.random.rand(2, 4),\n            'bbox_score': np.random.rand(2, ),\n            'category_id': [1, 2],\n            'keypoints': np.random.rand(2, 3, 2),\n            'keypoints_visible': np.random.rand(2, 3),\n            'area': np.random.rand(2, ),\n            'flip_indices': [0, 2, 1]\n        }\n        mixed_data_list = [sample_data.copy() for _ in range(1)]\n        sample_data.update({'mixed_data_list': mixed_data_list})\n\n        self.sample_data = sample_data\n\n    def test_apply_mix(self):\n        mixup = YOLOXMixUp()\n        transformed_data = mixup.apply_mix(self.sample_data)\n\n        # Check if the transformed data has the expected keys\n        self.assertTrue('img' in transformed_data)\n        self.assertTrue('img_shape' in transformed_data)\n        self.assertTrue('bbox' in transformed_data)\n        self.assertTrue('category_id' in transformed_data)\n        self.assertTrue('bbox_score' in transformed_data)\n        self.assertTrue('keypoints' in transformed_data)\n        self.assertTrue('keypoints_visible' in transformed_data)\n        self.assertTrue('area' in transformed_data)\n\n    def test_create_mixup_image(self):\n        mixup = YOLOXMixUp()\n        mixup_img, annos = mixup._create_mixup_image(\n            self.sample_data, self.sample_data['mixed_data_list'])\n\n        # Check if the mosaic image and annotations are generated correctly\n        self.assertEqual(mixup_img.shape, (480, 640, 3))\n        self.assertTrue('bboxes' in annos)\n        self.assertTrue('bbox_scores' in annos)\n        self.assertTrue('category_id' in annos)\n        self.assertTrue('keypoints' in annos)\n        self.assertTrue('keypoints_visible' in annos)\n        self.assertTrue('area' in annos)\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_pose3d_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nfrom copy import deepcopy\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import load\n\nfrom mmpose.datasets.transforms import RandomFlipAroundRoot\n\n\ndef get_h36m_sample():\n\n    def _parse_h36m_imgname(imgname):\n        \"\"\"Parse imgname to get information of subject, action and camera.\n\n        A typical h36m image filename is like:\n        S1_Directions_1.54138969_000001.jpg\n        \"\"\"\n        subj, rest = osp.basename(imgname).split('_', 1)\n        action, rest = rest.split('.', 1)\n        camera, rest = rest.split('_', 1)\n        return subj, action, camera\n\n    ann_flle = 'tests/data/h36m/test_h36m_body3d.npz'\n    camera_param_file = 'tests/data/h36m/cameras.pkl'\n\n    data = np.load(ann_flle)\n    cameras = load(camera_param_file)\n\n    imgnames = data['imgname']\n    keypoints = data['part'].astype(np.float32)\n    keypoints_3d = data['S'].astype(np.float32)\n    centers = data['center'].astype(np.float32)\n    scales = data['scale'].astype(np.float32)\n\n    idx = 0\n    target_idx = [0]\n\n    data_info = {\n        'keypoints': keypoints[idx, :, :2].reshape(1, -1, 2),\n        'keypoints_visible': keypoints[idx, :, 2].reshape(1, -1),\n        'keypoints_3d': keypoints_3d[idx, :, :3].reshape(1, -1, 3),\n        'keypoints_3d_visible': keypoints_3d[idx, :, 3].reshape(1, -1),\n        'scale': scales[idx],\n        'center': centers[idx].astype(np.float32).reshape(1, -1),\n        'id': idx,\n        'img_ids': [idx],\n        'img_paths': [imgnames[idx]],\n        'category_id': 1,\n        'iscrowd': 0,\n        'sample_idx': idx,\n        'lifting_target': keypoints_3d[target_idx, :, :3],\n        'lifting_target_visible': keypoints_3d[target_idx, :, 3],\n    }\n\n    # add camera parameters\n    subj, _, camera = _parse_h36m_imgname(imgnames[idx])\n    data_info['camera_param'] = cameras[(subj, camera)]\n\n    # add ann_info\n    ann_info = {}\n    ann_info['num_keypoints'] = 17\n    ann_info['dataset_keypoint_weights'] = np.full(17, 1.0, dtype=np.float32)\n    ann_info['flip_pairs'] = [[1, 4], [2, 5], [3, 6], [11, 14], [12, 15],\n                              [13, 16]]\n    ann_info['skeleton_links'] = []\n    ann_info['upper_body_ids'] = (0, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16)\n    ann_info['lower_body_ids'] = (1, 2, 3, 4, 5, 6)\n    ann_info['flip_indices'] = [\n        0, 4, 5, 6, 1, 2, 3, 7, 8, 9, 10, 14, 15, 16, 11, 12, 13\n    ]\n\n    data_info.update(ann_info)\n\n    return data_info\n\n\nclass TestRandomFlipAroundRoot(TestCase):\n\n    def setUp(self):\n        self.data_info = get_h36m_sample()\n        self.keypoints_flip_cfg = dict(center_mode='static', center_x=0.)\n        self.target_flip_cfg = dict(center_mode='root', center_index=0)\n\n    def test_init(self):\n        _ = RandomFlipAroundRoot(\n            self.keypoints_flip_cfg,\n            self.target_flip_cfg,\n            flip_prob=0.5,\n            flip_camera=False)\n\n    def test_transform(self):\n        kpts1 = self.data_info['keypoints']\n        kpts_vis1 = self.data_info['keypoints_visible']\n        tar1 = self.data_info['lifting_target']\n        tar_vis1 = self.data_info['lifting_target_visible']\n\n        transform = RandomFlipAroundRoot(\n            self.keypoints_flip_cfg, self.target_flip_cfg, flip_prob=1)\n        results = deepcopy(self.data_info)\n        results = transform(results)\n\n        kpts2 = results['keypoints']\n        kpts_vis2 = results['keypoints_visible']\n        tar2 = results['lifting_target']\n        tar_vis2 = results['lifting_target_visible']\n\n        self.assertEqual(kpts_vis2.shape, (1, 17))\n        self.assertEqual(tar_vis2.shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(kpts2.shape, (1, 17, 2))\n        self.assertEqual(tar2.shape, (1, 17, 3))\n\n        flip_indices = [\n            0, 4, 5, 6, 1, 2, 3, 7, 8, 9, 10, 14, 15, 16, 11, 12, 13\n        ]\n        for left, right in enumerate(flip_indices):\n            self.assertTrue(\n                np.allclose(-kpts1[0][left][:1], kpts2[0][right][:1], atol=4.))\n            self.assertTrue(\n                np.allclose(kpts1[0][left][1:], kpts2[0][right][1:], atol=4.))\n            self.assertTrue(\n                np.allclose(\n                    tar1[..., left, 1:], tar2[..., right, 1:], atol=4.))\n\n            self.assertTrue(\n                np.allclose(\n                    kpts_vis1[..., left], kpts_vis2[..., right], atol=4.))\n            self.assertTrue(\n                np.allclose(\n                    tar_vis1[..., left], tar_vis2[..., right], atol=4.))\n\n        # test camera flipping\n        transform = RandomFlipAroundRoot(\n            self.keypoints_flip_cfg,\n            self.target_flip_cfg,\n            flip_prob=1,\n            flip_camera=True)\n        results = deepcopy(self.data_info)\n        results = transform(results)\n\n        camera2 = results['camera_param']\n        self.assertTrue(\n            np.allclose(\n                -self.data_info['camera_param']['c'][0],\n                camera2['c'][0],\n                atol=4.))\n        self.assertTrue(\n            np.allclose(\n                -self.data_info['camera_param']['p'][0],\n                camera2['p'][0],\n                atol=4.))\n\n        # test label flipping\n        self.data_info['keypoint_labels'] = kpts1\n        self.data_info['keypoint_labels_visible'] = kpts_vis1\n        self.data_info['lifting_target_label'] = tar1\n\n        transform = RandomFlipAroundRoot(\n            self.keypoints_flip_cfg,\n            self.target_flip_cfg,\n            flip_prob=1,\n            flip_label=True)\n        results = transform(deepcopy(self.data_info))\n\n        kpts2 = results['keypoint_labels']\n        kpts_vis2 = results['keypoint_labels_visible']\n        tar2 = results['lifting_target_label']\n        tar_vis2 = results['lifting_target_visible']\n\n        self.assertEqual(kpts_vis2.shape, (1, 17))\n        self.assertEqual(tar_vis2.shape, (\n            1,\n            17,\n        ))\n        self.assertEqual(kpts2.shape, (1, 17, 2))\n        self.assertEqual(tar2.shape, (1, 17, 3))\n\n        flip_indices = [\n            0, 4, 5, 6, 1, 2, 3, 7, 8, 9, 10, 14, 15, 16, 11, 12, 13\n        ]\n        for left, right in enumerate(flip_indices):\n            self.assertTrue(\n                np.allclose(-kpts1[0][left][:1], kpts2[0][right][:1], atol=4.))\n            self.assertTrue(\n                np.allclose(kpts1[0][left][1:], kpts2[0][right][1:], atol=4.))\n            self.assertTrue(\n                np.allclose(\n                    tar1[..., left, 1:], tar2[..., right, 1:], atol=4.))\n\n            self.assertTrue(\n                np.allclose(\n                    kpts_vis1[..., left], kpts_vis2[..., right], atol=4.))\n            self.assertTrue(\n                np.allclose(\n                    tar_vis1[..., left], tar_vis2[..., right], atol=4.))\n"
  },
  {
    "path": "tests/test_datasets/test_transforms/test_topdown_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\nfrom unittest import TestCase\n\nfrom mmpose.datasets.transforms import TopdownAffine\nfrom mmpose.testing import get_coco_sample\n\n\nclass TestTopdownAffine(TestCase):\n\n    def setUp(self):\n        # prepare dummy top-down data sample with COCO metainfo\n        self.data_info = get_coco_sample(num_instances=1, with_bbox_cs=True)\n\n    def test_transform(self):\n        # without udp\n        transform = TopdownAffine(input_size=(192, 256), use_udp=False)\n        results = transform(deepcopy(self.data_info))\n        self.assertEqual(results['input_size'], (192, 256))\n        self.assertEqual(results['img'].shape, (256, 192, 3))\n        self.assertIn('transformed_keypoints', results)\n\n        # with udp\n        transform = TopdownAffine(input_size=(192, 256), use_udp=True)\n        results = transform(deepcopy(self.data_info))\n        self.assertEqual(results['input_size'], (192, 256))\n        self.assertEqual(results['img'].shape, (256, 192, 3))\n        self.assertIn('transformed_keypoints', results)\n\n    def test_repr(self):\n        transform = TopdownAffine(input_size=(192, 256), use_udp=False)\n        self.assertEqual(\n            repr(transform),\n            'TopdownAffine(input_size=(192, 256), use_udp=False)')\n"
  },
  {
    "path": "tests/test_engine/test_hooks/test_badcase_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport shutil\nimport time\nfrom unittest import TestCase\nfrom unittest.mock import MagicMock\n\nimport numpy as np\nfrom mmengine.config import ConfigDict\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.engine.hooks import BadCaseAnalysisHook\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.visualization import PoseLocalVisualizer\n\n\ndef _rand_poses(num_boxes, kpt_num, h, w):\n    center = np.random.rand(num_boxes, 2)\n    offset = np.random.rand(num_boxes, kpt_num, 2) / 2.0\n\n    pose = center[:, None, :] + offset.clip(0, 1)\n    pose[:, :, 0] *= w\n    pose[:, :, 1] *= h\n\n    return pose\n\n\nclass TestBadCaseHook(TestCase):\n\n    def setUp(self) -> None:\n        kpt_num = 16\n        PoseLocalVisualizer.get_instance('test_badcase_hook')\n\n        data_sample = PoseDataSample()\n        data_sample.set_metainfo({\n            'img_path':\n            osp.join(\n                osp.dirname(__file__), '../../data/coco/000000000785.jpg')\n        })\n        self.data_batch = {'data_samples': [data_sample] * 2}\n\n        pred_det_data_sample = data_sample.clone()\n        pred_instances = InstanceData()\n        pred_instances.keypoints = _rand_poses(1, kpt_num, 10, 12)\n        pred_det_data_sample.pred_instances = pred_instances\n\n        gt_instances = InstanceData()\n        gt_instances.keypoints = _rand_poses(1, kpt_num, 10, 12)\n        gt_instances.keypoints_visible = np.ones((1, kpt_num))\n        gt_instances.head_size = np.random.rand(1, 1)\n        gt_instances.bboxes = np.random.rand(1, 4)\n        pred_det_data_sample.gt_instances = gt_instances\n        self.outputs = [pred_det_data_sample] * 2\n\n    def test_after_test_iter(self):\n        runner = MagicMock()\n        runner.iter = 1\n\n        # test\n        timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())\n        out_dir = timestamp + '1'\n        runner.work_dir = timestamp\n        runner.timestamp = '1'\n        hook = BadCaseAnalysisHook(enable=False, out_dir=out_dir)\n        hook.after_test_iter(runner, 1, self.data_batch, self.outputs)\n        self.assertTrue(not osp.exists(f'{timestamp}/1/{out_dir}'))\n\n        hook = BadCaseAnalysisHook(\n            enable=True,\n            out_dir=out_dir,\n            metric_type='loss',\n            metric=ConfigDict(type='KeypointMSELoss'),\n            badcase_thr=-1,  # is_badcase = True\n        )\n        hook.after_test_iter(runner, 1, self.data_batch, self.outputs)\n        self.assertEqual(hook._test_index, 2)\n        self.assertTrue(osp.exists(f'{timestamp}/1/{out_dir}'))\n        # same image and preds/gts, so onlu one file\n        self.assertTrue(len(os.listdir(f'{timestamp}/1/{out_dir}')) == 1)\n\n        hook.after_test_epoch(runner)\n        self.assertTrue(osp.exists(f'{timestamp}/1/{out_dir}/results.json'))\n        shutil.rmtree(f'{timestamp}')\n\n        hook = BadCaseAnalysisHook(\n            enable=True,\n            out_dir=out_dir,\n            metric_type='accuracy',\n            metric=ConfigDict(type='MpiiPCKAccuracy'),\n            badcase_thr=-1,  # is_badcase = False\n        )\n        hook.after_test_iter(runner, 1, self.data_batch, self.outputs)\n        self.assertTrue(osp.exists(f'{timestamp}/1/{out_dir}'))\n        self.assertTrue(len(os.listdir(f'{timestamp}/1/{out_dir}')) == 0)\n        shutil.rmtree(f'{timestamp}')\n\n\nif __name__ == '__main__':\n    test = TestBadCaseHook()\n    test.setUp()\n    test.test_after_test_iter()\n"
  },
  {
    "path": "tests/test_engine/test_hooks/test_mode_switch_hooks.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\nfrom unittest.mock import Mock\n\nimport torch\nfrom mmengine.config import Config\nfrom mmengine.runner import Runner\nfrom torch.utils.data import Dataset\n\nfrom mmpose.engine.hooks import RTMOModeSwitchHook, YOLOXPoseModeSwitchHook\nfrom mmpose.utils import register_all_modules\n\n\nclass DummyDataset(Dataset):\n    METAINFO = dict()  # type: ignore\n    data = torch.randn(12, 2)\n    label = torch.ones(12)\n\n    @property\n    def metainfo(self):\n        return self.METAINFO\n\n    def __len__(self):\n        return self.data.size(0)\n\n    def __getitem__(self, index):\n        return dict(inputs=self.data[index], data_sample=self.label[index])\n\n\npipeline1 = [\n    dict(type='RandomHalfBody'),\n]\n\npipeline2 = [\n    dict(type='RandomFlip'),\n]\nregister_all_modules()\n\n\nclass TestYOLOXPoseModeSwitchHook(TestCase):\n\n    def test(self):\n        train_dataloader = dict(\n            dataset=DummyDataset(),\n            sampler=dict(type='DefaultSampler', shuffle=True),\n            batch_size=3,\n            num_workers=0)\n\n        runner = Mock()\n        runner.model = Mock()\n        runner.model.module = Mock()\n\n        runner.model.head.use_aux_loss = False\n        runner.cfg.train_dataloader = Config(train_dataloader)\n        runner.train_dataloader = Runner.build_dataloader(train_dataloader)\n        runner.train_dataloader.dataset.pipeline = pipeline1\n\n        hook = YOLOXPoseModeSwitchHook(\n            num_last_epochs=15, new_train_pipeline=pipeline2)\n\n        # test after change mode\n        runner.epoch = 284\n        runner.max_epochs = 300\n        hook.before_train_epoch(runner)\n        self.assertTrue(runner.model.bbox_head.use_aux_loss)\n        self.assertEqual(runner.train_loop.dataloader.dataset.pipeline,\n                         pipeline2)\n\n\nclass TestRTMOModeSwitchHook(TestCase):\n\n    def test(self):\n\n        runner = Mock()\n        runner.model = Mock()\n        runner.model.head = Mock()\n        runner.model.head.loss = Mock()\n\n        runner.model.head.attr1 = False\n        runner.model.head.loss.attr2 = 1.0\n\n        hook = RTMOModeSwitchHook(epoch_attributes={\n            0: {\n                'attr1': True\n            },\n            10: {\n                'loss.attr2': 0.5\n            }\n        })\n\n        # test after change mode\n        runner.epoch = 0\n        hook.before_train_epoch(runner)\n        self.assertTrue(runner.model.head.attr1)\n        self.assertEqual(runner.model.head.loss.attr2, 1.0)\n\n        runner.epoch = 10\n        hook.before_train_epoch(runner)\n        self.assertTrue(runner.model.head.attr1)\n        self.assertEqual(runner.model.head.loss.attr2, 0.5)\n"
  },
  {
    "path": "tests/test_engine/test_hooks/test_sync_norm_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\nfrom unittest.mock import Mock, patch\n\nimport torch.nn as nn\n\nfrom mmpose.engine.hooks import SyncNormHook\n\n\nclass TestSyncNormHook(TestCase):\n\n    @patch(\n        'mmpose.engine.hooks.sync_norm_hook.get_dist_info',\n        return_value=(0, 1))\n    def test_before_val_epoch_non_dist(self, mock):\n        model = nn.Sequential(\n            nn.Conv2d(1, 5, kernel_size=3), nn.BatchNorm2d(5, momentum=0.3),\n            nn.Linear(5, 10))\n        runner = Mock()\n        runner.model = model\n        hook = SyncNormHook()\n        hook.before_val_epoch(runner)\n\n    @patch(\n        'mmpose.engine.hooks.sync_norm_hook.get_dist_info',\n        return_value=(0, 2))\n    def test_before_val_epoch_dist(self, mock):\n        model = nn.Sequential(\n            nn.Conv2d(1, 5, kernel_size=3), nn.BatchNorm2d(5, momentum=0.3),\n            nn.Linear(5, 10))\n        runner = Mock()\n        runner.model = model\n        hook = SyncNormHook()\n        hook.before_val_epoch(runner)\n\n    @patch(\n        'mmpose.engine.hooks.sync_norm_hook.get_dist_info',\n        return_value=(0, 2))\n    def test_before_val_epoch_dist_no_norm(self, mock):\n        model = nn.Sequential(nn.Conv2d(1, 5, kernel_size=3), nn.Linear(5, 10))\n        runner = Mock()\n        runner.model = model\n        hook = SyncNormHook()\n        hook.before_val_epoch(runner)\n"
  },
  {
    "path": "tests/test_engine/test_hooks/test_visualization_hook.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nimport shutil\nimport time\nfrom unittest import TestCase\nfrom unittest.mock import MagicMock\n\nimport numpy as np\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.engine.hooks import PoseVisualizationHook\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.visualization import PoseLocalVisualizer\n\n\ndef _rand_poses(num_boxes, h, w):\n    center = np.random.rand(num_boxes, 2)\n    offset = np.random.rand(num_boxes, 5, 2) / 2.0\n\n    pose = center[:, None, :] + offset.clip(0, 1)\n    pose[:, :, 0] *= w\n    pose[:, :, 1] *= h\n\n    return pose\n\n\nclass TestVisualizationHook(TestCase):\n\n    def setUp(self) -> None:\n        PoseLocalVisualizer.get_instance('test_visualization_hook')\n\n        data_sample = PoseDataSample()\n        data_sample.set_metainfo({\n            'img_path':\n            osp.join(\n                osp.dirname(__file__), '../../data/coco/000000000785.jpg')\n        })\n        self.data_batch = {'data_samples': [data_sample] * 2}\n\n        pred_instances = InstanceData()\n        pred_instances.keypoints = _rand_poses(5, 10, 12)\n        pred_instances.score = np.random.rand(5, 5)\n        pred_det_data_sample = data_sample.clone()\n        pred_det_data_sample.pred_instances = pred_instances\n        self.outputs = [pred_det_data_sample] * 2\n\n    def test_after_val_iter(self):\n        runner = MagicMock()\n        runner.iter = 1\n        runner.val_evaluator.dataset_meta = dict()\n        hook = PoseVisualizationHook(interval=1, enable=True)\n        hook.after_val_iter(runner, 1, self.data_batch, self.outputs)\n\n    def test_after_test_iter(self):\n        runner = MagicMock()\n        runner.iter = 1\n        hook = PoseVisualizationHook(enable=True)\n        hook.after_test_iter(runner, 1, self.data_batch, self.outputs)\n        self.assertEqual(hook._test_index, 2)\n\n        # test\n        timestamp = time.strftime('%Y%m%d_%H%M%S', time.localtime())\n        out_dir = timestamp + '1'\n        runner.work_dir = timestamp\n        runner.timestamp = '1'\n        hook = PoseVisualizationHook(enable=False, out_dir=out_dir)\n        hook.after_test_iter(runner, 1, self.data_batch, self.outputs)\n        self.assertTrue(not osp.exists(f'{timestamp}/1/{out_dir}'))\n\n        hook = PoseVisualizationHook(enable=True, out_dir=out_dir)\n        hook.after_test_iter(runner, 1, self.data_batch, self.outputs)\n        self.assertTrue(osp.exists(f'{timestamp}/1/{out_dir}'))\n        shutil.rmtree(f'{timestamp}')\n"
  },
  {
    "path": "tests/test_engine/test_schedulers/test_lr_scheduler.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom mmengine.optim.scheduler import _ParamScheduler\nfrom mmengine.testing import assert_allclose\n\nfrom mmpose.engine.schedulers import ConstantLR\n\n\nclass ToyModel(torch.nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self.conv1 = torch.nn.Conv2d(1, 1, 1)\n        self.conv2 = torch.nn.Conv2d(1, 1, 1)\n\n    def forward(self, x):\n        return self.conv2(F.relu(self.conv1(x)))\n\n\nclass TestLRScheduler(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup the model and optimizer which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.model = ToyModel()\n        lr = 0.05\n        self.layer2_mult = 10\n        self.optimizer = optim.SGD([{\n            'params': self.model.conv1.parameters()\n        }, {\n            'params': self.model.conv2.parameters(),\n            'lr': lr * self.layer2_mult,\n        }],\n                                   lr=lr,\n                                   momentum=0.01,\n                                   weight_decay=5e-4)\n\n    def _test_scheduler_value(self,\n                              schedulers,\n                              targets,\n                              epochs=10,\n                              param_name='lr',\n                              step_kwargs=None):\n        if isinstance(schedulers, _ParamScheduler):\n            schedulers = [schedulers]\n        if step_kwargs is None:\n            step_kwarg = [{} for _ in range(len(schedulers))]\n            step_kwargs = [step_kwarg for _ in range(epochs)]\n        else:  # step_kwargs is not None\n            assert len(step_kwargs) == epochs\n            assert len(step_kwargs[0]) == len(schedulers)\n        for epoch in range(epochs):\n            for param_group, target in zip(self.optimizer.param_groups,\n                                           targets):\n                assert_allclose(\n                    target[epoch],\n                    param_group[param_name],\n                    msg='{} is wrong in epoch {}: expected {}, got {}'.format(\n                        param_name, epoch, target[epoch],\n                        param_group[param_name]),\n                    atol=1e-5,\n                    rtol=0)\n            [\n                scheduler.step(**step_kwargs[epoch][i])\n                for i, scheduler in enumerate(schedulers)\n            ]\n\n    def test_constant_scheduler(self):\n\n        # lr = 0.025     if epoch < 5\n        # lr = 0.005    if 5 <= epoch\n        epochs = 10\n        single_targets = [0.025] * 4 + [0.05] * 6\n        targets = [\n            single_targets, [x * self.layer2_mult for x in single_targets]\n        ]\n        scheduler = ConstantLR(self.optimizer, factor=1.0 / 2, end=5)\n        self._test_scheduler_value(scheduler, targets, epochs)\n\n        # remove factor range restriction\n        _ = ConstantLR(self.optimizer, factor=99, end=100)\n"
  },
  {
    "path": "tests/test_engine/test_schedulers/test_quadratic_warmup.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nimport torch.nn.functional as F\nimport torch.optim as optim\nfrom mmengine.optim.scheduler import _ParamScheduler\nfrom mmengine.testing import assert_allclose\n\nfrom mmpose.engine.schedulers import (QuadraticWarmupLR,\n                                      QuadraticWarmupMomentum,\n                                      QuadraticWarmupParamScheduler)\n\n\nclass ToyModel(torch.nn.Module):\n\n    def __init__(self):\n        super().__init__()\n        self.conv1 = torch.nn.Conv2d(1, 1, 1)\n        self.conv2 = torch.nn.Conv2d(1, 1, 1)\n\n    def forward(self, x):\n        return self.conv2(F.relu(self.conv1(x)))\n\n\nclass TestQuadraticWarmupScheduler(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup the model and optimizer which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.model = ToyModel()\n        self.optimizer = optim.SGD(\n            self.model.parameters(), lr=0.05, momentum=0.01, weight_decay=5e-4)\n\n    def _test_scheduler_value(self,\n                              schedulers,\n                              targets,\n                              epochs=10,\n                              param_name='lr'):\n        if isinstance(schedulers, _ParamScheduler):\n            schedulers = [schedulers]\n        for epoch in range(epochs):\n            for param_group, target in zip(self.optimizer.param_groups,\n                                           targets):\n                print(param_group[param_name])\n                assert_allclose(\n                    target[epoch],\n                    param_group[param_name],\n                    msg='{} is wrong in epoch {}: expected {}, got {}'.format(\n                        param_name, epoch, target[epoch],\n                        param_group[param_name]),\n                    atol=1e-5,\n                    rtol=0)\n            [scheduler.step() for scheduler in schedulers]\n\n    def test_quadratic_warmup_scheduler(self):\n        with self.assertRaises(ValueError):\n            QuadraticWarmupParamScheduler(self.optimizer, param_name='lr')\n        epochs = 10\n        iters = 5\n        warmup_factor = [pow((i + 1) / float(iters), 2) for i in range(iters)]\n        single_targets = [x * 0.05 for x in warmup_factor] + [0.05] * (\n            epochs - iters)\n        targets = [single_targets, [x * epochs for x in single_targets]]\n        scheduler = QuadraticWarmupParamScheduler(\n            self.optimizer, param_name='lr', end=iters)\n        self._test_scheduler_value(scheduler, targets, epochs)\n\n    def test_quadratic_warmup_scheduler_convert_iterbased(self):\n        epochs = 10\n        end = 5\n        epoch_length = 11\n\n        iters = end * epoch_length\n        warmup_factor = [pow((i + 1) / float(iters), 2) for i in range(iters)]\n        single_targets = [x * 0.05 for x in warmup_factor] + [0.05] * (\n            epochs * epoch_length - iters)\n        targets = [single_targets, [x * epochs for x in single_targets]]\n        scheduler = QuadraticWarmupParamScheduler.build_iter_from_epoch(\n            self.optimizer,\n            param_name='lr',\n            end=end,\n            epoch_length=epoch_length)\n        self._test_scheduler_value(scheduler, targets, epochs * epoch_length)\n\n    def test_quadratic_warmup_lr(self):\n        epochs = 10\n        iters = 5\n        warmup_factor = [pow((i + 1) / float(iters), 2) for i in range(iters)]\n        single_targets = [x * 0.05 for x in warmup_factor] + [0.05] * (\n            epochs - iters)\n        targets = [single_targets, [x * epochs for x in single_targets]]\n        scheduler = QuadraticWarmupLR(self.optimizer, end=iters)\n        self._test_scheduler_value(scheduler, targets, epochs)\n\n    def test_quadratic_warmup_momentum(self):\n        epochs = 10\n        iters = 5\n        warmup_factor = [pow((i + 1) / float(iters), 2) for i in range(iters)]\n        single_targets = [x * 0.01 for x in warmup_factor] + [0.01] * (\n            epochs - iters)\n        targets = [single_targets, [x * epochs for x in single_targets]]\n        scheduler = QuadraticWarmupMomentum(self.optimizer, end=iters)\n        self._test_scheduler_value(\n            scheduler, targets, epochs, param_name='momentum')\n"
  },
  {
    "path": "tests/test_evaluation/test_evaluator/test_multi_dataset_evaluator.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.evaluation.evaluators import MultiDatasetEvaluator\nfrom mmpose.testing import get_coco_sample\nfrom mmpose.utils import register_all_modules\n\n\nclass TestMultiDatasetEvaluator(TestCase):\n\n    def setUp(self) -> None:\n        register_all_modules()\n\n        aic_to_coco_converter = dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 6),\n                (1, 8),\n                (2, 10),\n                (3, 5),\n                (4, 7),\n                (5, 9),\n                (6, 12),\n                (7, 14),\n                (8, 16),\n                (9, 11),\n                (10, 13),\n                (11, 15),\n            ])\n\n        # val datasets\n        dataset_coco_val = dict(\n            type='CocoDataset',\n            data_root='data/coco',\n            test_mode=True,\n        )\n\n        dataset_aic_val = dict(\n            type='AicDataset',\n            data_root='data/aic/',\n            test_mode=True,\n        )\n\n        self.datasets = [dataset_coco_val, dataset_aic_val]\n\n        self.metrics = [\n            dict(type='CocoMetric', ann_file='tests/data/coco/test_coco.json'),\n            dict(\n                type='CocoMetric',\n                ann_file='tests/data/aic/test_aic.json',\n                use_area=False,\n                gt_converter=aic_to_coco_converter,\n                prefix='aic')\n        ]\n\n        data_sample1 = get_coco_sample(\n            img_shape=(240, 320), num_instances=2, with_bbox_cs=False)\n        data_sample1['dataset_name'] = 'coco'\n        data_sample1['id'] = 0\n        data_sample1['img_id'] = 100\n        data_sample1['gt_instances'] = dict(bbox_scores=np.ones(2), )\n        data_sample1['pred_instances'] = dict(\n            keypoints=data_sample1['keypoints'],\n            keypoint_scores=data_sample1['keypoints_visible'],\n        )\n        imgs1 = data_sample1.pop('img')\n\n        data_sample2 = get_coco_sample(\n            img_shape=(240, 320), num_instances=3, with_bbox_cs=False)\n        data_sample2['dataset_name'] = 'aic'\n        data_sample2['id'] = 1\n        data_sample2['img_id'] = 200\n        data_sample2['gt_instances'] = dict(bbox_scores=np.ones(3), )\n        data_sample2['pred_instances'] = dict(\n            keypoints=data_sample2['keypoints'],\n            keypoint_scores=data_sample2['keypoints_visible'],\n        )\n        imgs2 = data_sample2.pop('img')\n\n        self.data_batch = dict(\n            inputs=[imgs1, imgs2], data_samples=[data_sample1, data_sample2])\n        self.data_samples = [data_sample1, data_sample2]\n\n    def test_init(self):\n        evaluator = MultiDatasetEvaluator(self.metrics, self.datasets)\n        self.assertIn('metrics_dict', dir(evaluator))\n        self.assertEqual(len(evaluator.metrics_dict), 2)\n\n        with self.assertRaises(AssertionError):\n            evaluator = MultiDatasetEvaluator(self.metrics, self.datasets[:1])\n\n    def test_process(self):\n        evaluator = MultiDatasetEvaluator(self.metrics, self.datasets)\n        evaluator.dataset_meta = dict(dataset_name='default')\n        evaluator.process(self.data_samples, self.data_batch)\n\n        for metric in evaluator.metrics:\n            self.assertGreater(len(metric.results), 0)\n"
  },
  {
    "path": "tests/test_evaluation/test_functional/test_keypoint_eval.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nfrom numpy.testing import assert_array_almost_equal\n\nfrom mmpose.evaluation.functional import (keypoint_auc, keypoint_epe,\n                                          keypoint_mpjpe, keypoint_nme,\n                                          keypoint_pck_accuracy,\n                                          multilabel_classification_accuracy,\n                                          pose_pck_accuracy)\n\n\nclass TestKeypointEval(TestCase):\n\n    def test_keypoint_pck_accuracy(self):\n\n        output = np.zeros((2, 5, 2))\n        target = np.zeros((2, 5, 2))\n        mask = np.array([[True, True, False, True, True],\n                         [True, True, False, True, True]])\n\n        # first channel\n        output[0, 0] = [10, 0]\n        target[0, 0] = [10, 0]\n        # second channel\n        output[0, 1] = [20, 20]\n        target[0, 1] = [10, 10]\n        # third channel\n        output[0, 2] = [0, 0]\n        target[0, 2] = [-1, 0]\n        # fourth channel\n        output[0, 3] = [30, 30]\n        target[0, 3] = [30, 30]\n        # fifth channel\n        output[0, 4] = [0, 10]\n        target[0, 4] = [0, 10]\n\n        thr = np.full((2, 2), 10, dtype=np.float32)\n\n        acc, avg_acc, cnt = keypoint_pck_accuracy(output, target, mask, 0.5,\n                                                  thr)\n\n        assert_array_almost_equal(acc, np.array([1, 0.5, -1, 1, 1]), decimal=4)\n        self.assertAlmostEqual(avg_acc, 0.875, delta=1e-4)\n        self.assertAlmostEqual(cnt, 4, delta=1e-4)\n\n        acc, avg_acc, cnt = keypoint_pck_accuracy(output, target, mask, 0.5,\n                                                  np.zeros((2, 2)))\n        assert_array_almost_equal(\n            acc, np.array([-1, -1, -1, -1, -1]), decimal=4)\n        self.assertAlmostEqual(avg_acc, 0, delta=1e-4)\n        self.assertAlmostEqual(cnt, 0, delta=1e-4)\n\n        acc, avg_acc, cnt = keypoint_pck_accuracy(output, target, mask, 0.5,\n                                                  np.array([[0, 0], [10, 10]]))\n        assert_array_almost_equal(acc, np.array([1, 1, -1, 1, 1]), decimal=4)\n        self.assertAlmostEqual(avg_acc, 1, delta=1e-4)\n        self.assertAlmostEqual(cnt, 4, delta=1e-4)\n\n    def test_keypoint_auc(self):\n        output = np.zeros((1, 5, 2))\n        target = np.zeros((1, 5, 2))\n        mask = np.array([[True, True, False, True, True]])\n        # first channel\n        output[0, 0] = [10, 4]\n        target[0, 0] = [10, 0]\n        # second channel\n        output[0, 1] = [10, 18]\n        target[0, 1] = [10, 10]\n        # third channel\n        output[0, 2] = [0, 0]\n        target[0, 2] = [0, -1]\n        # fourth channel\n        output[0, 3] = [40, 40]\n        target[0, 3] = [30, 30]\n        # fifth channel\n        output[0, 4] = [20, 10]\n        target[0, 4] = [0, 10]\n\n        auc = keypoint_auc(output, target, mask, 20, 4)\n        self.assertAlmostEqual(auc, 0.375, delta=1e-4)\n\n    def test_keypoint_epe(self):\n        output = np.zeros((1, 5, 2))\n        target = np.zeros((1, 5, 2))\n        mask = np.array([[True, True, False, True, True]])\n        # first channel\n        output[0, 0] = [10, 4]\n        target[0, 0] = [10, 0]\n        # second channel\n        output[0, 1] = [10, 18]\n        target[0, 1] = [10, 10]\n        # third channel\n        output[0, 2] = [0, 0]\n        target[0, 2] = [-1, -1]\n        # fourth channel\n        output[0, 3] = [40, 40]\n        target[0, 3] = [30, 30]\n        # fifth channel\n        output[0, 4] = [20, 10]\n        target[0, 4] = [0, 10]\n\n        epe = keypoint_epe(output, target, mask)\n        self.assertAlmostEqual(epe, 11.5355339, delta=1e-4)\n\n    def test_keypoint_nme(self):\n        output = np.zeros((1, 5, 2))\n        target = np.zeros((1, 5, 2))\n        mask = np.array([[True, True, False, True, True]])\n        # first channel\n        output[0, 0] = [10, 4]\n        target[0, 0] = [10, 0]\n        # second channel\n        output[0, 1] = [10, 18]\n        target[0, 1] = [10, 10]\n        # third channel\n        output[0, 2] = [0, 0]\n        target[0, 2] = [-1, -1]\n        # fourth channel\n        output[0, 3] = [40, 40]\n        target[0, 3] = [30, 30]\n        # fifth channel\n        output[0, 4] = [20, 10]\n        target[0, 4] = [0, 10]\n\n        normalize_factor = np.ones((output.shape[0], output.shape[2]))\n\n        nme = keypoint_nme(output, target, mask, normalize_factor)\n        self.assertAlmostEqual(nme, 11.5355339, delta=1e-4)\n\n    def test_pose_pck_accuracy(self):\n        output = np.zeros((1, 5, 64, 64), dtype=np.float32)\n        target = np.zeros((1, 5, 64, 64), dtype=np.float32)\n        mask = np.array([[True, True, False, False, False]])\n        # first channel\n        output[0, 0, 20, 20] = 1\n        target[0, 0, 10, 10] = 1\n        # second channel\n        output[0, 1, 30, 30] = 1\n        target[0, 1, 30, 30] = 1\n\n        acc, avg_acc, cnt = pose_pck_accuracy(output, target, mask)\n\n        assert_array_almost_equal(acc, np.array([0, 1, -1, -1, -1]), decimal=4)\n        self.assertAlmostEqual(avg_acc, 0.5, delta=1e-4)\n        self.assertAlmostEqual(cnt, 2, delta=1e-4)\n\n    def test_multilabel_classification_accuracy(self):\n        output = np.array([[0.7, 0.8, 0.4], [0.8, 0.1, 0.1]])\n        target = np.array([[1, 0, 0], [1, 0, 1]])\n        mask = np.array([[True, True, True], [True, True, True]])\n        thr = 0.5\n        acc = multilabel_classification_accuracy(output, target, mask, thr)\n        self.assertEqual(acc, 0)\n\n        output = np.array([[0.7, 0.2, 0.4], [0.8, 0.1, 0.9]])\n        thr = 0.5\n        acc = multilabel_classification_accuracy(output, target, mask, thr)\n        self.assertEqual(acc, 1)\n\n        thr = 0.3\n        acc = multilabel_classification_accuracy(output, target, mask, thr)\n        self.assertEqual(acc, 0.5)\n\n        mask = np.array([[True, True, False], [True, True, True]])\n        acc = multilabel_classification_accuracy(output, target, mask, thr)\n        self.assertEqual(acc, 1)\n\n    def test_keypoint_mpjpe(self):\n        output = np.zeros((2, 5, 3))\n        target = np.zeros((2, 5, 3))\n        mask = np.array([[True, True, False, True, True],\n                         [True, True, False, True, True]])\n\n        # first channel\n        output[0, 0] = [1, 0, 0]\n        target[0, 0] = [1, 0, 0]\n        output[1, 0] = [1, 0, 0]\n        target[1, 0] = [1, 1, 0]\n        # second channel\n        output[0, 1] = [2, 2, 0]\n        target[0, 1] = [1, 1, 1]\n        output[1, 1] = [2, 2, 1]\n        target[1, 1] = [1, 0, 1]\n        # third channel\n        output[0, 2] = [0, 0, -1]\n        target[0, 2] = [-1, 0, 0]\n        output[1, 2] = [-1, 0, 0]\n        target[1, 2] = [-1, 0, 0]\n        # fourth channel\n        output[0, 3] = [3, 3, 1]\n        target[0, 3] = [3, 3, 1]\n        output[1, 3] = [0, 0, 3]\n        target[1, 3] = [0, 0, 3]\n        # fifth channel\n        output[0, 4] = [0, 1, 1]\n        target[0, 4] = [0, 1, 0]\n        output[1, 4] = [0, 0, 1]\n        target[1, 4] = [1, 1, 0]\n\n        mpjpe = keypoint_mpjpe(output, target, mask)\n        self.assertAlmostEqual(mpjpe, 0.9625211990796929, delta=1e-4)\n\n        p_mpjpe = keypoint_mpjpe(output, target, mask, 'procrustes')\n        self.assertAlmostEqual(p_mpjpe, 1.0047897634604497, delta=1e-4)\n\n        s_mpjpe = keypoint_mpjpe(output, target, mask, 'scale')\n        self.assertAlmostEqual(s_mpjpe, 1.0277129678465953, delta=1e-4)\n\n        with self.assertRaises(ValueError):\n            _ = keypoint_mpjpe(output, target, mask, 'alignment')\n"
  },
  {
    "path": "tests/test_evaluation/test_functional/test_nms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\n\nfrom mmpose.evaluation.functional.nms import nearby_joints_nms, nms_torch\n\n\nclass TestNearbyJointsNMS(TestCase):\n\n    def test_nearby_joints_nms(self):\n\n        kpts_db = []\n        keep_pose_inds = nearby_joints_nms(\n            kpts_db, 0.05, score_per_joint=True, max_dets=1)\n        self.assertEqual(len(keep_pose_inds), 0)\n\n        kpts_db = []\n        for _ in range(5):\n            kpts_db.append(\n                dict(keypoints=np.random.rand(3, 2), score=np.random.rand(3)))\n        keep_pose_inds = nearby_joints_nms(\n            kpts_db, 0.05, score_per_joint=True, max_dets=1)\n        self.assertEqual(len(keep_pose_inds), 1)\n        self.assertLess(keep_pose_inds[0], 5)\n\n        kpts_db = []\n        for _ in range(5):\n            kpts_db.append(\n                dict(keypoints=np.random.rand(3, 2), score=np.random.rand()))\n        keep_pose_inds = nearby_joints_nms(\n            kpts_db, 0.05, num_nearby_joints_thr=2)\n        self.assertLessEqual(len(keep_pose_inds), 5)\n        self.assertGreater(len(keep_pose_inds), 0)\n\n        with self.assertRaises(AssertionError):\n            _ = nearby_joints_nms(kpts_db, 0, num_nearby_joints_thr=2)\n\n        with self.assertRaises(AssertionError):\n            _ = nearby_joints_nms(kpts_db, 0.05, num_nearby_joints_thr=3)\n\n\nclass TestNMSTorch(TestCase):\n\n    def test_nms_torch(self):\n        bboxes = torch.tensor([[0, 0, 3, 3], [1, 0, 3, 3], [4, 4, 6, 6]],\n                              dtype=torch.float32)\n\n        scores = torch.tensor([0.9, 0.8, 0.7])\n\n        expected_result = torch.tensor([0, 2])\n        result = nms_torch(bboxes, scores, threshold=0.5)\n        self.assertTrue(torch.equal(result, expected_result))\n\n        expected_result = [torch.tensor([0, 1]), torch.tensor([2])]\n        result = nms_torch(bboxes, scores, threshold=0.5, return_group=True)\n        for res_out, res_expected in zip(result, expected_result):\n            self.assertTrue(torch.equal(res_out, res_expected))\n"
  },
  {
    "path": "tests/test_evaluation/test_functional/test_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom copy import deepcopy\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.evaluation.functional import (transform_ann, transform_pred,\n                                          transform_sigmas)\n\n\nclass TestKeypointEval(TestCase):\n\n    def test_transform_sigmas(self):\n\n        mapping = [(3, 0), (6, 1), (16, 2), (5, 3)]\n        num_keypoints = 5\n        sigmas = np.random.rand(17)\n        new_sigmas = transform_sigmas(sigmas, num_keypoints, mapping)\n        self.assertEqual(len(new_sigmas), 5)\n        for i, j in mapping:\n            self.assertEqual(sigmas[i], new_sigmas[j])\n\n    def test_transform_ann(self):\n        mapping = [(3, 0), (6, 1), (16, 2), (5, 3)]\n        num_keypoints = 5\n\n        kpt_info = dict(\n            num_keypoints=17,\n            keypoints=np.random.randint(3, size=(17 * 3, )).tolist())\n        kpt_info_copy = deepcopy(kpt_info)\n\n        _ = transform_ann(kpt_info, num_keypoints, mapping)\n\n        self.assertEqual(kpt_info['num_keypoints'], 5)\n        self.assertEqual(len(kpt_info['keypoints']), 15)\n        for i, j in mapping:\n            self.assertListEqual(kpt_info_copy['keypoints'][i * 3:i * 3 + 3],\n                                 kpt_info['keypoints'][j * 3:j * 3 + 3])\n\n    def test_transform_pred(self):\n        mapping = [(3, 0), (6, 1), (16, 2), (5, 3)]\n        num_keypoints = 5\n\n        kpt_info = dict(\n            num_keypoints=17,\n            keypoints=np.random.randint(3, size=(\n                1,\n                17,\n                3,\n            )),\n            keypoint_scores=np.ones((1, 17)))\n\n        _ = transform_pred(kpt_info, num_keypoints, mapping)\n\n        self.assertEqual(kpt_info['num_keypoints'], 5)\n        self.assertEqual(len(kpt_info['keypoints']), 1)\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_coco_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport os.path as osp\nimport tempfile\nfrom collections import defaultdict\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import dump, load\nfrom mmengine.logging import MessageHub\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets.datasets import CocoDataset\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.evaluation.metrics import CocoMetric\n\n\nclass TestCocoMetric(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n\n        # during CI on github, the unit tests for datasets will save ann_file\n        # into MessageHub, which will influence the unit tests for CocoMetric\n        msg = MessageHub.get_current_instance()\n        msg.runtime_info.clear()\n\n        self.tmp_dir = tempfile.TemporaryDirectory()\n\n        self.ann_file_coco = 'tests/data/coco/test_coco.json'\n        meta_info_coco = dict(from_file='configs/_base_/datasets/coco.py')\n        self.dataset_meta_coco = parse_pose_metainfo(meta_info_coco)\n        self.coco = COCO(self.ann_file_coco)\n        self.dataset_meta_coco['CLASSES'] = self.coco.loadCats(\n            self.coco.getCatIds())\n\n        self.topdown_data_coco = self._convert_ann_to_topdown_batch_data(\n            self.ann_file_coco)\n        assert len(self.topdown_data_coco) == 14\n        self.bottomup_data_coco = self._convert_ann_to_bottomup_batch_data(\n            self.ann_file_coco)\n        assert len(self.bottomup_data_coco) == 4\n        self.target_coco = {\n            'coco/AP': 1.0,\n            'coco/AP .5': 1.0,\n            'coco/AP .75': 1.0,\n            'coco/AP (M)': 1.0,\n            'coco/AP (L)': 1.0,\n            'coco/AR': 1.0,\n            'coco/AR .5': 1.0,\n            'coco/AR .75': 1.0,\n            'coco/AR (M)': 1.0,\n            'coco/AR (L)': 1.0,\n        }\n\n        self.ann_file_crowdpose = 'tests/data/crowdpose/test_crowdpose.json'\n        self.coco_crowdpose = COCO(self.ann_file_crowdpose)\n        meta_info_crowdpose = dict(\n            from_file='configs/_base_/datasets/crowdpose.py')\n        self.dataset_meta_crowdpose = parse_pose_metainfo(meta_info_crowdpose)\n        self.dataset_meta_crowdpose['CLASSES'] = self.coco_crowdpose.loadCats(\n            self.coco_crowdpose.getCatIds())\n\n        self.topdown_data_crowdpose = self._convert_ann_to_topdown_batch_data(\n            self.ann_file_crowdpose)\n        self.topdown_data_pseudo_coco = \\\n            self._convert_ann_to_topdown_batch_data(\n                self.ann_file_crowdpose,\n                num_pseudo_kpts=3)\n        assert len(self.topdown_data_crowdpose) == 5\n        self.bottomup_data_crowdpose = \\\n            self._convert_ann_to_bottomup_batch_data(self.ann_file_crowdpose)\n        assert len(self.bottomup_data_crowdpose) == 2\n\n        self.target_crowdpose = {\n            'crowdpose/AP': 1.0,\n            'crowdpose/AP .5': 1.0,\n            'crowdpose/AP .75': 1.0,\n            'crowdpose/AR': 1.0,\n            'crowdpose/AR .5': 1.0,\n            'crowdpose/AR .75': 1.0,\n            'crowdpose/AP(E)': -1.0,\n            'crowdpose/AP(M)': 1.0,\n            'crowdpose/AP(H)': -1.0,\n        }\n\n        self.ann_file_ap10k = 'tests/data/ap10k/test_ap10k.json'\n        self.coco_ap10k = COCO(self.ann_file_ap10k)\n        meta_info_ap10k = dict(from_file='configs/_base_/datasets/ap10k.py')\n        self.dataset_meta_ap10k = parse_pose_metainfo(meta_info_ap10k)\n        self.dataset_meta_ap10k['CLASSES'] = self.coco_ap10k.loadCats(\n            self.coco_ap10k.getCatIds())\n\n        self.topdown_data_ap10k = self._convert_ann_to_topdown_batch_data(\n            self.ann_file_ap10k)\n        assert len(self.topdown_data_ap10k) == 2\n        self.bottomup_data_ap10k = self._convert_ann_to_bottomup_batch_data(\n            self.ann_file_ap10k)\n        assert len(self.bottomup_data_ap10k) == 2\n\n        self.target_ap10k = {\n            'coco/AP': 1.0,\n            'coco/AP .5': 1.0,\n            'coco/AP .75': 1.0,\n            'coco/AP (M)': -1.0,\n            'coco/AP (L)': 1.0,\n            'coco/AR': 1.0,\n            'coco/AR .5': 1.0,\n            'coco/AR .75': 1.0,\n            'coco/AR (M)': -1.0,\n            'coco/AR (L)': 1.0,\n        }\n\n    def _convert_ann_to_topdown_batch_data(self,\n                                           ann_file,\n                                           num_pseudo_kpts: int = 0):\n        \"\"\"Convert annotations to topdown-style batch data.\"\"\"\n        topdown_data = []\n        db = load(ann_file)\n        imgid2info = dict()\n        for img in db['images']:\n            imgid2info[img['id']] = img\n        for ann in db['annotations']:\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n            keypoints = np.array(ann['keypoints']).reshape((1, -1, 3))\n\n            gt_instances = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32),\n                'bboxes': bboxes,\n            }\n\n            if num_pseudo_kpts > 0:\n                keypoints = np.concatenate(\n                    (keypoints, *((keypoints[:, :1], ) * num_pseudo_kpts)),\n                    axis=1)\n\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'category_id': ann.get('category_id', 1),\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances,\n                # dummy image_shape for testing\n                'ori_shape': [640, 480],\n                # store the raw annotation info to test without ann_file\n                'raw_ann_info': copy.deepcopy(ann),\n            }\n\n            # add crowd_index to data_sample if it is present in the image_info\n            if 'crowdIndex' in imgid2info[ann['image_id']]:\n                data_sample['crowd_index'] = imgid2info[\n                    ann['image_id']]['crowdIndex']\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n\n        return topdown_data\n\n    def _convert_ann_to_bottomup_batch_data(self, ann_file):\n        \"\"\"Convert annotations to bottomup-style batch data.\"\"\"\n        img2ann = defaultdict(list)\n        db = load(ann_file)\n        for ann in db['annotations']:\n            img2ann[ann['image_id']].append(ann)\n\n        bottomup_data = []\n        for img_id, anns in img2ann.items():\n            keypoints = np.array([ann['keypoints'] for ann in anns]).reshape(\n                (len(anns), -1, 3))\n\n            gt_instances = {\n                'bbox_scores': np.ones((len(anns)), dtype=np.float32)\n            }\n\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': [ann['id'] for ann in anns],\n                'img_id': img_id,\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            bottomup_data.append((data_batch, data_samples))\n        return bottomup_data\n\n    def tearDown(self):\n        self.tmp_dir.cleanup()\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test score_mode option\n        with self.assertRaisesRegex(ValueError,\n                                    '`score_mode` should be one of'):\n            _ = CocoMetric(ann_file=self.ann_file_coco, score_mode='invalid')\n\n        # test nms_mode option\n        with self.assertRaisesRegex(ValueError, '`nms_mode` should be one of'):\n            _ = CocoMetric(ann_file=self.ann_file_coco, nms_mode='invalid')\n\n        # test format_only option\n        with self.assertRaisesRegex(\n                AssertionError,\n                '`outfile_prefix` can not be None when `format_only` is True'):\n            _ = CocoMetric(\n                ann_file=self.ann_file_coco,\n                format_only=True,\n                outfile_prefix=None)\n\n    def test_other_methods(self):\n        \"\"\"test other useful methods.\"\"\"\n        # test `_sort_and_unique_bboxes` method\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco, score_mode='bbox', nms_mode='none')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n        # process one extra sample\n        data_batch, data_samples = self.topdown_data_coco[0]\n        metric_coco.process(data_batch, data_samples)\n        # an extra sample\n        eval_results = metric_coco.evaluate(\n            size=len(self.topdown_data_coco) + 1)\n        self.assertDictEqual(eval_results, self.target_coco)\n\n    def test_format_only(self):\n        \"\"\"test `format_only` option.\"\"\"\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            format_only=True,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n        # process one sample\n        data_batch, data_samples = self.topdown_data_coco[0]\n        metric_coco.process(data_batch, data_samples)\n        eval_results = metric_coco.evaluate(size=1)\n        self.assertDictEqual(eval_results, {})\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test.keypoints.json')))\n\n        # test when gt annotations are absent\n        db_ = load(self.ann_file_coco)\n        del db_['annotations']\n        tmp_ann_file = osp.join(self.tmp_dir.name, 'temp_ann.json')\n        dump(db_, tmp_ann_file, sort_keys=True, indent=4)\n        with self.assertRaisesRegex(\n                AssertionError,\n                'Ground truth annotations are required for evaluation'):\n            _ = CocoMetric(ann_file=tmp_ann_file, format_only=False)\n\n    def test_bottomup_evaluate(self):\n        \"\"\"test bottomup-style COCO metric evaluation.\"\"\"\n        # case1: score_mode='bbox', nms_mode='none'\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox',\n            nms_mode='none')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.bottomup_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.bottomup_data_coco))\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test.keypoints.json')))\n\n    def test_topdown_alignment(self):\n        \"\"\"Test whether the output of CocoMetric and the original\n        TopDownCocoDataset are the same.\"\"\"\n        topdown_data = []\n        db = load(self.ann_file_coco)\n\n        for ann in db['annotations']:\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n\n            keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n            keypoints[..., 0] = keypoints[..., 0] * 0.98\n            keypoints[..., 1] = keypoints[..., 1] * 1.02\n            keypoints[..., 2] = keypoints[..., 2] * 0.8\n\n            gt_instances = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32) * 0.98,\n                'bboxes': bboxes,\n            }\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances\n            }\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n\n        # case 1:\n        # typical setting: score_mode='bbox_keypoint', nms_mode='oks_nms'\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test_align1',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in topdown_data:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(topdown_data))\n\n        target = {\n            'coco/AP': 0.5287458745874587,\n            'coco/AP .5': 0.9042904290429042,\n            'coco/AP .75': 0.5009900990099009,\n            'coco/AP (M)': 0.42475247524752474,\n            'coco/AP (L)': 0.6219554455445544,\n            'coco/AR': 0.5833333333333333,\n            'coco/AR .5': 0.9166666666666666,\n            'coco/AR .75': 0.5833333333333334,\n            'coco/AR (M)': 0.44000000000000006,\n            'coco/AR (L)': 0.6857142857142857,\n        }\n\n        for key in eval_results.keys():\n            self.assertAlmostEqual(eval_results[key], target[key])\n\n        self.assertTrue(\n            osp.isfile(\n                osp.join(self.tmp_dir.name, 'test_align1.keypoints.json')))\n\n        # case 2: score_mode='bbox_rle', nms_mode='oks_nms'\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test_align2',\n            score_mode='bbox_rle',\n            nms_mode='oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in topdown_data:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(topdown_data))\n\n        target = {\n            'coco/AP': 0.5004950495049505,\n            'coco/AP .5': 0.8836633663366337,\n            'coco/AP .75': 0.4679867986798679,\n            'coco/AP (M)': 0.42475247524752474,\n            'coco/AP (L)': 0.5814108910891089,\n            'coco/AR': 0.5833333333333333,\n            'coco/AR .5': 0.9166666666666666,\n            'coco/AR .75': 0.5833333333333334,\n            'coco/AR (M)': 0.44000000000000006,\n            'coco/AR (L)': 0.6857142857142857,\n        }\n\n        for key in eval_results.keys():\n            self.assertAlmostEqual(eval_results[key], target[key])\n\n        self.assertTrue(\n            osp.isfile(\n                osp.join(self.tmp_dir.name, 'test_align2.keypoints.json')))\n\n        # case 3: score_mode='bbox_keypoint', nms_mode='soft_oks_nms'\n        topdown_data = []\n        anns = db['annotations']\n        for i, ann in enumerate(anns):\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n\n            keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n            keypoints[..., 0] = keypoints[..., 0] * (1 - i / 100)\n            keypoints[..., 1] = keypoints[..., 1] * (1 + i / 100)\n            keypoints[..., 2] = keypoints[..., 2] * (1 - i / 100)\n\n            gt_instances0 = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32),\n                'bboxes': bboxes,\n            }\n            pred_instances0 = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data0 = {'inputs': None}\n            data_sample0 = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances0,\n                'pred_instances': pred_instances0\n            }\n\n            keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n            keypoints[..., 0] = keypoints[..., 0] * (1 + i / 100)\n            keypoints[..., 1] = keypoints[..., 1] * (1 - i / 100)\n            keypoints[..., 2] = keypoints[..., 2] * (1 - 2 * i / 100)\n\n            gt_instances1 = {\n                'bbox_scales': bbox_scales,\n                'bboxes': bboxes,\n                'bbox_scores': np.ones(\n                    (1, ), dtype=np.float32) * (1 - 2 * i / 100)\n            }\n            pred_instances1 = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data1 = {'inputs': None}\n            data_sample1 = {\n                'id': ann['id'] + 1,\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances1,\n                'pred_instances': pred_instances1\n            }\n\n            # batch size = 2\n            data_batch = [data0, data1]\n            data_samples = [data_sample0, data_sample1]\n            topdown_data.append((data_batch, data_samples))\n\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test_align3',\n            score_mode='bbox_keypoint',\n            keypoint_score_thr=0.2,\n            nms_thr=0.9,\n            nms_mode='soft_oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in topdown_data:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(topdown_data) * 2)\n\n        target = {\n            'coco/AP': 0.17073707370737073,\n            'coco/AP .5': 0.25055005500550054,\n            'coco/AP .75': 0.10671067106710669,\n            'coco/AP (M)': 0.0,\n            'coco/AP (L)': 0.29315181518151806,\n            'coco/AR': 0.2416666666666666,\n            'coco/AR .5': 0.3333333333333333,\n            'coco/AR .75': 0.16666666666666666,\n            'coco/AR (M)': 0.0,\n            'coco/AR (L)': 0.41428571428571426,\n        }\n\n        for key in eval_results.keys():\n            self.assertAlmostEqual(eval_results[key], target[key])\n\n        self.assertTrue(\n            osp.isfile(\n                osp.join(self.tmp_dir.name, 'test_align3.keypoints.json')))\n\n    def test_topdown_evaluate(self):\n        \"\"\"test topdown-style COCO metric evaluation.\"\"\"\n        # case 1: score_mode='bbox', nms_mode='none'\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test1',\n            score_mode='bbox',\n            nms_mode='none')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test1.keypoints.json')))\n\n        # case 2: score_mode='bbox_keypoint', nms_mode='oks_nms'\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test2',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test2.keypoints.json')))\n\n        # case 3: score_mode='bbox_rle', nms_mode='soft_oks_nms'\n        metric_coco = CocoMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test3',\n            score_mode='bbox_rle',\n            nms_mode='soft_oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test3.keypoints.json')))\n\n        # case 4: test without providing ann_file\n        metric_coco = CocoMetric(outfile_prefix=f'{self.tmp_dir.name}/test4')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n        self.assertDictEqual(eval_results, self.target_coco)\n        # test whether convert the annotation to COCO format\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test4.gt.json')))\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test4.keypoints.json')))\n\n        # case 5: test Crowdpose dataset\n        metric_crowdpose = CocoMetric(\n            ann_file=self.ann_file_crowdpose,\n            outfile_prefix=f'{self.tmp_dir.name}/test5',\n            use_area=False,\n            iou_type='keypoints_crowd',\n            prefix='crowdpose')\n        metric_crowdpose.dataset_meta = self.dataset_meta_crowdpose\n        # process samples\n        for data_batch, data_samples in self.topdown_data_crowdpose:\n            metric_crowdpose.process(data_batch, data_samples)\n        eval_results = metric_crowdpose.evaluate(\n            size=len(self.topdown_data_crowdpose))\n        self.assertDictEqual(eval_results, self.target_crowdpose)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test5.keypoints.json')))\n\n        # case 6: test Crowdpose dataset + without ann_file\n        metric_crowdpose = CocoMetric(\n            outfile_prefix=f'{self.tmp_dir.name}/test6',\n            use_area=False,\n            iou_type='keypoints_crowd',\n            prefix='crowdpose')\n        metric_crowdpose.dataset_meta = self.dataset_meta_crowdpose\n        # process samples\n        for data_batch, data_samples in self.topdown_data_crowdpose:\n            metric_crowdpose.process(data_batch, data_samples)\n        eval_results = metric_crowdpose.evaluate(\n            size=len(self.topdown_data_crowdpose))\n        self.assertDictEqual(eval_results, self.target_crowdpose)\n        # test whether convert the annotation to COCO format\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test6.gt.json')))\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test6.keypoints.json')))\n\n        # case 7: test AP10k dataset\n        metric_ap10k = CocoMetric(\n            ann_file=self.ann_file_ap10k,\n            outfile_prefix=f'{self.tmp_dir.name}/test7')\n        metric_ap10k.dataset_meta = self.dataset_meta_ap10k\n        # process samples\n        for data_batch, data_samples in self.topdown_data_ap10k:\n            metric_ap10k.process(data_batch, data_samples)\n        eval_results = metric_ap10k.evaluate(size=len(self.topdown_data_ap10k))\n        for key in self.target_ap10k:\n            self.assertAlmostEqual(eval_results[key], self.target_ap10k[key])\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test7.keypoints.json')))\n\n        # case 8: test Crowdpose dataset + without ann_file\n        metric_ap10k = CocoMetric(outfile_prefix=f'{self.tmp_dir.name}/test8')\n        metric_ap10k.dataset_meta = self.dataset_meta_ap10k\n        # process samples\n        for data_batch, data_samples in self.topdown_data_ap10k:\n            metric_ap10k.process(data_batch, data_samples)\n        eval_results = metric_ap10k.evaluate(size=len(self.topdown_data_ap10k))\n        for key in self.target_ap10k:\n            self.assertAlmostEqual(eval_results[key], self.target_ap10k[key])\n        # test whether convert the annotation to COCO format\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test8.gt.json')))\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test8.keypoints.json')))\n\n    def test_gt_converter(self):\n\n        crowdpose_to_coco_converter = dict(\n            type='KeypointConverter',\n            num_keypoints=17,\n            mapping=[\n                (0, 5),\n                (1, 6),\n                (2, 7),\n                (3, 8),\n                (4, 9),\n                (5, 10),\n                (6, 11),\n                (7, 12),\n                (8, 13),\n                (9, 14),\n                (10, 15),\n                (11, 16),\n            ])\n\n        metric_crowdpose = CocoMetric(\n            ann_file=self.ann_file_crowdpose,\n            outfile_prefix=f'{self.tmp_dir.name}/test_convert',\n            use_area=False,\n            gt_converter=crowdpose_to_coco_converter,\n            iou_type='keypoints_crowd',\n            prefix='crowdpose')\n        metric_crowdpose.dataset_meta = self.dataset_meta_crowdpose\n\n        self.assertEqual(metric_crowdpose.dataset_meta['num_keypoints'], 17)\n        self.assertEqual(len(metric_crowdpose.dataset_meta['sigmas']), 17)\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_pseudo_coco:\n            metric_crowdpose.process(data_batch, data_samples)\n\n        _ = metric_crowdpose.evaluate(size=len(self.topdown_data_crowdpose))\n\n        self.assertTrue(\n            osp.isfile(\n                osp.join(self.tmp_dir.name, 'test_convert.keypoints.json')))\n\n    def test_get_ann_file_from_dataset(self):\n        _ = CocoDataset(ann_file=self.ann_file_coco, test_mode=True)\n        metric = CocoMetric(ann_file=None)\n        metric.dataset_meta = self.dataset_meta_coco\n        self.assertIsNotNone(metric.coco)\n\n        # clear message to avoid disturbing other tests\n        message = MessageHub.get_current_instance()\n        message.pop_info('coco_ann_file')\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_coco_wholebody_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport os.path as osp\nimport tempfile\nfrom collections import defaultdict\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import dump, load\nfrom mmengine.logging import MessageHub\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.evaluation.metrics import CocoWholeBodyMetric\n\n\nclass TestCocoWholeBodyMetric(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n\n        # during CI on github, the unit tests for datasets will save ann_file\n        # into MessageHub, which will influence the unit tests for\n        # CocoWholeBodyMetric\n        msg = MessageHub.get_current_instance()\n        msg.runtime_info.clear()\n\n        self.tmp_dir = tempfile.TemporaryDirectory()\n\n        self.ann_file_coco = 'tests/data/coco/test_coco_wholebody.json'\n        meta_info_coco = dict(\n            from_file='configs/_base_/datasets/coco_wholebody.py')\n        self.dataset_meta_coco = parse_pose_metainfo(meta_info_coco)\n        self.coco = COCO(self.ann_file_coco)\n        self.dataset_meta_coco['CLASSES'] = self.coco.loadCats(\n            self.coco.getCatIds())\n\n        self.topdown_data_coco = self._convert_ann_to_topdown_batch_data(\n            self.ann_file_coco)\n        assert len(self.topdown_data_coco) == 14\n        self.bottomup_data_coco = self._convert_ann_to_bottomup_batch_data(\n            self.ann_file_coco)\n        assert len(self.bottomup_data_coco) == 4\n        self.target_coco = {\n            'coco-wholebody/AP': 1.0,\n            'coco-wholebody/AP .5': 1.0,\n            'coco-wholebody/AP .75': 1.0,\n            'coco-wholebody/AP (M)': 1.0,\n            'coco-wholebody/AP (L)': 1.0,\n            'coco-wholebody/AR': 1.0,\n            'coco-wholebody/AR .5': 1.0,\n            'coco-wholebody/AR .75': 1.0,\n            'coco-wholebody/AR (M)': 1.0,\n            'coco-wholebody/AR (L)': 1.0,\n        }\n\n    def _convert_ann_to_topdown_batch_data(self, ann_file):\n        \"\"\"Convert annotations to topdown-style batch data.\"\"\"\n        topdown_data = []\n        db = load(ann_file)\n        imgid2info = dict()\n        for img in db['images']:\n            imgid2info[img['id']] = img\n        for ann in db['annotations']:\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n            _keypoints = np.array(ann['keypoints'] + ann['foot_kpts'] +\n                                  ann['face_kpts'] + ann['lefthand_kpts'] +\n                                  ann['righthand_kpts']).reshape(1, -1, 3)\n\n            gt_instances = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32),\n                'bboxes': bboxes,\n            }\n            pred_instances = {\n                'keypoints': _keypoints[..., :2],\n                'keypoint_scores': _keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'category_id': ann.get('category_id', 1),\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances,\n                # dummy image_shape for testing\n                'ori_shape': [640, 480],\n                # store the raw annotation info to test without ann_file\n                'raw_ann_info': copy.deepcopy(ann),\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n\n        return topdown_data\n\n    def _convert_ann_to_bottomup_batch_data(self, ann_file):\n        \"\"\"Convert annotations to bottomup-style batch data.\"\"\"\n        img2ann = defaultdict(list)\n        db = load(ann_file)\n        for ann in db['annotations']:\n            img2ann[ann['image_id']].append(ann)\n\n        bottomup_data = []\n        for img_id, anns in img2ann.items():\n            _keypoints = []\n            for ann in anns:\n                _keypoints.append(ann['keypoints'] + ann['foot_kpts'] +\n                                  ann['face_kpts'] + ann['lefthand_kpts'] +\n                                  ann['righthand_kpts'])\n            keypoints = np.array(_keypoints).reshape((len(anns), -1, 3))\n\n            gt_instances = {\n                'bbox_scores': np.ones((len(anns)), dtype=np.float32)\n            }\n\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': [ann['id'] for ann in anns],\n                'img_id': img_id,\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            bottomup_data.append((data_batch, data_samples))\n        return bottomup_data\n\n    def tearDown(self):\n        self.tmp_dir.cleanup()\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test score_mode option\n        with self.assertRaisesRegex(ValueError,\n                                    '`score_mode` should be one of'):\n            _ = CocoWholeBodyMetric(\n                ann_file=self.ann_file_coco, score_mode='invalid')\n\n        # test nms_mode option\n        with self.assertRaisesRegex(ValueError, '`nms_mode` should be one of'):\n            _ = CocoWholeBodyMetric(\n                ann_file=self.ann_file_coco, nms_mode='invalid')\n\n        # test format_only option\n        with self.assertRaisesRegex(\n                AssertionError,\n                '`outfile_prefix` can not be None when `format_only` is True'):\n            _ = CocoWholeBodyMetric(\n                ann_file=self.ann_file_coco,\n                format_only=True,\n                outfile_prefix=None)\n\n    def test_other_methods(self):\n        \"\"\"test other useful methods.\"\"\"\n        # test `_sort_and_unique_bboxes` method\n        metric_coco = CocoWholeBodyMetric(\n            ann_file=self.ann_file_coco, score_mode='bbox', nms_mode='none')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n        # process one extra sample\n        data_batch, data_samples = self.topdown_data_coco[0]\n        metric_coco.process(data_batch, data_samples)\n        # an extra sample\n        eval_results = metric_coco.evaluate(\n            size=len(self.topdown_data_coco) + 1)\n        self.assertDictEqual(eval_results, self.target_coco)\n\n    def test_format_only(self):\n        \"\"\"test `format_only` option.\"\"\"\n        metric_coco = CocoWholeBodyMetric(\n            ann_file=self.ann_file_coco,\n            format_only=True,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n        # process one sample\n        data_batch, data_samples = self.topdown_data_coco[0]\n        metric_coco.process(data_batch, data_samples)\n        eval_results = metric_coco.evaluate(size=1)\n        self.assertDictEqual(eval_results, {})\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test.keypoints.json')))\n\n        # test when gt annotations are absent\n        db_ = load(self.ann_file_coco)\n        del db_['annotations']\n        tmp_ann_file = osp.join(self.tmp_dir.name, 'temp_ann.json')\n        dump(db_, tmp_ann_file, sort_keys=True, indent=4)\n        with self.assertRaisesRegex(\n                AssertionError,\n                'Ground truth annotations are required for evaluation'):\n            _ = CocoWholeBodyMetric(ann_file=tmp_ann_file, format_only=False)\n\n    def test_bottomup_evaluate(self):\n        \"\"\"test bottomup-style COCO metric evaluation.\"\"\"\n        # case1: score_mode='bbox', nms_mode='none'\n        metric_coco = CocoWholeBodyMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox',\n            nms_mode='none')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.bottomup_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.bottomup_data_coco))\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test.keypoints.json')))\n\n    def test_topdown_evaluate(self):\n        \"\"\"test topdown-style COCO metric evaluation.\"\"\"\n        # case 1: score_mode='bbox', nms_mode='none'\n        metric_coco = CocoWholeBodyMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test1',\n            score_mode='bbox',\n            nms_mode='none')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test1.keypoints.json')))\n\n        # case 2: score_mode='bbox_keypoint', nms_mode='oks_nms'\n        metric_coco = CocoWholeBodyMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test2',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test2.keypoints.json')))\n\n        # case 3: score_mode='bbox_rle', nms_mode='soft_oks_nms'\n        metric_coco = CocoWholeBodyMetric(\n            ann_file=self.ann_file_coco,\n            outfile_prefix=f'{self.tmp_dir.name}/test3',\n            score_mode='bbox_rle',\n            nms_mode='soft_oks_nms')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n\n        self.assertDictEqual(eval_results, self.target_coco)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test3.keypoints.json')))\n\n        # case 4: test without providing ann_file\n        metric_coco = CocoWholeBodyMetric(\n            outfile_prefix=f'{self.tmp_dir.name}/test4')\n        metric_coco.dataset_meta = self.dataset_meta_coco\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric_coco.process(data_batch, data_samples)\n        eval_results = metric_coco.evaluate(size=len(self.topdown_data_coco))\n        self.assertDictEqual(eval_results, self.target_coco)\n        # test whether convert the annotation to COCO format\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test4.gt.json')))\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, 'test4.keypoints.json')))\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_hand_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport tempfile\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import load\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.codecs.utils import camera_to_pixel\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.evaluation import InterHandMetric\n\n\nclass TestInterHandMetric(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.tmp_dir = tempfile.TemporaryDirectory()\n\n        self.ann_file = 'tests/data/interhand2.6m/test_interhand2.6m_data.json'\n        meta_info = dict(from_file='configs/_base_/datasets/interhand3d.py')\n        self.dataset_meta = parse_pose_metainfo(meta_info)\n        self.coco = COCO(self.ann_file)\n\n        self.joint_file = ('tests/data/interhand2.6m/'\n                           'test_interhand2.6m_joint_3d.json')\n        with open(self.joint_file, 'r') as f:\n            self.joints = json.load(f)\n\n        self.camera_file = ('tests/data/interhand2.6m/'\n                            'test_interhand2.6m_camera.json')\n        with open(self.camera_file, 'r') as f:\n            self.cameras = json.load(f)\n\n        self.topdown_data = self._convert_ann_to_topdown_batch_data(\n            self.ann_file)\n        assert len(self.topdown_data) == 4\n        self.target = {\n            'MPJPE_all': 0.0,\n            'MPJPE_interacting': 0.0,\n            'MPJPE_single': 0.0,\n            'MRRPE': 0.0,\n            'HandednessAcc': 1.0\n        }\n\n    def encode_handtype(self, hand_type):\n        if hand_type == 'right':\n            return np.array([[1, 0]], dtype=np.float32)\n        elif hand_type == 'left':\n            return np.array([[0, 1]], dtype=np.float32)\n        elif hand_type == 'interacting':\n            return np.array([[1, 1]], dtype=np.float32)\n        else:\n            assert 0, f'Not support hand type: {hand_type}'\n\n    def _convert_ann_to_topdown_batch_data(self, ann_file):\n        \"\"\"Convert annotations to topdown-style batch data.\"\"\"\n        topdown_data = []\n        db = load(ann_file)\n        num_keypoints = 42\n        imgid2info = dict()\n        for img in db['images']:\n            imgid2info[img['id']] = img\n        for ann in db['annotations']:\n            image_id = ann['image_id']\n            img = imgid2info[image_id]\n            frame_idx = str(img['frame_idx'])\n            capture_id = str(img['capture'])\n            camera_name = img['camera']\n\n            camera_pos = np.array(\n                self.cameras[capture_id]['campos'][camera_name],\n                dtype=np.float32)\n            camera_rot = np.array(\n                self.cameras[capture_id]['camrot'][camera_name],\n                dtype=np.float32)\n            focal = np.array(\n                self.cameras[capture_id]['focal'][camera_name],\n                dtype=np.float32)\n            principal_pt = np.array(\n                self.cameras[capture_id]['princpt'][camera_name],\n                dtype=np.float32)\n            joint_world = np.array(\n                self.joints[capture_id][frame_idx]['world_coord'],\n                dtype=np.float32)\n            joint_valid = np.array(\n                ann['joint_valid'], dtype=np.float32).flatten()\n\n            keypoints_cam = np.dot(\n                camera_rot,\n                joint_world.transpose(1, 0) -\n                camera_pos.reshape(3, 1)).transpose(1, 0)\n            joint_img = camera_to_pixel(\n                keypoints_cam,\n                focal[0],\n                focal[1],\n                principal_pt[0],\n                principal_pt[1],\n                shift=True)[:, :2]\n\n            abs_depth = [keypoints_cam[20, 2], keypoints_cam[41, 2]]\n\n            rel_root_depth = keypoints_cam[41, 2] - keypoints_cam[20, 2]\n\n            joint_valid[:20] *= joint_valid[20]\n            joint_valid[21:] *= joint_valid[41]\n\n            joints_3d = np.zeros((num_keypoints, 3),\n                                 dtype=np.float32).reshape(1, -1, 3)\n            joints_3d[..., :2] = joint_img\n            joints_3d[..., :21,\n                      2] = keypoints_cam[:21, 2] - keypoints_cam[20, 2]\n            joints_3d[..., 21:,\n                      2] = keypoints_cam[21:, 2] - keypoints_cam[41, 2]\n            joints_3d_visible = np.minimum(1, joint_valid.reshape(-1, 1))\n            joints_3d_visible = joints_3d_visible.reshape(1, -1)\n\n            gt_instances = {\n                'keypoints_cam': keypoints_cam.reshape(1, -1, 3),\n                'keypoints_visible': joints_3d_visible,\n            }\n            pred_instances = {\n                'keypoints': joints_3d,\n                'hand_type': self.encode_handtype(ann['hand_type']),\n                'rel_root_depth': rel_root_depth,\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances,\n                'hand_type': self.encode_handtype(ann['hand_type']),\n                'hand_type_valid': np.array([ann['hand_type_valid']]),\n                'abs_depth': abs_depth,\n                'focal': focal,\n                'principal_pt': principal_pt,\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n\n        return topdown_data\n\n    def tearDown(self):\n        self.tmp_dir.cleanup()\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test modes option\n        with self.assertRaisesRegex(ValueError, '`mode` should be'):\n            _ = InterHandMetric(modes=['invalid'])\n\n    def test_topdown_evaluate(self):\n        \"\"\"test topdown-style COCO metric evaluation.\"\"\"\n        # case 1: modes='MPJPE'\n        metric = InterHandMetric(modes=['MPJPE'])\n        metric.dataset_meta = self.dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            metric.process(data_batch, data_samples)\n\n        eval_results = metric.evaluate(size=len(self.topdown_data))\n\n        for metric, err in eval_results.items():\n            self.assertAlmostEqual(err, self.target[metric], places=4)\n\n        # case 2: modes='MRRPE'\n        metric = InterHandMetric(modes=['MRRPE'])\n        metric.dataset_meta = self.dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            metric.process(data_batch, data_samples)\n\n        eval_results = metric.evaluate(size=len(self.topdown_data))\n\n        for metric, err in eval_results.items():\n            self.assertAlmostEqual(err, self.target[metric], places=4)\n\n        # case 2: modes='HandednessAcc'\n        metric = InterHandMetric(modes=['HandednessAcc'])\n        metric.dataset_meta = self.dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            metric.process(data_batch, data_samples)\n\n        eval_results = metric.evaluate(size=len(self.topdown_data))\n\n        for metric, err in eval_results.items():\n            self.assertAlmostEqual(err, self.target[metric], places=4)\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_keypoint_2d_metrics.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.evaluation.metrics import (AUC, EPE, NME, JhmdbPCKAccuracy,\n                                       MpiiPCKAccuracy, PCKAccuracy)\n\n\nclass TestPCKAccuracy(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.batch_size = 8\n        num_keypoints = 15\n        self.data_batch = []\n        self.data_samples = []\n\n        for i in range(self.batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.zeros((1, num_keypoints, 2))\n            keypoints[0, i] = [0.5 * i, 0.5 * i]\n            gt_instances.keypoints = keypoints\n            gt_instances.keypoints_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n            gt_instances.keypoints_visible[0, (2 * i) % 8, 0] = False\n            gt_instances.bboxes = np.random.random((1, 4)) * 20 * i\n            gt_instances.head_size = np.random.random((1, 1)) * 10 * i\n\n            pred_instances = InstanceData()\n            pred_instances.keypoints = keypoints\n\n            data = {'inputs': None}\n            data_sample = {\n                'gt_instances': gt_instances.to_dict(),\n                'pred_instances': pred_instances.to_dict(),\n            }\n\n            self.data_batch.append(data)\n            self.data_samples.append(data_sample)\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test invalid normalized_items\n        with self.assertRaisesRegex(\n                KeyError, \"Should be one of 'bbox', 'head', 'torso'\"):\n            PCKAccuracy(norm_item='invalid')\n\n    def test_evaluate(self):\n        \"\"\"test PCK accuracy evaluation metric.\"\"\"\n        # test normalized by 'bbox'\n        pck_metric = PCKAccuracy(thr=0.5, norm_item='bbox')\n        pck_metric.process(self.data_batch, self.data_samples)\n        pck = pck_metric.evaluate(self.batch_size)\n        target = {'PCK': 1.0}\n        self.assertDictEqual(pck, target)\n\n        # test normalized by 'head_size'\n        pckh_metric = PCKAccuracy(thr=0.3, norm_item='head')\n        pckh_metric.process(self.data_batch, self.data_samples)\n        pckh = pckh_metric.evaluate(self.batch_size)\n        target = {'PCKh': 1.0}\n        self.assertDictEqual(pckh, target)\n\n        # test normalized by 'torso_size'\n        tpck_metric = PCKAccuracy(thr=0.05, norm_item=['bbox', 'torso'])\n        tpck_metric.process(self.data_batch, self.data_samples)\n        tpck = tpck_metric.evaluate(self.batch_size)\n        self.assertIsInstance(tpck, dict)\n        target = {\n            'PCK': 1.0,\n            'tPCK': 1.0,\n        }\n        self.assertDictEqual(tpck, target)\n\n\nclass TestMpiiPCKAccuracy(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.batch_size = 8\n        num_keypoints = 16\n        self.data_batch = []\n        self.data_samples = []\n\n        for i in range(self.batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.zeros((1, num_keypoints, 2))\n            keypoints[0, i] = [0.5 * i, 0.5 * i]\n            gt_instances.keypoints = keypoints + 1.0\n            gt_instances.keypoints_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n            gt_instances.keypoints_visible[0, (2 * i) % 8, 0] = False\n            gt_instances.bboxes = np.random.random((1, 4)) * 20 * i\n            gt_instances.head_size = np.random.random((1, 1)) * 10 * i\n\n            pred_instances = InstanceData()\n            pred_instances.keypoints = keypoints\n\n            data = {'inputs': None}\n            data_sample = {\n                'gt_instances': gt_instances.to_dict(),\n                'pred_instances': pred_instances.to_dict(),\n            }\n\n            self.data_batch.append(data)\n            self.data_samples.append(data_sample)\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test invalid normalized_items\n        with self.assertRaisesRegex(\n                KeyError, \"Should be one of 'bbox', 'head', 'torso'\"):\n            MpiiPCKAccuracy(norm_item='invalid')\n\n    def test_evaluate(self):\n        \"\"\"test PCK accuracy evaluation metric.\"\"\"\n        # test normalized by 'head_size'\n        mpii_pck_metric = MpiiPCKAccuracy(thr=0.3, norm_item='head')\n        mpii_pck_metric.process(self.data_batch, self.data_samples)\n        pck_results = mpii_pck_metric.evaluate(self.batch_size)\n        target = {\n            'Head PCK': 100.0,\n            'Shoulder PCK': 100.0,\n            'Elbow PCK': 100.0,\n            'Wrist PCK': 100.0,\n            'Hip PCK': 100.0,\n            'Knee PCK': 100.0,\n            'Ankle PCK': 100.0,\n            'PCK': 100.0,\n            'PCK@0.1': 100.0,\n        }\n        self.assertDictEqual(pck_results, target)\n\n\nclass TestJhmdbPCKAccuracy(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.batch_size = 8\n        num_keypoints = 15\n        self.data_batch = []\n        self.data_samples = []\n\n        for i in range(self.batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.zeros((1, num_keypoints, 2))\n            keypoints[0, i] = [0.5 * i, 0.5 * i]\n            gt_instances.keypoints = keypoints\n            gt_instances.keypoints_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n            gt_instances.keypoints_visible[0, (2 * i) % 8, 0] = False\n            gt_instances.bboxes = np.random.random((1, 4)) * 20 * i\n            gt_instances.head_size = np.random.random((1, 1)) * 10 * i\n\n            pred_instances = InstanceData()\n            pred_instances.keypoints = keypoints\n\n            data = {'inputs': None}\n            data_sample = {\n                'gt_instances': gt_instances.to_dict(),\n                'pred_instances': pred_instances.to_dict(),\n            }\n\n            self.data_batch.append(data)\n            self.data_samples.append(data_sample)\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test invalid normalized_items\n        with self.assertRaisesRegex(\n                KeyError, \"Should be one of 'bbox', 'head', 'torso'\"):\n            JhmdbPCKAccuracy(norm_item='invalid')\n\n    def test_evaluate(self):\n        \"\"\"test PCK accuracy evaluation metric.\"\"\"\n        # test normalized by 'bbox_size'\n        jhmdb_pck_metric = JhmdbPCKAccuracy(thr=0.5, norm_item='bbox')\n        jhmdb_pck_metric.process(self.data_batch, self.data_samples)\n        pck_results = jhmdb_pck_metric.evaluate(self.batch_size)\n        target = {\n            'Head PCK': 1.0,\n            'Sho PCK': 1.0,\n            'Elb PCK': 1.0,\n            'Wri PCK': 1.0,\n            'Hip PCK': 1.0,\n            'Knee PCK': 1.0,\n            'Ank PCK': 1.0,\n            'PCK': 1.0,\n        }\n        self.assertDictEqual(pck_results, target)\n\n        # test normalized by 'torso_size'\n        jhmdb_tpck_metric = JhmdbPCKAccuracy(thr=0.2, norm_item='torso')\n        jhmdb_tpck_metric.process(self.data_batch, self.data_samples)\n        tpck_results = jhmdb_tpck_metric.evaluate(self.batch_size)\n        target = {\n            'Head tPCK': 1.0,\n            'Sho tPCK': 1.0,\n            'Elb tPCK': 1.0,\n            'Wri tPCK': 1.0,\n            'Hip tPCK': 1.0,\n            'Knee tPCK': 1.0,\n            'Ank tPCK': 1.0,\n            'tPCK': 1.0,\n        }\n        self.assertDictEqual(tpck_results, target)\n\n\nclass TestAUCandEPE(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        output = np.zeros((1, 5, 2))\n        target = np.zeros((1, 5, 2))\n        # first channel\n        output[0, 0] = [10, 4]\n        target[0, 0] = [10, 0]\n        # second channel\n        output[0, 1] = [10, 18]\n        target[0, 1] = [10, 10]\n        # third channel\n        output[0, 2] = [0, 0]\n        target[0, 2] = [0, -1]\n        # fourth channel\n        output[0, 3] = [40, 40]\n        target[0, 3] = [30, 30]\n        # fifth channel\n        output[0, 4] = [20, 10]\n        target[0, 4] = [0, 10]\n\n        gt_instances = InstanceData()\n        gt_instances.keypoints = target\n        gt_instances.keypoints_visible = np.array(\n            [[True, True, False, True, True]])\n\n        pred_instances = InstanceData()\n        pred_instances.keypoints = output\n\n        data = {'inputs': None}\n        data_sample = {\n            'gt_instances': gt_instances.to_dict(),\n            'pred_instances': pred_instances.to_dict()\n        }\n\n        self.data_batch = [data]\n        self.data_samples = [data_sample]\n\n    def test_auc_evaluate(self):\n        \"\"\"test AUC evaluation metric.\"\"\"\n        auc_metric = AUC(norm_factor=20, num_thrs=4)\n        auc_metric.process(self.data_batch, self.data_samples)\n        auc = auc_metric.evaluate(1)\n        target = {'AUC': 0.375}\n        self.assertDictEqual(auc, target)\n\n    def test_epe_evaluate(self):\n        \"\"\"test EPE evaluation metric.\"\"\"\n        epe_metric = EPE()\n        epe_metric.process(self.data_batch, self.data_samples)\n        epe = epe_metric.evaluate(1)\n        self.assertAlmostEqual(epe['EPE'], 11.5355339)\n\n\nclass TestNME(TestCase):\n\n    def _generate_data(self,\n                       batch_size: int = 1,\n                       num_keypoints: int = 5,\n                       norm_item: str = 'box_size') -> tuple:\n        \"\"\"Generate data_batch and data_samples according to different\n        settings.\"\"\"\n        data_batch = []\n        data_samples = []\n\n        for i in range(batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.zeros((1, num_keypoints, 2))\n            keypoints[0, i] = [0.5 * i, 0.5 * i]\n            gt_instances.keypoints = keypoints\n            gt_instances.keypoints_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n            gt_instances.keypoints_visible[0, (2 * i) % batch_size, 0] = False\n            gt_instances[norm_item] = np.random.random((1, 1)) * 20 * i\n\n            pred_instances = InstanceData()\n            pred_instances.keypoints = keypoints\n\n            data = {'inputs': None}\n            data_sample = {\n                'gt_instances': gt_instances.to_dict(),\n                'pred_instances': pred_instances.to_dict(),\n            }\n            data_batch.append(data)\n            data_samples.append(data_sample)\n\n        return data_batch, data_samples\n\n    def test_nme_evaluate(self):\n        \"\"\"test NME evaluation metric.\"\"\"\n        # test when norm_mode = 'use_norm_item'\n        # test norm_item = 'box_size' like in `AFLWDataset`\n        norm_item = 'box_size'\n        nme_metric = NME(norm_mode='use_norm_item', norm_item=norm_item)\n        aflw_meta_info = dict(from_file='configs/_base_/datasets/aflw.py')\n        aflw_dataset_meta = parse_pose_metainfo(aflw_meta_info)\n        nme_metric.dataset_meta = aflw_dataset_meta\n\n        data_batch, data_samples = self._generate_data(\n            batch_size=4, num_keypoints=19, norm_item=norm_item)\n        nme_metric.process(data_batch, data_samples)\n        nme = nme_metric.evaluate(4)\n        target = {'NME': 0.0}\n        self.assertDictEqual(nme, target)\n\n        # test when norm_mode = 'keypoint_distance'\n        # when `keypoint_indices = None`,\n        # use default `keypoint_indices` like in `Horse10Dataset`\n        nme_metric = NME(norm_mode='keypoint_distance')\n        horse10_meta_info = dict(\n            from_file='configs/_base_/datasets/horse10.py')\n        horse10_dataset_meta = parse_pose_metainfo(horse10_meta_info)\n        nme_metric.dataset_meta = horse10_dataset_meta\n\n        data_batch, data_samples = self._generate_data(\n            batch_size=4, num_keypoints=22)\n        nme_metric.process(data_batch, data_samples)\n        nme = nme_metric.evaluate(4)\n\n        target = {'NME': 0.0}\n        self.assertDictEqual(nme, target)\n\n        # test when norm_mode = 'keypoint_distance'\n        # specify custom `keypoint_indices`\n        keypoint_indices = [2, 4]\n        nme_metric = NME(\n            norm_mode='keypoint_distance', keypoint_indices=keypoint_indices)\n        coco_meta_info = dict(from_file='configs/_base_/datasets/coco.py')\n        coco_dataset_meta = parse_pose_metainfo(coco_meta_info)\n        nme_metric.dataset_meta = coco_dataset_meta\n\n        data_batch, data_samples = self._generate_data(\n            batch_size=2, num_keypoints=17)\n        nme_metric.process(data_batch, data_samples)\n        nme = nme_metric.evaluate(2)\n\n        target = {'NME': 0.0}\n        self.assertDictEqual(nme, target)\n\n    def test_exceptions_and_warnings(self):\n        \"\"\"test exceptions and warnings.\"\"\"\n        # test invalid norm_mode\n        with self.assertRaisesRegex(\n                KeyError,\n                \"`norm_mode` should be 'use_norm_item' or 'keypoint_distance'\"\n        ):\n            nme_metric = NME(norm_mode='invalid')\n\n        # test when norm_mode = 'use_norm_item' but do not specify norm_item\n        with self.assertRaisesRegex(\n                KeyError, '`norm_mode` is set to `\"use_norm_item\"`, '\n                'please specify the `norm_item`'):\n            nme_metric = NME(norm_mode='use_norm_item', norm_item=None)\n\n        # test when norm_mode = 'use_norm_item'\n        # but the `norm_item` do not in data_info\n        with self.assertRaisesRegex(\n                AssertionError,\n                'The ground truth data info do not have the expected '\n                'normalized factor'):\n            nme_metric = NME(norm_mode='use_norm_item', norm_item='norm_item1')\n            coco_meta_info = dict(from_file='configs/_base_/datasets/coco.py')\n            coco_dataset_meta = parse_pose_metainfo(coco_meta_info)\n            nme_metric.dataset_meta = coco_dataset_meta\n\n            data_batch, data_samples = self._generate_data(\n                norm_item='norm_item2')\n            # raise AssertionError here\n            nme_metric.process(data_batch, data_samples)\n\n        # test when norm_mode = 'keypoint_distance', `keypoint_indices` = None\n        # but the dataset_name not in `DEFAULT_KEYPOINT_INDICES`\n        with self.assertRaisesRegex(\n                KeyError, 'can not find the keypoint_indices in '\n                '`DEFAULT_KEYPOINT_INDICES`'):\n            nme_metric = NME(\n                norm_mode='keypoint_distance', keypoint_indices=None)\n            coco_meta_info = dict(from_file='configs/_base_/datasets/coco.py')\n            coco_dataset_meta = parse_pose_metainfo(coco_meta_info)\n            nme_metric.dataset_meta = coco_dataset_meta\n\n            data_batch, data_samples = self._generate_data()\n            nme_metric.process(data_batch, data_samples)\n            # raise KeyError here\n            _ = nme_metric.evaluate(1)\n\n        # test when len(keypoint_indices) is not 2\n        with self.assertRaisesRegex(\n                AssertionError,\n                'The keypoint indices used for normalization should be a pair.'\n        ):\n            nme_metric = NME(\n                norm_mode='keypoint_distance', keypoint_indices=[0, 1, 2])\n            coco_meta_info = dict(from_file='configs/_base_/datasets/coco.py')\n            coco_dataset_meta = parse_pose_metainfo(coco_meta_info)\n            nme_metric.dataset_meta = coco_dataset_meta\n\n            data_batch, data_samples = self._generate_data()\n            nme_metric.process(data_batch, data_samples)\n            # raise AssertionError here\n            _ = nme_metric.evaluate(1)\n\n        # test when dataset does not contain the required keypoint\n        with self.assertRaisesRegex(AssertionError,\n                                    'dataset does not contain the required'):\n            nme_metric = NME(\n                norm_mode='keypoint_distance', keypoint_indices=[17, 18])\n            coco_meta_info = dict(from_file='configs/_base_/datasets/coco.py')\n            coco_dataset_meta = parse_pose_metainfo(coco_meta_info)\n            nme_metric.dataset_meta = coco_dataset_meta\n\n            data_batch, predidata_samplesctions = self._generate_data()\n            nme_metric.process(data_batch, data_samples)\n            # raise AssertionError here\n            _ = nme_metric.evaluate(1)\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_keypoint_3d_metrics.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.evaluation import MPJPE\nfrom mmpose.structures import PoseDataSample\n\n\nclass TestMPJPE(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup variables used in every test method.\"\"\"\n        self.batch_size = 8\n        num_keypoints = 15\n        self.data_batch = []\n        self.data_samples = []\n\n        for i in range(self.batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.random.random((1, num_keypoints, 3))\n            gt_instances.lifting_target = np.random.random(\n                (1, num_keypoints, 3))\n            gt_instances.lifting_target_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n\n            pred_instances = InstanceData()\n            pred_instances.keypoints = keypoints + np.random.normal(\n                0, 0.01, keypoints.shape)\n\n            data = {'inputs': None}\n            data_sample = PoseDataSample(\n                gt_instances=gt_instances, pred_instances=pred_instances)\n            data_sample.set_metainfo(\n                dict(target_img_path=[\n                    'tests/data/h36m/S7/'\n                    'S7_Greeting.55011271/S7_Greeting.55011271_000396.jpg'\n                ]))\n\n            self.data_batch.append(data)\n            self.data_samples.append(data_sample.to_dict())\n\n    def test_init(self):\n        \"\"\"Test metric init method.\"\"\"\n        # Test invalid mode\n        with self.assertRaisesRegex(\n                KeyError, \"`mode` should be 'mpjpe', 'p-mpjpe', or 'n-mpjpe', \"\n                \"but got 'invalid'.\"):\n            MPJPE(mode='invalid')\n\n    def test_evaluate(self):\n        \"\"\"Test MPJPE evaluation metric.\"\"\"\n        mpjpe_metric = MPJPE(mode='mpjpe')\n        mpjpe_metric.process(self.data_batch, self.data_samples)\n        mpjpe = mpjpe_metric.evaluate(self.batch_size)\n        self.assertIsInstance(mpjpe, dict)\n        self.assertIn('MPJPE', mpjpe)\n        self.assertTrue(mpjpe['MPJPE'] >= 0)\n\n        p_mpjpe_metric = MPJPE(mode='p-mpjpe')\n        p_mpjpe_metric.process(self.data_batch, self.data_samples)\n        p_mpjpe = p_mpjpe_metric.evaluate(self.batch_size)\n        self.assertIsInstance(p_mpjpe, dict)\n        self.assertIn('P-MPJPE', p_mpjpe)\n        self.assertTrue(p_mpjpe['P-MPJPE'] >= 0)\n\n        n_mpjpe_metric = MPJPE(mode='n-mpjpe')\n        n_mpjpe_metric.process(self.data_batch, self.data_samples)\n        n_mpjpe = n_mpjpe_metric.evaluate(self.batch_size)\n        self.assertIsInstance(n_mpjpe, dict)\n        self.assertIn('N-MPJPE', n_mpjpe)\n        self.assertTrue(n_mpjpe['N-MPJPE'] >= 0)\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_keypoint_partition_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport copy\nimport os.path as osp\nimport tempfile\nfrom collections import defaultdict\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import load\nfrom mmengine.logging import MessageHub\nfrom mmengine.structures import InstanceData\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.evaluation.metrics import KeypointPartitionMetric\n\n\nclass TestKeypointPartitionMetricWrappingCocoMetric(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n\n        # during CI on github, the unit tests for datasets will save ann_file\n        # into MessageHub, which will influence the unit tests for CocoMetric\n        msg = MessageHub.get_current_instance()\n        msg.runtime_info.clear()\n\n        self.tmp_dir = tempfile.TemporaryDirectory()\n\n        self.ann_file_coco = \\\n            'tests/data/coco/test_keypoint_partition_metric.json'\n        meta_info_coco = dict(\n            from_file='configs/_base_/datasets/coco_wholebody.py')\n        self.dataset_meta_coco = parse_pose_metainfo(meta_info_coco)\n        self.coco = COCO(self.ann_file_coco)\n        self.dataset_meta_coco['CLASSES'] = self.coco.loadCats(\n            self.coco.getCatIds())\n\n        self.topdown_data_coco = self._convert_ann_to_topdown_batch_data(\n            self.ann_file_coco)\n        assert len(self.topdown_data_coco) == 14\n        self.bottomup_data_coco = self._convert_ann_to_bottomup_batch_data(\n            self.ann_file_coco)\n        assert len(self.bottomup_data_coco) == 4\n        \"\"\"\n        The target results were obtained from CocoWholebodyMetric with\n        score_mode='bbox' and nms_mode='none'. We cannot compare other\n        combinations of score_mode and nms_mode because CocoWholebodyMetric\n        calculates scores and nms using all keypoints while\n        KeypointPartitionMetric calculates scores and nms part by part.\n        As long as this case is tested correct, the other cases should be\n        correct.\n        \"\"\"\n        self.target_bbox_none = {\n            'body/coco/AP': 0.749,\n            'body/coco/AR': 0.800,\n            'foot/coco/AP': 0.840,\n            'foot/coco/AR': 0.850,\n            'face/coco/AP': 0.051,\n            'face/coco/AR': 0.050,\n            'left_hand/coco/AP': 0.283,\n            'left_hand/coco/AR': 0.300,\n            'right_hand/coco/AP': 0.383,\n            'right_hand/coco/AR': 0.380,\n            'all/coco/AP': 0.284,\n            'all/coco/AR': 0.450,\n        }\n\n    def _convert_ann_to_topdown_batch_data(self, ann_file):\n        \"\"\"Convert annotations to topdown-style batch data.\"\"\"\n        topdown_data = []\n        db = load(ann_file)\n        imgid2info = dict()\n        for img in db['images']:\n            imgid2info[img['id']] = img\n        for ann in db['annotations']:\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n            _keypoints = np.array(ann['keypoints']).reshape((1, -1, 3))\n\n            gt_instances = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32),\n                'bboxes': bboxes,\n                'keypoints': _keypoints[..., :2],\n                'keypoints_visible': _keypoints[..., 2:3]\n            }\n\n            # fake predictions\n            keypoints = np.zeros_like(_keypoints)\n            keypoints[..., 0] = _keypoints[..., 0] * 0.99\n            keypoints[..., 1] = _keypoints[..., 1] * 1.02\n            keypoints[..., 2] = _keypoints[..., 2] * 0.8\n\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'category_id': ann.get('category_id', 1),\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances,\n                # dummy image_shape for testing\n                'ori_shape': [640, 480],\n                # store the raw annotation info to test without ann_file\n                'raw_ann_info': copy.deepcopy(ann),\n            }\n\n            # add crowd_index to data_sample if it is present in the image_info\n            if 'crowdIndex' in imgid2info[ann['image_id']]:\n                data_sample['crowd_index'] = imgid2info[\n                    ann['image_id']]['crowdIndex']\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n\n        return topdown_data\n\n    def _convert_ann_to_bottomup_batch_data(self, ann_file):\n        \"\"\"Convert annotations to bottomup-style batch data.\"\"\"\n        img2ann = defaultdict(list)\n        db = load(ann_file)\n        for ann in db['annotations']:\n            img2ann[ann['image_id']].append(ann)\n\n        bottomup_data = []\n        for img_id, anns in img2ann.items():\n            _keypoints = np.array([ann['keypoints'] for ann in anns]).reshape(\n                (len(anns), -1, 3))\n\n            gt_instances = {\n                'bbox_scores': np.ones((len(anns)), dtype=np.float32),\n                'keypoints': _keypoints[..., :2],\n                'keypoints_visible': _keypoints[..., 2:3]\n            }\n\n            # fake predictions\n            keypoints = np.zeros_like(_keypoints)\n            keypoints[..., 0] = _keypoints[..., 0] * 0.99\n            keypoints[..., 1] = _keypoints[..., 1] * 1.02\n            keypoints[..., 2] = _keypoints[..., 2] * 0.8\n\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': [ann['id'] for ann in anns],\n                'img_id': img_id,\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances,\n                # dummy image_shape for testing\n                'ori_shape': [640, 480],\n                'raw_ann_info': copy.deepcopy(anns),\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            bottomup_data.append((data_batch, data_samples))\n        return bottomup_data\n\n    def _assert_outfiles(self, prefix):\n        for part in ['body', 'foot', 'face', 'left_hand', 'right_hand', 'all']:\n            self.assertTrue(\n                osp.isfile(\n                    osp.join(self.tmp_dir.name,\n                             f'{prefix}.{part}.keypoints.json')))\n\n    def tearDown(self):\n        self.tmp_dir.cleanup()\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test wrong metric type\n        with self.assertRaisesRegex(\n                ValueError, 'Metrics supported by KeypointPartitionMetric'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='Metric'), partitions=dict(all=range(133)))\n\n        # test ann_file arg warning\n        with self.assertWarnsRegex(UserWarning,\n                                   'does not support the ann_file argument'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='CocoMetric', ann_file=''),\n                partitions=dict(all=range(133)))\n\n        # test score_mode arg warning\n        with self.assertWarnsRegex(UserWarning, \"if score_mode is not 'bbox'\"):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='CocoMetric'),\n                partitions=dict(all=range(133)))\n\n        # test nms arg warning\n        with self.assertWarnsRegex(UserWarning, 'oks_nms and soft_oks_nms'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='CocoMetric'),\n                partitions=dict(all=range(133)))\n\n        # test partitions\n        with self.assertRaisesRegex(AssertionError, 'at least one partition'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='CocoMetric'), partitions=dict())\n\n        with self.assertRaisesRegex(AssertionError, 'should be a sequence'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='CocoMetric'), partitions=dict(all={}))\n\n        with self.assertRaisesRegex(AssertionError, 'at least one element'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='CocoMetric'), partitions=dict(all=[]))\n\n    def test_bottomup_evaluate(self):\n        \"\"\"test bottomup-style COCO metric evaluation.\"\"\"\n        # case1: score_mode='bbox', nms_mode='none'\n        metric = KeypointPartitionMetric(\n            metric=dict(\n                type='CocoMetric',\n                outfile_prefix=f'{self.tmp_dir.name}/test_bottomup',\n                score_mode='bbox',\n                nms_mode='none'),\n            partitions=dict(\n                body=range(17),\n                foot=range(17, 23),\n                face=range(23, 91),\n                left_hand=range(91, 112),\n                right_hand=range(112, 133),\n                all=range(133)))\n        metric.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.bottomup_data_coco:\n            metric.process(data_batch, data_samples)\n\n        eval_results = metric.evaluate(size=len(self.bottomup_data_coco))\n        for key in self.target_bbox_none.keys():\n            self.assertAlmostEqual(\n                eval_results[key], self.target_bbox_none[key], places=3)\n        self._assert_outfiles('test_bottomup')\n\n    def test_topdown_evaluate(self):\n        \"\"\"test topdown-style COCO metric evaluation.\"\"\"\n        # case 1: score_mode='bbox', nms_mode='none'\n        metric = KeypointPartitionMetric(\n            metric=dict(\n                type='CocoMetric',\n                outfile_prefix=f'{self.tmp_dir.name}/test_topdown1',\n                score_mode='bbox',\n                nms_mode='none'),\n            partitions=dict(\n                body=range(17),\n                foot=range(17, 23),\n                face=range(23, 91),\n                left_hand=range(91, 112),\n                right_hand=range(112, 133),\n                all=range(133)))\n        metric.dataset_meta = self.dataset_meta_coco\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data_coco:\n            metric.process(data_batch, data_samples)\n\n        eval_results = metric.evaluate(size=len(self.topdown_data_coco))\n        for key in self.target_bbox_none.keys():\n            self.assertAlmostEqual(\n                eval_results[key], self.target_bbox_none[key], places=3)\n        self._assert_outfiles('test_topdown1')\n\n\nclass TestKeypointPartitionMetricWrappingPCKAccuracy(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.batch_size = 8\n        num_keypoints = 24\n        self.data_batch = []\n        self.data_samples = []\n\n        for i in range(self.batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.zeros((1, num_keypoints, 2))\n            for j in range(num_keypoints):\n                keypoints[0, j] = [0.5 * i * j, 0.5 * i * j]\n            gt_instances.keypoints = keypoints\n            gt_instances.keypoints_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n            gt_instances.keypoints_visible[0, (2 * i) % 8, 0] = False\n            gt_instances.bboxes = np.array([[0.1, 0.2, 0.3, 0.4]]) * 20 * i\n            gt_instances.head_size = np.array([[0.1]]) * 10 * i\n\n            pred_instances = InstanceData()\n            # fake predictions\n            _keypoints = np.zeros_like(keypoints)\n            _keypoints[0, :, 0] = keypoints[0, :, 0] * 0.95\n            _keypoints[0, :, 1] = keypoints[0, :, 1] * 1.05\n            pred_instances.keypoints = _keypoints\n\n            data = {'inputs': None}\n            data_sample = {\n                'gt_instances': gt_instances.to_dict(),\n                'pred_instances': pred_instances.to_dict(),\n            }\n\n            self.data_batch.append(data)\n            self.data_samples.append(data_sample)\n\n    def test_init(self):\n        # test norm_item arg warning\n        with self.assertWarnsRegex(UserWarning,\n                                   'norm_item torso is used in JhmdbDataset'):\n            _ = KeypointPartitionMetric(\n                metric=dict(\n                    type='PCKAccuracy', thr=0.05, norm_item=['bbox', 'torso']),\n                partitions=dict(all=range(133)))\n\n    def test_evaluate(self):\n        \"\"\"test PCK accuracy evaluation metric.\"\"\"\n        # test normalized by 'bbox'\n        pck_metric = KeypointPartitionMetric(\n            metric=dict(type='PCKAccuracy', thr=0.5, norm_item='bbox'),\n            partitions=dict(\n                p1=range(10),\n                p2=range(10, 24),\n                all=range(24),\n            ))\n        pck_metric.process(self.data_batch, self.data_samples)\n        pck = pck_metric.evaluate(self.batch_size)\n        target = {'p1/PCK': 1.0, 'p2/PCK': 1.0, 'all/PCK': 1.0}\n        self.assertDictEqual(pck, target)\n\n        # test normalized by 'head_size'\n        pckh_metric = KeypointPartitionMetric(\n            metric=dict(type='PCKAccuracy', thr=0.3, norm_item='head'),\n            partitions=dict(\n                p1=range(10),\n                p2=range(10, 24),\n                all=range(24),\n            ))\n        pckh_metric.process(self.data_batch, self.data_samples)\n        pckh = pckh_metric.evaluate(self.batch_size)\n        target = {'p1/PCKh': 0.9, 'p2/PCKh': 0.0, 'all/PCKh': 0.375}\n        self.assertDictEqual(pckh, target)\n\n        # test normalized by 'torso_size'\n        tpck_metric = KeypointPartitionMetric(\n            metric=dict(\n                type='PCKAccuracy', thr=0.05, norm_item=['bbox', 'torso']),\n            partitions=dict(\n                p1=range(10),\n                p2=range(10, 24),\n                all=range(24),\n            ))\n        tpck_metric.process(self.data_batch, self.data_samples)\n        tpck = tpck_metric.evaluate(self.batch_size)\n        self.assertIsInstance(tpck, dict)\n        target = {\n            'p1/PCK': 0.6,\n            'p1/tPCK': 0.11428571428571428,\n            'p2/PCK': 0.0,\n            'p2/tPCK': 0.0,\n            'all/PCK': 0.25,\n            'all/tPCK': 0.047619047619047616\n        }\n        self.assertDictEqual(tpck, target)\n\n\nclass TestKeypointPartitionMetricWrappingAUCandEPE(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        output = np.zeros((1, 5, 2))\n        target = np.zeros((1, 5, 2))\n        # first channel\n        output[0, 0] = [10, 4]\n        target[0, 0] = [10, 0]\n        # second channel\n        output[0, 1] = [10, 18]\n        target[0, 1] = [10, 10]\n        # third channel\n        output[0, 2] = [0, 0]\n        target[0, 2] = [0, -1]\n        # fourth channel\n        output[0, 3] = [40, 40]\n        target[0, 3] = [30, 30]\n        # fifth channel\n        output[0, 4] = [20, 10]\n        target[0, 4] = [0, 10]\n\n        gt_instances = InstanceData()\n        gt_instances.keypoints = target\n        gt_instances.keypoints_visible = np.array(\n            [[True, True, False, True, True]])\n\n        pred_instances = InstanceData()\n        pred_instances.keypoints = output\n\n        data = {'inputs': None}\n        data_sample = {\n            'gt_instances': gt_instances.to_dict(),\n            'pred_instances': pred_instances.to_dict()\n        }\n\n        self.data_batch = [data]\n        self.data_samples = [data_sample]\n\n    def test_auc_evaluate(self):\n        \"\"\"test AUC evaluation metric.\"\"\"\n        auc_metric = KeypointPartitionMetric(\n            metric=dict(type='AUC', norm_factor=20, num_thrs=4),\n            partitions=dict(\n                p1=range(3),\n                p2=range(3, 5),\n                all=range(5),\n            ))\n        auc_metric.process(self.data_batch, self.data_samples)\n        auc = auc_metric.evaluate(1)\n        target = {'p1/AUC': 0.625, 'p2/AUC': 0.125, 'all/AUC': 0.375}\n        self.assertDictEqual(auc, target)\n\n    def test_epe_evaluate(self):\n        \"\"\"test EPE evaluation metric.\"\"\"\n        epe_metric = KeypointPartitionMetric(\n            metric=dict(type='EPE', ),\n            partitions=dict(\n                p1=range(3),\n                p2=range(3, 5),\n                all=range(5),\n            ))\n        epe_metric.process(self.data_batch, self.data_samples)\n        epe = epe_metric.evaluate(1)\n        target = {\n            'p1/EPE': 6.0,\n            'p2/EPE': 17.071067810058594,\n            'all/EPE': 11.535533905029297\n        }\n        self.assertDictEqual(epe, target)\n\n\nclass TestKeypointPartitionMetricWrappingNME(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.batch_size = 4\n        num_keypoints = 19\n        self.data_batch = []\n        self.data_samples = []\n\n        for i in range(self.batch_size):\n            gt_instances = InstanceData()\n            keypoints = np.zeros((1, num_keypoints, 2))\n            for j in range(num_keypoints):\n                keypoints[0, j] = [0.5 * i * j, 0.5 * i * j]\n            gt_instances.keypoints = keypoints\n            gt_instances.keypoints_visible = np.ones(\n                (1, num_keypoints, 1)).astype(bool)\n            gt_instances.keypoints_visible[0, (2 * i) % self.batch_size,\n                                           0] = False\n            gt_instances['box_size'] = np.array([[0.1]]) * 10 * i\n\n            pred_instances = InstanceData()\n            # fake predictions\n            _keypoints = np.zeros_like(keypoints)\n            _keypoints[0, :, 0] = keypoints[0, :, 0] * 0.95\n            _keypoints[0, :, 1] = keypoints[0, :, 1] * 1.05\n            pred_instances.keypoints = _keypoints\n\n            data = {'inputs': None}\n            data_sample = {\n                'gt_instances': gt_instances.to_dict(),\n                'pred_instances': pred_instances.to_dict(),\n            }\n\n            self.data_batch.append(data)\n            self.data_samples.append(data_sample)\n\n    def test_init(self):\n        # test norm_mode arg missing\n        with self.assertRaisesRegex(AssertionError, 'Missing norm_mode'):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='NME', ), partitions=dict(all=range(133)))\n\n        # test norm_mode = keypoint_distance\n        with self.assertRaisesRegex(ValueError,\n                                    \"NME norm_mode 'keypoint_distance'\"):\n            _ = KeypointPartitionMetric(\n                metric=dict(type='NME', norm_mode='keypoint_distance'),\n                partitions=dict(all=range(133)))\n\n    def test_nme_evaluate(self):\n        \"\"\"test NME evaluation metric.\"\"\"\n        # test when norm_mode = 'use_norm_item'\n        # test norm_item = 'box_size' like in `AFLWDataset`\n        nme_metric = KeypointPartitionMetric(\n            metric=dict(\n                type='NME', norm_mode='use_norm_item', norm_item='box_size'),\n            partitions=dict(\n                p1=range(10),\n                p2=range(10, 19),\n                all=range(19),\n            ))\n        nme_metric.process(self.data_batch, self.data_samples)\n        nme = nme_metric.evaluate(4)\n        target = {\n            'p1/NME': 0.1715388651247378,\n            'p2/NME': 0.4949747721354167,\n            'all/NME': 0.333256827460395\n        }\n        self.assertDictEqual(nme, target)\n"
  },
  {
    "path": "tests/test_evaluation/test_metrics/test_posetrack18_metric.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nimport tempfile\nfrom collections import defaultdict\nfrom unittest import TestCase\n\nimport numpy as np\nfrom mmengine.fileio import dump, load\n\nfrom mmpose.datasets.datasets.utils import parse_pose_metainfo\nfrom mmpose.evaluation.metrics import PoseTrack18Metric\n\n\nclass TestPoseTrack18Metric(TestCase):\n\n    def setUp(self):\n        \"\"\"Setup some variables which are used in every test method.\n\n        TestCase calls functions in this order: setUp() -> testMethod() ->\n        tearDown() -> cleanUp()\n        \"\"\"\n        self.tmp_dir = tempfile.TemporaryDirectory()\n        self.ann_file = 'tests/data/posetrack18/annotations/'\\\n            'test_posetrack18_val.json'\n        posetrack18_meta_info = dict(\n            from_file='configs/_base_/datasets/posetrack18.py')\n        self.posetrack18_dataset_meta = parse_pose_metainfo(\n            posetrack18_meta_info)\n\n        self.db = load(self.ann_file)\n\n        self.topdown_data = self._convert_ann_to_topdown_batch_data()\n        assert len(self.topdown_data) == 14\n        self.bottomup_data = self._convert_ann_to_bottomup_batch_data()\n        assert len(self.bottomup_data) == 3\n        self.target = {\n            'posetrack18/Head AP': 100.0,\n            'posetrack18/Shou AP': 100.0,\n            'posetrack18/Elb AP': 100.0,\n            'posetrack18/Wri AP': 100.0,\n            'posetrack18/Hip AP': 100.0,\n            'posetrack18/Knee AP': 100.0,\n            'posetrack18/Ankl AP': 100.0,\n            'posetrack18/AP': 100.0,\n        }\n\n    def _convert_ann_to_topdown_batch_data(self):\n        \"\"\"Convert annotations to topdown-style batch data.\"\"\"\n        topdown_data = []\n        for ann in self.db['annotations']:\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n            keypoints = np.array(ann['keypoints']).reshape((1, -1, 3))\n\n            gt_instances = {\n                'bbox_scales': bbox_scales,\n                'bboxes': bboxes,\n                'bbox_scores': np.ones((1, ), dtype=np.float32),\n            }\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n        return topdown_data\n\n    def _convert_ann_to_bottomup_batch_data(self):\n        \"\"\"Convert annotations to bottomup-style batch data.\"\"\"\n        img2ann = defaultdict(list)\n        for ann in self.db['annotations']:\n            img2ann[ann['image_id']].append(ann)\n\n        bottomup_data = []\n        for img_id, anns in img2ann.items():\n            keypoints = np.array([ann['keypoints'] for ann in anns]).reshape(\n                (len(anns), -1, 3))\n\n            gt_instances = {\n                'bbox_scores': np.ones((len(anns)), dtype=np.float32)\n            }\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': [ann['id'] for ann in anns],\n                'img_id': img_id,\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            bottomup_data.append((data_batch, data_samples))\n        return bottomup_data\n\n    def tearDown(self):\n        self.tmp_dir.cleanup()\n\n    def test_init(self):\n        \"\"\"test metric init method.\"\"\"\n        # test score_mode option\n        with self.assertRaisesRegex(ValueError,\n                                    '`score_mode` should be one of'):\n            _ = PoseTrack18Metric(ann_file=self.ann_file, score_mode='invalid')\n\n        # test nms_mode option\n        with self.assertRaisesRegex(ValueError, '`nms_mode` should be one of'):\n            _ = PoseTrack18Metric(ann_file=self.ann_file, nms_mode='invalid')\n\n        # test `format_only` option\n        with self.assertRaisesRegex(\n                AssertionError,\n                '`outfile_prefix` can not be None when `format_only` is True'):\n            _ = PoseTrack18Metric(\n                ann_file=self.ann_file, format_only=True, outfile_prefix=None)\n\n    def test_topdown_evaluate(self):\n        \"\"\"test topdown-style posetrack18 metric evaluation.\"\"\"\n        # case 1: score_mode='bbox', nms_mode='none'\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox',\n            nms_mode='none')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n\n        eval_results = posetrack18_metric.evaluate(size=len(self.topdown_data))\n\n        self.assertDictEqual(eval_results, self.target)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '003418_mpii_test.json')))\n\n        # case 2: score_mode='bbox_keypoint', nms_mode='oks_nms'\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n\n        eval_results = posetrack18_metric.evaluate(size=len(self.topdown_data))\n\n        self.assertDictEqual(eval_results, self.target)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '009473_mpii_test.json')))\n\n        # case 3: score_mode='bbox_keypoint', nms_mode='soft_oks_nms'\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox_keypoint',\n            nms_mode='soft_oks_nms')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n\n        eval_results = posetrack18_metric.evaluate(size=len(self.topdown_data))\n\n        self.assertDictEqual(eval_results, self.target)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '012834_mpii_test.json')))\n\n    def test_bottomup_evaluate(self):\n        \"\"\"test bottomup-style posetrack18 metric evaluation.\"\"\"\n        # case 1: score_mode='bbox', nms_mode='none'\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file, outfile_prefix=f'{self.tmp_dir.name}/test')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n\n        # process samples\n        for data_batch, data_samples in self.bottomup_data:\n            posetrack18_metric.process(data_batch, data_samples)\n\n        eval_results = posetrack18_metric.evaluate(\n            size=len(self.bottomup_data))\n        self.assertDictEqual(eval_results, self.target)\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '009473_mpii_test.json')))\n\n    def test_other_methods(self):\n        \"\"\"test other useful methods.\"\"\"\n        # test `_sort_and_unique_bboxes` method\n        posetrack18_metric = PoseTrack18Metric(ann_file=self.ann_file)\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n        # process one extra sample\n        data_batch, data_samples = self.topdown_data[0]\n        posetrack18_metric.process(data_batch, data_samples)\n        # an extra sample\n        eval_results = posetrack18_metric.evaluate(\n            size=len(self.topdown_data) + 1)\n        self.assertDictEqual(eval_results, self.target)\n\n    def test_format_only(self):\n        \"\"\"test `format_only` option.\"\"\"\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file,\n            format_only=True,\n            outfile_prefix=f'{self.tmp_dir.name}/test')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n        # process samples\n        for data_batch, data_samples in self.topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n        eval_results = posetrack18_metric.evaluate(size=len(self.topdown_data))\n        self.assertDictEqual(eval_results, {})\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '012834_mpii_test.json')))\n\n        # test when gt annotations are absent\n        db_ = load(self.ann_file)\n        del db_['annotations']\n        tmp_ann_file = osp.join(self.tmp_dir.name, 'temp_ann.json')\n        dump(db_, tmp_ann_file, sort_keys=True, indent=4)\n        with self.assertRaisesRegex(\n                AssertionError,\n                'Ground truth annotations are required for evaluation'):\n            _ = PoseTrack18Metric(ann_file=tmp_ann_file, format_only=False)\n\n    def test_topdown_alignment(self):\n        \"\"\"Test whether the output of PoseTrack18Metric and the original\n        TopDownPoseTrack18Dataset are the same.\"\"\"\n        self.skipTest('Skip test.')\n        topdown_data = []\n        for ann in self.db['annotations']:\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n\n            keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, 17, 3)\n            keypoints[..., 0] = keypoints[..., 0] * 0.98\n            keypoints[..., 1] = keypoints[..., 1] * 1.02\n            keypoints[..., 2] = keypoints[..., 2] * 0.8\n\n            gt_instances = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32) * 0.98,\n                'bboxes': bboxes,\n            }\n            pred_instances = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data = {'inputs': None}\n            data_sample = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances,\n                'pred_instances': pred_instances\n            }\n\n            # batch size = 1\n            data_batch = [data]\n            data_samples = [data_sample]\n            topdown_data.append((data_batch, data_samples))\n\n        # case 1:\n        # typical setting: score_mode='bbox_keypoint', nms_mode='oks_nms'\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox_keypoint',\n            nms_mode='oks_nms')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n\n        # process samples\n        for data_batch, data_samples in topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n\n        eval_results = posetrack18_metric.evaluate(size=len(topdown_data))\n\n        target = {\n            'posetrack18/Head AP': 84.6677132391418,\n            'posetrack18/Shou AP': 80.86734693877551,\n            'posetrack18/Elb AP': 83.0204081632653,\n            'posetrack18/Wri AP': 85.12396694214877,\n            'posetrack18/Hip AP': 75.14792899408285,\n            'posetrack18/Knee AP': 66.76515151515152,\n            'posetrack18/Ankl AP': 71.78571428571428,\n            'posetrack18/Total AP': 78.62827822638012,\n        }\n\n        for key in eval_results.keys():\n            self.assertAlmostEqual(eval_results[key], target[key])\n\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '012834_mpii_test.json')))\n\n        topdown_data = []\n        anns = self.db['annotations']\n        for i, ann in enumerate(anns):\n            w, h = ann['bbox'][2], ann['bbox'][3]\n            bboxes = np.array(ann['bbox'], dtype=np.float32).reshape(-1, 4)\n            bbox_scales = np.array([w * 1.25, h * 1.25]).reshape(-1, 2)\n\n            keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n            keypoints[..., 0] = keypoints[..., 0] * (1 - i / 100)\n            keypoints[..., 1] = keypoints[..., 1] * (1 + i / 100)\n            keypoints[..., 2] = keypoints[..., 2] * (1 - i / 100)\n\n            gt_instances0 = {\n                'bbox_scales': bbox_scales,\n                'bbox_scores': np.ones((1, ), dtype=np.float32),\n                'bboxes': bboxes,\n            }\n            pred_instances0 = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data0 = {'inputs': None}\n            data_sample0 = {\n                'id': ann['id'],\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances0,\n                'pred_instances': pred_instances0\n            }\n\n            keypoints = np.array(\n                ann['keypoints'], dtype=np.float32).reshape(1, -1, 3)\n            keypoints[..., 0] = keypoints[..., 0] * (1 + i / 100)\n            keypoints[..., 1] = keypoints[..., 1] * (1 - i / 100)\n            keypoints[..., 2] = keypoints[..., 2] * (1 - 2 * i / 100)\n\n            gt_instances1 = {\n                'bbox_scales': bbox_scales,\n                'bboxes': bboxes,\n                'bbox_scores': np.ones(\n                    (1, ), dtype=np.float32) * (1 - 2 * i / 100)\n            }\n            pred_instances1 = {\n                'keypoints': keypoints[..., :2],\n                'keypoint_scores': keypoints[..., -1],\n            }\n\n            data1 = {'inputs': None}\n            data_sample1 = {\n                'id': ann['id'] + 1,\n                'img_id': ann['image_id'],\n                'gt_instances': gt_instances1,\n                'pred_instances': pred_instances1\n            }\n\n            # batch size = 2\n            data_batch = [data0, data1]\n            data_samples = [data_sample0, data_sample1]\n            topdown_data.append((data_batch, data_samples))\n\n        # case 3: score_mode='bbox_keypoint', nms_mode='soft_oks_nms'\n        posetrack18_metric = PoseTrack18Metric(\n            ann_file=self.ann_file,\n            outfile_prefix=f'{self.tmp_dir.name}/test',\n            score_mode='bbox_keypoint',\n            keypoint_score_thr=0.2,\n            nms_thr=0.9,\n            nms_mode='soft_oks_nms')\n        posetrack18_metric.dataset_meta = self.posetrack18_dataset_meta\n\n        # process samples\n        for data_batch, data_samples in topdown_data:\n            posetrack18_metric.process(data_batch, data_samples)\n\n        eval_results = posetrack18_metric.evaluate(size=len(topdown_data) * 2)\n\n        target = {\n            'posetrack18/Head AP': 27.1062271062271068,\n            'posetrack18/Shou AP': 25.918367346938776,\n            'posetrack18/Elb AP': 22.67857142857143,\n            'posetrack18/Wri AP': 29.090909090909093,\n            'posetrack18/Hip AP': 18.40659340659341,\n            'posetrack18/Knee AP': 32.0,\n            'posetrack18/Ankl AP': 20.0,\n            'posetrack18/Total AP': 25.167170924313783,\n        }\n\n        for key in eval_results.keys():\n            self.assertAlmostEqual(eval_results[key], target[key])\n\n        self.assertTrue(\n            osp.isfile(osp.join(self.tmp_dir.name, '009473_mpii_test.json')))\n"
  },
  {
    "path": "tests/test_external/test_mim.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nfrom tempfile import TemporaryDirectory\nfrom unittest import TestCase\n\nfrom mim.commands import download\n\n\nclass TestMIM(TestCase):\n\n    def test_download(self):\n        with TemporaryDirectory() as tmp_dir:\n            ckpts = download(\n                'mmpose',\n                configs=['td-hm_hrnet-w48_8xb32-210e_coco-256x192'],\n                dest_root=tmp_dir)\n\n            self.assertEqual(len(ckpts), 1)\n            self.assertIn('td-hm_hrnet-w48_8xb32-210e_coco-256x192.py',\n                          os.listdir(tmp_dir))\n            self.assertIn(ckpts[0], os.listdir(tmp_dir))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_alexnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import AlexNet\n\n\nclass TestAlexNet(TestCase):\n\n    def test_alexnet_backbone(self):\n        \"\"\"Test alexnet backbone.\"\"\"\n        model = AlexNet(-1)\n        model.train()\n\n        imgs = torch.randn(1, 3, 256, 192)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, (1, 256, 7, 5))\n\n        model = AlexNet(1)\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, (1, 1))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_backbones_utils.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones.utils import (InvertedResidual, SELayer,\n                                           channel_shuffle, make_divisible)\n\n\nclass TestBackboneUtils(TestCase):\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (GroupNorm, _BatchNorm)):\n            return True\n        return False\n\n    def test_make_divisible(self):\n        # test min_value is None\n        result = make_divisible(34, 8, None)\n        self.assertEqual(result, 32)\n\n        # test when new_value > min_ratio * value\n        result = make_divisible(10, 8, min_ratio=0.9)\n        self.assertEqual(result, 16)\n\n        # test min_value = 0.8\n        result = make_divisible(33, 8, min_ratio=0.8)\n        self.assertEqual(result, 32)\n\n    def test_channel_shuffle(self):\n        x = torch.randn(1, 24, 56, 56)\n        with self.assertRaisesRegex(\n                AssertionError, 'num_channels should be divisible by groups'):\n            channel_shuffle(x, 7)\n\n        groups = 3\n        batch_size, num_channels, height, width = x.size()\n        channels_per_group = num_channels // groups\n        out = channel_shuffle(x, groups)\n        # test the output value when groups = 3\n        for b in range(batch_size):\n            for c in range(num_channels):\n                c_out = c % channels_per_group * groups + \\\n                        c // channels_per_group\n                for i in range(height):\n                    for j in range(width):\n                        self.assertEqual(x[b, c, i, j], out[b, c_out, i, j])\n\n    def test_inverted_residual(self):\n\n        with self.assertRaises(AssertionError):\n            # stride must be in [1, 2]\n            InvertedResidual(16, 16, 32, stride=3)\n\n        with self.assertRaises(AssertionError):\n            # se_cfg must be None or dict\n            InvertedResidual(16, 16, 32, se_cfg=list())\n\n        with self.assertRaises(AssertionError):\n            # in_channeld and out_channels must be the same if\n            # with_expand_conv is False\n            InvertedResidual(16, 16, 32, with_expand_conv=False)\n\n        # Test InvertedResidual forward, stride=1\n        block = InvertedResidual(16, 16, 32, stride=1)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertIsNone(getattr(block, 'se', None))\n        self.assertTrue(block.with_res_shortcut)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n\n        # Test InvertedResidual forward, stride=2\n        block = InvertedResidual(16, 16, 32, stride=2)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertFalse(block.with_res_shortcut)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 28, 28)))\n\n        # Test InvertedResidual forward with se layer\n        se_cfg = dict(channels=32)\n        block = InvertedResidual(16, 16, 32, stride=1, se_cfg=se_cfg)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertIsInstance(block.se, SELayer)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n\n        # Test InvertedResidual forward, with_expand_conv=False\n        block = InvertedResidual(32, 16, 32, with_expand_conv=False)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = block(x)\n        self.assertIsNone(getattr(block, 'expand_conv', None))\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n\n        # Test InvertedResidual forward with GroupNorm\n        block = InvertedResidual(\n            16, 16, 32, norm_cfg=dict(type='GN', num_groups=2))\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        for m in block.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, GroupNorm)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n\n        # Test InvertedResidual forward with HSigmoid\n        block = InvertedResidual(16, 16, 32, act_cfg=dict(type='HSigmoid'))\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n\n        # Test InvertedResidual forward with checkpoint\n        block = InvertedResidual(16, 16, 32, with_cp=True)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertTrue(block.with_cp)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_cpm.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import CPM\nfrom mmpose.models.backbones.cpm import CpmBlock\n\n\nclass TestCPM(TestCase):\n\n    def test_cpm_block(self):\n        with self.assertRaises(AssertionError):\n            # len(channels) == len(kernels)\n            CpmBlock(\n                3, channels=[3, 3, 3], kernels=[\n                    1,\n                ])\n\n        # Test CPM Block\n        model = CpmBlock(3, channels=[3, 3, 3], kernels=[1, 1, 1])\n        model.train()\n\n        imgs = torch.randn(1, 3, 10, 10)\n        feat = model(imgs)\n        self.assertEqual(feat.shape, torch.Size([1, 3, 10, 10]))\n\n    def test_cpm_backbone(self):\n        with self.assertRaises(AssertionError):\n            # CPM's num_stacks should larger than 0\n            CPM(in_channels=3, out_channels=17, num_stages=-1)\n\n        with self.assertRaises(AssertionError):\n            # CPM's in_channels should be 3\n            CPM(in_channels=2, out_channels=17)\n\n        # Test CPM\n        model = CPM(in_channels=3, out_channels=17, num_stages=1)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 256, 192)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[0].shape, torch.Size([1, 17, 32, 24]))\n\n        imgs = torch.randn(1, 3, 384, 288)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[0].shape, torch.Size([1, 17, 48, 36]))\n\n        imgs = torch.randn(1, 3, 368, 368)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[0].shape, torch.Size([1, 17, 46, 46]))\n\n        # Test CPM multi-stages\n        model = CPM(in_channels=3, out_channels=17, num_stages=2)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 368, 368)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(feat[0].shape, torch.Size([1, 17, 46, 46]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 17, 46, 46]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_csp_darknet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones.csp_darknet import CSPDarknet\n\n\ndef is_norm(modules):\n    \"\"\"Check if is one of the norms.\"\"\"\n    if isinstance(modules, (GroupNorm, _BatchNorm)):\n        return True\n    return False\n\n\ndef check_norm_state(modules, train_state):\n    \"\"\"Check if norm layer is in correct train state.\"\"\"\n    for mod in modules:\n        if isinstance(mod, _BatchNorm):\n            if mod.training != train_state:\n                return False\n    return True\n\n\nclass TestCSPDarknetBackbone(unittest.TestCase):\n\n    def test_invalid_frozen_stages(self):\n        with self.assertRaises(ValueError):\n            CSPDarknet(frozen_stages=6)\n\n    def test_invalid_out_indices(self):\n        with self.assertRaises(AssertionError):\n            CSPDarknet(out_indices=[6])\n\n    def test_frozen_stages(self):\n        frozen_stages = 1\n        model = CSPDarknet(frozen_stages=frozen_stages)\n        model.train()\n\n        for mod in model.stem.modules():\n            for param in mod.parameters():\n                self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'stage{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n    def test_norm_eval(self):\n        model = CSPDarknet(norm_eval=True)\n        model.train()\n\n        self.assertFalse(check_norm_state(model.modules(), True))\n\n    def test_csp_darknet_p5_forward(self):\n        model = CSPDarknet(\n            arch='P5', widen_factor=0.25, out_indices=range(0, 5))\n        model.train()\n\n        imgs = torch.randn(1, 3, 64, 64)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 5)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 32, 32)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 32, 16, 16)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 64, 8, 8)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 128, 4, 4)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 256, 2, 2)))\n\n    def test_csp_darknet_p6_forward(self):\n        model = CSPDarknet(\n            arch='P6',\n            widen_factor=0.25,\n            out_indices=range(0, 6),\n            spp_kernal_sizes=(3, 5, 7))\n        model.train()\n\n        imgs = torch.randn(1, 3, 128, 128)\n        feat = model(imgs)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 64, 64)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 32, 32, 32)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 64, 16, 16)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 128, 8, 8)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 192, 4, 4)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 256, 2, 2)))\n\n    def test_csp_darknet_custom_arch_forward(self):\n        arch_ovewrite = [[32, 56, 3, True, False], [56, 224, 2, True, False],\n                         [224, 512, 1, True, False]]\n        model = CSPDarknet(\n            arch_ovewrite=arch_ovewrite,\n            widen_factor=0.25,\n            out_indices=(0, 1, 2, 3))\n        model.train()\n\n        imgs = torch.randn(1, 3, 32, 32)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size((1, 8, 16, 16)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 14, 8, 8)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 56, 4, 4)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 128, 2, 2)))\n\n    def test_csp_darknet_custom_arch_norm(self):\n        model = CSPDarknet(widen_factor=0.125, out_indices=range(0, 5))\n        for m in model.modules():\n            if is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n        model.train()\n\n        imgs = torch.randn(1, 3, 64, 64)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 5)\n        self.assertEqual(feat[0].shape, torch.Size((1, 8, 32, 32)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 16, 16, 16)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 32, 8, 8)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 64, 4, 4)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 128, 2, 2)))\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_dstformer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import DSTFormer\nfrom mmpose.models.backbones.dstformer import AttentionBlock\n\n\nclass TestDSTFormer(TestCase):\n\n    def test_attention_block(self):\n        # BasicTemporalBlock with causal == False\n        block = AttentionBlock(dim=256, num_heads=2)\n        x = torch.rand(2, 17, 256)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 17, 256]))\n\n    def test_DSTFormer(self):\n        # Test DSTFormer with depth=2\n        model = DSTFormer(in_channels=3, depth=2, seq_len=2)\n        pose3d = torch.rand((1, 2, 17, 3))\n        feat = model(pose3d)\n        self.assertEqual(feat[0].shape, (2, 17, 256))\n\n        # Test DSTFormer with depth=4 and qkv_bias=False\n        model = DSTFormer(in_channels=3, depth=4, seq_len=2, qkv_bias=False)\n        pose3d = torch.rand((1, 2, 17, 3))\n        feat = model(pose3d)\n        self.assertEqual(feat[0].shape, (2, 17, 256))\n\n        # Test DSTFormer with depth=4 and att_fuse=False\n        model = DSTFormer(in_channels=3, depth=4, seq_len=2, att_fuse=False)\n        pose3d = torch.rand((1, 2, 17, 3))\n        feat = model(pose3d)\n        self.assertEqual(feat[0].shape, (2, 17, 256))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_hourglass.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import HourglassAENet, HourglassNet\n\n\nclass TestHourglass(TestCase):\n\n    def test_hourglass_backbone(self):\n        with self.assertRaises(AssertionError):\n            # HourglassNet's num_stacks should larger than 0\n            HourglassNet(num_stacks=0)\n\n        with self.assertRaises(AssertionError):\n            # len(stage_channels) should equal len(stage_blocks)\n            HourglassNet(\n                stage_channels=[256, 256, 384, 384, 384],\n                stage_blocks=[2, 2, 2, 2, 2, 4])\n\n        with self.assertRaises(AssertionError):\n            # len(stage_channels) should larger than downsample_times\n            HourglassNet(\n                downsample_times=5,\n                stage_channels=[256, 256, 384, 384, 384],\n                stage_blocks=[2, 2, 2, 2, 2])\n\n        # Test HourglassNet-52\n        model = HourglassNet(num_stacks=1)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 256, 256)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 64, 64]))\n\n        # Test HourglassNet-104\n        model = HourglassNet(num_stacks=2)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 256, 256)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 64, 64]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 256, 64, 64]))\n\n    def test_hourglass_ae_backbone(self):\n        with self.assertRaises(AssertionError):\n            # HourglassAENet's num_stacks should larger than 0\n            HourglassAENet(num_stacks=0)\n\n        with self.assertRaises(AssertionError):\n            # len(stage_channels) should larger than downsample_times\n            HourglassAENet(\n                downsample_times=5, stage_channels=[256, 256, 384, 384, 384])\n\n        # num_stack=1\n        model = HourglassAENet(num_stacks=1)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 256, 256)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[0].shape, torch.Size([1, 34, 64, 64]))\n\n        # num_stack=2\n        model = HourglassAENet(num_stacks=2)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 256, 256)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(feat[0].shape, torch.Size([1, 34, 64, 64]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 34, 64, 64]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_hrformer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones.hrformer import (HRFomerModule, HRFormer,\n                                              HRFormerBlock)\n\n\nclass TestHrformer(TestCase):\n\n    def test_hrformer_module(self):\n        norm_cfg = dict(type='BN')\n        block = HRFormerBlock\n        # Test multiscale forward\n        num_channles = (32, 64)\n        num_inchannels = [c * block.expansion for c in num_channles]\n        hrmodule = HRFomerModule(\n            num_branches=2,\n            block=block,\n            num_blocks=(2, 2),\n            num_inchannels=num_inchannels,\n            num_channels=num_channles,\n            num_heads=(1, 2),\n            num_window_sizes=(7, 7),\n            num_mlp_ratios=(4, 4),\n            drop_paths=(0., 0.),\n            norm_cfg=norm_cfg)\n\n        feats = [\n            torch.randn(1, num_inchannels[0], 64, 64),\n            torch.randn(1, num_inchannels[1], 32, 32)\n        ]\n        feats = hrmodule(feats)\n\n        self.assertGreater(len(str(hrmodule)), 0)\n        self.assertEqual(len(feats), 2)\n        self.assertEqual(feats[0].shape,\n                         torch.Size([1, num_inchannels[0], 64, 64]))\n        self.assertEqual(feats[1].shape,\n                         torch.Size([1, num_inchannels[1], 32, 32]))\n\n        # Test single scale forward\n        num_channles = (32, 64)\n        in_channels = [c * block.expansion for c in num_channles]\n        hrmodule = HRFomerModule(\n            num_branches=2,\n            block=block,\n            num_blocks=(2, 2),\n            num_inchannels=num_inchannels,\n            num_channels=num_channles,\n            num_heads=(1, 2),\n            num_window_sizes=(7, 7),\n            num_mlp_ratios=(4, 4),\n            drop_paths=(0., 0.),\n            norm_cfg=norm_cfg,\n            multiscale_output=False,\n        )\n\n        feats = [\n            torch.randn(1, in_channels[0], 64, 64),\n            torch.randn(1, in_channels[1], 32, 32)\n        ]\n        feats = hrmodule(feats)\n\n        self.assertEqual(len(feats), 1)\n        self.assertEqual(feats[0].shape,\n                         torch.Size([1, in_channels[0], 64, 64]))\n\n        # Test single branch HRFormer module\n        hrmodule = HRFomerModule(\n            num_branches=1,\n            block=block,\n            num_blocks=(1, ),\n            num_inchannels=[num_inchannels[0]],\n            num_channels=[num_channles[0]],\n            num_heads=(1, ),\n            num_window_sizes=(7, ),\n            num_mlp_ratios=(4, ),\n            drop_paths=(0.1, ),\n            norm_cfg=norm_cfg,\n        )\n\n        feats = [\n            torch.randn(1, in_channels[0], 64, 64),\n        ]\n        feats = hrmodule(feats)\n\n        self.assertEqual(len(feats), 1)\n        self.assertEqual(feats[0].shape,\n                         torch.Size([1, in_channels[0], 64, 64]))\n\n        # Value tests\n        kwargs = dict(\n            num_branches=2,\n            block=block,\n            num_blocks=(2, 2),\n            num_inchannels=num_inchannels,\n            num_channels=num_channles,\n            num_heads=(1, 2),\n            num_window_sizes=(7, 7),\n            num_mlp_ratios=(4, 4),\n            drop_paths=(0.1, 0.1),\n            norm_cfg=norm_cfg,\n        )\n\n        with self.assertRaises(ValueError):\n            # len(num_blocks) should equal num_branches\n            kwargs['num_blocks'] = [2, 2, 2]\n            HRFomerModule(**kwargs)\n        kwargs['num_blocks'] = [2, 2]\n\n        with self.assertRaises(ValueError):\n            # len(num_blocks) should equal num_branches\n            kwargs['num_channels'] = [2]\n            HRFomerModule(**kwargs)\n        kwargs['num_channels'] = [2, 2]\n\n        with self.assertRaises(ValueError):\n            # len(num_blocks) should equal num_branches\n            kwargs['num_inchannels'] = [2]\n            HRFomerModule(**kwargs)\n        kwargs['num_inchannels'] = [2, 2]\n\n    def test_hrformer_backbone(self):\n        norm_cfg = dict(type='BN')\n        # only have 3 stages\n        extra = dict(\n            drop_path_rate=0.2,\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(2, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='HRFORMERBLOCK',\n                window_sizes=(7, 7),\n                num_heads=(1, 2),\n                mlp_ratios=(4, 4),\n                num_blocks=(2, 2),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='HRFORMERBLOCK',\n                window_sizes=(7, 7, 7),\n                num_heads=(1, 2, 4),\n                mlp_ratios=(4, 4, 4),\n                num_blocks=(2, 2, 2),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='HRFORMERBLOCK',\n                window_sizes=(7, 7, 7, 7),\n                num_heads=(1, 2, 4, 8),\n                mlp_ratios=(4, 4, 4, 4),\n                num_blocks=(2, 2, 2, 2),\n                num_channels=(32, 64, 128, 256),\n                multiscale_output=True))\n\n        with self.assertRaises(ValueError):\n            # len(num_blocks) should equal num_branches\n            extra['stage4']['num_branches'] = 3\n            HRFormer(extra=extra)\n        extra['stage4']['num_branches'] = 4\n\n        # Test HRFormer-S\n        model = HRFormer(extra=extra, norm_cfg=norm_cfg)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 64, 64)\n        feats = model(imgs)\n        self.assertEqual(len(feats), 4)\n        self.assertEqual(feats[0].shape, torch.Size([1, 32, 16, 16]))\n        self.assertEqual(feats[3].shape, torch.Size([1, 256, 2, 2]))\n\n        # Test single scale output and model\n        # without relative position bias\n        extra['stage4']['multiscale_output'] = False\n        extra['with_rpe'] = False\n        model = HRFormer(extra=extra, norm_cfg=norm_cfg)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 64, 64)\n        feats = model(imgs)\n        self.assertIsInstance(feats, tuple)\n        self.assertEqual(len(feats), 1)\n        self.assertEqual(feats[-1].shape, torch.Size([1, 32, 16, 16]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_hrnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import HRNet\nfrom mmpose.models.backbones.hrnet import HRModule\nfrom mmpose.models.backbones.resnet import BasicBlock, Bottleneck\n\n\nclass TestHrnet(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is HRModule building block.\"\"\"\n        if isinstance(modules, (HRModule, )):\n            return True\n        return False\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (_BatchNorm, )):\n            return True\n        return False\n\n    @staticmethod\n    def all_zeros(modules):\n        \"\"\"Check if the weight(and bias) is all zero.\"\"\"\n        weight_zero = torch.equal(modules.weight.data,\n                                  torch.zeros_like(modules.weight.data))\n        if hasattr(modules, 'bias'):\n            bias_zero = torch.equal(modules.bias.data,\n                                    torch.zeros_like(modules.bias.data))\n        else:\n            bias_zero = True\n\n        return weight_zero and bias_zero\n\n    def test_hrmodule(self):\n        # Test HRModule forward\n        block = HRModule(\n            num_branches=1,\n            blocks=BasicBlock,\n            num_blocks=(4, ),\n            in_channels=[\n                64,\n            ],\n            num_channels=(64, ))\n\n        x = torch.randn(2, 64, 56, 56)\n        x_out = block([x])\n        self.assertEqual(x_out[0].shape, torch.Size([2, 64, 56, 56]))\n\n    def test_hrnet_backbone(self):\n        extra = dict(\n            stage1=dict(\n                num_modules=1,\n                num_branches=1,\n                block='BOTTLENECK',\n                num_blocks=(4, ),\n                num_channels=(64, )),\n            stage2=dict(\n                num_modules=1,\n                num_branches=2,\n                block='BASIC',\n                num_blocks=(4, 4),\n                num_channels=(32, 64)),\n            stage3=dict(\n                num_modules=4,\n                num_branches=3,\n                block='BASIC',\n                num_blocks=(4, 4, 4),\n                num_channels=(32, 64, 128)),\n            stage4=dict(\n                num_modules=3,\n                num_branches=4,\n                block='BASIC',\n                num_blocks=(4, 4, 4, 4),\n                num_channels=(32, 64, 128, 256)))\n\n        model = HRNet(extra, in_channels=3)\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 32, 56, 56]))\n\n        # Test HRNet zero initialization of residual\n        model = HRNet(extra, in_channels=3, zero_init_residual=True)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, Bottleneck):\n                self.assertTrue(self.all_zeros(m.norm3))\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 32, 56, 56]))\n\n        # Test HRNet with the first three stages frozen\n        frozen_stages = 3\n        model = HRNet(extra, in_channels=3, frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        if frozen_stages >= 0:\n            self.assertFalse(model.norm1.training)\n            self.assertFalse(model.norm2.training)\n            for layer in [model.conv1, model.norm1, model.conv2, model.norm2]:\n                for param in layer.parameters():\n                    self.assertFalse(param.requires_grad)\n\n        for i in range(1, frozen_stages + 1):\n            if i == 1:\n                layer = getattr(model, 'layer1')\n            else:\n                layer = getattr(model, f'stage{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n            if i < 4:\n                layer = getattr(model, f'transition{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_litehrnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import LiteHRNet\nfrom mmpose.models.backbones.litehrnet import LiteHRModule\nfrom mmpose.models.backbones.resnet import Bottleneck\n\n\nclass TestLiteHrnet(TestCase):\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (_BatchNorm, )):\n            return True\n        return False\n\n    @staticmethod\n    def all_zeros(modules):\n        \"\"\"Check if the weight(and bias) is all zero.\"\"\"\n        weight_zero = torch.equal(modules.weight.data,\n                                  torch.zeros_like(modules.weight.data))\n        if hasattr(modules, 'bias'):\n            bias_zero = torch.equal(modules.bias.data,\n                                    torch.zeros_like(modules.bias.data))\n        else:\n            bias_zero = True\n\n        return weight_zero and bias_zero\n\n    def test_litehrmodule(self):\n        # Test LiteHRModule forward\n        block = LiteHRModule(\n            num_branches=1,\n            num_blocks=1,\n            in_channels=[\n                40,\n            ],\n            reduce_ratio=8,\n            module_type='LITE')\n\n        x = torch.randn(2, 40, 56, 56)\n        x_out = block([[x]])\n        self.assertEqual(x_out[0][0].shape, torch.Size([2, 40, 56, 56]))\n\n        block = LiteHRModule(\n            num_branches=1,\n            num_blocks=1,\n            in_channels=[\n                40,\n            ],\n            reduce_ratio=8,\n            module_type='NAIVE')\n\n        x = torch.randn(2, 40, 56, 56)\n        x_out = block([x])\n        self.assertEqual(x_out[0].shape, torch.Size([2, 40, 56, 56]))\n\n        with self.assertRaises(ValueError):\n            block = LiteHRModule(\n                num_branches=1,\n                num_blocks=1,\n                in_channels=[\n                    40,\n                ],\n                reduce_ratio=8,\n                module_type='none')\n\n    def test_litehrnet_backbone(self):\n        extra = dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(2, 4, 2),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('LITE', 'LITE', 'LITE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True)\n\n        model = LiteHRNet(extra, in_channels=3)\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 40, 56, 56]))\n\n        # Test HRNet zero initialization of residual\n        model = LiteHRNet(extra, in_channels=3)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, Bottleneck):\n                self.assertTrue(self.all_zeros(m.norm3))\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 40, 56, 56]))\n\n        extra = dict(\n            stem=dict(stem_channels=32, out_channels=32, expand_ratio=1),\n            num_stages=3,\n            stages_spec=dict(\n                num_modules=(2, 4, 2),\n                num_branches=(2, 3, 4),\n                num_blocks=(2, 2, 2),\n                module_type=('NAIVE', 'NAIVE', 'NAIVE'),\n                with_fuse=(True, True, True),\n                reduce_ratios=(8, 8, 8),\n                num_channels=(\n                    (40, 80),\n                    (40, 80, 160),\n                    (40, 80, 160, 320),\n                )),\n            with_head=True)\n\n        model = LiteHRNet(extra, in_channels=3)\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 40, 56, 56]))\n\n        # Test HRNet zero initialization of residual\n        model = LiteHRNet(extra, in_channels=3)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, Bottleneck):\n                self.assertTrue(self.all_zeros(m.norm3))\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 40, 56, 56]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_mobilenet_v2.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import MobileNetV2\nfrom mmpose.models.backbones.mobilenet_v2 import InvertedResidual\n\n\nclass TestMobilenetV2(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is ResNet building block.\"\"\"\n        if isinstance(modules, (InvertedResidual, )):\n            return True\n        return False\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (GroupNorm, _BatchNorm)):\n            return True\n        return False\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_mobilenetv2_invertedresidual(self):\n\n        with self.assertRaises(AssertionError):\n            # stride must be in [1, 2]\n            InvertedResidual(16, 24, stride=3, expand_ratio=6)\n\n        # Test InvertedResidual with checkpoint forward, stride=1\n        block = InvertedResidual(16, 24, stride=1, expand_ratio=6)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 24, 56, 56)))\n\n        # Test InvertedResidual with expand_ratio=1\n        block = InvertedResidual(16, 16, stride=1, expand_ratio=1)\n        self.assertEqual(len(block.conv), 2)\n\n        # Test InvertedResidual with use_res_connect\n        block = InvertedResidual(16, 16, stride=1, expand_ratio=6)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertTrue(block.use_res_connect)\n        self.assertEqual(x_out.shape, torch.Size((1, 16, 56, 56)))\n\n        # Test InvertedResidual with checkpoint forward, stride=2\n        block = InvertedResidual(16, 24, stride=2, expand_ratio=6)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 24, 28, 28)))\n\n        # Test InvertedResidual with checkpoint forward\n        block = InvertedResidual(\n            16, 24, stride=1, expand_ratio=6, with_cp=True)\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 24, 56, 56)))\n\n        # Test InvertedResidual with act_cfg=dict(type='ReLU')\n        block = InvertedResidual(\n            16, 24, stride=1, expand_ratio=6, act_cfg=dict(type='ReLU'))\n        x = torch.randn(1, 16, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 24, 56, 56)))\n\n    def test_mobilenetv2_backbone(self):\n        with self.assertRaises(TypeError):\n            # pretrained must be a string path\n            model = MobileNetV2()\n            model.init_weights(pretrained=0)\n\n        with self.assertRaises(ValueError):\n            # frozen_stages must in range(1, 8)\n            MobileNetV2(frozen_stages=8)\n\n        with self.assertRaises(ValueError):\n            # tout_indices in range(-1, 8)\n            MobileNetV2(out_indices=[8])\n\n        # Test MobileNetV2 with first stage frozen\n        frozen_stages = 1\n        model = MobileNetV2(frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n\n        for mod in model.conv1.modules():\n            for param in mod.parameters():\n                self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test MobileNetV2 with norm_eval=True\n        model = MobileNetV2(norm_eval=True)\n        model.init_weights()\n        model.train()\n\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test MobileNetV2 forward with widen_factor=1.0\n        model = MobileNetV2(widen_factor=1.0, out_indices=range(0, 8))\n        model.init_weights()\n        model.train()\n\n        self.assertTrue(self.check_norm_state(model.modules(), True))\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 8)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 24, 56, 56)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 32, 28, 28)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 64, 14, 14)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 96, 14, 14)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 160, 7, 7)))\n        self.assertEqual(feat[6].shape, torch.Size((1, 320, 7, 7)))\n        self.assertEqual(feat[7].shape, torch.Size((1, 1280, 7, 7)))\n\n        # Test MobileNetV2 forward with widen_factor=0.5\n        model = MobileNetV2(widen_factor=0.5, out_indices=range(0, 7))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 7)\n        self.assertEqual(feat[0].shape, torch.Size((1, 8, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 16, 56, 56)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 16, 28, 28)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 32, 14, 14)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 48, 14, 14)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 80, 7, 7)))\n        self.assertEqual(feat[6].shape, torch.Size((1, 160, 7, 7)))\n\n        # Test MobileNetV2 forward with widen_factor=2.0\n        model = MobileNetV2(widen_factor=2.0)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size((1, 2560, 7, 7)))\n\n        # Test MobileNetV2 forward with out_indices=None\n        model = MobileNetV2(widen_factor=1.0)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size((1, 1280, 7, 7)))\n\n        # Test MobileNetV2 forward with dict(type='ReLU')\n        model = MobileNetV2(\n            widen_factor=1.0,\n            act_cfg=dict(type='ReLU'),\n            out_indices=range(0, 7))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 7)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 24, 56, 56)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 32, 28, 28)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 64, 14, 14)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 96, 14, 14)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 160, 7, 7)))\n        self.assertEqual(feat[6].shape, torch.Size((1, 320, 7, 7)))\n\n        # Test MobileNetV2 with GroupNorm forward\n        model = MobileNetV2(widen_factor=1.0, out_indices=range(0, 7))\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 7)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 24, 56, 56)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 32, 28, 28)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 64, 14, 14)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 96, 14, 14)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 160, 7, 7)))\n        self.assertEqual(feat[6].shape, torch.Size((1, 320, 7, 7)))\n\n        # Test MobileNetV2 with BatchNorm forward\n        model = MobileNetV2(\n            widen_factor=1.0,\n            norm_cfg=dict(type='GN', num_groups=2, requires_grad=True),\n            out_indices=range(0, 7))\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, GroupNorm)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 7)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 24, 56, 56)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 32, 28, 28)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 64, 14, 14)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 96, 14, 14)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 160, 7, 7)))\n        self.assertEqual(feat[6].shape, torch.Size((1, 320, 7, 7)))\n\n        # Test MobileNetV2 with layers 1, 3, 5 out forward\n        model = MobileNetV2(widen_factor=1.0, out_indices=(0, 2, 4))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 32, 28, 28)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 96, 14, 14)))\n\n        # Test MobileNetV2 with checkpoint forward\n        model = MobileNetV2(\n            widen_factor=1.0, with_cp=True, out_indices=range(0, 7))\n        for m in model.modules():\n            if self.is_block(m):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 7)\n        self.assertEqual(feat[0].shape, torch.Size((1, 16, 112, 112)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 24, 56, 56)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 32, 28, 28)))\n        self.assertEqual(feat[3].shape, torch.Size((1, 64, 14, 14)))\n        self.assertEqual(feat[4].shape, torch.Size((1, 96, 14, 14)))\n        self.assertEqual(feat[5].shape, torch.Size((1, 160, 7, 7)))\n        self.assertEqual(feat[6].shape, torch.Size((1, 320, 7, 7)))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_mobilenet_v3.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import MobileNetV3\nfrom mmpose.models.backbones.utils import InvertedResidual\n\n\nclass TestMobilenetV3(TestCase):\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (GroupNorm, _BatchNorm)):\n            return True\n        return False\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_mobilenetv3_backbone(self):\n        with self.assertRaises(AssertionError):\n            # arch must in [small, big]\n            MobileNetV3(arch='others')\n\n        with self.assertRaises(ValueError):\n            # frozen_stages must less than 12 when arch is small\n            MobileNetV3(arch='small', frozen_stages=12)\n\n        with self.assertRaises(ValueError):\n            # frozen_stages must less than 16 when arch is big\n            MobileNetV3(arch='big', frozen_stages=16)\n\n        with self.assertRaises(ValueError):\n            # max out_indices must less than 11 when arch is small\n            MobileNetV3(arch='small', out_indices=(11, ))\n\n        with self.assertRaises(ValueError):\n            # max out_indices must less than 15 when arch is big\n            MobileNetV3(arch='big', out_indices=(15, ))\n\n        # Test MobileNetv3\n        model = MobileNetV3()\n        model.init_weights()\n        model.train()\n\n        # Test MobileNetv3 with first stage frozen\n        frozen_stages = 1\n        model = MobileNetV3(frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        for param in model.conv1.parameters():\n            self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test MobileNetv3 with norm eval\n        model = MobileNetV3(norm_eval=True, out_indices=range(0, 11))\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test MobileNetv3 forward with small arch\n        model = MobileNetV3(out_indices=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 11)\n        self.assertEqual(feat[0].shape, torch.Size([1, 16, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 24, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 24, 28, 28]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 40, 14, 14]))\n        self.assertEqual(feat[4].shape, torch.Size([1, 40, 14, 14]))\n        self.assertEqual(feat[5].shape, torch.Size([1, 40, 14, 14]))\n        self.assertEqual(feat[6].shape, torch.Size([1, 48, 14, 14]))\n        self.assertEqual(feat[7].shape, torch.Size([1, 48, 14, 14]))\n        self.assertEqual(feat[8].shape, torch.Size([1, 96, 7, 7]))\n        self.assertEqual(feat[9].shape, torch.Size([1, 96, 7, 7]))\n        self.assertEqual(feat[10].shape, torch.Size([1, 96, 7, 7]))\n\n        # Test MobileNetv3 forward with small arch and GroupNorm\n        model = MobileNetV3(\n            out_indices=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10),\n            norm_cfg=dict(type='GN', num_groups=2, requires_grad=True))\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, GroupNorm)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 11)\n        self.assertEqual(feat[0].shape, torch.Size([1, 16, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 24, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 24, 28, 28]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 40, 14, 14]))\n        self.assertEqual(feat[4].shape, torch.Size([1, 40, 14, 14]))\n        self.assertEqual(feat[5].shape, torch.Size([1, 40, 14, 14]))\n        self.assertEqual(feat[6].shape, torch.Size([1, 48, 14, 14]))\n        self.assertEqual(feat[7].shape, torch.Size([1, 48, 14, 14]))\n        self.assertEqual(feat[8].shape, torch.Size([1, 96, 7, 7]))\n        self.assertEqual(feat[9].shape, torch.Size([1, 96, 7, 7]))\n        self.assertEqual(feat[10].shape, torch.Size([1, 96, 7, 7]))\n\n        # Test MobileNetv3 forward with big arch\n        model = MobileNetV3(\n            arch='big',\n            out_indices=(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 15)\n        self.assertEqual(feat[0].shape, torch.Size([1, 16, 112, 112]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 24, 56, 56]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 24, 56, 56]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 40, 28, 28]))\n        self.assertEqual(feat[4].shape, torch.Size([1, 40, 28, 28]))\n        self.assertEqual(feat[5].shape, torch.Size([1, 40, 28, 28]))\n        self.assertEqual(feat[6].shape, torch.Size([1, 80, 14, 14]))\n        self.assertEqual(feat[7].shape, torch.Size([1, 80, 14, 14]))\n        self.assertEqual(feat[8].shape, torch.Size([1, 80, 14, 14]))\n        self.assertEqual(feat[9].shape, torch.Size([1, 80, 14, 14]))\n        self.assertEqual(feat[10].shape, torch.Size([1, 112, 14, 14]))\n        self.assertEqual(feat[11].shape, torch.Size([1, 112, 14, 14]))\n        self.assertEqual(feat[12].shape, torch.Size([1, 160, 14, 14]))\n        self.assertEqual(feat[13].shape, torch.Size([1, 160, 7, 7]))\n        self.assertEqual(feat[14].shape, torch.Size([1, 160, 7, 7]))\n\n        # Test MobileNetv3 forward with big arch\n        model = MobileNetV3(arch='big', out_indices=(0, ))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 16, 112, 112]))\n\n        # Test MobileNetv3 with checkpoint forward\n        model = MobileNetV3(with_cp=True)\n        for m in model.modules():\n            if isinstance(m, InvertedResidual):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 96, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_mspn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import MSPN\n\n\nclass TestMSPN(TestCase):\n\n    def test_mspn_backbone(self):\n        with self.assertRaises(AssertionError):\n            # MSPN's num_stages should larger than 0\n            MSPN(num_stages=0)\n        with self.assertRaises(AssertionError):\n            # MSPN's num_units should larger than 1\n            MSPN(num_units=1)\n        with self.assertRaises(AssertionError):\n            # len(num_blocks) should equal num_units\n            MSPN(num_units=2, num_blocks=[2, 2, 2])\n\n        # Test MSPN's outputs\n        model = MSPN(num_stages=2, num_units=2, num_blocks=[2, 2])\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 511, 511)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(len(feat[0]), 2)\n        self.assertEqual(len(feat[1]), 2)\n        self.assertEqual(feat[0][0].shape, torch.Size([1, 256, 64, 64]))\n        self.assertEqual(feat[0][1].shape, torch.Size([1, 256, 128, 128]))\n        self.assertEqual(feat[1][0].shape, torch.Size([1, 256, 64, 64]))\n        self.assertEqual(feat[1][1].shape, torch.Size([1, 256, 128, 128]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_pvt.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones.pvt import (PVTEncoderLayer,\n                                         PyramidVisionTransformer,\n                                         PyramidVisionTransformerV2)\n\n\nclass TestPVT(TestCase):\n\n    def test_pvt_block(self):\n        # test PVT structure and forward\n        block = PVTEncoderLayer(\n            embed_dims=64, num_heads=4, feedforward_channels=256)\n        self.assertEqual(block.ffn.embed_dims, 64)\n        self.assertEqual(block.attn.num_heads, 4)\n        self.assertEqual(block.ffn.feedforward_channels, 256)\n        x = torch.randn(1, 56 * 56, 64)\n        x_out = block(x, (56, 56))\n        self.assertEqual(x_out.shape, torch.Size([1, 56 * 56, 64]))\n\n    def test_pvt(self):\n        \"\"\"Test PVT backbone.\"\"\"\n\n        # test pretrained image size\n        with self.assertRaises(AssertionError):\n            PyramidVisionTransformer(pretrain_img_size=(224, 224, 224))\n\n        # test padding\n        model = PyramidVisionTransformer(\n            paddings=['corner', 'corner', 'corner', 'corner'])\n        temp = torch.randn((1, 3, 32, 32))\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 128, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 320, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 512, 1, 1))\n\n        # Test absolute position embedding\n        temp = torch.randn((1, 3, 224, 224))\n        model = PyramidVisionTransformer(\n            pretrain_img_size=224, use_abs_pos_embed=True)\n        model.init_weights()\n        model(temp)\n\n        # Test normal inference\n        temp = torch.randn((1, 3, 32, 32))\n        model = PyramidVisionTransformer()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 128, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 320, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 512, 1, 1))\n\n        # Test abnormal inference size\n        temp = torch.randn((1, 3, 33, 33))\n        model = PyramidVisionTransformer()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 128, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 320, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 512, 1, 1))\n\n        # Test abnormal inference size\n        temp = torch.randn((1, 3, 112, 137))\n        model = PyramidVisionTransformer()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 28, 34))\n        self.assertEqual(outs[1].shape, (1, 128, 14, 17))\n        self.assertEqual(outs[2].shape, (1, 320, 7, 8))\n        self.assertEqual(outs[3].shape, (1, 512, 3, 4))\n\n    def test_pvtv2(self):\n        \"\"\"Test PVTv2 backbone.\"\"\"\n\n        with self.assertRaises(TypeError):\n            # Pretrained arg must be str or None.\n            PyramidVisionTransformerV2(pretrained=123)\n\n        # test pretrained image size\n        with self.assertRaises(AssertionError):\n            PyramidVisionTransformerV2(pretrain_img_size=(224, 224, 224))\n\n        # test init_cfg with pretrained model\n        model = PyramidVisionTransformerV2(\n            embed_dims=32,\n            num_layers=[2, 2, 2, 2],\n            init_cfg=dict(\n                type='Pretrained',\n                checkpoint='https://github.com/whai362/PVT/'\n                'releases/download/v2/pvt_v2_b0.pth'))\n        model.init_weights()\n\n        # test init weights from scratch\n        model = PyramidVisionTransformerV2(\n            embed_dims=32, num_layers=[2, 2, 2, 2])\n        model.init_weights()\n\n        # Test normal inference\n        temp = torch.randn((1, 3, 32, 32))\n        model = PyramidVisionTransformerV2()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 128, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 320, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 512, 1, 1))\n\n        # Test abnormal inference size\n        temp = torch.randn((1, 3, 31, 31))\n        model = PyramidVisionTransformerV2()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 128, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 320, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 512, 1, 1))\n\n        # Test abnormal inference size\n        temp = torch.randn((1, 3, 112, 137))\n        model = PyramidVisionTransformerV2()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 64, 28, 35))\n        self.assertEqual(outs[1].shape, (1, 128, 14, 18))\n        self.assertEqual(outs[2].shape, (1, 320, 7, 9))\n        self.assertEqual(outs[3].shape, (1, 512, 4, 5))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_regnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import RegNet\n\n\nclass TestRegnet(TestCase):\n\n    regnet_test_data = [\n        ('regnetx_400mf',\n         dict(w0=24, wa=24.48, wm=2.54, group_w=16, depth=22,\n              bot_mul=1.0), [32, 64, 160, 384]),\n        ('regnetx_800mf',\n         dict(w0=56, wa=35.73, wm=2.28, group_w=16, depth=16,\n              bot_mul=1.0), [64, 128, 288, 672]),\n        ('regnetx_1.6gf',\n         dict(w0=80, wa=34.01, wm=2.25, group_w=24, depth=18,\n              bot_mul=1.0), [72, 168, 408, 912]),\n        ('regnetx_3.2gf',\n         dict(w0=88, wa=26.31, wm=2.25, group_w=48, depth=25,\n              bot_mul=1.0), [96, 192, 432, 1008]),\n        ('regnetx_4.0gf',\n         dict(w0=96, wa=38.65, wm=2.43, group_w=40, depth=23,\n              bot_mul=1.0), [80, 240, 560, 1360]),\n        ('regnetx_6.4gf',\n         dict(w0=184, wa=60.83, wm=2.07, group_w=56, depth=17,\n              bot_mul=1.0), [168, 392, 784, 1624]),\n        ('regnetx_8.0gf',\n         dict(w0=80, wa=49.56, wm=2.88, group_w=120, depth=23,\n              bot_mul=1.0), [80, 240, 720, 1920]),\n        ('regnetx_12gf',\n         dict(w0=168, wa=73.36, wm=2.37, group_w=112, depth=19,\n              bot_mul=1.0), [224, 448, 896, 2240]),\n    ]\n\n    def _test_regnet_backbone(self, arch_name, arch, out_channels):\n        with self.assertRaises(AssertionError):\n            # ResNeXt depth should be in [50, 101, 152]\n            RegNet(arch_name + '233')\n\n        # output the last feature map\n        model = RegNet(arch_name)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, (1, out_channels[-1], 7, 7))\n\n        # output feature map of all stages\n        model = RegNet(arch_name, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, out_channels[0], 56, 56))\n        self.assertEqual(feat[1].shape, (1, out_channels[1], 28, 28))\n        self.assertEqual(feat[2].shape, (1, out_channels[2], 14, 14))\n        self.assertEqual(feat[3].shape, (1, out_channels[3], 7, 7))\n\n    def test_regnet_backbone(self):\n        for arch_name, arch, out_channels in self.regnet_test_data:\n            with self.subTest(\n                    arch_name=arch_name, arch=arch, out_channels=out_channels):\n                self._test_regnet_backbone(arch_name, arch, out_channels)\n\n    def _test_custom_arch(self, arch_name, arch, out_channels):\n        # output the last feature map\n        model = RegNet(arch)\n        model.init_weights()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, (1, out_channels[-1], 7, 7))\n\n        # output feature map of all stages\n        model = RegNet(arch, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, out_channels[0], 56, 56))\n        self.assertEqual(feat[1].shape, (1, out_channels[1], 28, 28))\n        self.assertEqual(feat[2].shape, (1, out_channels[2], 14, 14))\n        self.assertEqual(feat[3].shape, (1, out_channels[3], 7, 7))\n\n    def test_custom_arch(self):\n        for arch_name, arch, out_channels in self.regnet_test_data:\n            with self.subTest(\n                    arch_name=arch_name, arch=arch, out_channels=out_channels):\n                self._test_custom_arch(arch_name, arch, out_channels)\n\n    def test_exception(self):\n        # arch must be a str or dict\n        with self.assertRaises(TypeError):\n            _ = RegNet(50)\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_resnest.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import ResNeSt\nfrom mmpose.models.backbones.resnest import Bottleneck as BottleneckS\n\n\nclass TestResnest(TestCase):\n\n    def test_bottleneck(self):\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            BottleneckS(\n                64, 64, radix=2, reduction_factor=4, style='tensorflow')\n\n        # Test ResNeSt Bottleneck structure\n        block = BottleneckS(\n            64, 256, radix=2, reduction_factor=4, stride=2, style='pytorch')\n        self.assertEqual(block.avd_layer.stride, 2)\n        self.assertEqual(block.conv2.channels, 64)\n\n        # Test ResNeSt Bottleneck forward\n        block = BottleneckS(64, 64, radix=2, reduction_factor=4)\n        x = torch.randn(2, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 64, 56, 56]))\n\n    def test_resnest(self):\n        with self.assertRaises(KeyError):\n            # ResNeSt depth should be in [50, 101, 152, 200]\n            ResNeSt(depth=18)\n\n        # Test ResNeSt with radix 2, reduction_factor 4\n        model = ResNeSt(\n            depth=50, radix=2, reduction_factor=4, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([2, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([2, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([2, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([2, 2048, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_resnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nimport torch.nn as nn\nfrom mmcv.cnn import ConvModule\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm\n\nfrom mmpose.models.backbones import ResNet, ResNetV1d\nfrom mmpose.models.backbones.resnet import (BasicBlock, Bottleneck, ResLayer,\n                                            get_expansion)\n\n\nclass TestResnet(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is ResNet building block.\"\"\"\n        if isinstance(modules, (BasicBlock, Bottleneck)):\n            return True\n        return False\n\n    @staticmethod\n    def all_zeros(modules):\n        \"\"\"Check if the weight(and bias) is all zero.\"\"\"\n        weight_zero = torch.equal(modules.weight.data,\n                                  torch.zeros_like(modules.weight.data))\n        if hasattr(modules, 'bias'):\n            bias_zero = torch.equal(modules.bias.data,\n                                    torch.zeros_like(modules.bias.data))\n        else:\n            bias_zero = True\n\n        return weight_zero and bias_zero\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_get_expansion(self):\n        self.assertEqual(get_expansion(Bottleneck, 2), 2)\n        self.assertEqual(get_expansion(BasicBlock), 1)\n        self.assertEqual(get_expansion(Bottleneck), 4)\n\n        class MyResBlock(nn.Module):\n\n            expansion = 8\n\n        self.assertEqual(get_expansion(MyResBlock), 8)\n\n        # expansion must be an integer or None\n        with self.assertRaises(TypeError):\n            get_expansion(Bottleneck, '0')\n\n        # expansion is not specified and cannot be inferred\n        with self.assertRaises(TypeError):\n\n            class SomeModule(nn.Module):\n                pass\n\n            get_expansion(SomeModule)\n\n    def test_basic_block(self):\n        # expansion must be 1\n        with self.assertRaises(AssertionError):\n            BasicBlock(64, 64, expansion=2)\n\n        # BasicBlock with stride 1, out_channels == in_channels\n        block = BasicBlock(64, 64)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 64)\n        self.assertEqual(block.out_channels, 64)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 64)\n        self.assertEqual(block.conv1.kernel_size, (3, 3))\n        self.assertEqual(block.conv1.stride, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 64)\n        self.assertEqual(block.conv2.out_channels, 64)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n        # BasicBlock with stride 1 and downsample\n        downsample = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=1, bias=False), nn.BatchNorm2d(128))\n        block = BasicBlock(64, 128, downsample=downsample)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 128)\n        self.assertEqual(block.out_channels, 128)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 128)\n        self.assertEqual(block.conv1.kernel_size, (3, 3))\n        self.assertEqual(block.conv1.stride, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 128)\n        self.assertEqual(block.conv2.out_channels, 128)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 128, 56, 56]))\n\n        # BasicBlock with stride 2 and downsample\n        downsample = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=1, stride=2, bias=False),\n            nn.BatchNorm2d(128))\n        block = BasicBlock(64, 128, stride=2, downsample=downsample)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 128)\n        self.assertEqual(block.out_channels, 128)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 128)\n        self.assertEqual(block.conv1.kernel_size, (3, 3))\n        self.assertEqual(block.conv1.stride, (2, 2))\n        self.assertEqual(block.conv2.in_channels, 128)\n        self.assertEqual(block.conv2.out_channels, 128)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 128, 28, 28]))\n\n        # forward with checkpointing\n        block = BasicBlock(64, 64, with_cp=True)\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 64, 56, 56, requires_grad=True)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_bottleneck(self):\n        # style must be in ['pytorch', 'caffe']\n        with self.assertRaises(AssertionError):\n            Bottleneck(64, 64, style='tensorflow')\n\n        # expansion must be divisible by out_channels\n        with self.assertRaises(AssertionError):\n            Bottleneck(64, 64, expansion=3)\n\n        # Test Bottleneck style\n        block = Bottleneck(64, 64, stride=2, style='pytorch')\n        self.assertEqual(block.conv1.stride, (1, 1))\n        self.assertEqual(block.conv2.stride, (2, 2))\n        block = Bottleneck(64, 64, stride=2, style='caffe')\n        self.assertEqual(block.conv1.stride, (2, 2))\n        self.assertEqual(block.conv2.stride, (1, 1))\n\n        # Bottleneck with stride 1\n        block = Bottleneck(64, 64, style='pytorch')\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 16)\n        self.assertEqual(block.out_channels, 64)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 16)\n        self.assertEqual(block.conv1.kernel_size, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 16)\n        self.assertEqual(block.conv2.out_channels, 16)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        self.assertEqual(block.conv3.in_channels, 16)\n        self.assertEqual(block.conv3.out_channels, 64)\n        self.assertEqual(block.conv3.kernel_size, (1, 1))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # Bottleneck with stride 1 and downsample\n        downsample = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=1), nn.BatchNorm2d(128))\n        block = Bottleneck(64, 128, style='pytorch', downsample=downsample)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 32)\n        self.assertEqual(block.out_channels, 128)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 32)\n        self.assertEqual(block.conv1.kernel_size, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 32)\n        self.assertEqual(block.conv2.out_channels, 32)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        self.assertEqual(block.conv3.in_channels, 32)\n        self.assertEqual(block.conv3.out_channels, 128)\n        self.assertEqual(block.conv3.kernel_size, (1, 1))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 128, 56, 56))\n\n        # Bottleneck with stride 2 and downsample\n        downsample = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=1, stride=2), nn.BatchNorm2d(128))\n        block = Bottleneck(\n            64, 128, stride=2, style='pytorch', downsample=downsample)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 128, 28, 28))\n\n        # Bottleneck with expansion 2\n        block = Bottleneck(64, 64, style='pytorch', expansion=2)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 32)\n        self.assertEqual(block.out_channels, 64)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 32)\n        self.assertEqual(block.conv1.kernel_size, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 32)\n        self.assertEqual(block.conv2.out_channels, 32)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        self.assertEqual(block.conv3.in_channels, 32)\n        self.assertEqual(block.conv3.out_channels, 64)\n        self.assertEqual(block.conv3.kernel_size, (1, 1))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # Test Bottleneck with checkpointing\n        block = Bottleneck(64, 64, with_cp=True)\n        block.train()\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 64, 56, 56, requires_grad=True)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_basicblock_reslayer(self):\n        # 3 BasicBlock w/o downsample\n        layer = ResLayer(BasicBlock, 3, 32, 32)\n        self.assertEqual(len(layer), 3)\n        for i in range(3):\n            self.assertEqual(layer[i].in_channels, 32)\n            self.assertEqual(layer[i].out_channels, 32)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 32, 56, 56))\n\n        # 3 BasicBlock w/ stride 1 and downsample\n        layer = ResLayer(BasicBlock, 3, 32, 64)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 2)\n        self.assertIsInstance(layer[0].downsample[0], nn.Conv2d)\n        self.assertEqual(layer[0].downsample[0].stride, (1, 1))\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # 3 BasicBlock w/ stride 2 and downsample\n        layer = ResLayer(BasicBlock, 3, 32, 64, stride=2)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 2)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 2)\n        self.assertIsInstance(layer[0].downsample[0], nn.Conv2d)\n        self.assertEqual(layer[0].downsample[0].stride, (2, 2))\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 28, 28))\n\n        # 3 BasicBlock w/ stride 2 and downsample with avg pool\n        layer = ResLayer(BasicBlock, 3, 32, 64, stride=2, avg_down=True)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 2)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 3)\n        self.assertIsInstance(layer[0].downsample[0], nn.AvgPool2d)\n        self.assertEqual(layer[0].downsample[0].stride, 2)\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 28, 28))\n\n    def test_bottleneck_reslayer(self):\n        # 3 Bottleneck w/o downsample\n        layer = ResLayer(Bottleneck, 3, 32, 32)\n        self.assertEqual(len(layer), 3)\n        for i in range(3):\n            self.assertEqual(layer[i].in_channels, 32)\n            self.assertEqual(layer[i].out_channels, 32)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 32, 56, 56))\n\n        # 3 Bottleneck w/ stride 1 and downsample\n        layer = ResLayer(Bottleneck, 3, 32, 64)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 1)\n        self.assertEqual(layer[0].conv1.out_channels, 16)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 2)\n        self.assertIsInstance(layer[0].downsample[0], nn.Conv2d)\n        self.assertEqual(layer[0].downsample[0].stride, (1, 1))\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 16)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # 3 Bottleneck w/ stride 2 and downsample\n        layer = ResLayer(Bottleneck, 3, 32, 64, stride=2)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 2)\n        self.assertEqual(layer[0].conv1.out_channels, 16)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 2)\n        self.assertIsInstance(layer[0].downsample[0], nn.Conv2d)\n        self.assertEqual(layer[0].downsample[0].stride, (2, 2))\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 16)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 28, 28))\n\n        # 3 Bottleneck w/ stride 2 and downsample with avg pool\n        layer = ResLayer(Bottleneck, 3, 32, 64, stride=2, avg_down=True)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 2)\n        self.assertEqual(layer[0].conv1.out_channels, 16)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 3)\n        self.assertIsInstance(layer[0].downsample[0], nn.AvgPool2d)\n        self.assertEqual(layer[0].downsample[0].stride, 2)\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 16)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 28, 28))\n\n        # 3 Bottleneck with custom expansion\n        layer = ResLayer(Bottleneck, 3, 32, 32, expansion=2)\n        self.assertEqual(len(layer), 3)\n        for i in range(3):\n            self.assertEqual(layer[i].in_channels, 32)\n            self.assertEqual(layer[i].out_channels, 32)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertEqual(layer[i].conv1.out_channels, 16)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 32, 56, 56))\n\n    def test_resnet(self):\n        \"\"\"Test resnet backbone.\"\"\"\n        with self.assertRaises(KeyError):\n            # ResNet depth should be in [18, 34, 50, 101, 152]\n            ResNet(20)\n\n        with self.assertRaises(AssertionError):\n            # In ResNet: 1 <= num_stages <= 4\n            ResNet(50, num_stages=0)\n\n        with self.assertRaises(AssertionError):\n            # In ResNet: 1 <= num_stages <= 4\n            ResNet(50, num_stages=5)\n\n        with self.assertRaises(AssertionError):\n            # len(strides) == len(dilations) == num_stages\n            ResNet(50, strides=(1, ), dilations=(1, 1), num_stages=3)\n\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            ResNet(50, style='tensorflow')\n\n        # Test ResNet50 norm_eval=True\n        model = ResNet(50, norm_eval=True)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test ResNet50 with torchvision pretrained weight\n        init_cfg = dict(type='Pretrained', checkpoint='torchvision://resnet50')\n        model = ResNet(depth=50, norm_eval=True, init_cfg=init_cfg)\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test ResNet50 with first stage frozen\n        frozen_stages = 1\n        model = ResNet(50, frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        self.assertFalse(model.norm1.training)\n        for layer in [model.conv1, model.norm1]:\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test ResNet18 forward\n        model = ResNet(18, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 64, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 128, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 256, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 512, 7, 7))\n\n        # Test ResNet50 with BatchNorm forward\n        model = ResNet(50, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 256, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 512, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 1024, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 2048, 7, 7))\n\n        # Test ResNet50 with layers 1, 2, 3 out forward\n        model = ResNet(50, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, (1, 256, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 512, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 1024, 14, 14))\n\n        # Test ResNet50 with layers 3 (top feature maps) out forward\n        model = ResNet(50, out_indices=(3, ))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[-1].shape, (1, 2048, 7, 7))\n\n        # Test ResNet50 with checkpoint forward\n        model = ResNet(50, out_indices=(0, 1, 2, 3), with_cp=True)\n        for m in model.modules():\n            if self.is_block(m):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 256, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 512, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 1024, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 2048, 7, 7))\n\n        # zero initialization of residual blocks\n        model = ResNet(50, out_indices=(0, 1, 2, 3), zero_init_residual=True)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, Bottleneck):\n                self.assertTrue(self.all_zeros(m.norm3))\n            elif isinstance(m, BasicBlock):\n                self.assertTrue(self.all_zeros(m.norm2))\n\n        # non-zero initialization of residual blocks\n        model = ResNet(50, out_indices=(0, 1, 2, 3), zero_init_residual=False)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, Bottleneck):\n                self.assertFalse(self.all_zeros(m.norm3))\n            elif isinstance(m, BasicBlock):\n                self.assertFalse(self.all_zeros(m.norm2))\n\n    def test_resnet_v1d(self):\n        model = ResNetV1d(depth=50, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        self.assertEqual(len(model.stem), 3)\n        for i in range(3):\n            self.assertIsInstance(model.stem[i], ConvModule)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model.stem(imgs)\n        self.assertEqual(feat.shape, (1, 64, 112, 112))\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 256, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 512, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 1024, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 2048, 7, 7))\n\n        # Test ResNet50V1d with first stage frozen\n        frozen_stages = 1\n        model = ResNetV1d(depth=50, frozen_stages=frozen_stages)\n        self.assertEqual(len(model.stem), 3)\n        for i in range(3):\n            self.assertIsInstance(model.stem[i], ConvModule)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.stem, False))\n        for param in model.stem.parameters():\n            self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n    def test_resnet_half_channel(self):\n        model = ResNet(50, base_channels=32, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 128, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 256, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 512, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 1024, 7, 7))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_resnext.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import ResNeXt\nfrom mmpose.models.backbones.resnext import Bottleneck as BottleneckX\n\n\nclass TestResnext(TestCase):\n\n    def test_bottleneck(self):\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            BottleneckX(\n                64, 64, groups=32, width_per_group=4, style='tensorflow')\n\n        # Test ResNeXt Bottleneck structure\n        block = BottleneckX(\n            64, 256, groups=32, width_per_group=4, stride=2, style='pytorch')\n        self.assertEqual(block.conv2.stride, (2, 2))\n        self.assertEqual(block.conv2.groups, 32)\n        self.assertEqual(block.conv2.out_channels, 128)\n\n        # Test ResNeXt Bottleneck forward\n        block = BottleneckX(\n            64, 64, base_channels=16, groups=32, width_per_group=4)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_resnext(self):\n        with self.assertRaises(KeyError):\n            # ResNeXt depth should be in [50, 101, 152]\n            ResNeXt(depth=18)\n\n        # Test ResNeXt with group 32, width_per_group 4\n        model = ResNeXt(\n            depth=50, groups=32, width_per_group=4, out_indices=(0, 1, 2, 3))\n        for m in model.modules():\n            if isinstance(m, BottleneckX):\n                self.assertEqual(m.conv2.groups, 32)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 2048, 7, 7]))\n\n        # Test ResNeXt with layers 3 out forward\n        model = ResNeXt(\n            depth=50, groups=32, width_per_group=4, out_indices=(3, ))\n        for m in model.modules():\n            if isinstance(m, BottleneckX):\n                self.assertEqual(m.conv2.groups, 32)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 2048, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_rsn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import RSN\n\n\nclass TestRSN(TestCase):\n\n    def test_rsn_backbone(self):\n        with self.assertRaises(AssertionError):\n            # RSN's num_stages should larger than 0\n            RSN(num_stages=0)\n        with self.assertRaises(AssertionError):\n            # RSN's num_steps should larger than 1\n            RSN(num_steps=1)\n        with self.assertRaises(AssertionError):\n            # RSN's num_units should larger than 1\n            RSN(num_units=1)\n        with self.assertRaises(AssertionError):\n            # len(num_blocks) should equal num_units\n            RSN(num_units=2, num_blocks=[2, 2, 2])\n\n        # Test RSN's outputs\n        model = RSN(num_stages=2, num_units=2, num_blocks=[2, 2])\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 511, 511)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(len(feat[0]), 2)\n        self.assertEqual(len(feat[1]), 2)\n        self.assertEqual(feat[0][0].shape, torch.Size([1, 256, 64, 64]))\n        self.assertEqual(feat[0][1].shape, torch.Size([1, 256, 128, 128]))\n        self.assertEqual(feat[1][0].shape, torch.Size([1, 256, 64, 64]))\n        self.assertEqual(feat[1][1].shape, torch.Size([1, 256, 128, 128]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_scnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import SCNet\nfrom mmpose.models.backbones.scnet import SCBottleneck, SCConv\n\n\nclass TestSCnet(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is SCNet building block.\"\"\"\n        if isinstance(modules, (SCBottleneck, )):\n            return True\n        return False\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (_BatchNorm, )):\n            return True\n        return False\n\n    @staticmethod\n    def all_zeros(modules):\n        \"\"\"Check if the weight(and bias) is all zero.\"\"\"\n        weight_zero = torch.equal(modules.weight.data,\n                                  torch.zeros_like(modules.weight.data))\n        if hasattr(modules, 'bias'):\n            bias_zero = torch.equal(modules.bias.data,\n                                    torch.zeros_like(modules.bias.data))\n        else:\n            bias_zero = True\n\n        return weight_zero and bias_zero\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_scnet_scconv(self):\n        # Test scconv forward\n        layer = SCConv(64, 64, 1, 4)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_scnet_bottleneck(self):\n        # Test Bottleneck forward\n        block = SCBottleneck(64, 64)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_scnet_backbone(self):\n        \"\"\"Test scnet backbone.\"\"\"\n        with self.assertRaises(KeyError):\n            # SCNet depth should be in [50, 101]\n            SCNet(20)\n\n        with self.assertRaises(TypeError):\n            # pretrained must be a string path\n            model = SCNet(50)\n            model.init_weights(pretrained=0)\n\n        # Test SCNet norm_eval=True\n        model = SCNet(50, norm_eval=True)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test SCNet50 with first stage frozen\n        frozen_stages = 1\n        model = SCNet(50, frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        self.assertFalse(model.norm1.training)\n        for layer in [model.conv1, model.norm1]:\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test SCNet with BatchNorm forward\n        model = SCNet(50, out_indices=(0, 1, 2, 3))\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([2, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([2, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([2, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([2, 2048, 7, 7]))\n\n        # Test SCNet with layers 1, 2, 3 out forward\n        model = SCNet(50, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size([2, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([2, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([2, 1024, 14, 14]))\n\n        # Test SEResNet50 with layers 3 (top feature maps) out forward\n        model = SCNet(50, out_indices=(3, ))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([2, 2048, 7, 7]))\n\n        # Test SEResNet50 with checkpoint forward\n        model = SCNet(50, out_indices=(0, 1, 2, 3), with_cp=True)\n        for m in model.modules():\n            if self.is_block(m):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([2, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([2, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([2, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([2, 2048, 7, 7]))\n\n        # Test SCNet zero initialization of residual\n        model = SCNet(50, out_indices=(0, 1, 2, 3), zero_init_residual=True)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, SCBottleneck):\n                self.assertTrue(self.all_zeros(m.norm3))\n        model.train()\n\n        imgs = torch.randn(2, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([2, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([2, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([2, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([2, 2048, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_seresnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import AvgPool2d\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import SEResNet\nfrom mmpose.models.backbones.resnet import ResLayer\nfrom mmpose.models.backbones.seresnet import SEBottleneck, SELayer\n\n\nclass TestSEResnet(TestCase):\n\n    @staticmethod\n    def all_zeros(modules):\n        \"\"\"Check if the weight(and bias) is all zero.\"\"\"\n        weight_zero = torch.equal(modules.weight.data,\n                                  torch.zeros_like(modules.weight.data))\n        if hasattr(modules, 'bias'):\n            bias_zero = torch.equal(modules.bias.data,\n                                    torch.zeros_like(modules.bias.data))\n        else:\n            bias_zero = True\n\n        return weight_zero and bias_zero\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_selayer(self):\n        # Test selayer forward\n        layer = SELayer(64)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n        # Test selayer forward with different ratio\n        layer = SELayer(64, ratio=8)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_bottleneck(self):\n\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            SEBottleneck(64, 64, style='tensorflow')\n\n        # Test SEBottleneck with checkpoint forward\n        block = SEBottleneck(64, 64, with_cp=True)\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n        # Test Bottleneck style\n        block = SEBottleneck(64, 256, stride=2, style='pytorch')\n        self.assertEqual(block.conv1.stride, (1, 1))\n        self.assertEqual(block.conv2.stride, (2, 2))\n        block = SEBottleneck(64, 256, stride=2, style='caffe')\n        self.assertEqual(block.conv1.stride, (2, 2))\n        self.assertEqual(block.conv2.stride, (1, 1))\n\n        # Test Bottleneck forward\n        block = SEBottleneck(64, 64)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_res_layer(self):\n        # Test ResLayer of 3 Bottleneck w\\o downsample\n        layer = ResLayer(SEBottleneck, 3, 64, 64, se_ratio=16)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].conv1.in_channels, 64)\n        self.assertEqual(layer[0].conv1.out_channels, 16)\n        for i in range(1, len(layer)):\n            self.assertEqual(layer[i].conv1.in_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 16)\n        for i in range(len(layer)):\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n        # Test ResLayer of 3 SEBottleneck with downsample\n        layer = ResLayer(SEBottleneck, 3, 64, 256, se_ratio=16)\n        self.assertEqual(layer[0].downsample[0].out_channels, 256)\n        for i in range(1, len(layer)):\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 256, 56, 56]))\n\n        # Test ResLayer of 3 SEBottleneck with stride=2\n        layer = ResLayer(SEBottleneck, 3, 64, 256, stride=2, se_ratio=8)\n        self.assertEqual(layer[0].downsample[0].out_channels, 256)\n        self.assertEqual(layer[0].downsample[0].stride, (2, 2))\n        for i in range(1, len(layer)):\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 256, 28, 28]))\n\n        # Test ResLayer of 3 SEBottleneck with stride=2 and average downsample\n        layer = ResLayer(\n            SEBottleneck, 3, 64, 256, stride=2, avg_down=True, se_ratio=8)\n        self.assertIsInstance(layer[0].downsample[0], AvgPool2d)\n        self.assertEqual(layer[0].downsample[1].out_channels, 256)\n        self.assertEqual(layer[0].downsample[1].stride, (1, 1))\n        for i in range(1, len(layer)):\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 256, 28, 28]))\n\n    def test_seresnet(self):\n        \"\"\"Test resnet backbone.\"\"\"\n        with self.assertRaises(KeyError):\n            # SEResNet depth should be in [50, 101, 152]\n            SEResNet(20)\n\n        with self.assertRaises(AssertionError):\n            # In SEResNet: 1 <= num_stages <= 4\n            SEResNet(50, num_stages=0)\n\n        with self.assertRaises(AssertionError):\n            # In SEResNet: 1 <= num_stages <= 4\n            SEResNet(50, num_stages=5)\n\n        with self.assertRaises(AssertionError):\n            # len(strides) == len(dilations) == num_stages\n            SEResNet(50, strides=(1, ), dilations=(1, 1), num_stages=3)\n\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            SEResNet(50, style='tensorflow')\n\n        # Test SEResNet50 norm_eval=True\n        model = SEResNet(50, norm_eval=True)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test SEResNet50 with torchvision pretrained weight\n        init_cfg = dict(type='Pretrained', checkpoint='torchvision://resnet50')\n        model = SEResNet(depth=50, norm_eval=True, init_cfg=init_cfg)\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test SEResNet50 with first stage frozen\n        frozen_stages = 1\n        model = SEResNet(50, frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        self.assertFalse(model.norm1.training)\n        for layer in [model.conv1, model.norm1]:\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test SEResNet50 with BatchNorm forward\n        model = SEResNet(50, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 2048, 7, 7]))\n\n        # Test SEResNet50 with layers 1, 2, 3 out forward\n        model = SEResNet(50, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 1024, 14, 14]))\n\n        # Test SEResNet50 with layers 3 (top feature maps) out forward\n        model = SEResNet(50, out_indices=(3, ))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 2048, 7, 7]))\n\n        # Test SEResNet50 with checkpoint forward\n        model = SEResNet(50, out_indices=(0, 1, 2, 3), with_cp=True)\n        for m in model.modules():\n            if isinstance(m, SEBottleneck):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 2048, 7, 7]))\n\n        # Test SEResNet50 zero initialization of residual\n        model = SEResNet(50, out_indices=(0, 1, 2, 3), zero_init_residual=True)\n        model.init_weights()\n        for m in model.modules():\n            if isinstance(m, SEBottleneck):\n                self.assertTrue(self.all_zeros(m.norm3))\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 2048, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_seresnext.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import SEResNeXt\nfrom mmpose.models.backbones.seresnext import SEBottleneck as SEBottleneckX\n\n\nclass TestSEResnext(TestCase):\n\n    def test_bottleneck(self):\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            SEBottleneckX(\n                64, 64, groups=32, width_per_group=4, style='tensorflow')\n\n        # Test SEResNeXt Bottleneck structure\n        block = SEBottleneckX(\n            64, 256, groups=32, width_per_group=4, stride=2, style='pytorch')\n        self.assertEqual(block.width_per_group, 4)\n        self.assertEqual(block.conv2.stride, (2, 2))\n        self.assertEqual(block.conv2.groups, 32)\n        self.assertEqual(block.conv2.out_channels, 128)\n        self.assertEqual(block.conv2.out_channels, block.mid_channels)\n\n        # Test SEResNeXt Bottleneck structure (groups=1)\n        block = SEBottleneckX(\n            64, 256, groups=1, width_per_group=4, stride=2, style='pytorch')\n        self.assertEqual(block.conv2.stride, (2, 2))\n        self.assertEqual(block.conv2.groups, 1)\n        self.assertEqual(block.conv2.out_channels, 64)\n        self.assertEqual(block.mid_channels, 64)\n        self.assertEqual(block.conv2.out_channels, block.mid_channels)\n\n        # Test SEResNeXt Bottleneck forward\n        block = SEBottleneckX(\n            64, 64, base_channels=16, groups=32, width_per_group=4)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_seresnext(self):\n        with self.assertRaises(KeyError):\n            # SEResNeXt depth should be in [50, 101, 152]\n            SEResNeXt(depth=18)\n\n        # Test SEResNeXt with group 32, width_per_group 4\n        model = SEResNeXt(\n            depth=50, groups=32, width_per_group=4, out_indices=(0, 1, 2, 3))\n        for m in model.modules():\n            if isinstance(m, SEBottleneckX):\n                self.assertEqual(m.conv2.groups, 32)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size([1, 256, 56, 56]))\n        self.assertEqual(feat[1].shape, torch.Size([1, 512, 28, 28]))\n        self.assertEqual(feat[2].shape, torch.Size([1, 1024, 14, 14]))\n        self.assertEqual(feat[3].shape, torch.Size([1, 2048, 7, 7]))\n\n        # Test SEResNeXt with layers 3 out forward\n        model = SEResNeXt(\n            depth=50, groups=32, width_per_group=4, out_indices=(3, ))\n        for m in model.modules():\n            if isinstance(m, SEBottleneckX):\n                self.assertEqual(m.conv2.groups, 32)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 2048, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_shufflenet_v1.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import ShuffleNetV1\nfrom mmpose.models.backbones.shufflenet_v1 import ShuffleUnit\n\n\nclass TestShufflenetV1(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is ResNet building block.\"\"\"\n        if isinstance(modules, (ShuffleUnit, )):\n            return True\n        return False\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (GroupNorm, _BatchNorm)):\n            return True\n        return False\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_shufflenetv1_shuffleuint(self):\n\n        with self.assertRaises(ValueError):\n            # combine must be in ['add', 'concat']\n            ShuffleUnit(24, 16, groups=3, first_block=True, combine='test')\n\n        with self.assertRaises(AssertionError):\n            # inplanes must be equal tp = outplanes when combine='add'\n            ShuffleUnit(64, 24, groups=4, first_block=True, combine='add')\n\n        # Test ShuffleUnit with combine='add'\n        block = ShuffleUnit(24, 24, groups=3, first_block=True, combine='add')\n        x = torch.randn(1, 24, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 24, 56, 56)))\n\n        # Test ShuffleUnit with combine='concat'\n        block = ShuffleUnit(\n            24, 240, groups=3, first_block=True, combine='concat')\n        x = torch.randn(1, 24, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 240, 28, 28)))\n\n        # Test ShuffleUnit with checkpoint forward\n        block = ShuffleUnit(\n            24, 24, groups=3, first_block=True, combine='add', with_cp=True)\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 24, 56, 56)\n        x.requires_grad = True\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 24, 56, 56)))\n\n    def test_shufflenetv1_backbone(self):\n\n        with self.assertRaises(ValueError):\n            # frozen_stages must be in  range(-1, 4)\n            ShuffleNetV1(frozen_stages=10)\n\n        with self.assertRaises(ValueError):\n            # the item in out_indices must be in  range(0, 4)\n            ShuffleNetV1(out_indices=[5])\n\n        with self.assertRaises(ValueError):\n            # groups must be in  [1, 2, 3, 4, 8]\n            ShuffleNetV1(groups=10)\n\n        # Test ShuffleNetV1 norm state\n        model = ShuffleNetV1()\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), True))\n\n        # Test ShuffleNetV1 with first stage frozen\n        frozen_stages = 1\n        model = ShuffleNetV1(\n            frozen_stages=frozen_stages, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n        for param in model.conv1.parameters():\n            self.assertFalse(param.requires_grad)\n        for i in range(frozen_stages):\n            layer = model.layers[i]\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test ShuffleNetV1 forward with groups=1\n        model = ShuffleNetV1(groups=1, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 144, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 288, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 576, 7, 7)))\n\n        # Test ShuffleNetV1 forward with groups=2\n        model = ShuffleNetV1(groups=2, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 200, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 400, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 800, 7, 7)))\n\n        # Test ShuffleNetV1 forward with groups=3\n        model = ShuffleNetV1(groups=3, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 240, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 480, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 960, 7, 7)))\n\n        # Test ShuffleNetV1 forward with groups=4\n        model = ShuffleNetV1(groups=4, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 272, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 544, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 1088, 7, 7)))\n\n        # Test ShuffleNetV1 forward with groups=8\n        model = ShuffleNetV1(groups=8, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 384, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 768, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 1536, 7, 7)))\n\n        # Test ShuffleNetV1 forward with GroupNorm forward\n        model = ShuffleNetV1(\n            groups=3,\n            norm_cfg=dict(type='GN', num_groups=2, requires_grad=True),\n            out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, GroupNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, torch.Size((1, 240, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 480, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 960, 7, 7)))\n\n        # Test ShuffleNetV1 forward with layers 1, 2 forward\n        model = ShuffleNetV1(groups=3, out_indices=(1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(feat[0].shape, torch.Size((1, 480, 14, 14)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 960, 7, 7)))\n\n        # Test ShuffleNetV1 forward with layers 2 forward\n        model = ShuffleNetV1(groups=3, out_indices=(2, ))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size((1, 960, 7, 7)))\n\n        # Test ShuffleNetV1 forward with checkpoint forward\n        model = ShuffleNetV1(groups=3, with_cp=True)\n        for m in model.modules():\n            if self.is_block(m):\n                self.assertTrue(m.with_cp)\n\n        # Test ShuffleNetV1 with norm_eval\n        model = ShuffleNetV1(norm_eval=True)\n        model.init_weights()\n        model.train()\n\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_shufflenet_v2.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import ShuffleNetV2\nfrom mmpose.models.backbones.shufflenet_v2 import InvertedResidual\n\n\nclass TestShufflenetV2(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is ResNet building block.\"\"\"\n        if isinstance(modules, (InvertedResidual, )):\n            return True\n        return False\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (GroupNorm, _BatchNorm)):\n            return True\n        return False\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_shufflenetv2_invertedresidual(self):\n\n        with self.assertRaises(AssertionError):\n            # when stride==1, in_channels should be equal to\n            # out_channels // 2 * 2\n            InvertedResidual(24, 32, stride=1)\n\n        with self.assertRaises(AssertionError):\n            # when in_channels !=  out_channels // 2 * 2, stride should not be\n            # equal to 1.\n            InvertedResidual(24, 32, stride=1)\n\n        # Test InvertedResidual forward\n        block = InvertedResidual(24, 48, stride=2)\n        x = torch.randn(1, 24, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 48, 28, 28)))\n\n        # Test InvertedResidual with checkpoint forward\n        block = InvertedResidual(48, 48, stride=1, with_cp=True)\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 48, 56, 56)\n        x.requires_grad = True\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size((1, 48, 56, 56)))\n\n    def test_shufflenetv2_backbone(self):\n\n        with self.assertRaises(ValueError):\n            # groups must be in 0.5, 1.0, 1.5, 2.0]\n            ShuffleNetV2(widen_factor=3.0)\n\n        with self.assertRaises(ValueError):\n            # frozen_stages must be in [0, 1, 2, 3]\n            ShuffleNetV2(widen_factor=1.0, frozen_stages=4)\n\n        with self.assertRaises(ValueError):\n            # out_indices must be in [0, 1, 2, 3]\n            ShuffleNetV2(widen_factor=1.0, out_indices=(4, ))\n\n        with self.assertRaises(TypeError):\n            # init_weights must have no parameter\n            model = ShuffleNetV2()\n            model.init_weights(pretrained=1)\n\n        # Test ShuffleNetV2 norm state\n        model = ShuffleNetV2()\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), True))\n\n        # Test ShuffleNetV2 with first stage frozen\n        frozen_stages = 1\n        model = ShuffleNetV2(frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        for param in model.conv1.parameters():\n            self.assertFalse(param.requires_grad)\n        for i in range(0, frozen_stages):\n            layer = model.layers[i]\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test ShuffleNetV2 with norm_eval\n        model = ShuffleNetV2(norm_eval=True)\n        model.init_weights()\n        model.train()\n\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test ShuffleNetV2 forward with widen_factor=0.5\n        model = ShuffleNetV2(widen_factor=0.5, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size((1, 48, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 96, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 192, 7, 7)))\n\n        # Test ShuffleNetV2 forward with widen_factor=1.0\n        model = ShuffleNetV2(widen_factor=1.0, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size((1, 116, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 232, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 464, 7, 7)))\n\n        # Test ShuffleNetV2 forward with widen_factor=1.5\n        model = ShuffleNetV2(widen_factor=1.5, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size((1, 176, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 352, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 704, 7, 7)))\n\n        # Test ShuffleNetV2 forward with widen_factor=2.0\n        model = ShuffleNetV2(widen_factor=2.0, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, torch.Size((1, 244, 28, 28)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 488, 14, 14)))\n        self.assertEqual(feat[2].shape, torch.Size((1, 976, 7, 7)))\n\n        # Test ShuffleNetV2 forward with layers 3 forward\n        model = ShuffleNetV2(widen_factor=1.0, out_indices=(2, ))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size((1, 464, 7, 7)))\n\n        # Test ShuffleNetV2 forward with layers 1 2 forward\n        model = ShuffleNetV2(widen_factor=1.0, out_indices=(1, 2))\n        model.init_weights()\n        model.train()\n\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, _BatchNorm)\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(feat[0].shape, torch.Size((1, 232, 14, 14)))\n        self.assertEqual(feat[1].shape, torch.Size((1, 464, 7, 7)))\n\n        # Test ShuffleNetV2 forward with checkpoint forward\n        model = ShuffleNetV2(widen_factor=1.0, with_cp=True)\n        for m in model.modules():\n            if self.is_block(m):\n                self.assertTrue(m.with_cp)\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_swin.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones.swin import SwinBlock, SwinTransformer\n\n\nclass TestSwin(TestCase):\n\n    def test_swin_block(self):\n        # test SwinBlock structure and forward\n        block = SwinBlock(embed_dims=64, num_heads=4, feedforward_channels=256)\n        self.assertEqual(block.ffn.embed_dims, 64)\n        self.assertEqual(block.attn.w_msa.num_heads, 4)\n        self.assertEqual(block.ffn.feedforward_channels, 256)\n        x = torch.randn(1, 56 * 56, 64)\n        x_out = block(x, (56, 56))\n        self.assertEqual(x_out.shape, torch.Size([1, 56 * 56, 64]))\n\n        # Test BasicBlock with checkpoint forward\n        block = SwinBlock(\n            embed_dims=64, num_heads=4, feedforward_channels=256, with_cp=True)\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 56 * 56, 64)\n        x_out = block(x, (56, 56))\n        self.assertEqual(x_out.shape, torch.Size([1, 56 * 56, 64]))\n\n    def test_swin_transformer(self):\n        \"\"\"Test Swin Transformer backbone.\"\"\"\n\n        with self.assertRaises(AssertionError):\n            # Because swin uses non-overlapping patch embed, so the stride of\n            # patch embed must be equal to patch size.\n            SwinTransformer(strides=(2, 2, 2, 2), patch_size=4)\n\n        # test pretrained image size\n        with self.assertRaises(AssertionError):\n            SwinTransformer(pretrain_img_size=(224, 224, 224))\n\n        # Test absolute position embedding\n        temp = torch.randn((1, 3, 224, 224))\n        model = SwinTransformer(pretrain_img_size=224, use_abs_pos_embed=True)\n        model.init_weights()\n        model(temp)\n\n        # Test patch norm\n        model = SwinTransformer(patch_norm=False)\n        model(temp)\n\n        # Test normal inference\n        temp = torch.randn((1, 3, 32, 32))\n        model = SwinTransformer()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 96, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 192, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 384, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 768, 1, 1))\n\n        # Test abnormal inference size\n        temp = torch.randn((1, 3, 31, 31))\n        model = SwinTransformer()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 96, 8, 8))\n        self.assertEqual(outs[1].shape, (1, 192, 4, 4))\n        self.assertEqual(outs[2].shape, (1, 384, 2, 2))\n        self.assertEqual(outs[3].shape, (1, 768, 1, 1))\n\n        # Test abnormal inference size\n        temp = torch.randn((1, 3, 112, 137))\n        model = SwinTransformer()\n        outs = model(temp)\n        self.assertEqual(outs[0].shape, (1, 96, 28, 35))\n        self.assertEqual(outs[1].shape, (1, 192, 14, 18))\n        self.assertEqual(outs[2].shape, (1, 384, 7, 9))\n        self.assertEqual(outs[3].shape, (1, 768, 4, 5))\n\n        model = SwinTransformer(frozen_stages=4)\n        model.train()\n        for p in model.parameters():\n            self.assertFalse(p.requires_grad)\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_tcn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\n\nfrom mmpose.models.backbones import TCN\nfrom mmpose.models.backbones.tcn import BasicTemporalBlock\n\n\nclass TestTCN(TestCase):\n\n    def test_basic_temporal_block(self):\n        with self.assertRaises(AssertionError):\n            # padding( + shift) should not be larger than x.shape[2]\n            block = BasicTemporalBlock(1024, 1024, dilation=81)\n            x = torch.rand(2, 1024, 150)\n            x_out = block(x)\n\n        with self.assertRaises(AssertionError):\n            # when use_stride_conv is True, shift + kernel_size // 2 should\n            # not be larger than x.shape[2]\n            block = BasicTemporalBlock(\n                1024, 1024, kernel_size=5, causal=True, use_stride_conv=True)\n            x = torch.rand(2, 1024, 3)\n            x_out = block(x)\n\n        # BasicTemporalBlock with causal == False\n        block = BasicTemporalBlock(1024, 1024)\n        x = torch.rand(2, 1024, 241)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 1024, 235]))\n\n        # BasicTemporalBlock with causal == True\n        block = BasicTemporalBlock(1024, 1024, causal=True)\n        x = torch.rand(2, 1024, 241)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 1024, 235]))\n\n        # BasicTemporalBlock with residual == False\n        block = BasicTemporalBlock(1024, 1024, residual=False)\n        x = torch.rand(2, 1024, 241)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 1024, 235]))\n\n        # BasicTemporalBlock, use_stride_conv == True\n        block = BasicTemporalBlock(1024, 1024, use_stride_conv=True)\n        x = torch.rand(2, 1024, 81)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 1024, 27]))\n\n        # BasicTemporalBlock with use_stride_conv == True and causal == True\n        block = BasicTemporalBlock(\n            1024, 1024, use_stride_conv=True, causal=True)\n        x = torch.rand(2, 1024, 81)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([2, 1024, 27]))\n\n    def test_tcn_backbone(self):\n        with self.assertRaises(AssertionError):\n            # num_blocks should equal len(kernel_sizes) - 1\n            TCN(in_channels=34, num_blocks=3, kernel_sizes=(3, 3, 3))\n\n        with self.assertRaises(AssertionError):\n            # kernel size should be odd\n            TCN(in_channels=34, kernel_sizes=(3, 4, 3))\n\n        # Test TCN with 2 blocks (use_stride_conv == False)\n        model = TCN(in_channels=34, num_blocks=2, kernel_sizes=(3, 3, 3))\n        pose2d = torch.rand((2, 34, 243))\n        feat = model(pose2d)\n        self.assertEqual(len(feat), 2)\n        self.assertEqual(feat[0].shape, (2, 1024, 235))\n        self.assertEqual(feat[1].shape, (2, 1024, 217))\n\n        # Test TCN with 4 blocks and weight norm clip\n        max_norm = 0.1\n        model = TCN(\n            in_channels=34,\n            num_blocks=4,\n            kernel_sizes=(3, 3, 3, 3, 3),\n            max_norm=max_norm)\n        pose2d = torch.rand((2, 34, 243))\n        feat = model(pose2d)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (2, 1024, 235))\n        self.assertEqual(feat[1].shape, (2, 1024, 217))\n        self.assertEqual(feat[2].shape, (2, 1024, 163))\n        self.assertEqual(feat[3].shape, (2, 1024, 1))\n\n        for module in model.modules():\n            if isinstance(module, torch.nn.modules.conv._ConvNd):\n                norm = module.weight.norm().item()\n                np.testing.assert_allclose(\n                    np.maximum(norm, max_norm), max_norm, rtol=1e-4)\n\n        # Test TCN with 4 blocks (use_stride_conv == True)\n        model = TCN(\n            in_channels=34,\n            num_blocks=4,\n            kernel_sizes=(3, 3, 3, 3, 3),\n            use_stride_conv=True)\n        pose2d = torch.rand((2, 34, 243))\n        feat = model(pose2d)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (2, 1024, 27))\n        self.assertEqual(feat[1].shape, (2, 1024, 9))\n        self.assertEqual(feat[2].shape, (2, 1024, 3))\n        self.assertEqual(feat[3].shape, (2, 1024, 1))\n\n        # Check that the model w. or w/o use_stride_conv will have the same\n        # output and gradient after a forward+backward pass\n        model1 = TCN(\n            in_channels=34,\n            stem_channels=4,\n            num_blocks=1,\n            kernel_sizes=(3, 3),\n            dropout=0,\n            residual=False,\n            norm_cfg=None)\n        model2 = TCN(\n            in_channels=34,\n            stem_channels=4,\n            num_blocks=1,\n            kernel_sizes=(3, 3),\n            dropout=0,\n            residual=False,\n            norm_cfg=None,\n            use_stride_conv=True)\n        for m in model1.modules():\n            if isinstance(m, nn.Conv1d):\n                nn.init.constant_(m.weight, 0.5)\n                if m.bias is not None:\n                    nn.init.constant_(m.bias, 0)\n        for m in model2.modules():\n            if isinstance(m, nn.Conv1d):\n                nn.init.constant_(m.weight, 0.5)\n                if m.bias is not None:\n                    nn.init.constant_(m.bias, 0)\n        input1 = torch.rand((1, 34, 9))\n        input2 = input1.clone()\n        outputs1 = model1(input1)\n        outputs2 = model2(input2)\n        for output1, output2 in zip(outputs1, outputs2):\n            self.assertTrue(torch.isclose(output1, output2).all())\n\n        criterion = nn.MSELoss()\n        target = torch.rand(output1.shape)\n        loss1 = criterion(output1, target)\n        loss2 = criterion(output2, target)\n        loss1.backward()\n        loss2.backward()\n        for m1, m2 in zip(model1.modules(), model2.modules()):\n            if isinstance(m1, nn.Conv1d):\n                self.assertTrue(\n                    torch.isclose(m1.weight.grad, m2.weight.grad).all())\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_v2v_net.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.backbones import V2VNet\n\n\nclass TestV2Vnet(TestCase):\n\n    def test_v2v_net(self):\n        \"\"\"Test V2VNet.\"\"\"\n        model = V2VNet(input_channels=17, output_channels=15)\n        input = torch.randn(2, 17, 32, 32, 32)\n        output = model(input)\n        self.assertIsInstance(output, tuple)\n        self.assertEqual(output[-1].shape, (2, 15, 32, 32, 32))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_vgg.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm\n\nfrom mmpose.models.backbones import VGG\n\n\nclass TestVGG(TestCase):\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_vgg(self):\n        \"\"\"Test VGG backbone.\"\"\"\n        with self.assertRaises(KeyError):\n            # VGG depth should be in [11, 13, 16, 19]\n            VGG(18)\n\n        with self.assertRaises(AssertionError):\n            # In VGG: 1 <= num_stages <= 5\n            VGG(11, num_stages=0)\n\n        with self.assertRaises(AssertionError):\n            # In VGG: 1 <= num_stages <= 5\n            VGG(11, num_stages=6)\n\n        with self.assertRaises(AssertionError):\n            # len(dilations) == num_stages\n            VGG(11, dilations=(1, 1), num_stages=3)\n\n        # Test VGG11 norm_eval=True\n        model = VGG(11, norm_eval=True)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test VGG11 forward without classifiers\n        model = VGG(11, out_indices=(0, 1, 2, 3, 4))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 5)\n        self.assertEqual(feat[0].shape, (1, 64, 112, 112))\n        self.assertEqual(feat[1].shape, (1, 128, 56, 56))\n        self.assertEqual(feat[2].shape, (1, 256, 28, 28))\n        self.assertEqual(feat[3].shape, (1, 512, 14, 14))\n        self.assertEqual(feat[4].shape, (1, 512, 7, 7))\n\n        # Test VGG11 forward with classifiers\n        model = VGG(11, num_classes=10, out_indices=(0, 1, 2, 3, 4, 5))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 6)\n        self.assertEqual(feat[0].shape, (1, 64, 112, 112))\n        self.assertEqual(feat[1].shape, (1, 128, 56, 56))\n        self.assertEqual(feat[2].shape, (1, 256, 28, 28))\n        self.assertEqual(feat[3].shape, (1, 512, 14, 14))\n        self.assertEqual(feat[4].shape, (1, 512, 7, 7))\n        self.assertEqual(feat[5].shape, (1, 10))\n\n        # Test VGG11BN forward\n        model = VGG(11, norm_cfg=dict(type='BN'), out_indices=(0, 1, 2, 3, 4))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 5)\n        self.assertEqual(feat[0].shape, (1, 64, 112, 112))\n        self.assertEqual(feat[1].shape, (1, 128, 56, 56))\n        self.assertEqual(feat[2].shape, (1, 256, 28, 28))\n        self.assertEqual(feat[3].shape, (1, 512, 14, 14))\n        self.assertEqual(feat[4].shape, (1, 512, 7, 7))\n\n        # Test VGG11BN forward with classifiers\n        model = VGG(\n            11,\n            num_classes=10,\n            norm_cfg=dict(type='BN'),\n            out_indices=(0, 1, 2, 3, 4, 5))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 6)\n        self.assertEqual(feat[0].shape, (1, 64, 112, 112))\n        self.assertEqual(feat[1].shape, (1, 128, 56, 56))\n        self.assertEqual(feat[2].shape, (1, 256, 28, 28))\n        self.assertEqual(feat[3].shape, (1, 512, 14, 14))\n        self.assertEqual(feat[4].shape, (1, 512, 7, 7))\n        self.assertEqual(feat[5].shape, (1, 10))\n\n        # Test VGG13 with layers 1, 2, 3 out forward\n        model = VGG(13, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, (1, 64, 112, 112))\n        self.assertEqual(feat[1].shape, (1, 128, 56, 56))\n        self.assertEqual(feat[2].shape, (1, 256, 28, 28))\n\n        # Test VGG16 with top feature maps out forward\n        model = VGG(16)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[-1].shape, (1, 512, 7, 7))\n\n        # Test VGG19 with classification score out forward\n        model = VGG(19, num_classes=10)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 1)\n        self.assertEqual(feat[-1].shape, (1, 10))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_vipnas_mbv3.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom torch.nn.modules import GroupNorm\nfrom torch.nn.modules.batchnorm import _BatchNorm\n\nfrom mmpose.models.backbones import ViPNAS_MobileNetV3\nfrom mmpose.models.backbones.utils import InvertedResidual\n\n\nclass TestVipnasMbv3(TestCase):\n\n    @staticmethod\n    def is_norm(modules):\n        \"\"\"Check if is one of the norms.\"\"\"\n        if isinstance(modules, (GroupNorm, _BatchNorm)):\n            return True\n        return False\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_mobilenetv3_backbone(self):\n        with self.assertRaises(TypeError):\n            # init_weights must have no parameter\n            model = ViPNAS_MobileNetV3()\n            model.init_weights(pretrained=0)\n\n        with self.assertRaises(AttributeError):\n            # frozen_stages must no more than 21\n            model = ViPNAS_MobileNetV3(frozen_stages=22)\n            model.train()\n\n        # Test MobileNetv3\n        model = ViPNAS_MobileNetV3()\n        model.init_weights()\n        model.train()\n\n        # Test MobileNetv3 with first stage frozen\n        frozen_stages = 1\n        model = ViPNAS_MobileNetV3(frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        for param in model.conv1.parameters():\n            self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test MobileNetv3 with norm eval\n        model = ViPNAS_MobileNetV3(norm_eval=True)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test MobileNetv3 forward\n        model = ViPNAS_MobileNetV3()\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 160, 7, 7]))\n\n        # Test MobileNetv3 forward with GroupNorm\n        model = ViPNAS_MobileNetV3(\n            norm_cfg=dict(type='GN', num_groups=2, requires_grad=True))\n        for m in model.modules():\n            if self.is_norm(m):\n                self.assertIsInstance(m, GroupNorm)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 160, 7, 7]))\n\n        # Test MobileNetv3 with checkpoint forward\n        model = ViPNAS_MobileNetV3(with_cp=True)\n        for m in model.modules():\n            if isinstance(m, InvertedResidual):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, torch.Size([1, 160, 7, 7]))\n"
  },
  {
    "path": "tests/test_models/test_backbones/test_vipnas_resnet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nimport torch.nn as nn\nfrom mmengine.utils.dl_utils.parrots_wrapper import _BatchNorm\n\nfrom mmpose.models.backbones import ViPNAS_ResNet\nfrom mmpose.models.backbones.vipnas_resnet import (ViPNAS_Bottleneck,\n                                                   ViPNAS_ResLayer,\n                                                   get_expansion)\n\n\nclass TestVipnasResnet(TestCase):\n\n    @staticmethod\n    def is_block(modules):\n        \"\"\"Check if is ViPNAS_ResNet building block.\"\"\"\n        if isinstance(modules, (ViPNAS_Bottleneck)):\n            return True\n        return False\n\n    @staticmethod\n    def all_zeros(modules):\n        \"\"\"Check if the weight(and bias) is all zero.\"\"\"\n        weight_zero = torch.equal(modules.weight.data,\n                                  torch.zeros_like(modules.weight.data))\n        if hasattr(modules, 'bias'):\n            bias_zero = torch.equal(modules.bias.data,\n                                    torch.zeros_like(modules.bias.data))\n        else:\n            bias_zero = True\n\n        return weight_zero and bias_zero\n\n    @staticmethod\n    def check_norm_state(modules, train_state):\n        \"\"\"Check if norm layer is in correct train state.\"\"\"\n        for mod in modules:\n            if isinstance(mod, _BatchNorm):\n                if mod.training != train_state:\n                    return False\n        return True\n\n    def test_get_expansion(self):\n        self.assertEqual(get_expansion(ViPNAS_Bottleneck, 2), 2)\n        self.assertEqual(get_expansion(ViPNAS_Bottleneck), 1)\n\n        class MyResBlock(nn.Module):\n\n            expansion = 8\n\n        self.assertEqual(get_expansion(MyResBlock), 8)\n\n        # expansion must be an integer or None\n        with self.assertRaises(TypeError):\n            get_expansion(ViPNAS_Bottleneck, '0')\n\n        # expansion is not specified and cannot be inferred\n        with self.assertRaises(TypeError):\n\n            class SomeModule(nn.Module):\n                pass\n\n            get_expansion(SomeModule)\n\n    def test_vipnas_bottleneck(self):\n        # style must be in ['pytorch', 'caffe']\n        with self.assertRaises(AssertionError):\n            ViPNAS_Bottleneck(64, 64, style='tensorflow')\n\n        # expansion must be divisible by out_channels\n        with self.assertRaises(AssertionError):\n            ViPNAS_Bottleneck(64, 64, expansion=3)\n\n        # Test ViPNAS_Bottleneck style\n        block = ViPNAS_Bottleneck(64, 64, stride=2, style='pytorch')\n        self.assertEqual(block.conv1.stride, (1, 1))\n        self.assertEqual(block.conv2.stride, (2, 2))\n        block = ViPNAS_Bottleneck(64, 64, stride=2, style='caffe')\n        self.assertEqual(block.conv1.stride, (2, 2))\n        self.assertEqual(block.conv2.stride, (1, 1))\n\n        # ViPNAS_Bottleneck with stride 1\n        block = ViPNAS_Bottleneck(64, 64, style='pytorch')\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 16)\n        self.assertEqual(block.out_channels, 64)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 16)\n        self.assertEqual(block.conv1.kernel_size, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 16)\n        self.assertEqual(block.conv2.out_channels, 16)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        self.assertEqual(block.conv3.in_channels, 16)\n        self.assertEqual(block.conv3.out_channels, 64)\n        self.assertEqual(block.conv3.kernel_size, (1, 1))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # ViPNAS_Bottleneck with stride 1 and downsample\n        downsample = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=1), nn.BatchNorm2d(128))\n        block = ViPNAS_Bottleneck(\n            64, 128, style='pytorch', downsample=downsample)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 32)\n        self.assertEqual(block.out_channels, 128)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 32)\n        self.assertEqual(block.conv1.kernel_size, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 32)\n        self.assertEqual(block.conv2.out_channels, 32)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        self.assertEqual(block.conv3.in_channels, 32)\n        self.assertEqual(block.conv3.out_channels, 128)\n        self.assertEqual(block.conv3.kernel_size, (1, 1))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 128, 56, 56))\n\n        # ViPNAS_Bottleneck with stride 2 and downsample\n        downsample = nn.Sequential(\n            nn.Conv2d(64, 128, kernel_size=1, stride=2), nn.BatchNorm2d(128))\n        block = ViPNAS_Bottleneck(\n            64, 128, stride=2, style='pytorch', downsample=downsample)\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 128, 28, 28))\n\n        # ViPNAS_Bottleneck with expansion 2\n        block = ViPNAS_Bottleneck(64, 64, style='pytorch', expansion=2)\n        self.assertEqual(block.in_channels, 64)\n        self.assertEqual(block.mid_channels, 32)\n        self.assertEqual(block.out_channels, 64)\n        self.assertEqual(block.conv1.in_channels, 64)\n        self.assertEqual(block.conv1.out_channels, 32)\n        self.assertEqual(block.conv1.kernel_size, (1, 1))\n        self.assertEqual(block.conv2.in_channels, 32)\n        self.assertEqual(block.conv2.out_channels, 32)\n        self.assertEqual(block.conv2.kernel_size, (3, 3))\n        self.assertEqual(block.conv3.in_channels, 32)\n        self.assertEqual(block.conv3.out_channels, 64)\n        self.assertEqual(block.conv3.kernel_size, (1, 1))\n        x = torch.randn(1, 64, 56, 56)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # Test ViPNAS_Bottleneck with checkpointing\n        block = ViPNAS_Bottleneck(64, 64, with_cp=True)\n        block.train()\n        self.assertTrue(block.with_cp)\n        x = torch.randn(1, 64, 56, 56, requires_grad=True)\n        x_out = block(x)\n        self.assertEqual(x_out.shape, torch.Size([1, 64, 56, 56]))\n\n    def test_vipnas_bottleneck_reslayer(self):\n        # 3 Bottleneck w/o downsample\n        layer = ViPNAS_ResLayer(ViPNAS_Bottleneck, 3, 32, 32)\n        self.assertEqual(len(layer), 3)\n        for i in range(3):\n            self.assertEqual(layer[i].in_channels, 32)\n            self.assertEqual(layer[i].out_channels, 32)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 32, 56, 56))\n\n        # 3 ViPNAS_Bottleneck w/ stride 1 and downsample\n        layer = ViPNAS_ResLayer(ViPNAS_Bottleneck, 3, 32, 64)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 1)\n        self.assertEqual(layer[0].conv1.out_channels, 64)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 2)\n        self.assertIsInstance(layer[0].downsample[0], nn.Conv2d)\n        self.assertEqual(layer[0].downsample[0].stride, (1, 1))\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 64)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 56, 56))\n\n        # 3 ViPNAS_Bottleneck w/ stride 2 and downsample\n        layer = ViPNAS_ResLayer(ViPNAS_Bottleneck, 3, 32, 64, stride=2)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 2)\n        self.assertEqual(layer[0].conv1.out_channels, 64)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 2)\n        self.assertIsInstance(layer[0].downsample[0], nn.Conv2d)\n        self.assertEqual(layer[0].downsample[0].stride, (2, 2))\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 64)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 28, 28))\n\n        # 3 ViPNAS_Bottleneck w/ stride 2 and downsample with avg pool\n        layer = ViPNAS_ResLayer(\n            ViPNAS_Bottleneck, 3, 32, 64, stride=2, avg_down=True)\n        self.assertEqual(len(layer), 3)\n        self.assertEqual(layer[0].in_channels, 32)\n        self.assertEqual(layer[0].out_channels, 64)\n        self.assertEqual(layer[0].stride, 2)\n        self.assertEqual(layer[0].conv1.out_channels, 64)\n        self.assertEqual(\n            layer[0].downsample is not None and len(layer[0].downsample), 3)\n        self.assertIsInstance(layer[0].downsample[0], nn.AvgPool2d)\n        self.assertEqual(layer[0].downsample[0].stride, 2)\n        for i in range(1, 3):\n            self.assertEqual(layer[i].in_channels, 64)\n            self.assertEqual(layer[i].out_channels, 64)\n            self.assertEqual(layer[i].conv1.out_channels, 64)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 64, 28, 28))\n\n        # 3 ViPNAS_Bottleneck with custom expansion\n        layer = ViPNAS_ResLayer(ViPNAS_Bottleneck, 3, 32, 32, expansion=2)\n        self.assertEqual(len(layer), 3)\n        for i in range(3):\n            self.assertEqual(layer[i].in_channels, 32)\n            self.assertEqual(layer[i].out_channels, 32)\n            self.assertEqual(layer[i].stride, 1)\n            self.assertEqual(layer[i].conv1.out_channels, 16)\n            self.assertIsNone(layer[i].downsample)\n        x = torch.randn(1, 32, 56, 56)\n        x_out = layer(x)\n        self.assertEqual(x_out.shape, (1, 32, 56, 56))\n\n    def test_resnet(self):\n        \"\"\"Test ViPNAS_ResNet backbone.\"\"\"\n        with self.assertRaises(KeyError):\n            # ViPNAS_ResNet depth should be in [50]\n            ViPNAS_ResNet(20)\n\n        with self.assertRaises(AssertionError):\n            # In ViPNAS_ResNet: 1 <= num_stages <= 4\n            ViPNAS_ResNet(50, num_stages=0)\n\n        with self.assertRaises(AssertionError):\n            # In ViPNAS_ResNet: 1 <= num_stages <= 4\n            ViPNAS_ResNet(50, num_stages=5)\n\n        with self.assertRaises(AssertionError):\n            # len(strides) == len(dilations) == num_stages\n            ViPNAS_ResNet(50, strides=(1, ), dilations=(1, 1), num_stages=3)\n\n        with self.assertRaises(TypeError):\n            # init_weights must have no parameter\n            model = ViPNAS_ResNet(50)\n            model.init_weights(pretrained=0)\n\n        with self.assertRaises(AssertionError):\n            # Style must be in ['pytorch', 'caffe']\n            ViPNAS_ResNet(50, style='tensorflow')\n\n        # Test ViPNAS_ResNet50 norm_eval=True\n        model = ViPNAS_ResNet(50, norm_eval=True)\n        model.init_weights()\n        model.train()\n        self.assertTrue(self.check_norm_state(model.modules(), False))\n\n        # Test ViPNAS_ResNet50 with first stage frozen\n        frozen_stages = 1\n        model = ViPNAS_ResNet(50, frozen_stages=frozen_stages)\n        model.init_weights()\n        model.train()\n        self.assertFalse(model.norm1.training)\n        for layer in [model.conv1, model.norm1]:\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n        for i in range(1, frozen_stages + 1):\n            layer = getattr(model, f'layer{i}')\n            for mod in layer.modules():\n                if isinstance(mod, _BatchNorm):\n                    self.assertFalse(mod.training)\n            for param in layer.parameters():\n                self.assertFalse(param.requires_grad)\n\n        # Test ViPNAS_ResNet50 with BatchNorm forward\n        model = ViPNAS_ResNet(50, out_indices=(0, 1, 2, 3))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 80, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 160, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 304, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 608, 7, 7))\n\n        # Test ViPNAS_ResNet50 with layers 1, 2, 3 out forward\n        model = ViPNAS_ResNet(50, out_indices=(0, 1, 2))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 3)\n        self.assertEqual(feat[0].shape, (1, 80, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 160, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 304, 14, 14))\n\n        # Test ViPNAS_ResNet50 with layers 3 (top feature maps) out forward\n        model = ViPNAS_ResNet(50, out_indices=(3, ))\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertIsInstance(feat, tuple)\n        self.assertEqual(feat[-1].shape, (1, 608, 7, 7))\n\n        # Test ViPNAS_ResNet50 with checkpoint forward\n        model = ViPNAS_ResNet(50, out_indices=(0, 1, 2, 3), with_cp=True)\n        for m in model.modules():\n            if self.is_block(m):\n                self.assertTrue(m.with_cp)\n        model.init_weights()\n        model.train()\n\n        imgs = torch.randn(1, 3, 224, 224)\n        feat = model(imgs)\n        self.assertEqual(len(feat), 4)\n        self.assertEqual(feat[0].shape, (1, 80, 56, 56))\n        self.assertEqual(feat[1].shape, (1, 160, 28, 28))\n        self.assertEqual(feat[2].shape, (1, 304, 14, 14))\n        self.assertEqual(feat[3].shape, (1, 608, 7, 7))\n"
  },
  {
    "path": "tests/test_models/test_data_preprocessors/test_data_preprocessor.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.logging import MessageHub\n\nfrom mmpose.models.data_preprocessors import (BatchSyncRandomResize,\n                                              PoseDataPreprocessor)\nfrom mmpose.structures import PoseDataSample\n\n\nclass TestPoseDataPreprocessor(TestCase):\n\n    def test_init(self):\n        # test mean is None\n        processor = PoseDataPreprocessor()\n        self.assertTrue(not hasattr(processor, 'mean'))\n        self.assertTrue(processor._enable_normalize is False)\n\n        # test mean is not None\n        processor = PoseDataPreprocessor(mean=[0, 0, 0], std=[1, 1, 1])\n        self.assertTrue(hasattr(processor, 'mean'))\n        self.assertTrue(hasattr(processor, 'std'))\n        self.assertTrue(processor._enable_normalize)\n\n        # please specify both mean and std\n        with self.assertRaises(AssertionError):\n            PoseDataPreprocessor(mean=[0, 0, 0])\n\n        # bgr2rgb and rgb2bgr cannot be set to True at the same time\n        with self.assertRaises(AssertionError):\n            PoseDataPreprocessor(bgr_to_rgb=True, rgb_to_bgr=True)\n\n    def test_forward(self):\n        processor = PoseDataPreprocessor(mean=[0, 0, 0], std=[1, 1, 1])\n\n        data = {\n            'inputs': [torch.randint(0, 256, (3, 11, 10))],\n            'data_samples': [PoseDataSample()]\n        }\n        out_data = processor(data)\n        batch_inputs, batch_data_samples = out_data['inputs'], out_data[\n            'data_samples']\n\n        self.assertEqual(batch_inputs.shape, (1, 3, 11, 10))\n        self.assertEqual(len(batch_data_samples), 1)\n\n        # test channel_conversion\n        processor = PoseDataPreprocessor(\n            mean=[0., 0., 0.], std=[1., 1., 1.], bgr_to_rgb=True)\n        out_data = processor(data)\n        batch_inputs, batch_data_samples = out_data['inputs'], out_data[\n            'data_samples']\n        self.assertEqual(batch_inputs.shape, (1, 3, 11, 10))\n        self.assertEqual(len(batch_data_samples), 1)\n\n        # test padding\n        data = {\n            'inputs': [\n                torch.randint(0, 256, (3, 10, 11)),\n                torch.randint(0, 256, (3, 9, 14))\n            ],\n            'data_samples': [PoseDataSample()] * 2\n        }\n        processor = PoseDataPreprocessor(\n            mean=[0., 0., 0.], std=[1., 1., 1.], bgr_to_rgb=True)\n        out_data = processor(data)\n        batch_inputs, batch_data_samples = out_data['inputs'], out_data[\n            'data_samples']\n        self.assertEqual(batch_inputs.shape, (2, 3, 10, 14))\n        self.assertEqual(len(batch_data_samples), 2)\n\n        # test pad_size_divisor\n        data = {\n            'inputs': [\n                torch.randint(0, 256, (3, 10, 11)),\n                torch.randint(0, 256, (3, 9, 24))\n            ],\n            'data_samples': [PoseDataSample()] * 2\n        }\n        processor = PoseDataPreprocessor(\n            mean=[0., 0., 0.], std=[1., 1., 1.], pad_size_divisor=5)\n        out_data = processor(data)\n        batch_inputs, batch_data_samples = out_data['inputs'], out_data[\n            'data_samples']\n        self.assertEqual(batch_inputs.shape, (2, 3, 10, 25))\n        self.assertEqual(len(batch_data_samples), 2)\n        for data_samples, expected_shape in zip(batch_data_samples,\n                                                [(10, 15), (10, 25)]):\n            self.assertEqual(data_samples.pad_shape, expected_shape)\n\n    def test_batch_sync_random_resize(self):\n        processor = PoseDataPreprocessor(batch_augments=[\n            dict(\n                type='BatchSyncRandomResize',\n                random_size_range=(320, 320),\n                size_divisor=32,\n                interval=1)\n        ])\n        self.assertTrue(\n            isinstance(processor.batch_augments[0], BatchSyncRandomResize))\n        message_hub = MessageHub.get_instance('test_batch_sync_random_resize')\n        message_hub.update_info('iter', 0)\n        packed_inputs = {\n            'inputs': [\n                torch.randint(0, 256, (3, 128, 128)),\n                torch.randint(0, 256, (3, 128, 128))\n            ],\n            'data_samples': [PoseDataSample()] * 2\n        }\n        batch_inputs = processor(packed_inputs, training=True)['inputs']\n        self.assertEqual(batch_inputs.shape, (2, 3, 128, 128))\n\n        # resize after one iter\n        message_hub.update_info('iter', 1)\n        packed_inputs = {\n            'inputs': [\n                torch.randint(0, 256, (3, 128, 128)),\n                torch.randint(0, 256, (3, 128, 128))\n            ],\n            'data_samples':\n            [PoseDataSample(metainfo=dict(img_shape=(128, 128)))] * 2\n        }\n        batch_inputs = processor(packed_inputs, training=True)['inputs']\n        self.assertEqual(batch_inputs.shape, (2, 3, 320, 320))\n\n        packed_inputs = {\n            'inputs': [\n                torch.randint(0, 256, (3, 128, 128)),\n                torch.randint(0, 256, (3, 128, 128))\n            ],\n            'data_samples': [PoseDataSample()] * 2\n        }\n        batch_inputs = processor(packed_inputs, training=False)['inputs']\n        self.assertEqual(batch_inputs.shape, (2, 3, 128, 128))\n"
  },
  {
    "path": "tests/test_models/test_distillers/test_dwpose_distiller.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.model.utils import revert_sync_batchnorm\nfrom parameterized import parameterized\n\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.testing import get_packed_inputs, get_pose_estimator_cfg\nfrom mmpose.utils import register_all_modules\n\nconfigs = [\n    'wholebody_2d_keypoint/dwpose/ubody/'\n    's1_dis/dwpose_l_dis_m_coco-ubody-256x192.py',\n    'wholebody_2d_keypoint/dwpose/ubody/'\n    's2_dis/dwpose_m-mm_coco-ubody-256x192.py',\n    'wholebody_2d_keypoint/dwpose/coco-wholebody/'\n    's1_dis/dwpose_l_dis_m_coco-256x192.py',\n    'wholebody_2d_keypoint/dwpose/coco-wholebody/'\n    's2_dis/dwpose_m-mm_coco-256x192.py',\n]\n\nconfigs_with_devices = [(config, ('cpu', 'cuda')) for config in configs]\n\n\nclass TestDWPoseDistiller(TestCase):\n\n    def setUp(self) -> None:\n        register_all_modules()\n\n    @parameterized.expand(configs)\n    def test_init(self, config):\n        dis_cfg = get_pose_estimator_cfg(config)\n        model_cfg = get_pose_estimator_cfg(dis_cfg.student_cfg)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n        model = build_pose_estimator(model_cfg)\n        model = revert_sync_batchnorm(model)\n        self.assertTrue(model.backbone)\n        self.assertTrue(model.head)\n        if model_cfg.get('neck', None):\n            self.assertTrue(model.neck)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_loss(self, config, devices):\n        dis_cfg = get_pose_estimator_cfg(config)\n        model_cfg = get_pose_estimator_cfg(dis_cfg.student_cfg)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n            model = revert_sync_batchnorm(model)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2, num_keypoints=133)\n            data = model.data_preprocessor(packed_inputs, training=True)\n            losses = model.forward(**data, mode='loss')\n            self.assertIsInstance(losses, dict)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_predict(self, config, devices):\n        dis_cfg = get_pose_estimator_cfg(config)\n        model_cfg = get_pose_estimator_cfg(dis_cfg.student_cfg)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n            model = revert_sync_batchnorm(model)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2, num_keypoints=133)\n            model.eval()\n            with torch.no_grad():\n                data = model.data_preprocessor(packed_inputs, training=True)\n                batch_results = model.forward(**data, mode='predict')\n                self.assertEqual(len(batch_results), 2)\n                self.assertIsInstance(batch_results[0], PoseDataSample)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_tensor(self, config, devices):\n        dis_cfg = get_pose_estimator_cfg(config)\n        model_cfg = get_pose_estimator_cfg(dis_cfg.student_cfg)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n            model = revert_sync_batchnorm(model)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2, num_keypoints=133)\n            data = model.data_preprocessor(packed_inputs, training=True)\n            batch_results = model.forward(**data, mode='tensor')\n            self.assertIsInstance(batch_results, (tuple, torch.Tensor))\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_ae_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom itertools import product\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom mmengine.utils import is_tuple_of\n\nfrom mmpose.codecs import AssociativeEmbedding  # noqa\nfrom mmpose.models.heads import AssociativeEmbeddingHead\nfrom mmpose.registry import KEYPOINT_CODECS\nfrom mmpose.testing._utils import get_packed_inputs\n\n\nclass TestAssociativeEmbeddingHead(TestCase):\n\n    def _get_tags(self, heatmaps, keypoint_indices, tag_per_keypoint: bool):\n\n        K, H, W = heatmaps.shape\n        N = keypoint_indices.shape[0]\n\n        if tag_per_keypoint:\n            tags = np.zeros((K, H, W), dtype=np.float32)\n        else:\n            tags = np.zeros((1, H, W), dtype=np.float32)\n\n        for n, k in product(range(N), range(K)):\n            y, x = np.unravel_index(keypoint_indices[n, k, 0], (H, W))\n            if tag_per_keypoint:\n                tags[k, y, x] = n\n            else:\n                tags[0, y, x] = n\n\n        return tags\n\n    def test_forward(self):\n\n        head = AssociativeEmbeddingHead(\n            in_channels=32,\n            num_keypoints=17,\n            tag_dim=1,\n            tag_per_keypoint=True,\n            deconv_out_channels=None)\n\n        feats = [torch.rand(1, 32, 64, 64)]\n        output = head.forward(feats)  # should be (heatmaps, tags)\n        self.assertTrue(is_tuple_of(output, torch.Tensor))\n        self.assertEqual(output[0].shape, (1, 17, 64, 64))\n        self.assertEqual(output[1].shape, (1, 17, 64, 64))\n\n    def test_predict(self):\n\n        codec_cfg = dict(\n            type='AssociativeEmbedding',\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=False,\n            decode_keypoint_order=[\n                0, 1, 2, 3, 4, 5, 6, 11, 12, 7, 8, 9, 10, 13, 14, 15, 16\n            ])\n\n        # get test data\n        codec = KEYPOINT_CODECS.build(codec_cfg)\n        batch_data_samples = get_packed_inputs(\n            1,\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            img_shape=(256, 256))['data_samples']\n\n        keypoints = batch_data_samples[0].gt_instances['keypoints']\n        keypoints_visible = batch_data_samples[0].gt_instances[\n            'keypoints_visible']\n\n        encoded = codec.encode(keypoints, keypoints_visible)\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n\n        tags = self._get_tags(\n            heatmaps, keypoint_indices, tag_per_keypoint=True)\n\n        dummy_feat = np.concatenate((heatmaps, tags), axis=0)\n        feats = [torch.from_numpy(dummy_feat)[None]]\n\n        head = AssociativeEmbeddingHead(\n            in_channels=34,\n            num_keypoints=17,\n            tag_dim=1,\n            tag_per_keypoint=True,\n            deconv_out_channels=None,\n            final_layer=None,\n            decoder=codec_cfg)\n\n        preds = head.predict(feats, batch_data_samples)\n        self.assertTrue(np.allclose(preds[0].keypoints, keypoints, atol=4.0))\n\n    def test_loss(self):\n\n        codec_cfg = dict(\n            type='AssociativeEmbedding',\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            use_udp=False,\n            decode_keypoint_order=[\n                0, 1, 2, 3, 4, 5, 6, 11, 12, 7, 8, 9, 10, 13, 14, 15, 16\n            ])\n\n        # get test data\n        codec = KEYPOINT_CODECS.build(codec_cfg)\n\n        batch_data_samples = get_packed_inputs(\n            1,\n            input_size=(256, 256),\n            heatmap_size=(64, 64),\n            img_shape=(256, 256))['data_samples']\n\n        keypoints = batch_data_samples[0].gt_instances['keypoints']\n        keypoints_visible = batch_data_samples[0].gt_instances[\n            'keypoints_visible']\n        encoded = codec.encode(keypoints, keypoints_visible)\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n        keypoint_weights = encoded['keypoint_weights']\n\n        heatmap_mask = np.ones((1, ) + heatmaps.shape[1:], dtype=np.float32)\n        batch_data_samples[0].gt_fields = PixelData(\n            heatmaps=heatmaps, heatmap_mask=heatmap_mask).to_tensor()\n        batch_data_samples[0].gt_instance_labels = InstanceData(\n            keypoint_indices=keypoint_indices,\n            keypoint_weights=keypoint_weights).to_tensor()\n\n        feats = [torch.rand(1, 32, 64, 64)]\n        head = AssociativeEmbeddingHead(\n            in_channels=32,\n            num_keypoints=17,\n            tag_dim=1,\n            tag_per_keypoint=True,\n            deconv_out_channels=None)\n\n        losses = head.loss(feats, batch_data_samples)\n        for name in ['loss_kpt', 'loss_pull', 'loss_push']:\n            self.assertIn(name, losses)\n            self.assertIsInstance(losses[name], torch.Tensor)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_cid_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\n\nfrom mmpose.models.heads import CIDHead\nfrom mmpose.testing import get_coco_sample, get_packed_inputs\nfrom mmpose.utils.tensor_utils import to_tensor\n\n\nclass TestCIDHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 1,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 128, 128)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        if len(feats) > 1:\n            feats = [[x] for x in feats]\n\n        return feats\n\n    def _get_data_samples(self):\n        data_samples = get_packed_inputs(\n            1,\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            img_shape=(512, 512))['data_samples']\n        return data_samples\n\n    def test_forward(self):\n\n        head = CIDHead(in_channels=32, num_keypoints=17, gfd_channels=32)\n\n        feats = [torch.rand(1, 32, 128, 128)]\n        with torch.no_grad():\n            output = head.forward(feats)\n            self.assertIsInstance(output, torch.Tensor)\n            self.assertEqual(output.shape[1:], (17, 128, 128))\n\n    def test_predict(self):\n\n        codec = dict(\n            type='DecoupledHeatmap',\n            input_size=(512, 512),\n            heatmap_size=(128, 128))\n\n        head = CIDHead(\n            in_channels=32, num_keypoints=17, gfd_channels=32, decoder=codec)\n\n        feats = self._get_feats()\n        data_samples = self._get_data_samples()\n        with torch.no_grad():\n            preds = head.predict(feats, data_samples)\n            self.assertEqual(len(preds), 1)\n            self.assertEqual(preds[0].keypoints.shape[1:], (17, 2))\n            self.assertEqual(preds[0].keypoint_scores.shape[1:], (17, ))\n\n        # tta\n        with torch.no_grad():\n            feats_flip = self._get_feats(feat_shapes=[(32, 128,\n                                                       128), (32, 128, 128)])\n            preds = head.predict(feats_flip, data_samples,\n                                 dict(flip_test=True))\n            self.assertEqual(len(preds), 1)\n            self.assertEqual(preds[0].keypoints.shape[1:], (17, 2))\n            self.assertEqual(preds[0].keypoint_scores.shape[1:], (17, ))\n\n        # output heatmaps\n        with torch.no_grad():\n            _, pred_fields = head.predict(feats, data_samples,\n                                          dict(output_heatmaps=True))\n            self.assertEqual(len(pred_fields), 1)\n            self.assertEqual(pred_fields[0].heatmaps.shape[1:], (128, 128))\n            self.assertEqual(pred_fields[0].heatmaps.shape[0] % 17, 0)\n\n    def test_loss(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n        data['bbox'] = np.tile(data['bbox'], 2).reshape(-1, 4, 2)\n        data['bbox'][:, 1:3, 0] = data['bbox'][:, 0:2, 0]\n\n        codec_cfg = dict(\n            type='DecoupledHeatmap',\n            input_size=(512, 512),\n            heatmap_size=(128, 128))\n\n        head = CIDHead(\n            in_channels=32,\n            num_keypoints=17,\n            gfd_channels=32,\n            decoder=codec_cfg,\n            coupled_heatmap_loss=dict(\n                type='FocalHeatmapLoss', loss_weight=1.0),\n            decoupled_heatmap_loss=dict(\n                type='FocalHeatmapLoss', loss_weight=4.0),\n            contrastive_loss=dict(type='InfoNCELoss', loss_weight=1.0))\n\n        encoded = head.decoder.encode(data['keypoints'],\n                                      data['keypoints_visible'], data['bbox'])\n        feats = self._get_feats()\n        data_samples = self._get_data_samples()\n        for data_sample in data_samples:\n            data_sample.gt_fields.set_data({\n                'heatmaps':\n                to_tensor(encoded['heatmaps']),\n                'instance_heatmaps':\n                to_tensor(encoded['instance_heatmaps'])\n            })\n            data_sample.gt_instance_labels.set_data(\n                {'instance_coords': to_tensor(encoded['instance_coords'])})\n            data_sample.gt_instance_labels.set_data(\n                {'keypoint_weights': to_tensor(encoded['keypoint_weights'])})\n\n        losses = head.loss(feats, data_samples)\n        self.assertIn('loss/heatmap_coupled', losses)\n        self.assertEqual(losses['loss/heatmap_coupled'].ndim, 0)\n        self.assertIn('loss/heatmap_decoupled', losses)\n        self.assertEqual(losses['loss/heatmap_decoupled'].ndim, 0)\n        self.assertIn('loss/contrastive', losses)\n        self.assertEqual(losses['loss/contrastive'].ndim, 0)\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_cpm_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import nn\n\nfrom mmpose.models.heads import CPMHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestCPMHead(TestCase):\n\n    def _get_feats(self,\n                   batch_size: int = 2,\n                   feat_shapes: List[Tuple[int, int, int]] = [(17, 32, 24)]):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n        return feats\n\n    def _get_data_samples(self, batch_size: int = 2):\n        batch_data_samples = get_packed_inputs(\n            batch_size=batch_size,\n            num_instances=1,\n            num_keypoints=17,\n            img_shape=(128, 128),\n            input_size=(192, 256),\n            heatmap_size=(24, 32),\n            with_heatmap=True,\n            with_reg_label=False)['data_samples']\n        return batch_data_samples\n\n    def test_init(self):\n        # w/o deconv\n        head = CPMHead(\n            num_stages=1,\n            in_channels=256,\n            out_channels=17,\n            deconv_out_channels=None)\n        self.assertTrue(isinstance(head.multi_deconv_layers, nn.ModuleList))\n        self.assertTrue(isinstance(head.multi_deconv_layers[0], nn.Identity))\n\n        # w/ deconv\n        head = CPMHead(\n            num_stages=1,\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4))\n        self.assertTrue(isinstance(head.multi_deconv_layers, nn.ModuleList))\n        self.assertTrue(isinstance(head.multi_deconv_layers[0], nn.Sequential))\n\n        # w/o final layer\n        head = CPMHead(\n            num_stages=6, in_channels=17, out_channels=17, final_layer=None)\n        self.assertTrue(isinstance(head.multi_final_layers, nn.ModuleList))\n        self.assertTrue(isinstance(head.multi_final_layers[0], nn.Identity))\n\n        # w/ decoder\n        head = CPMHead(\n            num_stages=1,\n            in_channels=32,\n            out_channels=17,\n            decoder=dict(\n                type='MSRAHeatmap',\n                input_size=(192, 256),\n                heatmap_size=(48, 64),\n                sigma=2.))\n        self.assertIsNotNone(head.decoder)\n\n        # the same loss for different stages\n        head = CPMHead(\n            num_stages=6,\n            in_channels=17,\n            out_channels=17,\n            final_layer=None,\n            loss=dict(type='KeypointMSELoss', use_target_weight=True),\n        )\n        self.assertTrue(isinstance(head.loss_module, nn.Module))\n\n        # different loss for different stages\n        num_stages = 6\n        head = CPMHead(\n            num_stages=num_stages,\n            in_channels=17,\n            out_channels=17,\n            final_layer=None,\n            loss=[dict(type='KeypointMSELoss', use_target_weight=True)] * 6,\n        )\n        self.assertTrue(isinstance(head.loss_module, nn.ModuleList))\n        self.assertTrue(len(head.loss_module), num_stages)\n\n    def test_predict(self):\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(24, 32),\n            sigma=2.)\n\n        # num_stages = 6, final_layer = None\n        head = CPMHead(\n            num_stages=6,\n            in_channels=17,\n            out_channels=17,\n            final_layer=None,\n            decoder=decoder_cfg)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'length of feature maps did not match the `num_stages`'):\n            feats = self._get_feats(batch_size=2, feat_shapes=[(17, 32, 24)])\n            batch_data_samples = self._get_data_samples(batch_size=2)\n            _ = head.predict(feats, batch_data_samples)\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(17, 32, 24)] * 6)\n        batch_data_samples = self._get_data_samples(batch_size=2)\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # num_stages = 1, final_layer = dict(kernel_size=1)\n        head = CPMHead(\n            num_stages=1,\n            in_channels=32,\n            out_channels=17,\n            final_layer=dict(kernel_size=1),\n            decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 32, 24)])\n        batch_data_samples = self._get_data_samples(batch_size=2)\n        preds, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n        self.assertTrue(len(pred_heatmaps), 2)\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 32, 24))\n\n    def test_tta(self):\n        # flip test: heatmap\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(24, 32),\n            sigma=2.)\n\n        head = CPMHead(\n            num_stages=1,\n            in_channels=32,\n            out_channels=17,\n            final_layer=dict(kernel_size=1),\n            decoder=decoder_cfg)\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = self._get_data_samples(batch_size=2)\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(\n                                 flip_test=True,\n                                 flip_mode='heatmap',\n                                 shift_heatmap=True,\n                             ))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        # num_stages = 1\n        head = CPMHead(\n            num_stages=1,\n            in_channels=32,\n            out_channels=17,\n            final_layer=dict(kernel_size=1))\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 32, 24)])\n        batch_data_samples = self._get_data_samples(batch_size=2)\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n        num_stages = 6\n        head = CPMHead(\n            num_stages=num_stages,\n            in_channels=17,\n            out_channels=17,\n            final_layer=None,\n            loss=[dict(type='KeypointMSELoss', use_target_weight=True)] *\n            num_stages)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'length of feature maps did not match the `num_stages`'):\n            feats = self._get_feats(batch_size=2, feat_shapes=[(17, 32, 24)])\n            batch_data_samples = self._get_data_samples(batch_size=2)\n            _ = head.loss(feats, batch_data_samples)\n\n        feats = self._get_feats(\n            batch_size=2, feat_shapes=[(17, 32, 24)] * num_stages)\n        batch_data_samples = self._get_data_samples(batch_size=2)\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n    def test_errors(self):\n        # Invalid arguments\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = CPMHead(\n                num_stages=1,\n                in_channels=17,\n                out_channels=17,\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(4, 4))\n\n        with self.assertRaisesRegex(ValueError, 'Unsupported kernel size'):\n            _ = CPMHead(\n                num_stages=1,\n                in_channels=17,\n                out_channels=17,\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(1, ))\n\n        with self.assertRaisesRegex(ValueError, 'did not match `num_stages`'):\n            _ = CPMHead(\n                num_stages=6,\n                in_channels=17,\n                out_channels=17,\n                loss=[dict(type='KeypointMSELoss', use_target_weight=True)] *\n                4)\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_heatmap_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import nn\n\nfrom mmpose.models.heads import HeatmapHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestHeatmapHead(TestCase):\n\n    def _get_feats(self,\n                   batch_size: int = 2,\n                   feat_shapes: List[Tuple[int, int, int]] = [(32, 8, 6)]):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n        return feats\n\n    def test_init(self):\n        # w/o deconv\n        head = HeatmapHead(\n            in_channels=32, out_channels=17, deconv_out_channels=None)\n        self.assertTrue(isinstance(head.deconv_layers, nn.Identity))\n\n        # w/ deconv and w/o conv\n        head = HeatmapHead(\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4))\n        self.assertTrue(isinstance(head.deconv_layers, nn.Sequential))\n        self.assertTrue(isinstance(head.conv_layers, nn.Identity))\n\n        # w/ both deconv and conv\n        head = HeatmapHead(\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            conv_out_channels=(32, ),\n            conv_kernel_sizes=(1, ))\n        self.assertTrue(isinstance(head.deconv_layers, nn.Sequential))\n        self.assertTrue(isinstance(head.conv_layers, nn.Sequential))\n\n        # w/o final layer\n        head = HeatmapHead(in_channels=32, out_channels=17, final_layer=None)\n        self.assertTrue(isinstance(head.final_layer, nn.Identity))\n\n        # w/ decoder\n        head = HeatmapHead(\n            in_channels=32,\n            out_channels=17,\n            decoder=dict(\n                type='MSRAHeatmap',\n                input_size=(192, 256),\n                heatmap_size=(48, 64),\n                sigma=2.))\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        head = HeatmapHead(\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(256, 256),\n            deconv_kernel_sizes=(4, 4),\n            conv_out_channels=(256, ),\n            conv_kernel_sizes=(1, ),\n            decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # output heatmap\n        head = HeatmapHead(\n            in_channels=32, out_channels=17, decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        _, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertTrue(len(pred_heatmaps), 2)\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 64, 48))\n\n    def test_tta(self):\n        # flip test: heatmap\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        head = HeatmapHead(\n            in_channels=32, out_channels=17, decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(\n                                 flip_test=True,\n                                 flip_mode='heatmap',\n                                 shift_heatmap=True,\n                             ))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # flip test: udp_combine\n        decoder_cfg = dict(\n            type='UDPHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            heatmap_type='combined')\n        head = HeatmapHead(\n            in_channels=32, out_channels=17 * 3, decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(\n                                 flip_test=True,\n                                 flip_mode='udp_combined',\n                                 shift_heatmap=False,\n                             ))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        head = HeatmapHead(in_channels=32, out_channels=17)\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n    def test_errors(self):\n        # Invalid arguments\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = HeatmapHead(\n                in_channels=32,\n                out_channels=17,\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(4, 4))\n\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = HeatmapHead(\n                in_channels=32, out_channels=17, conv_out_channels=(256, ))\n\n        with self.assertRaisesRegex(ValueError, 'Unsupported kernel size'):\n            _ = HeatmapHead(\n                in_channels=16,\n                out_channels=17,\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(1, ))\n\n    def test_state_dict_compatible(self):\n        # Typical setting for HRNet\n        head = HeatmapHead(\n            in_channels=32, out_channels=17, deconv_out_channels=None)\n\n        state_dict = {\n            'final_layer.weight': torch.zeros((17, 32, 1, 1)),\n            'final_layer.bias': torch.zeros((17))\n        }\n        head.load_state_dict(state_dict)\n\n        # Typical setting for Resnet\n        head = HeatmapHead(in_channels=2048, out_channels=17)\n\n        state_dict = {\n            'deconv_layers.0.weight': torch.zeros([2048, 256, 4, 4]),\n            'deconv_layers.1.weight': torch.zeros([256]),\n            'deconv_layers.1.bias': torch.zeros([256]),\n            'deconv_layers.1.running_mean': torch.zeros([256]),\n            'deconv_layers.1.running_var': torch.zeros([256]),\n            'deconv_layers.1.num_batches_tracked': torch.zeros([]),\n            'deconv_layers.3.weight': torch.zeros([256, 256, 4, 4]),\n            'deconv_layers.4.weight': torch.zeros([256]),\n            'deconv_layers.4.bias': torch.zeros([256]),\n            'deconv_layers.4.running_mean': torch.zeros([256]),\n            'deconv_layers.4.running_var': torch.zeros([256]),\n            'deconv_layers.4.num_batches_tracked': torch.zeros([]),\n            'deconv_layers.6.weight': torch.zeros([256, 256, 4, 4]),\n            'deconv_layers.7.weight': torch.zeros([256]),\n            'deconv_layers.7.bias': torch.zeros([256]),\n            'deconv_layers.7.running_mean': torch.zeros([256]),\n            'deconv_layers.7.running_var': torch.zeros([256]),\n            'deconv_layers.7.num_batches_tracked': torch.zeros([]),\n            'final_layer.weight': torch.zeros([17, 256, 1, 1]),\n            'final_layer.bias': torch.zeros([17])\n        }\n        head.load_state_dict(state_dict)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_mspn_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import Tensor, nn\n\nfrom mmpose.models.heads import MSPNHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestMSPNHead(TestCase):\n\n    def _get_feats(\n        self,\n        num_stages: int = 1,\n        num_units: int = 4,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(17, 64, 48)]\n    ) -> List[List[Tensor]]:\n        feats_stages = []\n        for i in range(num_stages):\n            feats_units = []\n            for j in range(num_units):\n                feats_units.append(\n                    torch.rand(\n                        (batch_size, ) + feat_shapes[j], dtype=torch.float32))\n            feats_stages.append(feats_units)\n\n        return feats_stages\n\n    def _get_data_samples(self,\n                          batch_size: int = 2,\n                          heatmap_size=(48, 64),\n                          num_levels=1):\n        batch_data_samples = get_packed_inputs(\n            batch_size=batch_size,\n            num_instances=1,\n            num_keypoints=17,\n            img_shape=(128, 128),\n            input_size=(192, 256),\n            heatmap_size=heatmap_size,\n            with_heatmap=True,\n            with_reg_label=False,\n            num_levels=num_levels)['data_samples']\n\n        return batch_data_samples\n\n    def test_init(self):\n        # w/ decoder\n        head = MSPNHead(\n            num_stages=1,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=256,\n            out_channels=17,\n            use_prm=False,\n            norm_cfg=dict(type='BN'),\n            level_indices=[0, 1, 2, 3],\n            decoder=dict(\n                type='MegviiHeatmap',\n                input_size=(192, 256),\n                heatmap_size=(48, 64),\n                kernel_size=11))\n        self.assertIsNotNone(head.decoder)\n\n        # the same loss for different stages\n        head = MSPNHead(\n            num_stages=1,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=256,\n            out_channels=17,\n            use_prm=False,\n            norm_cfg=dict(type='BN'),\n            loss=dict(type='KeypointMSELoss', use_target_weight=True),\n            level_indices=[0, 1, 2, 3],\n        )\n        self.assertTrue(isinstance(head.loss_module, nn.Module))\n\n        # different loss for different stages and different units\n        head = MSPNHead(\n            num_stages=2,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=256,\n            out_channels=17,\n            use_prm=False,\n            norm_cfg=dict(type='BN'),\n            loss=[dict(type='KeypointMSELoss', use_target_weight=True)] * 8,\n            level_indices=[0, 1, 2, 3, 1, 2, 3, 4],\n        )\n        self.assertTrue(isinstance(head.loss_module, nn.ModuleList))\n        self.assertTrue(len(head.loss_module), 8)\n\n    def test_loss(self):\n        # num_stages = 1, num_units = 4, unit_channels = 16\n        # the same loss for all different stages and units\n        unit_channels = 16\n        head = MSPNHead(\n            num_stages=1,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=unit_channels,\n            out_channels=17,\n            level_indices=[0, 1, 2, 3])\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'length of feature maps did not match the `num_stages`'):\n            feats = self._get_feats(\n                num_stages=2,\n                num_units=4,\n                batch_size=2,\n                feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                             (unit_channels, 32, 24), (unit_channels, 64, 48)])\n            batch_data_samples = self._get_data_samples(\n                batch_size=2, heatmap_size=(48, 64), num_levels=8)\n            _ = head.loss(feats, batch_data_samples)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'length of feature maps did not match the `num_units`'):\n            feats = self._get_feats(\n                num_stages=1,\n                num_units=2,\n                batch_size=2,\n                feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12)])\n            batch_data_samples = self._get_data_samples(\n                batch_size=2, heatmap_size=(48, 64), num_levels=2)\n            _ = head.loss(feats, batch_data_samples)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'number of feature map channels did not match'):\n            feats = self._get_feats(\n                num_stages=1,\n                num_units=4,\n                batch_size=2,\n                feat_shapes=[(unit_channels * 2, 8, 6),\n                             (unit_channels * 2, 16, 12),\n                             (unit_channels * 2, 32, 24),\n                             (unit_channels * 2, 64, 48)])\n            batch_data_samples = self._get_data_samples(\n                batch_size=2, heatmap_size=(48, 64), num_levels=4)\n            _ = head.loss(feats, batch_data_samples)\n\n        feats = self._get_feats(\n            num_stages=1,\n            num_units=4,\n            batch_size=2,\n            feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                         (unit_channels, 32, 24), (unit_channels, 64, 48)])\n        batch_data_samples = self._get_data_samples(\n            batch_size=2, heatmap_size=(48, 64), num_levels=4)\n        for ds in batch_data_samples:\n            ds.gt_instance_labels = InstanceData(\n                keypoint_weights=ds.gt_instance_labels.keypoint_weights.\n                transpose(0, 1))\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n        # num_stages = 4, num_units = 4, unit_channels = 16\n        # different losses for different stages and units\n        unit_channels = 16\n        head = MSPNHead(\n            num_stages=4,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=unit_channels,\n            out_channels=17,\n            loss=([\n                dict(\n                    type='KeypointMSELoss',\n                    use_target_weight=True,\n                    loss_weight=0.25)\n            ] * 3 + [\n                dict(\n                    type='KeypointOHKMMSELoss',\n                    use_target_weight=True,\n                    loss_weight=0.1)\n            ]) * 4,\n            level_indices=[0, 1, 2, 3] * 3 + [1, 2, 3, 4])\n\n        feats = self._get_feats(\n            num_stages=4,\n            num_units=4,\n            batch_size=2,\n            feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                         (unit_channels, 32, 24), (unit_channels, 64, 48)])\n        batch_data_samples = self._get_data_samples(\n            batch_size=2, heatmap_size=(48, 64), num_levels=16)\n        for ds in batch_data_samples:\n            ds.gt_instance_labels = InstanceData(\n                keypoint_weights=ds.gt_instance_labels.keypoint_weights.\n                transpose(0, 1))\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n    def test_predict(self):\n        decoder_cfg = dict(\n            type='MegviiHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            kernel_size=11)\n\n        # num_stages = 1, num_units = 4, unit_channels = 16\n        unit_channels = 16\n        head = MSPNHead(\n            num_stages=1,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=unit_channels,\n            out_channels=17,\n            level_indices=[0, 1, 2, 3],\n            decoder=decoder_cfg)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'length of feature maps did not match the `num_stages`'):\n            feats = self._get_feats(\n                num_stages=2,\n                num_units=4,\n                batch_size=2,\n                feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                             (unit_channels, 32, 24), (unit_channels, 64, 48)])\n            batch_data_samples = self._get_data_samples(\n                batch_size=2, heatmap_size=(48, 64), num_levels=8)\n            _ = head.predict(feats, batch_data_samples)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'length of feature maps did not match the `num_units`'):\n            feats = self._get_feats(\n                num_stages=1,\n                num_units=2,\n                batch_size=2,\n                feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12)])\n            batch_data_samples = self._get_data_samples(\n                batch_size=2, heatmap_size=(48, 64), num_levels=2)\n            _ = head.predict(feats, batch_data_samples)\n\n        with self.assertRaisesRegex(\n                AssertionError,\n                'number of feature map channels did not match'):\n            feats = self._get_feats(\n                num_stages=1,\n                num_units=4,\n                batch_size=2,\n                feat_shapes=[(unit_channels * 2, 8, 6),\n                             (unit_channels * 2, 16, 12),\n                             (unit_channels * 2, 32, 24),\n                             (unit_channels * 2, 64, 48)])\n            batch_data_samples = self._get_data_samples(\n                batch_size=2, heatmap_size=(48, 64), num_levels=4)\n            _ = head.predict(feats, batch_data_samples)\n\n        feats = self._get_feats(\n            num_stages=1,\n            num_units=4,\n            batch_size=2,\n            feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                         (unit_channels, 32, 24), (unit_channels, 64, 48)])\n        batch_data_samples = self._get_data_samples(\n            batch_size=2, heatmap_size=(48, 64), num_levels=4)\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # num_stages = 4, num_units = 4, unit_channels = 16\n        unit_channels = 16\n        head = MSPNHead(\n            num_stages=4,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=unit_channels,\n            out_channels=17,\n            level_indices=[0, 1, 2, 3] * 3 + [1, 2, 3, 4],\n            decoder=decoder_cfg)\n        feats = self._get_feats(\n            num_stages=4,\n            num_units=4,\n            batch_size=2,\n            feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                         (unit_channels, 32, 24), (unit_channels, 64, 48)])\n        batch_data_samples = self._get_data_samples(\n            batch_size=2, heatmap_size=(48, 64), num_levels=16)\n        preds, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n        self.assertTrue(len(pred_heatmaps), 2)\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 64, 48))\n\n    def test_tta(self):\n        # flip test: heatmap\n        decoder_cfg = dict(\n            type='MegviiHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            kernel_size=11)\n\n        unit_channels = 16\n        head = MSPNHead(\n            num_stages=1,\n            num_units=4,\n            out_shape=(64, 48),\n            unit_channels=unit_channels,\n            out_channels=17,\n            level_indices=[0, 1, 2, 3],\n            decoder=decoder_cfg)\n\n        feats = self._get_feats(\n            num_stages=1,\n            num_units=4,\n            batch_size=2,\n            feat_shapes=[(unit_channels, 8, 6), (unit_channels, 16, 12),\n                         (unit_channels, 32, 24), (unit_channels, 64, 48)])\n        batch_data_samples = self._get_data_samples(batch_size=2)\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(\n                                 flip_test=True,\n                                 flip_mode='heatmap',\n                                 shift_heatmap=True,\n                             ))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_errors(self):\n        # Invalid arguments\n        with self.assertRaisesRegex(ValueError, 'The length of level_indices'):\n            _ = MSPNHead(\n                num_stages=2,\n                num_units=4,\n                out_shape=(64, 48),\n                unit_channels=256,\n                out_channels=17,\n                level_indices=[0])\n        with self.assertRaisesRegex(ValueError, 'The length of loss_module'):\n            _ = MSPNHead(\n                num_stages=2,\n                num_units=4,\n                out_shape=(64, 48),\n                unit_channels=256,\n                out_channels=17,\n                level_indices=[0, 1, 2, 3, 1, 2, 3, 4],\n                loss=[dict(type='KeypointMSELoss', use_target_weight=True)] *\n                3)\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_rtmcc_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nimport torch.nn as nn\nfrom mmengine.structures import InstanceData\nfrom mmengine.utils import digit_version\nfrom mmengine.utils.dl_utils import TORCH_VERSION\n\nfrom mmpose.models.heads import RTMCCHead\nfrom mmpose.models.utils import RTMCCBlock\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestRTMCCHead(TestCase):\n\n    def _get_feats(self,\n                   batch_size: int = 2,\n                   feat_shapes: List[Tuple[int, int, int]] = [(32, 6, 8)]):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n        return feats\n\n    def test_init(self):\n\n        if digit_version(TORCH_VERSION) < digit_version('1.7.0'):\n            return unittest.skip('RTMCCHead requires PyTorch >= 1.7')\n\n        # original version\n        head = RTMCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            final_layer_kernel_size=7,\n            gau_cfg=dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='SiLU',\n                use_rel_bias=False,\n                pos_enc=False),\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='gaussian',\n                sigma=(4.9, 5.66),\n                simcc_split_ratio=2.0,\n                normalize=False))\n        self.assertIsNotNone(head.decoder)\n        self.assertTrue(isinstance(head.final_layer, nn.Conv2d))\n        self.assertTrue(isinstance(head.mlp, nn.Sequential))\n        self.assertTrue(isinstance(head.gau, RTMCCBlock))\n        self.assertTrue(isinstance(head.cls_x, nn.Linear))\n        self.assertTrue(isinstance(head.cls_y, nn.Linear))\n\n        # w/ 1x1 conv\n        head = RTMCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            final_layer_kernel_size=1,\n            gau_cfg=dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='SiLU',\n                use_rel_bias=False,\n                pos_enc=False),\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='gaussian',\n                sigma=(4.9, 5.66),\n                simcc_split_ratio=2.0,\n                normalize=False))\n        self.assertIsNotNone(head.decoder)\n        self.assertTrue(isinstance(head.final_layer, nn.Conv2d))\n        self.assertTrue(isinstance(head.mlp, nn.Sequential))\n        self.assertTrue(isinstance(head.gau, RTMCCBlock))\n        self.assertTrue(isinstance(head.cls_x, nn.Linear))\n        self.assertTrue(isinstance(head.cls_y, nn.Linear))\n\n        # hidden_dims\n        head = RTMCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            final_layer_kernel_size=7,\n            gau_cfg=dict(\n                hidden_dims=512,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='SiLU',\n                use_rel_bias=False,\n                pos_enc=False),\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='gaussian',\n                sigma=(4.9, 5.66),\n                simcc_split_ratio=2.0,\n                normalize=False))\n        self.assertIsNotNone(head.decoder)\n        self.assertTrue(isinstance(head.final_layer, nn.Conv2d))\n        self.assertTrue(isinstance(head.mlp, nn.Sequential))\n        self.assertTrue(isinstance(head.gau, RTMCCBlock))\n        self.assertTrue(isinstance(head.cls_x, nn.Linear))\n        self.assertTrue(isinstance(head.cls_y, nn.Linear))\n\n        # s = 256\n        head = RTMCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            final_layer_kernel_size=7,\n            gau_cfg=dict(\n                hidden_dims=256,\n                s=256,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='SiLU',\n                use_rel_bias=False,\n                pos_enc=False),\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='gaussian',\n                sigma=(4.9, 5.66),\n                simcc_split_ratio=2.0,\n                normalize=False))\n        self.assertIsNotNone(head.decoder)\n        self.assertTrue(isinstance(head.final_layer, nn.Conv2d))\n        self.assertTrue(isinstance(head.mlp, nn.Sequential))\n        self.assertTrue(isinstance(head.gau, RTMCCBlock))\n        self.assertTrue(isinstance(head.cls_x, nn.Linear))\n        self.assertTrue(isinstance(head.cls_y, nn.Linear))\n\n    def test_predict(self):\n\n        if digit_version(TORCH_VERSION) < digit_version('1.7.0'):\n            return unittest.skip('RTMCCHead requires PyTorch >= 1.7')\n\n        decoder_cfg_list = []\n        # original version\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=(4.9, 5.66),\n            simcc_split_ratio=2.0,\n            normalize=False)\n        decoder_cfg_list.append(decoder_cfg)\n\n        # single sigma\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=6.,\n            simcc_split_ratio=2.0,\n            normalize=False)\n        decoder_cfg_list.append(decoder_cfg)\n\n        # normalize\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=6.,\n            simcc_split_ratio=2.0,\n            normalize=True)\n        decoder_cfg_list.append(decoder_cfg)\n\n        # dark\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=6.,\n            simcc_split_ratio=2.0,\n            use_dark=True)\n        decoder_cfg_list.append(decoder_cfg)\n\n        for decoder_cfg in decoder_cfg_list:\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # 1x1 conv\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=1,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            # hidden dims\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=512,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # s\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=64,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # expansion factor\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=3,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # drop path\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.1,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # act fn\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='ReLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # use_rel_bias\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=True,\n                    pos_enc=False),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # pos_enc\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=True),\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, _ = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # output_heatmaps\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                decoder=decoder_cfg,\n            )\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, pred_heatmaps = head.predict(\n                feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(preds[0].keypoint_x_labels.shape, (1, 17, 384))\n            self.assertEqual(preds[0].keypoint_y_labels.shape, (1, 17, 512))\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n            self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 512, 384))\n\n    def test_tta(self):\n        if digit_version(TORCH_VERSION) < digit_version('1.7.0'):\n            return unittest.skip('RTMCCHead requires PyTorch >= 1.7')\n\n        # flip test\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=(4.9, 5.66),\n            simcc_split_ratio=2.0,\n            normalize=False)\n\n        head = RTMCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            final_layer_kernel_size=7,\n            gau_cfg=dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='SiLU',\n                use_rel_bias=False,\n                pos_enc=False),\n            decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, simcc_split_ratio=2.0,\n            with_simcc_label=True)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(flip_test=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        if digit_version(TORCH_VERSION) < digit_version('1.7.0'):\n            return unittest.skip('RTMCCHead requires PyTorch >= 1.7')\n\n        decoder_cfg_list = []\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=(4.9, 5.66),\n            simcc_split_ratio=2.0,\n            normalize=False)\n        decoder_cfg_list.append(decoder_cfg)\n\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=(4.9, 5.66),\n            simcc_split_ratio=2.0,\n            normalize=True)\n        decoder_cfg_list.append(decoder_cfg)\n\n        # decoder\n        for decoder_cfg in decoder_cfg_list:\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                loss=dict(\n                    type='KLDiscretLoss',\n                    use_target_weight=True,\n                    beta=1.,\n                    label_softmax=False,\n                ),\n                decoder=decoder_cfg)\n\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2, simcc_split_ratio=2.0,\n                with_simcc_label=True)['data_samples']\n            losses = head.loss(feats, batch_data_samples)\n            self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n            self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n            self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n            # beta = 10\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                loss=dict(\n                    type='KLDiscretLoss',\n                    use_target_weight=True,\n                    beta=10.,\n                    label_softmax=False,\n                ),\n                decoder=decoder_cfg)\n\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2, simcc_split_ratio=2.0,\n                with_simcc_label=True)['data_samples']\n            losses = head.loss(feats, batch_data_samples)\n            self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n            self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n            self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n            # label softmax\n            head = RTMCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                final_layer_kernel_size=7,\n                gau_cfg=dict(\n                    hidden_dims=256,\n                    s=128,\n                    expansion_factor=2,\n                    dropout_rate=0.,\n                    drop_path=0.,\n                    act_fn='SiLU',\n                    use_rel_bias=False,\n                    pos_enc=False),\n                loss=dict(\n                    type='KLDiscretLoss',\n                    use_target_weight=True,\n                    beta=10.,\n                    label_softmax=True,\n                ),\n                decoder=decoder_cfg)\n\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2, simcc_split_ratio=2.0,\n                with_simcc_label=True)['data_samples']\n            losses = head.loss(feats, batch_data_samples)\n            self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n            self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n            self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_simcc_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.models.heads import SimCCHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestSimCCHead(TestCase):\n\n    def _get_feats(self,\n                   batch_size: int = 2,\n                   feat_shapes: List[Tuple[int, int, int]] = [(32, 6, 8)]):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n        return feats\n\n    def test_init(self):\n\n        # w/ gaussian decoder\n        head = SimCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='gaussian',\n                sigma=6.,\n                simcc_split_ratio=2.0))\n        self.assertIsNotNone(head.decoder)\n\n        # w/ label-smoothing decoder\n        head = SimCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=3.0,\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='standard',\n                sigma=6.,\n                simcc_split_ratio=3.0,\n                label_smooth_weight=0.1))\n        self.assertIsNotNone(head.decoder)\n\n        # w/ one-hot decoder\n        head = SimCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=3.0,\n            decoder=dict(\n                type='SimCCLabel',\n                input_size=(192, 256),\n                smoothing_type='standard',\n                sigma=6.,\n                simcc_split_ratio=3.0))\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg1 = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=2.,\n            simcc_split_ratio=2.0)\n\n        decoder_cfg2 = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='standard',\n            sigma=2.,\n            simcc_split_ratio=2.0)\n\n        decoder_cfg3 = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='standard',\n            sigma=2.,\n            simcc_split_ratio=2.0,\n            label_smooth_weight=0.1)\n\n        for decoder_cfg in [decoder_cfg1, decoder_cfg2, decoder_cfg3]:\n\n            head = SimCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds = head.predict(feats, batch_data_samples)\n\n            self.assertTrue(len(preds), 2)\n            self.assertIsInstance(preds[0], InstanceData)\n            self.assertEqual(\n                preds[0].keypoints.shape,\n                batch_data_samples[0].gt_instances.keypoints.shape)\n\n            # input transform: output heatmap\n            head = SimCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                decoder=decoder_cfg)\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2,\n                simcc_split_ratio=decoder_cfg['simcc_split_ratio'],\n                with_simcc_label=True)['data_samples']\n            preds, pred_heatmaps = head.predict(\n                feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n            self.assertEqual(preds[0].keypoint_x_labels.shape,\n                             (1, 17, 192 * 2))\n            self.assertEqual(preds[0].keypoint_y_labels.shape,\n                             (1, 17, 256 * 2))\n            self.assertTrue(len(pred_heatmaps), 2)\n            self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 512, 384))\n\n    def test_tta(self):\n        # flip test\n        decoder_cfg = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=2.,\n            simcc_split_ratio=2.0)\n\n        head = SimCCHead(\n            in_channels=32,\n            out_channels=17,\n            input_size=(192, 256),\n            in_featuremap_size=(6, 8),\n            simcc_split_ratio=2.0,\n            decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, simcc_split_ratio=2.0,\n            with_simcc_label=True)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(flip_test=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        decoder_cfg1 = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='gaussian',\n            sigma=2.,\n            simcc_split_ratio=2.0)\n\n        decoder_cfg2 = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='standard',\n            sigma=2.,\n            simcc_split_ratio=2.0)\n\n        decoder_cfg3 = dict(\n            type='SimCCLabel',\n            input_size=(192, 256),\n            smoothing_type='standard',\n            sigma=2.,\n            simcc_split_ratio=2.0,\n            label_smooth_weight=0.1)\n\n        # decoder\n        for decoder_cfg in [decoder_cfg1, decoder_cfg2, decoder_cfg3]:\n            head = SimCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(6, 8),\n                simcc_split_ratio=2.0,\n                decoder=decoder_cfg)\n\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2, simcc_split_ratio=2.0,\n                with_simcc_label=True)['data_samples']\n            losses = head.loss(feats, batch_data_samples)\n            self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n            self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n            self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n    def test_errors(self):\n        # Invalid arguments\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = SimCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(48, 64),\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(4, 4))\n\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = SimCCHead(\n                in_channels=32,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(48, 64),\n                conv_out_channels=(256, ),\n                conv_kernel_sizes=(1, 1))\n\n        with self.assertRaisesRegex(ValueError, 'Unsupported kernel size'):\n            _ = SimCCHead(\n                in_channels=16,\n                out_channels=17,\n                input_size=(192, 256),\n                in_featuremap_size=(48, 64),\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(1, ))\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_heatmap_heads/test_vipnas_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import nn\n\nfrom mmpose.models.heads import ViPNASHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestViPNASHead(TestCase):\n\n    def _get_feats(self,\n                   batch_size: int = 2,\n                   feat_shapes: List[Tuple[int, int, int]] = [(32, 6, 8)]):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n        return feats\n\n    def test_init(self):\n        # w/o deconv\n        head = ViPNASHead(\n            in_channels=32, out_channels=17, deconv_out_channels=None)\n        self.assertTrue(isinstance(head.deconv_layers, nn.Identity))\n\n        # w/ deconv and w/o conv\n        head = ViPNASHead(\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            deconv_num_groups=(1, 1))\n        self.assertTrue(isinstance(head.deconv_layers, nn.Sequential))\n        self.assertTrue(isinstance(head.conv_layers, nn.Identity))\n\n        # w/ both deconv and conv\n        head = ViPNASHead(\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            deconv_num_groups=(1, 1),\n            conv_out_channels=(32, ),\n            conv_kernel_sizes=(1, ))\n        self.assertTrue(isinstance(head.deconv_layers, nn.Sequential))\n        self.assertTrue(isinstance(head.conv_layers, nn.Sequential))\n\n        # w/o final layer\n        head = ViPNASHead(in_channels=32, out_channels=17, final_layer=None)\n        self.assertTrue(isinstance(head.final_layer, nn.Identity))\n\n        # w/ decoder\n        head = ViPNASHead(\n            in_channels=32,\n            out_channels=17,\n            decoder=dict(\n                type='MSRAHeatmap',\n                input_size=(192, 256),\n                heatmap_size=(48, 64),\n                sigma=2.))\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        head = ViPNASHead(\n            in_channels=32,\n            out_channels=17,\n            deconv_out_channels=(256, 256),\n            deconv_kernel_sizes=(4, 4),\n            deconv_num_groups=(1, 1),\n            conv_out_channels=(256, ),\n            conv_kernel_sizes=(1, ),\n            decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # input transform: output heatmap\n        head = ViPNASHead(in_channels=32, out_channels=17, decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        _, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertTrue(len(pred_heatmaps), 2)\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 64, 48))\n\n    def test_tta(self):\n        # flip test: heatmap\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        # input transform: select\n        head = ViPNASHead(in_channels=32, out_channels=17, decoder=decoder_cfg)\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(\n                                 flip_test=True,\n                                 flip_mode='heatmap',\n                                 shift_heatmap=True,\n                             ))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        head = ViPNASHead(in_channels=32, out_channels=17)\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n    def test_errors(self):\n        # Invalid arguments\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = ViPNASHead(\n                in_channels=32,\n                out_channels=17,\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(4, 4))\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = ViPNASHead(\n                in_channels=32,\n                out_channels=17,\n                deconv_out_channels=(256, 256),\n                deconv_kernel_sizes=(4, 4),\n                deconv_num_groups=(1, ))\n\n        with self.assertRaisesRegex(ValueError, 'Got mismatched lengths'):\n            _ = ViPNASHead(\n                in_channels=32,\n                out_channels=17,\n                conv_out_channels=(256, ),\n                conv_kernel_sizes=(1, 1))\n\n        with self.assertRaisesRegex(ValueError, 'Unsupported kernel size'):\n            _ = ViPNASHead(\n                in_channels=16,\n                out_channels=17,\n                deconv_out_channels=(256, ),\n                deconv_kernel_sizes=(1, ),\n                deconv_num_groups=(1, ))\n\n    def test_state_dict_compatible(self):\n        # Typical setting for MobileNetV3\n        head = ViPNASHead(\n            in_channels=160,\n            out_channels=17,\n            deconv_out_channels=(160, 160, 160),\n            deconv_num_groups=(160, 160, 160))\n\n        state_dict = {\n            'deconv_layers.0.weight': torch.zeros([160, 1, 4, 4]),\n            'deconv_layers.1.weight': torch.zeros([160]),\n            'deconv_layers.1.bias': torch.zeros([160]),\n            'deconv_layers.1.running_mean': torch.zeros([160]),\n            'deconv_layers.1.running_var': torch.zeros([160]),\n            'deconv_layers.1.num_batches_tracked': torch.zeros([]),\n            'deconv_layers.3.weight': torch.zeros([160, 1, 4, 4]),\n            'deconv_layers.4.weight': torch.zeros([160]),\n            'deconv_layers.4.bias': torch.zeros([160]),\n            'deconv_layers.4.running_mean': torch.zeros([160]),\n            'deconv_layers.4.running_var': torch.zeros([160]),\n            'deconv_layers.4.num_batches_tracked': torch.zeros([]),\n            'deconv_layers.6.weight': torch.zeros([160, 1, 4, 4]),\n            'deconv_layers.7.weight': torch.zeros([160]),\n            'deconv_layers.7.bias': torch.zeros([160]),\n            'deconv_layers.7.running_mean': torch.zeros([160]),\n            'deconv_layers.7.running_var': torch.zeros([160]),\n            'deconv_layers.7.num_batches_tracked': torch.zeros([]),\n            'final_layer.weight': torch.zeros([17, 160, 1, 1]),\n            'final_layer.bias': torch.zeros([17])\n        }\n        head.load_state_dict(state_dict)\n\n        # Typical setting for Resnet\n        head = ViPNASHead(in_channels=608, out_channels=17)\n\n        state_dict = {\n            'deconv_layers.0.weight': torch.zeros([608, 9, 4, 4]),\n            'deconv_layers.1.weight': torch.zeros([144]),\n            'deconv_layers.1.bias': torch.zeros([144]),\n            'deconv_layers.1.running_mean': torch.zeros([144]),\n            'deconv_layers.1.running_var': torch.zeros([144]),\n            'deconv_layers.1.num_batches_tracked': torch.zeros([]),\n            'deconv_layers.3.weight': torch.zeros([144, 9, 4, 4]),\n            'deconv_layers.4.weight': torch.zeros([144]),\n            'deconv_layers.4.bias': torch.zeros([144]),\n            'deconv_layers.4.running_mean': torch.zeros([144]),\n            'deconv_layers.4.running_var': torch.zeros([144]),\n            'deconv_layers.4.num_batches_tracked': torch.zeros([]),\n            'deconv_layers.6.weight': torch.zeros([144, 9, 4, 4]),\n            'deconv_layers.7.weight': torch.zeros([144]),\n            'deconv_layers.7.bias': torch.zeros([144]),\n            'deconv_layers.7.running_mean': torch.zeros([144]),\n            'deconv_layers.7.running_var': torch.zeros([144]),\n            'deconv_layers.7.num_batches_tracked': torch.zeros([]),\n            'final_layer.weight': torch.zeros([17, 144, 1, 1]),\n            'final_layer.bias': torch.zeros([17])\n        }\n        head.load_state_dict(state_dict)\n"
  },
  {
    "path": "tests/test_models/test_heads/test_hybrid_heads/test_dekr_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.utils import is_tuple_of\n\nfrom mmpose.models.heads import DEKRHead\nfrom mmpose.testing import get_coco_sample, get_packed_inputs\nfrom mmpose.utils.tensor_utils import to_tensor\n\n\nclass TestDEKRHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 1,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 128, 128)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        if len(feats) > 1:\n            feats = [[x] for x in feats]\n\n        return feats\n\n    def _get_data_samples(self):\n        data_samples = get_packed_inputs(\n            1,\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            img_shape=(512, 512))['data_samples']\n        return data_samples\n\n    def test_forward(self):\n\n        head = DEKRHead(in_channels=32, num_keypoints=17)\n\n        feats = [torch.rand(1, 32, 128, 128)]\n        output = head.forward(feats)  # should be (heatmaps, displacements)\n        self.assertTrue(is_tuple_of(output, torch.Tensor))\n        self.assertEqual(output[0].shape, (1, 18, 128, 128))\n        self.assertEqual(output[1].shape, (1, 34, 128, 128))\n\n    def test_predict(self):\n\n        codec_cfg = dict(\n            type='SPR',\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, 2),\n            generate_keypoint_heatmaps=True,\n        )\n\n        head = DEKRHead(in_channels=32, num_keypoints=17, decoder=codec_cfg)\n\n        feats = self._get_feats()\n        data_samples = self._get_data_samples()\n        with torch.no_grad():\n            preds = head.predict(feats, data_samples)\n            self.assertEqual(len(preds), 1)\n            self.assertEqual(preds[0].keypoints.shape[1:], (17, 2))\n            self.assertEqual(preds[0].keypoint_scores.shape[1:], (17, ))\n\n        # predict with rescore net\n        head = DEKRHead(\n            in_channels=32,\n            num_keypoints=17,\n            decoder=codec_cfg,\n            rescore_cfg=dict(in_channels=74, norm_indexes=(5, 6)))\n\n        with torch.no_grad():\n            preds = head.predict(feats, data_samples)\n            self.assertEqual(len(preds), 1)\n            self.assertEqual(preds[0].keypoints.shape[1:], (17, 2))\n            self.assertEqual(preds[0].keypoint_scores.shape[1:], (17, ))\n\n        # tta\n        with torch.no_grad():\n            feats_flip = self._get_feats(feat_shapes=[(32, 128,\n                                                       128), (32, 128, 128)])\n            preds = head.predict(feats_flip, data_samples,\n                                 dict(flip_test=True))\n            self.assertEqual(len(preds), 1)\n            self.assertEqual(preds[0].keypoints.shape[1:], (17, 2))\n            self.assertEqual(preds[0].keypoint_scores.shape[1:], (17, ))\n\n        # output heatmaps\n        with torch.no_grad():\n            _, pred_fields = head.predict(feats, data_samples,\n                                          dict(output_heatmaps=True))\n            self.assertEqual(len(pred_fields), 1)\n            self.assertEqual(pred_fields[0].heatmaps.shape, (18, 128, 128))\n            self.assertEqual(pred_fields[0].displacements.shape,\n                             (34, 128, 128))\n\n    def test_loss(self):\n        data = get_coco_sample(img_shape=(512, 512), num_instances=1)\n\n        codec_cfg = dict(\n            type='SPR',\n            input_size=(512, 512),\n            heatmap_size=(128, 128),\n            sigma=(4, 2),\n            generate_keypoint_heatmaps=True,\n        )\n\n        head = DEKRHead(\n            in_channels=32,\n            num_keypoints=17,\n            decoder=codec_cfg,\n            heatmap_loss=dict(type='KeypointMSELoss', use_target_weight=True),\n            displacement_loss=dict(\n                type='SoftWeightSmoothL1Loss',\n                use_target_weight=True,\n                supervise_empty=False,\n                beta=1 / 9,\n            ))\n\n        encoded = head.decoder.encode(data['keypoints'],\n                                      data['keypoints_visible'])\n        feats = self._get_feats()\n        data_samples = self._get_data_samples()\n        for data_sample in data_samples:\n            data_sample.gt_fields.set_data(\n                {k: to_tensor(v)\n                 for k, v in encoded.items()})\n\n        losses = head.loss(feats, data_samples)\n        self.assertIn('loss/heatmap', losses)\n        self.assertEqual(losses['loss/heatmap'].ndim, 0)\n        self.assertIn('loss/displacement', losses)\n        self.assertEqual(losses['loss/displacement'].ndim, 0)\n"
  },
  {
    "path": "tests/test_models/test_heads/test_hybrid_heads/test_vis_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\nfrom torch import nn\n\nfrom mmpose.models.heads import VisPredictHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestVisPredictHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 8, 6)],\n    ):\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n        return feats\n\n    def test_init(self):\n        codec = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n                deconv_out_channels=None,\n                loss=dict(type='KeypointMSELoss', use_target_weight=True),\n                decoder=codec))\n\n        self.assertTrue(isinstance(head.vis_head, nn.Sequential))\n        self.assertEqual(head.vis_head[2].weight.shape, (17, 32))\n        self.assertIsNotNone(head.pose_head)\n\n    def test_forward(self):\n\n        codec = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2)\n\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n                deconv_out_channels=None,\n                loss=dict(type='KeypointMSELoss', use_target_weight=True),\n                decoder=codec))\n\n        feats = [torch.rand(1, 32, 128, 128)]\n        output_pose, output_vis = head.forward(feats)\n\n        self.assertIsInstance(output_pose, torch.Tensor)\n        self.assertEqual(output_pose.shape, (1, 17, 128, 128))\n\n        self.assertIsInstance(output_vis, torch.Tensor)\n        self.assertEqual(output_vis.shape, (1, 17))\n\n    def test_predict(self):\n\n        codec = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n                deconv_out_channels=None,\n                loss=dict(type='KeypointMSELoss', use_target_weight=True),\n                decoder=codec))\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 128, 128)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n\n        preds, _ = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n        self.assertEqual(\n            preds[0].keypoint_scores.shape,\n            batch_data_samples[0].gt_instance_labels.keypoint_weights.shape)\n\n        # output heatmap\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n                decoder=codec))\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        _, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 64, 48))\n\n    def test_tta(self):\n        # flip test: vis and heatmap\n        decoder_cfg = dict(\n            type='MSRAHeatmap',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2.)\n\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n                decoder=decoder_cfg))\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        preds, _ = head.predict([feats, feats],\n                                batch_data_samples,\n                                test_cfg=dict(\n                                    flip_test=True,\n                                    flip_mode='heatmap',\n                                    shift_heatmap=True,\n                                ))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n        self.assertEqual(\n            preds[0].keypoint_scores.shape,\n            batch_data_samples[0].gt_instance_labels.keypoint_weights.shape)\n\n    def test_loss(self):\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n            ))\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n        self.assertIsInstance(losses['loss_vis'], torch.Tensor)\n        self.assertEqual(losses['loss_vis'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_vis'], torch.Tensor)\n\n        head = VisPredictHead(\n            pose_cfg=dict(\n                type='HeatmapHead',\n                in_channels=32,\n                out_channels=17,\n            ))\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n        self.assertIsInstance(losses['loss_vis'], torch.Tensor)\n        self.assertEqual(losses['loss_vis'].shape, torch.Size(()))\n        self.assertIsInstance(losses['acc_vis'], torch.Tensor)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_regression_heads/test_dsnt_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.models.heads import DSNTHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestDSNTHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 6, 8)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        return feats\n\n    def test_init(self):\n        # square heatmap\n        head = DSNTHead(\n            in_channels=32, in_featuremap_size=(8, 8), num_joints=17)\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 64))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 64, 1))\n        self.assertIsNone(head.decoder)\n\n        # rectangle heatmap\n        head = DSNTHead(\n            in_channels=32, in_featuremap_size=(6, 8), num_joints=17)\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6 * 8))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8 * 8, 1))\n        self.assertIsNone(head.decoder)\n\n        # 2 deconv + 1x1 conv\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            conv_out_channels=(32, ),\n            conv_kernel_sizes=(1, ),\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6 * 4))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8 * 4, 1))\n        self.assertIsNone(head.decoder)\n\n        # 2 deconv + w/o 1x1 conv\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            conv_out_channels=(32, ),\n            conv_kernel_sizes=(1, ),\n            final_layer=None,\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6 * 4))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8 * 4, 1))\n        self.assertIsNone(head.decoder)\n\n        # w/o deconv and 1x1 conv\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=tuple(),\n            deconv_kernel_sizes=tuple(),\n            final_layer=None,\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8, 1))\n        self.assertIsNone(head.decoder)\n\n        # w/o deconv and 1x1 conv\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=None,\n            deconv_kernel_sizes=None,\n            final_layer=None,\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8, 1))\n        self.assertIsNone(head.decoder)\n\n        # w/ decoder\n        head = DSNTHead(\n            in_channels=1024,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=dict(\n                type='IntegralRegressionLabel',\n                input_size=(192, 256),\n                heatmap_size=(48, 64),\n                sigma=2))\n\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg = dict(\n            type='IntegralRegressionLabel',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2)\n\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_reg_label=False)['data_samples']\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # output heatmap\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_reg_label=False)['data_samples']\n        _, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertTrue(len(pred_heatmaps), 2)\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 8 * 8, 6 * 8))\n\n    def test_tta(self):\n        decoder_cfg = dict(\n            type='IntegralRegressionLabel',\n            input_size=(192, 256),\n            heatmap_size=(48, 64),\n            sigma=2)\n\n        # inputs transform: select\n        head = DSNTHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_reg_label=False)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(flip_test=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        for dist_loss in ['l1', 'l2']:\n            head = DSNTHead(\n                in_channels=32,\n                in_featuremap_size=(6, 8),\n                num_joints=17,\n                loss=dict(\n                    type='MultipleLossWrapper',\n                    losses=[\n                        dict(type='SmoothL1Loss', use_target_weight=True),\n                        dict(type='JSDiscretLoss', use_target_weight=True)\n                    ]))\n\n            feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n            batch_data_samples = get_packed_inputs(\n                batch_size=2, with_reg_label=True)['data_samples']\n            losses = head.loss(feats, batch_data_samples)\n\n            self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n            self.assertEqual(losses['loss_kpt'].shape, torch.Size())\n            self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_regression_heads/test_integral_regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.models.heads import IntegralRegressionHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestIntegralRegressionHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 6, 8)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        return feats\n\n    def test_init(self):\n        # square heatmap\n        head = IntegralRegressionHead(\n            in_channels=32, in_featuremap_size=(8, 8), num_joints=17)\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 64))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 64, 1))\n        self.assertIsNone(head.decoder)\n\n        # rectangle heatmap\n        head = IntegralRegressionHead(\n            in_channels=32, in_featuremap_size=(6, 8), num_joints=17)\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6 * 8))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8 * 8, 1))\n        self.assertIsNone(head.decoder)\n\n        # 2 deconv + 1x1 conv\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            conv_out_channels=(32, ),\n            conv_kernel_sizes=(1, ),\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6 * 4))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8 * 4, 1))\n        self.assertIsNone(head.decoder)\n\n        # 2 deconv + w/o 1x1 conv\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=(32, 32),\n            deconv_kernel_sizes=(4, 4),\n            conv_out_channels=(32, ),\n            conv_kernel_sizes=(1, ),\n            final_layer=None,\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6 * 4))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8 * 4, 1))\n        self.assertIsNone(head.decoder)\n\n        # w/o deconv and 1x1 conv\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=tuple(),\n            deconv_kernel_sizes=tuple(),\n            final_layer=None,\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8, 1))\n        self.assertIsNone(head.decoder)\n\n        # w/o deconv and 1x1 conv\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            deconv_out_channels=None,\n            deconv_kernel_sizes=None,\n            final_layer=None,\n        )\n        self.assertEqual(head.linspace_x.shape, (1, 1, 1, 6))\n        self.assertEqual(head.linspace_y.shape, (1, 1, 8, 1))\n        self.assertIsNone(head.decoder)\n\n        # w/ decoder\n        head = IntegralRegressionHead(\n            in_channels=1024,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=dict(type='RegressionLabel', input_size=(192, 256)),\n        )\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg = dict(type='RegressionLabel', input_size=(192, 256))\n\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n        # output heatmap\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        _, pred_heatmaps = head.predict(\n            feats, batch_data_samples, test_cfg=dict(output_heatmaps=True))\n\n        self.assertTrue(len(pred_heatmaps), 2)\n        self.assertIsInstance(pred_heatmaps[0], PixelData)\n        self.assertEqual(pred_heatmaps[0].heatmaps.shape, (17, 8 * 8, 6 * 8))\n\n    def test_tta(self):\n        decoder_cfg = dict(type='RegressionLabel', input_size=(192, 256))\n\n        # inputs transform: select\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(\n                                 flip_test=True,\n                                 shift_coords=True,\n                                 shift_heatmap=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        head = IntegralRegressionHead(\n            in_channels=32,\n            in_featuremap_size=(6, 8),\n            num_joints=17,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 8, 6)])\n        batch_data_samples = get_packed_inputs(batch_size=2)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size())\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_regression_heads/test_regression_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.models.heads import RegressionHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestRegressionHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 1, 1)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        return feats\n\n    def test_init(self):\n\n        head = RegressionHead(in_channels=1024, num_joints=17)\n        self.assertEqual(head.fc.weight.shape, (17 * 2, 1024))\n        self.assertIsNone(head.decoder)\n\n        # w/ decoder\n        head = RegressionHead(\n            in_channels=1024,\n            num_joints=17,\n            decoder=dict(type='RegressionLabel', input_size=(192, 256)),\n        )\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg = dict(type='RegressionLabel', input_size=(192, 256))\n\n        head = RegressionHead(\n            in_channels=32,\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 1, 1)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_tta(self):\n        decoder_cfg = dict(type='RegressionLabel', input_size=(192, 256))\n\n        # inputs transform: select\n        head = RegressionHead(\n            in_channels=32,\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 1, 1)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(flip_test=True, shift_coords=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        head = RegressionHead(\n            in_channels=32,\n            num_joints=17,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 1, 1)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size())\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_heads/test_regression_heads/test_rle_head.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.models.heads import RLEHead\nfrom mmpose.testing import get_packed_inputs\n\n\nclass TestRLEHead(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 1, 1)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        return feats\n\n    def test_init(self):\n\n        # w/ sigma\n        head = RLEHead(in_channels=1024, num_joints=17)\n        self.assertEqual(head.fc.weight.shape, (17 * 4, 1024))\n        self.assertIsNone(head.decoder)\n\n        # w/ decoder\n        head = RLEHead(\n            in_channels=1024,\n            num_joints=17,\n            decoder=dict(type='RegressionLabel', input_size=(192, 256)),\n        )\n        self.assertIsNotNone(head.decoder)\n\n    def test_predict(self):\n        decoder_cfg = dict(type='RegressionLabel', input_size=(192, 256))\n\n        head = RLEHead(\n            in_channels=32,\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 1, 1)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        preds = head.predict(feats, batch_data_samples)\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_tta(self):\n        decoder_cfg = dict(type='RegressionLabel', input_size=(192, 256))\n\n        head = RLEHead(\n            in_channels=32,\n            num_joints=17,\n            decoder=decoder_cfg,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 1, 1)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        preds = head.predict([feats, feats],\n                             batch_data_samples,\n                             test_cfg=dict(flip_test=True))\n\n        self.assertTrue(len(preds), 2)\n        self.assertIsInstance(preds[0], InstanceData)\n        self.assertEqual(preds[0].keypoints.shape,\n                         batch_data_samples[0].gt_instances.keypoints.shape)\n\n    def test_loss(self):\n        head = RLEHead(\n            in_channels=32,\n            num_joints=17,\n        )\n\n        feats = self._get_feats(batch_size=2, feat_shapes=[(32, 1, 1)])\n        batch_data_samples = get_packed_inputs(\n            batch_size=2, with_heatmap=False)['data_samples']\n        losses = head.loss(feats, batch_data_samples)\n\n        self.assertIsInstance(losses['loss_kpt'], torch.Tensor)\n        self.assertEqual(losses['loss_kpt'].shape, torch.Size())\n        self.assertIsInstance(losses['acc_pose'], torch.Tensor)\n\n    def test_state_dict_compatible(self):\n\n        head = RLEHead(in_channels=2048, num_joints=17)\n\n        state_dict = {\n            'fc.weight': torch.zeros((17 * 4, 2048)),\n            'fc.bias': torch.zeros((17 * 4)),\n            'loss.flow_model.loc': torch.zeros(torch.Size([2])),\n            'loss.flow_model.cov': torch.zeros(torch.Size([2, 2])),\n            'loss.flow_model.mask': torch.zeros(torch.Size([6, 2])),\n            'loss.flow_model.s.0.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.s.0.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.0.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.s.0.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.0.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.s.0.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.s.1.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.s.1.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.1.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.s.1.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.1.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.s.1.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.s.2.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.s.2.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.2.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.s.2.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.2.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.s.2.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.s.3.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.s.3.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.3.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.s.3.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.3.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.s.3.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.s.4.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.s.4.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.4.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.s.4.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.4.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.s.4.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.s.5.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.s.5.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.5.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.s.5.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.s.5.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.s.5.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.t.0.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.t.0.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.0.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.t.0.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.0.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.t.0.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.t.1.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.t.1.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.1.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.t.1.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.1.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.t.1.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.t.2.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.t.2.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.2.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.t.2.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.2.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.t.2.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.t.3.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.t.3.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.3.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.t.3.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.3.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.t.3.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.t.4.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.t.4.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.4.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.t.4.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.4.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.t.4.4.bias': torch.zeros(torch.Size([2])),\n            'loss.flow_model.t.5.0.weight': torch.zeros(torch.Size([64, 2])),\n            'loss.flow_model.t.5.0.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.5.2.weight': torch.zeros(torch.Size([64, 64])),\n            'loss.flow_model.t.5.2.bias': torch.zeros(torch.Size([64])),\n            'loss.flow_model.t.5.4.weight': torch.zeros(torch.Size([2, 64])),\n            'loss.flow_model.t.5.4.bias': torch.zeros(torch.Size([2]))\n        }\n        head.load_state_dict(state_dict)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_losses/test_ae_loss.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom itertools import product\nfrom typing import Tuple\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nimport torch.nn as nn\nfrom torch import Tensor\n\nfrom mmpose.codecs.associative_embedding import AssociativeEmbedding\nfrom mmpose.models.losses.ae_loss import AssociativeEmbeddingLoss\nfrom mmpose.testing._utils import get_coco_sample\n\n\nclass AELoss(nn.Module):\n    \"\"\"Associative Embedding loss in MMPose v0.x.\"\"\"\n\n    def __init__(self, loss_type):\n        super().__init__()\n        self.loss_type = loss_type\n\n    @staticmethod\n    def _make_input(t, requires_grad=False, device=torch.device('cpu')):\n        \"\"\"Make zero inputs for AE loss.\n\n        Args:\n            t (torch.Tensor): input\n            requires_grad (bool): Option to use requires_grad.\n            device: torch device\n\n        Returns:\n            torch.Tensor: zero input.\n        \"\"\"\n        inp = torch.autograd.Variable(t, requires_grad=requires_grad)\n        inp = inp.sum()\n        inp = inp.to(device)\n        return inp\n\n    def singleTagLoss(self, pred_tag, joints):\n        \"\"\"Associative embedding loss for one image.\n\n        Note:\n            - heatmaps weight: W\n            - heatmaps height: H\n            - max_num_people: M\n            - num_keypoints: K\n\n        Args:\n            pred_tag (torch.Tensor[KxHxW,1]): tag of output for one image.\n            joints (torch.Tensor[M,K,2]): joints information for one image.\n        \"\"\"\n        tags = []\n        pull = 0\n        pred_tag = pred_tag.view(17, -1, 1)\n        for joints_per_person in joints:\n            tmp = []\n            for k, joint in enumerate(joints_per_person):\n                if joint[1] > 0:\n                    tmp.append(pred_tag[k, joint[0]])\n            if len(tmp) == 0:\n                continue\n            tmp = torch.stack(tmp)\n            tags.append(torch.mean(tmp, dim=0))\n            pull = pull + torch.mean((tmp - tags[-1].expand_as(tmp))**2)\n\n        num_tags = len(tags)\n        if num_tags == 0:\n            return (self._make_input(\n                torch.zeros(1).float(), device=pred_tag.device),\n                    self._make_input(\n                        torch.zeros(1).float(), device=pred_tag.device))\n        elif num_tags == 1:\n            return (self._make_input(\n                torch.zeros(1).float(), device=pred_tag.device), pull)\n\n        tags = torch.stack(tags)\n\n        size = (num_tags, num_tags)\n        A = tags.expand(*size)\n        B = A.permute(1, 0)\n\n        diff = A - B\n\n        if self.loss_type == 'exp':\n            diff = torch.pow(diff, 2)\n            push = torch.exp(-diff)\n            push = torch.sum(push)\n        elif self.loss_type == 'max':\n            diff = 1 - torch.abs(diff)\n            push = torch.clamp(diff, min=0).sum() - num_tags\n        else:\n            raise ValueError('Unknown ae loss type')\n\n        push_loss = push / ((num_tags - 1) * num_tags) * 0.5\n        pull_loss = pull / (num_tags)\n\n        return push_loss, pull_loss\n\n    def forward(self, tags, keypoint_indices):\n        assert tags.shape[0] == len(keypoint_indices)\n\n        pull_loss = 0.\n        push_loss = 0.\n\n        for i in range(tags.shape[0]):\n            _push, _pull = self.singleTagLoss(tags[i].view(-1, 1),\n                                              keypoint_indices[i])\n            pull_loss += _pull\n            push_loss += _push\n\n        return pull_loss, push_loss\n\n\nclass TestAssociativeEmbeddingLoss(TestCase):\n\n    def _make_input(self, num_instance: int) -> Tuple[Tensor, Tensor]:\n\n        encoder = AssociativeEmbedding(\n            input_size=(256, 256), heatmap_size=(64, 64))\n\n        data = get_coco_sample(\n            img_shape=(256, 256), num_instances=num_instance)\n        encoded = encoder.encode(data['keypoints'], data['keypoints_visible'])\n        heatmaps = encoded['heatmaps']\n        keypoint_indices = encoded['keypoint_indices']\n\n        tags = self._get_tags(\n            heatmaps, keypoint_indices, tag_per_keypoint=True)\n\n        batch_tags = torch.from_numpy(tags[None])\n        batch_keypoint_indices = [torch.from_numpy(keypoint_indices)]\n\n        return batch_tags, batch_keypoint_indices\n\n    def _get_tags(self,\n                  heatmaps,\n                  keypoint_indices,\n                  tag_per_keypoint: bool,\n                  with_randomness: bool = True):\n\n        K, H, W = heatmaps.shape\n        N = keypoint_indices.shape[0]\n\n        if tag_per_keypoint:\n            tags = np.zeros((K, H, W), dtype=np.float32)\n        else:\n            tags = np.zeros((1, H, W), dtype=np.float32)\n\n        for n, k in product(range(N), range(K)):\n            y, x = np.unravel_index(keypoint_indices[n, k, 0], (H, W))\n\n            randomness = np.random.rand() if with_randomness else 0\n\n            if tag_per_keypoint:\n                tags[k, y, x] = n + randomness\n            else:\n                tags[0, y, x] = n + randomness\n\n        return tags\n\n    def test_loss(self):\n\n        tags, keypoint_indices = self._make_input(num_instance=2)\n\n        # test loss calculation\n        loss_module = AssociativeEmbeddingLoss()\n        pull_loss, push_loss = loss_module(tags, keypoint_indices)\n        _pull_loss, _push_loss = AELoss('exp')(tags, keypoint_indices)\n\n        self.assertTrue(torch.allclose(pull_loss, _pull_loss))\n        self.assertTrue(torch.allclose(push_loss, _push_loss))\n\n        # test loss weight\n        loss_module = AssociativeEmbeddingLoss(loss_weight=0.)\n        pull_loss, push_loss = loss_module(tags, keypoint_indices)\n\n        self.assertTrue(torch.allclose(pull_loss, torch.zeros(1)))\n        self.assertTrue(torch.allclose(push_loss, torch.zeros(1)))\n\n        # test push loss factor\n        loss_module = AssociativeEmbeddingLoss(push_loss_factor=0.)\n        pull_loss, push_loss = loss_module(tags, keypoint_indices)\n\n        self.assertFalse(torch.allclose(pull_loss, torch.zeros(1)))\n        self.assertTrue(torch.allclose(push_loss, torch.zeros(1)))\n"
  },
  {
    "path": "tests/test_models/test_losses/test_classification_losses.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.losses.classification_loss import InfoNCELoss, VariFocalLoss\n\n\nclass TestInfoNCELoss(TestCase):\n\n    def test_loss(self):\n\n        # test loss w/o target_weight\n        loss = InfoNCELoss(temperature=0.05)\n\n        fake_pred = torch.arange(5 * 2).reshape(5, 2).float()\n        self.assertTrue(\n            torch.allclose(loss(fake_pred), torch.tensor(5.4026), atol=1e-4))\n\n        # check if the value of temperature is positive\n        with self.assertRaises(AssertionError):\n            loss = InfoNCELoss(temperature=0.)\n\n\nclass TestVariFocalLoss(TestCase):\n\n    def test_forward_no_target_weight_mean_reduction(self):\n        # Test the forward method with no target weight and mean reduction\n        output = torch.tensor([[0.3, -0.2], [-0.1, 0.4]], dtype=torch.float32)\n        target = torch.tensor([[1.0, 0.0], [0.0, 1.0]], dtype=torch.float32)\n\n        loss_func = VariFocalLoss(use_target_weight=False, reduction='mean')\n        loss = loss_func(output, target)\n\n        # Calculate expected loss manually or using an alternative method\n        expected_loss = 0.31683\n        self.assertAlmostEqual(loss.item(), expected_loss, places=5)\n\n    def test_forward_with_target_weight_sum_reduction(self):\n        # Test the forward method with target weight and sum reduction\n        output = torch.tensor([[0.3, -0.2], [-0.1, 0.4]], dtype=torch.float32)\n        target = torch.tensor([[1.0, 0.0], [0.0, 1.0]], dtype=torch.float32)\n        target_weight = torch.tensor([1.0, 0.5], dtype=torch.float32)\n\n        loss_func = VariFocalLoss(use_target_weight=True, reduction='sum')\n        loss = loss_func(output, target, target_weight)\n\n        # Calculate expected loss manually or using an alternative method\n        expected_loss = 0.956299\n        self.assertAlmostEqual(loss.item(), expected_loss, places=5)\n\n    def test_inf_nan_handling(self):\n        # Test handling of inf and nan values\n        output = torch.tensor([[float('inf'), float('-inf')],\n                               [float('nan'), 0.4]],\n                              dtype=torch.float32)\n        target = torch.tensor([[1.0, 0.0], [0.0, 1.0]], dtype=torch.float32)\n\n        loss_func = VariFocalLoss(use_target_weight=False, reduction='mean')\n        loss = loss_func(output, target)\n\n        # Check if loss is valid (not nan or inf)\n        self.assertFalse(torch.isnan(loss).item())\n        self.assertFalse(torch.isinf(loss).item())\n"
  },
  {
    "path": "tests/test_models/test_losses/test_heatmap_losses.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.losses.heatmap_loss import (AdaptiveWingLoss,\n                                               FocalHeatmapLoss,\n                                               KeypointMSELoss, MLECCLoss)\n\n\nclass TestAdaptiveWingLoss(TestCase):\n\n    def test_loss(self):\n\n        # test loss w/o target_weight\n        loss = AdaptiveWingLoss(use_target_weight=False)\n\n        fake_pred = torch.zeros((1, 3, 2, 2))\n        fake_label = torch.zeros((1, 3, 2, 2))\n        self.assertTrue(\n            torch.allclose(loss(fake_pred, fake_label), torch.tensor(0.)))\n\n        fake_pred = torch.ones((1, 3, 2, 2))\n        fake_label = torch.zeros((1, 3, 2, 2))\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label), torch.tensor(8.4959), atol=1e-4))\n\n        # test loss w/ target_weight\n        loss = AdaptiveWingLoss(use_target_weight=True)\n\n        fake_pred = torch.zeros((1, 3, 2, 2))\n        fake_label = torch.zeros((1, 3, 2, 2))\n        fake_weight = torch.tensor([1, 0, 1]).reshape(1, 3).float()\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight), torch.tensor(0.)))\n\n\nclass TestFocalHeatmapLoss(TestCase):\n\n    def test_loss(self):\n\n        loss = FocalHeatmapLoss(use_target_weight=False)\n\n        fake_pred = torch.zeros((1, 3, 5, 5))\n        fake_label = torch.zeros((1, 3, 5, 5))\n\n        self.assertTrue(\n            torch.allclose(loss(fake_pred, fake_label), torch.tensor(0.)))\n\n        fake_pred = torch.ones((1, 3, 5, 5)) * 0.4\n        fake_label = torch.ones((1, 3, 5, 5)) * 0.6\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label), torch.tensor(0.1569), atol=1e-4))\n\n        # test loss w/ target_weight\n        loss = FocalHeatmapLoss(use_target_weight=True)\n\n        fake_weight = torch.arange(3 * 5 * 5).reshape(1, 3, 5, 5).float()\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight),\n                torch.tensor(5.8062),\n                atol=1e-4))\n\n\nclass TestKeypointMSELoss(TestCase):\n\n    def test_loss(self):\n\n        # test loss w/o target_weight and without mask\n        loss = KeypointMSELoss(\n            use_target_weight=False, skip_empty_channel=False)\n\n        fake_pred = torch.zeros((1, 4, 4, 4))\n        fake_label = torch.zeros((1, 4, 4, 4))\n\n        self.assertTrue(\n            torch.allclose(loss(fake_pred, fake_label), torch.tensor(0.)))\n\n        fake_pred = torch.ones((1, 4, 4, 4)) * 0.5\n        fake_label = torch.ones((1, 4, 4, 4)) * 0.5\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label), torch.tensor(0.), atol=1e-4))\n\n        # test loss w/ target_weight and without mask\n        loss = KeypointMSELoss(\n            use_target_weight=True, skip_empty_channel=False)\n\n        fake_weight = torch.ones((1, 4)).float()\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight),\n                torch.tensor(0.),\n                atol=1e-4))\n\n        # test loss w/ target_weight and with mask\n        loss = KeypointMSELoss(\n            use_target_weight=True, skip_empty_channel=False)\n\n        fake_mask = torch.ones((1, 1, 4, 4)).float()\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight, fake_mask),\n                torch.tensor(0.),\n                atol=1e-4))\n\n        # test loss w/ target_weight and skip empty channels\n        loss = KeypointMSELoss(use_target_weight=True, skip_empty_channel=True)\n\n        fake_mask = torch.ones((1, 1, 4, 4)).float()\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight, fake_mask),\n                torch.tensor(0.),\n                atol=1e-4))\n\n\nclass TestMLECCLoss(TestCase):\n\n    def setUp(self):\n        self.outputs = (torch.rand(10, 2, 5), torch.rand(10, 2, 5))\n        self.targets = (torch.rand(10, 2, 5), torch.rand(10, 2, 5))\n\n    def test_mean_reduction_log_mode(self):\n        loss_func = MLECCLoss(reduction='mean', mode='log')\n        loss = loss_func(self.outputs, self.targets)\n        self.assertIsInstance(loss, torch.Tensor)\n\n    def test_sum_reduction_linear_mode(self):\n        loss_func = MLECCLoss(reduction='sum', mode='linear')\n        loss = loss_func(self.outputs, self.targets)\n        self.assertIsInstance(loss, torch.Tensor)\n\n    def test_none_reduction_square_mode(self):\n        loss_func = MLECCLoss(reduction='none', mode='square')\n        loss = loss_func(self.outputs, self.targets)\n        self.assertIsInstance(loss, torch.Tensor)\n\n    def test_target_weight(self):\n        target_weight = torch.rand(10)  # Random weights\n        loss_func = MLECCLoss(use_target_weight=True)\n        loss = loss_func(self.outputs, self.targets, target_weight)\n        self.assertIsInstance(loss, torch.Tensor)\n\n    def test_invalid_reduction(self):\n        with self.assertRaises(AssertionError):\n            MLECCLoss(reduction='invalid_reduction')\n\n    def test_invalid_mode(self):\n        with self.assertRaises(AssertionError):\n            MLECCLoss(mode='invalid_mode')\n"
  },
  {
    "path": "tests/test_models/test_losses/test_regression_losses.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.losses.regression_loss import SoftWeightSmoothL1Loss\n\n\nclass TestSoftWeightSmoothL1Loss(TestCase):\n\n    def test_loss(self):\n\n        # test loss w/o target_weight\n        loss = SoftWeightSmoothL1Loss(use_target_weight=False, beta=0.5)\n\n        fake_pred = torch.zeros((1, 3, 2))\n        fake_label = torch.zeros((1, 3, 2))\n        self.assertTrue(\n            torch.allclose(loss(fake_pred, fake_label), torch.tensor(0.)))\n\n        fake_pred = torch.ones((1, 3, 2))\n        fake_label = torch.zeros((1, 3, 2))\n        self.assertTrue(\n            torch.allclose(loss(fake_pred, fake_label), torch.tensor(.75)))\n\n        # test loss w/ target_weight\n        loss = SoftWeightSmoothL1Loss(\n            use_target_weight=True, supervise_empty=True)\n\n        fake_pred = torch.ones((1, 3, 2))\n        fake_label = torch.zeros((1, 3, 2))\n        fake_weight = torch.arange(6).reshape(1, 3, 2).float()\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight), torch.tensor(1.25)))\n\n        # test loss that does not take empty channels into account\n        loss = SoftWeightSmoothL1Loss(\n            use_target_weight=True, supervise_empty=False)\n        self.assertTrue(\n            torch.allclose(\n                loss(fake_pred, fake_label, fake_weight), torch.tensor(1.5)))\n\n        with self.assertRaises(ValueError):\n            _ = loss.smooth_l1_loss(fake_pred, fake_label, reduction='fake')\n\n        output = loss.smooth_l1_loss(fake_pred, fake_label, reduction='sum')\n        self.assertTrue(torch.allclose(output, torch.tensor(3.0)))\n"
  },
  {
    "path": "tests/test_models/test_necks/test_fmap_proc_neck.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom typing import List, Tuple\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.necks import FeatureMapProcessor\n\n\nclass TestFeatureMapProcessor(TestCase):\n\n    def _get_feats(\n        self,\n        batch_size: int = 2,\n        feat_shapes: List[Tuple[int, int, int]] = [(32, 1, 1)],\n    ):\n\n        feats = [\n            torch.rand((batch_size, ) + shape, dtype=torch.float32)\n            for shape in feat_shapes\n        ]\n\n        return feats\n\n    def test_init(self):\n\n        neck = FeatureMapProcessor(select_index=0)\n        self.assertSequenceEqual(neck.select_index, (0, ))\n\n        with self.assertRaises(AssertionError):\n            neck = FeatureMapProcessor(scale_factor=0.0)\n\n    def test_call(self):\n\n        inputs = self._get_feats(\n            batch_size=2, feat_shapes=[(2, 16, 16), (4, 8, 8), (8, 4, 4)])\n\n        neck = FeatureMapProcessor(select_index=0)\n        output = neck(inputs)\n        self.assertEqual(len(output), 1)\n        self.assertSequenceEqual(output[0].shape, (2, 2, 16, 16))\n\n        neck = FeatureMapProcessor(select_index=(2, 1))\n        output = neck(inputs)\n        self.assertEqual(len(output), 2)\n        self.assertSequenceEqual(output[1].shape, (2, 4, 8, 8))\n        self.assertSequenceEqual(output[0].shape, (2, 8, 4, 4))\n\n        neck = FeatureMapProcessor(select_index=(1, 2), concat=True)\n        output = neck(inputs)\n        self.assertEqual(len(output), 1)\n        self.assertSequenceEqual(output[0].shape, (2, 12, 8, 8))\n\n        neck = FeatureMapProcessor(\n            select_index=(2, 1), concat=True, scale_factor=2)\n        output = neck(inputs)\n        self.assertEqual(len(output), 1)\n        self.assertSequenceEqual(output[0].shape, (2, 12, 8, 8))\n\n        neck = FeatureMapProcessor(concat=True, apply_relu=True)\n        output = neck(inputs)\n        self.assertEqual(len(output), 1)\n        self.assertSequenceEqual(output[0].shape, (2, 14, 16, 16))\n        self.assertGreaterEqual(output[0].max(), 0)\n"
  },
  {
    "path": "tests/test_models/test_necks/test_yolox_pafpn.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.necks import YOLOXPAFPN\n\n\nclass TestYOLOXPAFPN(TestCase):\n\n    def test_forward(self):\n        in_channels = [128, 256, 512]\n        out_channels = 256\n        num_csp_blocks = 3\n\n        model = YOLOXPAFPN(\n            in_channels=in_channels,\n            out_channels=out_channels,\n            num_csp_blocks=num_csp_blocks)\n        model.train()\n\n        inputs = [\n            torch.randn(1, c, 64 // (2**i), 64 // (2**i))\n            for i, c in enumerate(in_channels)\n        ]\n        outputs = model(inputs)\n\n        self.assertEqual(len(outputs), len(in_channels))\n        for out in outputs:\n            self.assertEqual(out.shape[1], out_channels)\n"
  },
  {
    "path": "tests/test_models/test_pose_estimators/test_bottomup.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom unittest import TestCase\n\nimport torch\nfrom parameterized import parameterized\n\nfrom mmpose.testing import get_packed_inputs, get_pose_estimator_cfg\nfrom mmpose.utils import register_all_modules\n\nconfigs = [\n    'body_2d_keypoint/associative_embedding/coco/'\n    'ae_hrnet-w32_8xb24-300e_coco-512x512.py'\n]\n\nconfigs_with_devices = [(config, ('cpu', 'cuda')) for config in configs]\n\n\nclass TestTopdownPoseEstimator(TestCase):\n\n    def setUp(self) -> None:\n        register_all_modules()\n\n    @parameterized.expand(configs)\n    def test_init(self, config):\n        model_cfg = get_pose_estimator_cfg(config)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n        model = build_pose_estimator(model_cfg)\n        self.assertTrue(model.backbone)\n        self.assertTrue(model.head)\n        if model_cfg.get('neck', None):\n            self.assertTrue(model.neck)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_tensor(self, config, devices):\n        model_cfg = get_pose_estimator_cfg(config)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2)\n            data = model.data_preprocessor(packed_inputs, training=True)\n            batch_results = model.forward(**data, mode='tensor')\n            self.assertIsInstance(batch_results, (tuple, torch.Tensor))\n"
  },
  {
    "path": "tests/test_models/test_pose_estimators/test_topdown.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\nfrom unittest import TestCase\n\nimport torch\nfrom parameterized import parameterized\n\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.testing import get_packed_inputs, get_pose_estimator_cfg\nfrom mmpose.utils import register_all_modules\n\nconfigs = [\n    'body_2d_keypoint/topdown_heatmap/coco/'\n    'td-hm_hrnet-w32_8xb64-210e_coco-256x192.py',\n    'configs/body_2d_keypoint/topdown_regression/coco/'\n    'td-reg_res50_8xb64-210e_coco-256x192.py',\n    'configs/body_2d_keypoint/simcc/coco/'\n    'simcc_mobilenetv2_wo-deconv-8xb64-210e_coco-256x192.py',\n]\n\nconfigs_with_devices = [(config, ('cpu', 'cuda')) for config in configs]\n\n\nclass TestTopdownPoseEstimator(TestCase):\n\n    def setUp(self) -> None:\n        register_all_modules()\n\n    @parameterized.expand(configs)\n    def test_init(self, config):\n        model_cfg = get_pose_estimator_cfg(config)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n        model = build_pose_estimator(model_cfg)\n        self.assertTrue(model.backbone)\n        self.assertTrue(model.head)\n        if model_cfg.get('neck', None):\n            self.assertTrue(model.neck)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_loss(self, config, devices):\n        model_cfg = get_pose_estimator_cfg(config)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2)\n            data = model.data_preprocessor(packed_inputs, training=True)\n            losses = model.forward(**data, mode='loss')\n            self.assertIsInstance(losses, dict)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_predict(self, config, devices):\n        model_cfg = get_pose_estimator_cfg(config)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2)\n            model.eval()\n            with torch.no_grad():\n                data = model.data_preprocessor(packed_inputs, training=True)\n                batch_results = model.forward(**data, mode='predict')\n                self.assertEqual(len(batch_results), 2)\n                self.assertIsInstance(batch_results[0], PoseDataSample)\n\n    @parameterized.expand(configs_with_devices)\n    def test_forward_tensor(self, config, devices):\n        model_cfg = get_pose_estimator_cfg(config)\n        model_cfg.backbone.init_cfg = None\n\n        from mmpose.models import build_pose_estimator\n\n        for device in devices:\n            model = build_pose_estimator(model_cfg)\n\n            if device == 'cuda':\n                if not torch.cuda.is_available():\n                    return unittest.skip('test requires GPU and torch+cuda')\n                model = model.cuda()\n\n            packed_inputs = get_packed_inputs(2)\n            data = model.data_preprocessor(packed_inputs, training=True)\n            batch_results = model.forward(**data, mode='tensor')\n            self.assertIsInstance(batch_results, (tuple, torch.Tensor))\n"
  },
  {
    "path": "tests/test_models/test_utils/test_check_and_update_config.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport unittest\n\nfrom mmpose.models.utils import check_and_update_config\n\n\nclass TestCheckAndUpdateConfig(unittest.TestCase):\n\n    def test_case_1(self):\n        neck = None\n        head = dict(\n            type='HeatmapHead',\n            in_channels=768,\n            out_channels=17,\n            deconv_out_channels=[],\n            deconv_kernel_sizes=[],\n            loss=dict(type='KeypointMSELoss', use_target_weight=True),\n            decoder='codec',\n            align_corners=False,\n            extra=dict(upsample=4, final_conv_kernel=3))\n        neck, head = check_and_update_config(neck, head)\n\n        self.assertDictEqual(\n            neck,\n            dict(\n                type='FeatureMapProcessor',\n                scale_factor=4.0,\n                apply_relu=True,\n            ))\n        self.assertIn('final_layer', head)\n        self.assertDictEqual(head['final_layer'],\n                             dict(kernel_size=3, padding=1))\n        self.assertNotIn('extra', head)\n        self.assertNotIn('input_transform', head)\n        self.assertNotIn('input_index', head)\n        self.assertNotIn('align_corners', head)\n\n    def test_case_2(self):\n        neck = None\n        head = dict(\n            type='CIDHead',\n            in_channels=(48, 96, 192, 384),\n            num_keypoints=17,\n            gfd_channels=48,\n            input_transform='resize_concat',\n            input_index=(0, 1, 2, 3),\n            coupled_heatmap_loss=dict(\n                type='FocalHeatmapLoss', loss_weight=1.0),\n            decoupled_heatmap_loss=dict(\n                type='FocalHeatmapLoss', loss_weight=4.0),\n        )\n        neck, head = check_and_update_config(neck, head)\n\n        self.assertDictEqual(\n            neck,\n            dict(\n                type='FeatureMapProcessor',\n                concat=True,\n                select_index=(0, 1, 2, 3),\n            ))\n        self.assertEqual(head['in_channels'], 720)\n        self.assertNotIn('input_transform', head)\n        self.assertNotIn('input_index', head)\n        self.assertNotIn('align_corners', head)\n\n    def test_case_3(self):\n        neck = None\n        head = dict(\n            type='HeatmapHead',\n            in_channels=(64, 128, 320, 512),\n            out_channels=17,\n            input_index=3,\n            has_final_layer=False,\n            loss=dict(type='KeypointMSELoss', use_target_weight=True))\n        neck, head = check_and_update_config(neck, head)\n\n        self.assertDictEqual(\n            neck, dict(\n                type='FeatureMapProcessor',\n                select_index=3,\n            ))\n        self.assertEqual(head['in_channels'], 512)\n        self.assertIn('final_layer', head)\n        self.assertIsNone(head['final_layer'])\n        self.assertNotIn('input_transform', head)\n        self.assertNotIn('input_index', head)\n        self.assertNotIn('align_corners', head)\n\n    def test_case_4(self):\n        neck = None\n        head = dict(\n            type='RTMCCHead',\n            in_channels=768,\n            out_channels=17,\n            input_size='input_size',\n            in_featuremap_size=(9, 12),\n            simcc_split_ratio='simcc_split_ratio',\n            final_layer_kernel_size=7,\n            gau_cfg=dict(\n                hidden_dims=256,\n                s=128,\n                expansion_factor=2,\n                dropout_rate=0.,\n                drop_path=0.,\n                act_fn='SiLU',\n                use_rel_bias=False,\n                pos_enc=False))\n        neck, head_new = check_and_update_config(neck, head)\n\n        self.assertIsNone(neck)\n        self.assertDictEqual(head, head_new)\n\n\nif __name__ == '__main__':\n    unittest.main()\n"
  },
  {
    "path": "tests/test_models/test_utils/test_transformers.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.models.utils.transformer import GAUEncoder, SinePositionalEncoding\n\n\nclass TestSinePositionalEncoding(TestCase):\n\n    def test_init(self):\n\n        spe = SinePositionalEncoding(out_channels=128)\n        self.assertTrue(hasattr(spe, 'dim_t'))\n        self.assertFalse(spe.dim_t.requires_grad)\n        self.assertEqual(spe.dim_t.size(0), 128 // 2)\n\n        spe = SinePositionalEncoding(out_channels=128, learnable=True)\n        self.assertTrue(spe.dim_t.requires_grad)\n\n        spe = SinePositionalEncoding(out_channels=128, eval_size=10)\n        self.assertTrue(hasattr(spe, 'pos_enc_10'))\n        self.assertEqual(spe.pos_enc_10.size(-1), 128)\n\n        spe = SinePositionalEncoding(\n            out_channels=128, eval_size=(2, 3), spatial_dim=2)\n        self.assertTrue(hasattr(spe, 'pos_enc_(2, 3)'))\n        self.assertSequenceEqual(\n            getattr(spe, 'pos_enc_(2, 3)').shape[-2:], (128, 2))\n\n    def test_generate_speoding(self):\n\n        # spatial_dim = 1\n        spe = SinePositionalEncoding(out_channels=128)\n        pos_enc = spe.generate_pos_encoding(size=10)\n        self.assertSequenceEqual(pos_enc.shape, (10, 128))\n\n        position = torch.arange(8)\n        pos_enc = spe.generate_pos_encoding(position=position)\n        self.assertSequenceEqual(pos_enc.shape, (8, 128))\n\n        with self.assertRaises(AssertionError):\n            pos_enc = spe.generate_pos_encoding(size=10, position=position)\n\n        # spatial_dim = 2\n        spe = SinePositionalEncoding(out_channels=128, spatial_dim=2)\n        pos_enc = spe.generate_pos_encoding(size=10)\n        self.assertSequenceEqual(pos_enc.shape, (100, 128, 2))\n\n        pos_enc = spe.generate_pos_encoding(size=(5, 6))\n        self.assertSequenceEqual(pos_enc.shape, (30, 128, 2))\n\n        position = torch.arange(8).unsqueeze(1).repeat(1, 2)\n        pos_enc = spe.generate_pos_encoding(position=position)\n        self.assertSequenceEqual(pos_enc.shape, (8, 128, 2))\n\n        with self.assertRaises(AssertionError):\n            pos_enc = spe.generate_pos_encoding(size=10, position=position)\n\n        with self.assertRaises(ValueError):\n            pos_enc = spe.generate_pos_encoding(size=position)\n\n    def test_apply_additional_pos_enc(self):\n\n        # spatial_dim = 1\n        spe = SinePositionalEncoding(out_channels=128)\n        pos_enc = spe.generate_pos_encoding(size=10)\n        feature = torch.randn(2, 3, 10, 128)\n        out_feature = spe.apply_additional_pos_enc(feature, pos_enc,\n                                                   spe.spatial_dim)\n        self.assertSequenceEqual(feature.shape, out_feature.shape)\n\n        # spatial_dim = 2\n        spe = SinePositionalEncoding(out_channels=128 // 2, spatial_dim=2)\n        pos_enc = spe.generate_pos_encoding(size=(2, 5))\n        feature = torch.randn(2, 3, 10, 128)\n        out_feature = spe.apply_additional_pos_enc(feature, pos_enc,\n                                                   spe.spatial_dim)\n        self.assertSequenceEqual(feature.shape, out_feature.shape)\n\n    def test_apply_rotary_pos_enc(self):\n\n        # spatial_dim = 1\n        spe = SinePositionalEncoding(out_channels=128)\n        pos_enc = spe.generate_pos_encoding(size=10)\n        feature = torch.randn(2, 3, 10, 128)\n        out_feature = spe.apply_rotary_pos_enc(feature, pos_enc,\n                                               spe.spatial_dim)\n        self.assertSequenceEqual(feature.shape, out_feature.shape)\n\n        # spatial_dim = 2\n        spe = SinePositionalEncoding(out_channels=128, spatial_dim=2)\n        pos_enc = spe.generate_pos_encoding(size=(2, 5))\n        feature = torch.randn(2, 3, 10, 128)\n        out_feature = spe.apply_rotary_pos_enc(feature, pos_enc,\n                                               spe.spatial_dim)\n        self.assertSequenceEqual(feature.shape, out_feature.shape)\n\n\nclass TestGAUEncoder(TestCase):\n\n    def test_init(self):\n        gau = GAUEncoder(in_token_dims=64, out_token_dims=64)\n        self.assertTrue(gau.shortcut)\n\n        gau = GAUEncoder(in_token_dims=64, out_token_dims=64, dropout_rate=0.5)\n        self.assertTrue(hasattr(gau, 'dropout'))\n\n    def test_forward(self):\n        gau = GAUEncoder(in_token_dims=64, out_token_dims=64)\n\n        # compatibility with various dimension input\n        feat = torch.randn(2, 3, 64)\n        with torch.no_grad():\n            out_feat = gau.forward(feat)\n        self.assertSequenceEqual(feat.shape, out_feat.shape)\n\n        feat = torch.randn(1, 2, 3, 64)\n        with torch.no_grad():\n            out_feat = gau.forward(feat)\n        self.assertSequenceEqual(feat.shape, out_feat.shape)\n\n        feat = torch.randn(1, 2, 3, 4, 64)\n        with torch.no_grad():\n            out_feat = gau.forward(feat)\n        self.assertSequenceEqual(feat.shape, out_feat.shape)\n\n        # positional encoding\n        gau = GAUEncoder(\n            s=32, in_token_dims=64, out_token_dims=64, pos_enc=True)\n        feat = torch.randn(2, 3, 64)\n        spe = SinePositionalEncoding(out_channels=32)\n        pos_enc = spe.generate_pos_encoding(size=3)\n        with torch.no_grad():\n            out_feat = gau.forward(feat, pos_enc=pos_enc)\n        self.assertSequenceEqual(feat.shape, out_feat.shape)\n\n        gau = GAUEncoder(\n            s=32,\n            in_token_dims=64,\n            out_token_dims=64,\n            pos_enc=True,\n            spatial_dim=2)\n        feat = torch.randn(1, 2, 6, 64)\n        spe = SinePositionalEncoding(out_channels=32, spatial_dim=2)\n        pos_enc = spe.generate_pos_encoding(size=(2, 3))\n        with torch.no_grad():\n            out_feat = gau.forward(feat, pos_enc=pos_enc)\n        self.assertSequenceEqual(feat.shape, out_feat.shape)\n\n        # mask\n        gau = GAUEncoder(in_token_dims=64, out_token_dims=64)\n\n        # compatibility with various dimension input\n        feat = torch.randn(2, 3, 64)\n        mask = torch.rand(2, 3, 3)\n        with torch.no_grad():\n            out_feat = gau.forward(feat, mask=mask)\n        self.assertSequenceEqual(feat.shape, out_feat.shape)\n"
  },
  {
    "path": "tests/test_structures/test_bbox/test_bbox_overlaps.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport torch\n\nfrom mmpose.structures.bbox import bbox_overlaps  # Import your function here\n\n\nclass TestBBoxOverlaps(TestCase):\n\n    def test_bbox_overlaps_iou(self):\n        bboxes1 = torch.FloatTensor([\n            [0, 0, 10, 10],\n            [10, 10, 20, 20],\n            [32, 32, 38, 42],\n        ])\n        bboxes2 = torch.FloatTensor([\n            [0, 0, 10, 20],\n            [0, 10, 10, 19],\n            [10, 10, 20, 20],\n        ])\n        overlaps = bbox_overlaps(bboxes1, bboxes2)\n\n        expected_overlaps = torch.FloatTensor([\n            [0.5000, 0.0000, 0.0000],\n            [0.0000, 0.0000, 1.0000],\n            [0.0000, 0.0000, 0.0000],\n        ])\n\n        self.assertTrue(\n            torch.allclose(overlaps, expected_overlaps, rtol=1e-4, atol=1e-4))\n\n    def test_bbox_overlaps_iof(self):\n        bboxes1 = torch.FloatTensor([\n            [0, 0, 10, 10],\n            [10, 10, 20, 20],\n            [32, 32, 38, 42],\n        ])\n        bboxes2 = torch.FloatTensor([\n            [0, 0, 10, 20],\n            [0, 10, 10, 19],\n            [10, 10, 20, 20],\n        ])\n        overlaps = bbox_overlaps(bboxes1, bboxes2, mode='iof')\n\n        expected_overlaps = torch.FloatTensor([\n            [1., 0., 0.],\n            [0., 0., 1.],\n            [0., 0., 0.],\n        ])\n\n        self.assertTrue(\n            torch.allclose(overlaps, expected_overlaps, rtol=1e-4, atol=1e-4))\n\n    def test_bbox_overlaps_giou(self):\n        bboxes1 = torch.FloatTensor([\n            [0, 0, 10, 10],\n            [10, 10, 20, 20],\n            [32, 32, 38, 42],\n        ])\n        bboxes2 = torch.FloatTensor([\n            [0, 0, 10, 20],\n            [0, 10, 10, 19],\n            [10, 10, 20, 20],\n        ])\n        overlaps = bbox_overlaps(bboxes1, bboxes2, mode='giou')\n\n        expected_overlaps = torch.FloatTensor([\n            [0.5000, 0.0000, -0.5000],\n            [-0.2500, -0.0500, 1.0000],\n            [-0.8371, -0.8766, -0.8214],\n        ])\n\n        self.assertTrue(\n            torch.allclose(overlaps, expected_overlaps, rtol=1e-4, atol=1e-4))\n"
  },
  {
    "path": "tests/test_structures/test_bbox/test_bbox_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.structures.bbox import (bbox_clip_border, bbox_corner2xyxy,\n                                    bbox_xyxy2corner, get_pers_warp_matrix,\n                                    get_warp_matrix)\n\n\nclass TestBBoxClipBorder(TestCase):\n\n    def test_bbox_clip_border_2D(self):\n        bbox = np.array([[10, 20], [60, 80], [-5, 25], [100, 120]])\n        shape = (50, 50)  # Example image shape\n        clipped_bbox = bbox_clip_border(bbox, shape)\n\n        expected_bbox = np.array([[10, 20], [50, 50], [0, 25], [50, 50]])\n\n        self.assertTrue(np.array_equal(clipped_bbox, expected_bbox))\n\n    def test_bbox_clip_border_4D(self):\n        bbox = np.array([\n            [[10, 20, 30, 40], [40, 50, 80, 90]],\n            [[-5, 0, 30, 40], [70, 80, 120, 130]],\n        ])\n        shape = (50, 60)  # Example image shape\n        clipped_bbox = bbox_clip_border(bbox, shape)\n\n        expected_bbox = np.array([\n            [[10, 20, 30, 40], [40, 50, 50, 60]],\n            [[0, 0, 30, 40], [50, 60, 50, 60]],\n        ])\n\n        self.assertTrue(np.array_equal(clipped_bbox, expected_bbox))\n\n\nclass TestBBoxXYXY2Corner(TestCase):\n\n    def test_bbox_xyxy2corner_single(self):\n        bbox = np.array([0, 0, 100, 50])\n        corners = bbox_xyxy2corner(bbox)\n\n        expected_corners = np.array([[0, 0], [0, 50], [100, 0], [100, 50]])\n\n        self.assertTrue(np.array_equal(corners, expected_corners))\n\n    def test_bbox_xyxy2corner_multiple(self):\n        bboxes = np.array([[0, 0, 100, 50], [10, 20, 200, 150]])\n        corners = bbox_xyxy2corner(bboxes)\n\n        expected_corners = np.array([[[0, 0], [0, 50], [100, 0], [100, 50]],\n                                     [[10, 20], [10, 150], [200, 20],\n                                      [200, 150]]])\n\n        self.assertTrue(np.array_equal(corners, expected_corners))\n\n\nclass TestBBoxCorner2XYXY(TestCase):\n\n    def test_bbox_corner2xyxy_single(self):\n\n        corners = np.array([[0, 0], [0, 50], [100, 0], [100, 50]])\n        xyxy = bbox_corner2xyxy(corners)\n        expected_xyxy = np.array([0, 0, 100, 50])\n\n        self.assertTrue(np.array_equal(xyxy, expected_xyxy))\n\n    def test_bbox_corner2xyxy_multiple(self):\n\n        corners = np.array([[[0, 0], [0, 50], [100, 0], [100, 50]],\n                            [[10, 20], [10, 150], [200, 20], [200, 150]]])\n        xyxy = bbox_corner2xyxy(corners)\n        expected_xyxy = np.array([[0, 0, 100, 50], [10, 20, 200, 150]])\n\n        self.assertTrue(np.array_equal(xyxy, expected_xyxy))\n\n\nclass TestGetPersWarpMatrix(TestCase):\n\n    def test_get_pers_warp_matrix_identity(self):\n        center = np.array([0, 0])\n        translate = np.array([0, 0])\n        scale = 1.0\n        rot = 0.0\n        shear = np.array([0.0, 0.0])\n        warp_matrix = get_pers_warp_matrix(center, translate, scale, rot,\n                                           shear)\n\n        expected_matrix = np.array([[1, 0, 0], [0, 1, 0], [0, 0, 1]],\n                                   dtype=np.float32)\n\n        self.assertTrue(np.array_equal(warp_matrix, expected_matrix))\n\n    def test_get_pers_warp_matrix_translation(self):\n        center = np.array([0, 0])\n        translate = np.array([10, 20])\n        scale = 1.0\n        rot = 0.0\n        shear = np.array([0.0, 0.0])\n        warp_matrix = get_pers_warp_matrix(center, translate, scale, rot,\n                                           shear)\n\n        expected_matrix = np.array([[1, 0, 10], [0, 1, 20], [0, 0, 1]],\n                                   dtype=np.float32)\n\n        self.assertTrue(np.array_equal(warp_matrix, expected_matrix))\n\n    def test_get_pers_warp_matrix_scale_rotation_shear(self):\n        center = np.array([0, 0])\n        translate = np.array([0, 0])\n        scale = 1.5\n        rot = 45.0\n        shear = np.array([15.0, 30.0])\n        warp_matrix = get_pers_warp_matrix(center, translate, scale, rot,\n                                           shear)\n\n        expected_matrix = np.array([\n            [1.3448632, -0.77645713, 0.],\n            [1.6730325, 0.44828773, 0.],\n            [0., 0., 1.],\n        ],\n                                   dtype=np.float32)\n\n        # Use np.allclose to compare floating-point arrays within a tolerance\n        self.assertTrue(\n            np.allclose(warp_matrix, expected_matrix, rtol=1e-3, atol=1e-3))\n\n\nclass TestGetWarpMatrix(TestCase):\n\n    def test_basic_transformation(self):\n        # Test with basic parameters\n        center = np.array([100, 100])\n        scale = np.array([50, 50])\n        rot = 0\n        output_size = (200, 200)\n        warp_matrix = get_warp_matrix(center, scale, rot, output_size)\n        expected_matrix = np.array([[4, 0, -300], [0, 4, -300]])\n        np.testing.assert_array_almost_equal(warp_matrix, expected_matrix)\n\n    def test_rotation(self):\n        # Test with rotation\n        center = np.array([100, 100])\n        scale = np.array([50, 50])\n        rot = 45  # 45 degree rotation\n        output_size = (200, 200)\n        warp_matrix = get_warp_matrix(center, scale, rot, output_size)\n        expected_matrix = np.array([[2.828427, 2.828427, -465.685303],\n                                    [-2.828427, 2.828427, 100.]])\n        np.testing.assert_array_almost_equal(warp_matrix, expected_matrix)\n\n    def test_shift(self):\n        # Test with shift\n        center = np.array([100, 100])\n        scale = np.array([50, 50])\n        rot = 0\n        output_size = (200, 200)\n        shift = (0.1, 0.1)  # 10% shift\n        warp_matrix = get_warp_matrix(\n            center, scale, rot, output_size, shift=shift)\n        expected_matrix = np.array([[4, 0, -320], [0, 4, -320]])\n        np.testing.assert_array_almost_equal(warp_matrix, expected_matrix)\n\n    def test_inverse(self):\n        # Test inverse transformation\n        center = np.array([100, 100])\n        scale = np.array([50, 50])\n        rot = 0\n        output_size = (200, 200)\n        warp_matrix = get_warp_matrix(\n            center, scale, rot, output_size, inv=True)\n        expected_matrix = np.array([[0.25, 0, 75], [0, 0.25, 75]])\n        np.testing.assert_array_almost_equal(warp_matrix, expected_matrix)\n\n    def test_aspect_ratio(self):\n        # Test with fix_aspect_ratio set to False\n        center = np.array([100, 100])\n        scale = np.array([50, 20])\n        rot = 0\n        output_size = (200, 200)\n        warp_matrix = get_warp_matrix(\n            center, scale, rot, output_size, fix_aspect_ratio=False)\n        expected_matrix = np.array([[4, 0, -300], [0, 10, -900]])\n        np.testing.assert_array_almost_equal(warp_matrix, expected_matrix)\n"
  },
  {
    "path": "tests/test_structures/test_keypoint/test_keypoint_transforms.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.structures import keypoint_clip_border\n\n\nclass TestKeypointClipBorder(TestCase):\n\n    def test_keypoint_clip_border(self):\n        keypoints = np.array([[[10, 20], [30, 40], [-5, 25], [50, 60]]])\n        keypoints_visible = np.array([[1.0, 0.8, 0.5, 1.0]])\n        shape = (50, 50)  # Example frame shape\n\n        clipped_keypoints, clipped_keypoints_visible = keypoint_clip_border(\n            keypoints, keypoints_visible, shape)\n\n        # Check if keypoints outside the frame have visibility set to 0.0\n        self.assertEqual(clipped_keypoints_visible[0, 2], 0.0)\n        self.assertEqual(clipped_keypoints_visible[0, 3], 0.0)\n\n        # Check if keypoints inside the frame have unchanged visibility values\n        self.assertEqual(clipped_keypoints_visible[0, 0], 1.0)\n        self.assertEqual(clipped_keypoints_visible[0, 1], 0.8)\n\n        # Check if keypoints array shapes remain unchanged\n        self.assertEqual(keypoints.shape, clipped_keypoints.shape)\n        self.assertEqual(keypoints_visible.shape,\n                         clipped_keypoints_visible.shape)\n\n        keypoints = np.array([[[10, 20], [30, 40], [-5, 25], [50, 60]]])\n        keypoints_visible = np.array([[1.0, 0.8, 0.5, 1.0]])\n        keypoints_visible_weight = np.array([[1.0, 0.0, 1.0, 1.0]])\n        keypoints_visible = np.stack(\n            (keypoints_visible, keypoints_visible_weight), axis=-1)\n        shape = (50, 50)  # Example frame shape\n\n        clipped_keypoints, clipped_keypoints_visible = keypoint_clip_border(\n            keypoints, keypoints_visible, shape)\n\n        # Check if keypoints array shapes remain unchanged\n        self.assertEqual(keypoints.shape, clipped_keypoints.shape)\n        self.assertEqual(keypoints_visible.shape,\n                         clipped_keypoints_visible.shape)\n\n        # Check if keypoints outside the frame have visibility set to 0.0\n        self.assertEqual(clipped_keypoints_visible[0, 2, 0], 0.0)\n        self.assertEqual(clipped_keypoints_visible[0, 3, 0], 0.0)\n\n        # Check if keypoints inside the frame have unchanged visibility values\n        self.assertEqual(clipped_keypoints_visible[0, 0, 0], 1.0)\n        self.assertEqual(clipped_keypoints_visible[0, 1, 0], 0.8)\n\n        # Check if the visibility weights remain unchanged\n        self.assertSequenceEqual(clipped_keypoints_visible[..., 1].tolist(),\n                                 keypoints_visible[..., 1].tolist())\n"
  },
  {
    "path": "tests/test_structures/test_multilevel_pixel_data.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nfrom mmengine.structures import PixelData\n\nfrom mmpose.structures import MultilevelPixelData\n\n\nclass TestMultilevelPixelData(TestCase):\n\n    def get_multi_level_pixel_data(self):\n        metainfo = dict(num_keypoints=17)\n        sizes = [(64, 48), (32, 24), (16, 12)]\n        heatmaps = [np.random.rand(17, h, w) for h, w in sizes]\n        masks = [torch.rand(1, h, w) for h, w in sizes]\n        data = MultilevelPixelData(\n            metainfo=metainfo, heatmaps=heatmaps, masks=masks)\n\n        return data\n\n    def test_init(self):\n\n        data = self.get_multi_level_pixel_data()\n        self.assertIn('num_keypoints', data)\n        self.assertTrue(data.nlevel == 3)\n        self.assertTrue(data.shape == ((64, 48), (32, 24), (16, 12)))\n        self.assertTrue(isinstance(data[0], PixelData))\n\n    def test_setter(self):\n        # test `set_field`\n        data = self.get_multi_level_pixel_data()\n        sizes = [(64, 48), (32, 24), (16, 8)]\n        offset_maps = [torch.rand(2, h, w) for h, w in sizes]\n        data.offset_maps = offset_maps\n\n        # test `to_tensor`\n        data = self.get_multi_level_pixel_data()\n        self.assertTrue(isinstance(data[0].heatmaps, np.ndarray))\n        data = data.to_tensor()\n        self.assertTrue(isinstance(data[0].heatmaps, torch.Tensor))\n\n        # test `cpu`\n        data = self.get_multi_level_pixel_data()\n        self.assertTrue(isinstance(data[0].heatmaps, np.ndarray))\n        self.assertTrue(isinstance(data[0].masks, torch.Tensor))\n        self.assertTrue(data[0].masks.device.type == 'cpu')\n        data = data.cpu()\n        self.assertTrue(isinstance(data[0].heatmaps, np.ndarray))\n        self.assertTrue(data[0].masks.device.type == 'cpu')\n\n        # test `to`\n        data = self.get_multi_level_pixel_data()\n        self.assertTrue(data[0].masks.device.type == 'cpu')\n        data = data.to('cpu')\n        self.assertTrue(data[0].masks.device.type == 'cpu')\n\n        # test `numpy`\n        data = self.get_multi_level_pixel_data()\n        self.assertTrue(isinstance(data[0].masks, torch.Tensor))\n        data = data.numpy()\n        self.assertTrue(isinstance(data[0].masks, np.ndarray))\n\n    def test_deleter(self):\n\n        data = self.get_multi_level_pixel_data()\n\n        for key in ['heatmaps', 'masks']:\n            self.assertIn(key, data)\n            exec(f'del data.{key}')\n            self.assertNotIn(key, data)\n"
  },
  {
    "path": "tests/test_structures/test_pose_data_sample.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.structures import MultilevelPixelData, PoseDataSample\n\n\nclass TestPoseDataSample(TestCase):\n\n    def get_pose_data_sample(self, multilevel: bool = False):\n        # meta\n        pose_meta = dict(\n            img_shape=(600, 900),  # [h, w, c]\n            crop_size=(256, 192),  # [h, w]\n            heatmap_size=(64, 48),  # [h, w]\n        )\n        # gt_instances\n        gt_instances = InstanceData()\n        gt_instances.bboxes = torch.rand(1, 4)\n        gt_instances.keypoints = torch.rand(1, 17, 2)\n        gt_instances.keypoints_visible = torch.rand(1, 17)\n\n        # pred_instances\n        pred_instances = InstanceData()\n        pred_instances.keypoints = torch.rand(1, 17, 2)\n        pred_instances.keypoint_scores = torch.rand(1, 17)\n\n        # gt_fields\n        if multilevel:\n            # generate multilevel gt_fields\n            metainfo = dict(num_keypoints=17)\n            sizes = [(64, 48), (32, 24), (16, 12)]\n            heatmaps = [np.random.rand(17, h, w) for h, w in sizes]\n            masks = [torch.rand(1, h, w) for h, w in sizes]\n            gt_fields = MultilevelPixelData(\n                metainfo=metainfo, heatmaps=heatmaps, masks=masks)\n        else:\n            gt_fields = PixelData()\n            gt_fields.heatmaps = torch.rand(17, 64, 48)\n\n        # pred_fields\n        pred_fields = PixelData()\n        pred_fields.heatmaps = torch.rand(17, 64, 48)\n\n        data_sample = PoseDataSample(\n            gt_instances=gt_instances,\n            pred_instances=pred_instances,\n            gt_fields=gt_fields,\n            pred_fields=pred_fields,\n            metainfo=pose_meta)\n\n        return data_sample\n\n    @staticmethod\n    def _equal(x, y):\n        if type(x) != type(y):\n            return False\n        if isinstance(x, torch.Tensor):\n            return torch.allclose(x, y)\n        elif isinstance(x, np.ndarray):\n            return np.allclose(x, y)\n        else:\n            return x == y\n\n    def test_init(self):\n\n        data_sample = self.get_pose_data_sample()\n        self.assertIn('img_shape', data_sample)\n        self.assertTrue(len(data_sample.gt_instances) == 1)\n\n    def test_setter(self):\n\n        data_sample = self.get_pose_data_sample()\n\n        # test gt_instances\n        data_sample.gt_instances = InstanceData()\n\n        # test gt_fields\n        data_sample.gt_fields = PixelData()\n\n        # test multilevel gt_fields\n        data_sample = self.get_pose_data_sample(multilevel=True)\n        data_sample.gt_fields = MultilevelPixelData()\n\n        # test pred_instances as pytorch tensor\n        pred_instances_data = dict(\n            keypoints=torch.rand(1, 17, 2), scores=torch.rand(1, 17, 1))\n        data_sample.pred_instances = InstanceData(**pred_instances_data)\n\n        self.assertTrue(\n            self._equal(data_sample.pred_instances.keypoints,\n                        pred_instances_data['keypoints']))\n        self.assertTrue(\n            self._equal(data_sample.pred_instances.scores,\n                        pred_instances_data['scores']))\n\n        # test pred_fields as numpy array\n        pred_fields_data = dict(heatmaps=np.random.rand(17, 64, 48))\n        data_sample.pred_fields = PixelData(**pred_fields_data)\n\n        self.assertTrue(\n            self._equal(data_sample.pred_fields.heatmaps,\n                        pred_fields_data['heatmaps']))\n\n        # test to_tensor\n        data_sample = data_sample.to_tensor()\n        self.assertTrue(\n            self._equal(data_sample.pred_fields.heatmaps,\n                        torch.from_numpy(pred_fields_data['heatmaps'])))\n\n    def test_deleter(self):\n\n        data_sample = self.get_pose_data_sample()\n\n        for key in [\n                'gt_instances',\n                'pred_instances',\n                'gt_fields',\n                'pred_fields',\n        ]:\n            self.assertIn(key, data_sample)\n            exec(f'del data_sample.{key}')\n            self.assertNotIn(key, data_sample)\n"
  },
  {
    "path": "tests/test_utils/test_setup_env.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport datetime\nimport sys\nfrom unittest import TestCase\n\nfrom mmengine import DefaultScope\n\nfrom mmpose.utils import register_all_modules\n\n\nclass TestSetupEnv(TestCase):\n\n    def test_register_all_modules(self):\n        from mmpose.registry import DATASETS\n\n        dataset_name = 'CocoDataset'\n        dataset_module = 'mmpose.datasets.datasets.body.coco_dataset'\n\n        # not init default scope\n        module = dataset_module\n        while '.' in module:\n            sys.modules.pop(module, None)\n            module = module.rsplit('.', 1)[0]\n        DATASETS._module_dict.pop(dataset_name, None)\n        self.assertFalse(dataset_name in DATASETS.module_dict)\n        register_all_modules(init_default_scope=False)\n        self.assertTrue(dataset_name in DATASETS.module_dict)\n\n        # init default scope\n        module = dataset_module\n        while '.' in module:\n            sys.modules.pop(module, None)\n            module = module.rsplit('.', 1)[0]\n        DATASETS._module_dict.pop(dataset_name, None)\n        self.assertFalse(dataset_name in DATASETS.module_dict)\n        register_all_modules(init_default_scope=True)\n        self.assertTrue(dataset_name in DATASETS.module_dict)\n        self.assertEqual(DefaultScope.get_current_instance().scope_name,\n                         'mmpose')\n\n        # init default scope when another scope is init\n        name = f'test-{datetime.datetime.now()}'\n        DefaultScope.get_instance(name, scope_name='test')\n        with self.assertWarnsRegex(\n                Warning, 'The current default scope \"test\" is not \"mmpose\"'):\n            register_all_modules(init_default_scope=True)\n"
  },
  {
    "path": "tests/test_visualization/test_fast_visualizer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nfrom unittest import TestCase\n\nimport numpy as np\n\nfrom mmpose.visualization import FastVisualizer\n\n\nclass TestFastVisualizer(TestCase):\n\n    def setUp(self):\n        self.metainfo = {\n            'keypoint_id2name': {\n                0: 'nose',\n                1: 'left_eye',\n                2: 'right_eye'\n            },\n            'keypoint_name2id': {\n                'nose': 0,\n                'left_eye': 1,\n                'right_eye': 2\n            },\n            'keypoint_colors': np.array([[255, 0, 0], [0, 255, 0], [0, 0,\n                                                                    255]]),\n            'skeleton_links': [(0, 1), (1, 2)],\n            'skeleton_link_colors': np.array([[255, 255, 0], [255, 0, 255]])\n        }\n        self.visualizer = FastVisualizer(self.metainfo)\n\n    def test_init(self):\n        self.assertEqual(self.visualizer.radius, 6)\n        self.assertEqual(self.visualizer.line_width, 3)\n        self.assertEqual(self.visualizer.kpt_thr, 0.3)\n        self.assertEqual(self.visualizer.keypoint_id2name,\n                         self.metainfo['keypoint_id2name'])\n        self.assertEqual(self.visualizer.keypoint_name2id,\n                         self.metainfo['keypoint_name2id'])\n        np.testing.assert_array_equal(self.visualizer.keypoint_colors,\n                                      self.metainfo['keypoint_colors'])\n        self.assertEqual(self.visualizer.skeleton_links,\n                         self.metainfo['skeleton_links'])\n        np.testing.assert_array_equal(self.visualizer.skeleton_link_colors,\n                                      self.metainfo['skeleton_link_colors'])\n\n    def test_draw_pose(self):\n        img = np.zeros((480, 640, 3), dtype=np.uint8)\n        instances = type('Instances', (object, ), {})()\n        instances.keypoints = np.array([[[100, 100], [200, 200], [300, 300]]],\n                                       dtype=np.float32)\n        instances.keypoint_scores = np.array([[0.5, 0.5, 0.5]],\n                                             dtype=np.float32)\n\n        self.visualizer.draw_pose(img, instances)\n\n        # Check if keypoints are drawn\n        self.assertNotEqual(img[100, 100].tolist(), [0, 0, 0])\n        self.assertNotEqual(img[200, 200].tolist(), [0, 0, 0])\n        self.assertNotEqual(img[300, 300].tolist(), [0, 0, 0])\n\n        # Check if skeleton links are drawn\n        self.assertNotEqual(img[150, 150].tolist(), [0, 0, 0])\n        self.assertNotEqual(img[250, 250].tolist(), [0, 0, 0])\n\n    def test_draw_pose_with_none_instances(self):\n        img = np.zeros((480, 640, 3), dtype=np.uint8)\n        instances = None\n\n        self.visualizer.draw_pose(img, instances)\n\n        # Check if the image is still empty (black)\n        self.assertEqual(np.count_nonzero(img), 0)\n"
  },
  {
    "path": "tests/test_visualization/test_pose_visualizer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nfrom unittest import TestCase\n\nimport cv2\nimport numpy as np\nimport torch\nfrom mmengine.structures import InstanceData, PixelData\n\nfrom mmpose.structures import PoseDataSample\nfrom mmpose.visualization import PoseLocalVisualizer\n\n\nclass TestPoseLocalVisualizer(TestCase):\n\n    def setUp(self):\n        self.visualizer = PoseLocalVisualizer(show_keypoint_weight=True)\n\n    def _get_dataset_meta(self):\n        # None: kpt or link is hidden\n        pose_kpt_color = [None] + [(127, 127, 127)] * 2 + ['red']\n        pose_link_color = [(127, 127, 127)] * 2 + [None]\n        skeleton_links = [[0, 1], [1, 2], [2, 3]]\n        return {\n            'keypoint_colors': pose_kpt_color,\n            'skeleton_link_colors': pose_link_color,\n            'skeleton_links': skeleton_links\n        }\n\n    def test_set_dataset_meta(self):\n        dataset_meta = self._get_dataset_meta()\n        self.visualizer.set_dataset_meta(dataset_meta)\n        self.assertEqual(len(self.visualizer.kpt_color), 4)\n        self.assertEqual(self.visualizer.kpt_color[-1], 'red')\n        self.assertListEqual(self.visualizer.skeleton[-1], [2, 3])\n\n        self.visualizer.dataset_meta = None\n        self.visualizer.set_dataset_meta(dataset_meta)\n        self.assertIsNotNone(self.visualizer.dataset_meta)\n\n    def test_add_datasample(self):\n        h, w = 100, 100\n        image = np.zeros((h, w, 3), dtype=np.uint8)\n        out_file = 'out_file.jpg'\n\n        dataset_meta = self._get_dataset_meta()\n        self.visualizer.set_dataset_meta(dataset_meta)\n\n        # setting keypoints\n        gt_instances = InstanceData()\n        gt_instances.keypoints = np.array([[[1, 1], [20, 20], [40, 40],\n                                            [80, 80]]],\n                                          dtype=np.float32)\n\n        # setting bounding box\n        gt_instances.bboxes = np.array([[20, 30, 50, 70]])\n\n        # setting heatmap\n        heatmap = torch.randn(10, 100, 100) * 0.05\n        for i in range(10):\n            heatmap[i][i * 10:(i + 1) * 10, i * 10:(i + 1) * 10] += 5\n        gt_heatmap = PixelData()\n        gt_heatmap.heatmaps = heatmap\n\n        # test gt_sample\n        pred_pose_data_sample = PoseDataSample()\n        pred_pose_data_sample.gt_instances = gt_instances\n        pred_pose_data_sample.gt_fields = gt_heatmap\n        pred_instances = gt_instances.clone()\n        pred_instances.scores = np.array([[0.9, 0.4, 1.7, -0.2]],\n                                         dtype=np.float32)\n        pred_pose_data_sample.pred_instances = pred_instances\n\n        self.visualizer.add_datasample(\n            'image',\n            image,\n            data_sample=pred_pose_data_sample,\n            draw_bbox=True,\n            out_file=out_file)\n        self._assert_image_and_shape(out_file, (h, w * 2, 3))\n\n        self.visualizer.show_keypoint_weight = False\n        self.visualizer.add_datasample(\n            'image',\n            image,\n            data_sample=pred_pose_data_sample,\n            draw_pred=False,\n            draw_heatmap=True,\n            out_file=out_file)\n        self._assert_image_and_shape(out_file, ((h * 2), w, 3))\n\n        self.visualizer.add_datasample(\n            'image',\n            image,\n            data_sample=pred_pose_data_sample,\n            draw_heatmap=True,\n            out_file=out_file)\n        self._assert_image_and_shape(out_file, ((h * 2), (w * 2), 3))\n\n    def test_simcc_visualization(self):\n        img = np.zeros((512, 512, 3), dtype=np.uint8)\n        heatmap = torch.randn([17, 512, 512])\n        pixelData = PixelData()\n        pixelData.heatmaps = heatmap\n        self.visualizer._draw_instance_xy_heatmap(pixelData, img, 10)\n\n    def _assert_image_and_shape(self, out_file, out_shape):\n        self.assertTrue(os.path.exists(out_file))\n        drawn_img = cv2.imread(out_file)\n        self.assertTupleEqual(drawn_img.shape, out_shape)\n        os.remove(out_file)\n"
  },
  {
    "path": "tools/analysis_tools/analyze_logs.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport json\nfrom collections import defaultdict\n\nimport matplotlib.pyplot as plt\nimport numpy as np\nimport seaborn as sns\n\n\ndef cal_train_time(log_dicts, args):\n    for i, log_dict in enumerate(log_dicts):\n        print(f'{\"-\" * 5}Analyze train time of {args.json_logs[i]}{\"-\" * 5}')\n        all_times = []\n        for epoch in log_dict.keys():\n            if args.include_outliers:\n                all_times.append(log_dict[epoch]['time'])\n            else:\n                all_times.append(log_dict[epoch]['time'][1:])\n        all_times = np.array(all_times)\n        epoch_ave_time = all_times.mean(-1)\n        slowest_epoch = epoch_ave_time.argmax()\n        fastest_epoch = epoch_ave_time.argmin()\n        std_over_epoch = epoch_ave_time.std()\n        print(f'slowest epoch {slowest_epoch + 1}, '\n              f'average time is {epoch_ave_time[slowest_epoch]:.4f}')\n        print(f'fastest epoch {fastest_epoch + 1}, '\n              f'average time is {epoch_ave_time[fastest_epoch]:.4f}')\n        print(f'time std over epochs is {std_over_epoch:.4f}')\n        print(f'average iter time: {np.mean(all_times):.4f} s/iter')\n        print()\n\n\ndef plot_curve(log_dicts, args):\n    if args.backend is not None:\n        plt.switch_backend(args.backend)\n    sns.set_style(args.style)\n    # if legend is None, use {filename}_{key} as legend\n    legend = args.legend\n    if legend is None:\n        legend = []\n        for json_log in args.json_logs:\n            for metric in args.keys:\n                legend.append(f'{json_log}_{metric}')\n    assert len(legend) == (len(args.json_logs) * len(args.keys))\n    metrics = args.keys\n\n    num_metrics = len(metrics)\n    for i, log_dict in enumerate(log_dicts):\n        epochs = list(log_dict.keys())\n        for j, metric in enumerate(metrics):\n            print(f'plot curve of {args.json_logs[i]}, metric is {metric}')\n            if metric not in log_dict[epochs[0]]:\n                raise KeyError(\n                    f'{args.json_logs[i]} does not contain metric {metric}')\n            xs = []\n            ys = []\n            for epoch in epochs:\n                xs.append(np.array(log_dict[epoch]['step']))\n                ys.append(np.array(log_dict[epoch][metric]))\n            xs = np.concatenate(xs)\n            ys = np.concatenate(ys)\n            plt.xlabel('step')\n            plt.plot(xs, ys, label=legend[i * num_metrics + j], linewidth=0.5)\n            plt.legend()\n        if args.title is not None:\n            plt.title(args.title)\n    if args.out is None:\n        plt.show()\n    else:\n        print(f'save curve to: {args.out}')\n        plt.savefig(args.out)\n        plt.cla()\n\n\ndef add_plot_parser(subparsers):\n    parser_plt = subparsers.add_parser(\n        'plot_curve', help='parser for plotting curves')\n    parser_plt.add_argument(\n        'json_logs',\n        type=str,\n        nargs='+',\n        help='path of train log in json format')\n    parser_plt.add_argument(\n        '--keys',\n        type=str,\n        nargs='+',\n        default=['loss_kpt'],\n        help='the metric that you want to plot')\n    parser_plt.add_argument('--title', type=str, help='title of figure')\n    parser_plt.add_argument(\n        '--legend',\n        type=str,\n        nargs='+',\n        default=None,\n        help='legend of each plot')\n    parser_plt.add_argument(\n        '--backend', type=str, default=None, help='backend of plt')\n    parser_plt.add_argument(\n        '--style', type=str, default='dark', help='style of plt')\n    parser_plt.add_argument('--out', type=str, default=None)\n\n\ndef add_time_parser(subparsers):\n    parser_time = subparsers.add_parser(\n        'cal_train_time',\n        help='parser for computing the average time per training iteration')\n    parser_time.add_argument(\n        'json_logs',\n        type=str,\n        nargs='+',\n        help='path of train log in json format')\n    parser_time.add_argument(\n        '--include-outliers',\n        action='store_true',\n        help='include the first value of every epoch when computing '\n        'the average time')\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Analyze Json Log')\n    # currently only support plot curve and calculate average train time\n    subparsers = parser.add_subparsers(dest='task', help='task parser')\n    add_plot_parser(subparsers)\n    add_time_parser(subparsers)\n    args = parser.parse_args()\n    return args\n\n\ndef load_json_logs(json_logs):\n    # load and convert json_logs to log_dict, key is epoch, value is a sub dict\n    # keys of sub dict is different metrics, e.g. memory, top1_acc\n    # value of sub dict is a list of corresponding values of all iterations\n    log_dicts = [dict() for _ in json_logs]\n    for json_log, log_dict in zip(json_logs, log_dicts):\n        with open(json_log, 'r') as log_file:\n            for line in log_file:\n                log = json.loads(line.strip())\n                # skip lines without `epoch` field\n                if 'epoch' not in log:\n                    continue\n                epoch = log.pop('epoch')\n                if epoch not in log_dict:\n                    log_dict[epoch] = defaultdict(list)\n                for k, v in log.items():\n                    log_dict[epoch][k].append(v)\n    return log_dicts\n\n\ndef main():\n    args = parse_args()\n\n    json_logs = args.json_logs\n    for json_log in json_logs:\n        assert json_log.endswith('.json')\n\n    log_dicts = load_json_logs(json_logs)\n\n    eval(args.task)(log_dicts, args)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/analysis_tools/get_flops.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\n\nimport numpy as np\nimport torch\nfrom mmengine.config import DictAction\nfrom mmengine.logging import MMLogger\n\nfrom mmpose.apis.inference import init_model\n\ntry:\n    from mmengine.analysis import get_model_complexity_info\n    from mmengine.analysis.print_helper import _format_size\nexcept ImportError:\n    raise ImportError('Please upgrade mmengine >= 0.6.0')\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='Get complexity information from a model config')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument(\n        '--device', default='cpu', help='Device used for model initialization')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        default={},\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. For example, '\n        \"'--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'\")\n    parser.add_argument(\n        '--input-shape',\n        type=int,\n        nargs='+',\n        default=[256, 192],\n        help='input image size')\n    parser.add_argument(\n        '--batch-size',\n        '-b',\n        type=int,\n        default=1,\n        help='Input batch size. If specified and greater than 1, it takes a '\n        'callable method that generates a batch input. Otherwise, it will '\n        'generate a random tensor with input shape to calculate FLOPs.')\n    parser.add_argument(\n        '--show-arch-info',\n        '-s',\n        action='store_true',\n        help='Whether to show model arch information')\n    args = parser.parse_args()\n    return args\n\n\ndef batch_constructor(flops_model, batch_size, input_shape):\n    \"\"\"Generate a batch of tensors to the model.\"\"\"\n    batch = {}\n\n    inputs = torch.randn(batch_size, *input_shape).new_empty(\n        (batch_size, *input_shape),\n        dtype=next(flops_model.parameters()).dtype,\n        device=next(flops_model.parameters()).device)\n\n    batch['inputs'] = inputs\n    return batch\n\n\ndef inference(args, input_shape, logger):\n    model = init_model(\n        args.config,\n        checkpoint=None,\n        device=args.device,\n        cfg_options=args.cfg_options)\n\n    if hasattr(model, '_forward'):\n        model.forward = model._forward\n    else:\n        raise NotImplementedError(\n            'FLOPs counter is currently not currently supported with {}'.\n            format(model.__class__.__name__))\n\n    if args.batch_size > 1:\n        outputs = {}\n        avg_flops = []\n        logger.info('Running get_flops with batch size specified as {}'.format(\n            args.batch_size))\n        batch = batch_constructor(model, args.batch_size, input_shape)\n        for i in range(args.batch_size):\n            result = get_model_complexity_info(\n                model,\n                input_shape,\n                inputs=batch['inputs'],\n                show_table=True,\n                show_arch=args.show_arch_info)\n            avg_flops.append(result['flops'])\n        mean_flops = _format_size(int(np.average(avg_flops)))\n        outputs['flops_str'] = mean_flops\n        outputs['params_str'] = result['params_str']\n        outputs['out_table'] = result['out_table']\n        outputs['out_arch'] = result['out_arch']\n    else:\n        outputs = get_model_complexity_info(\n            model,\n            input_shape,\n            inputs=None,\n            show_table=True,\n            show_arch=args.show_arch_info)\n    return outputs\n\n\ndef main():\n    args = parse_args()\n    logger = MMLogger.get_instance(name='MMLogger')\n\n    if len(args.input_shape) == 1:\n        input_shape = (3, args.input_shape[0], args.input_shape[0])\n    elif len(args.input_shape) == 2:\n        input_shape = (3, ) + tuple(args.input_shape)\n    else:\n        raise ValueError('invalid input shape')\n\n    if args.device == 'cuda:0':\n        assert torch.cuda.is_available(\n        ), 'No valid cuda device detected, please double check...'\n\n    outputs = inference(args, input_shape, logger)\n    flops = outputs['flops_str']\n    params = outputs['params_str']\n    split_line = '=' * 30\n    input_shape = (args.batch_size, ) + input_shape\n    print(f'{split_line}\\nInput shape: {input_shape}\\n'\n          f'Flops: {flops}\\nParams: {params}\\n{split_line}')\n    print(outputs['out_table'])\n    if args.show_arch_info:\n        print(outputs['out_arch'])\n    print('!!!Please be cautious if you use the results in papers. '\n          'You may need to check if all ops are supported and verify that the '\n          'flops computation is correct.')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/analysis_tools/print_config.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\n\nfrom mmengine import Config, DictAction\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Print the whole config')\n    parser.add_argument('config', help='config file path')\n    parser.add_argument(\n        '--options', nargs='+', action=DictAction, help='arguments in dict')\n    args = parser.parse_args()\n\n    return args\n\n\ndef main():\n    args = parse_args()\n\n    cfg = Config.fromfile(args.config)\n    if args.options is not None:\n        cfg.merge_from_dict(args.options)\n    print(f'Config:\\n{cfg.pretty_text}')\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/dataset_converters/300vw2coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport math\nimport multiprocessing\nimport os\nimport subprocess\nfrom glob import glob\nfrom os.path import join\n\nimport numpy as np\nfrom PIL import Image\n\n\ndef extract_frames(video_path):\n    # Get the base path and video name\n    base_path, video_name = os.path.split(video_path)\n    # Remove the extension from the video name to get the folder name\n    folder_name = 'imgs'\n    # Create the new folder path\n    folder_path = os.path.join(base_path, folder_name)\n\n    if not os.path.exists(folder_path):\n        # Create the folder if it doesn't exist;\n        os.makedirs(folder_path)\n\n        # Create the output file pattern\n        output_pattern = os.path.join(folder_path, '%06d.png')\n\n        # Call ffmpeg to extract the frames\n        subprocess.call([\n            'ffmpeg', '-i', video_path, '-q:v', '0', '-start_number', '1',\n            output_pattern\n        ])\n    else:\n        # Skip this video if the frame folder already exist!\n        print(f'{folder_path} already exist. Skip {video_path}!')\n        return\n\n\nclass Base300VW:\n\n    def __init__(self):\n        extra_path = './tests/data/300vw/broken_frames.npy'\n        self.broken_frames = np.load(extra_path, allow_pickle=True).item()\n        self.videos_full = [\n            '001', '002', '003', '004', '007', '009', '010', '011', '013',\n            '015', '016', '017', '018', '019', '020', '022', '025', '027',\n            '028', '029', '031', '033', '034', '035', '037', '039', '041',\n            '043', '044', '046', '047', '048', '049', '053', '057', '059',\n            '112', '113', '114', '115', '119', '120', '123', '124', '125',\n            '126', '138', '143', '144', '150', '158', '160', '203', '204',\n            '205', '208', '211', '212', '213', '214', '218', '223', '224',\n            '225', '401', '402', '403', '404', '405', '406', '407', '408',\n            '409', '410', '411', '412', '505', '506', '507', '508', '509',\n            '510', '511', '514', '515', '516', '517', '518', '519', '520',\n            '521', '522', '524', '525', '526', '528', '529', '530', '531',\n            '533', '537', '538', '540', '541', '546', '547', '548', '550',\n            '551', '553', '557', '558', '559', '562'\n        ]\n\n        # Category 1 in laboratory and naturalistic well-lit conditions\n        self.videos_test_1 = [\n            '114', '124', '125', '126', '150', '158', '401', '402', '505',\n            '506', '507', '508', '509', '510', '511', '514', '515', '518',\n            '519', '520', '521', '522', '524', '525', '537', '538', '540',\n            '541', '546', '547', '548'\n        ]\n        # Category 2 in real-world human-computer interaction applications\n        self.videos_test_2 = [\n            '203', '208', '211', '212', '213', '214', '218', '224', '403',\n            '404', '405', '406', '407', '408', '409', '412', '550', '551',\n            '553'\n        ]\n        # Category 3 in arbitrary conditions\n        self.videos_test_3 = [\n            '410', '411', '516', '517', '526', '528', '529', '530', '531',\n            '533', '557', '558', '559', '562'\n        ]\n\n        self.videos_test = \\\n            self.videos_test_1 + self.videos_test_2 + self.videos_test_3\n        self.videos_train = [\n            i for i in self.videos_full if i not in self.videos_test\n        ]\n\n        self.videos_part = ['001', '401']\n\n        self.point_num = 68\n\n\nclass Preprocess300VW(Base300VW):\n\n    def __init__(self, dataset_root):\n        super().__init__()\n        self.dataset_root = dataset_root\n        self._extract_frames()\n        self.json_data = self._init_json_data()\n\n    def _init_json_data(self):\n        \"\"\"Initialize JSON data structure.\"\"\"\n        return {\n            'images': [],\n            'annotations': [],\n            'categories': [{\n                'id': 1,\n                'name': 'person'\n            }]\n        }\n\n    def _extract_frames(self):\n        \"\"\"Extract frames from videos.\"\"\"\n        all_video_paths = glob(os.path.join(self.dataset_root, '*/vid.avi'))\n        with multiprocessing.Pool() as pool:\n            pool.map(extract_frames, all_video_paths)\n\n    def _extract_keypoints_from_pts(self, file_path):\n        \"\"\"Extract keypoints from .pts files.\"\"\"\n        keypoints = []\n        with open(file_path, 'r') as file:\n            file_content = file.read()\n        start_index = file_content.find('{')\n        end_index = file_content.rfind('}')\n        if start_index != -1 and end_index != -1:\n            data_inside_braces = file_content[start_index + 1:end_index]\n            lines = data_inside_braces.split('\\n')\n            for line in lines:\n                if line.strip():\n                    x, y = map(float, line.split())\n                    keypoints.extend([x, y])\n        else:\n            print('No data found inside braces.')\n        return keypoints\n\n    def _get_video_list(self, video_list):\n        \"\"\"Get video list based on input type.\"\"\"\n        if isinstance(video_list, list):\n            return self.videos_part\n        elif isinstance(video_list, str):\n            if hasattr(self, video_list):\n                return getattr(self, video_list)\n            else:\n                raise KeyError\n        elif video_list is None:\n            return self.videos_part\n        else:\n            raise ValueError\n\n    def _process_image(self, img_path):\n        \"\"\"Process image and return image dictionary.\"\"\"\n        image_dict = {}\n        image_dict['file_name'] = os.path.relpath(img_path, self.dataset_root)\n        image_pic = Image.open(img_path)\n        pic_width, pic_height = image_pic.size\n        image_dict['height'] = pic_height\n        image_dict['width'] = pic_width\n        image_pic.close()\n        return image_dict\n\n    def _process_annotation(self, annot_path, image_id, anno_id):\n        \"\"\"Process annotation and return annotation dictionary.\"\"\"\n        annotation = {\n            'segmentation': [],\n            'num_keypoints': self.point_num,\n            'iscrowd': 0,\n            'category_id': 1,\n        }\n        keypoints = self._extract_keypoints_from_pts(annot_path)\n        keypoints3 = []\n        for kp_i in range(1, 68 * 2 + 1):\n            keypoints3.append(keypoints[kp_i - 1])\n            if kp_i % 2 == 0:\n                keypoints3.append(1)\n        annotation['keypoints'] = keypoints3\n        annotation = self._calculate_annotation_properties(\n            annotation, keypoints)\n        annotation['image_id'] = image_id\n        annotation['id'] = anno_id\n        return annotation\n\n    def _calculate_annotation_properties(self, annotation, keypoints):\n        \"\"\"Calculate properties for annotation.\"\"\"\n        keypoints_x = []\n        keypoints_y = []\n        for j in range(self.point_num * 2):\n            if j % 2 == 0:\n                keypoints_x.append(keypoints[j])\n            else:\n                keypoints_y.append(keypoints[j])\n        x_left = min(keypoints_x)\n        x_right = max(keypoints_x)\n        y_low = min(keypoints_y)\n        y_high = max(keypoints_y)\n        w = x_right - x_left\n        h = y_high - y_low\n        annotation['scale'] = math.ceil(max(w, h)) / 200\n        annotation['area'] = w * h\n        annotation['center'] = [(x_left + x_right) / 2, (y_low + y_high) / 2]\n        return annotation\n\n    def convert_annotations(self,\n                            video_list=None,\n                            json_save_name='anno_300vw.json'):\n        \"\"\"Convert 300vw original annotations to coco format.\"\"\"\n        video_list = self._get_video_list(video_list)\n        image_id = 0\n        anno_id = 0\n        for video_id in video_list:\n            annot_root = join(self.dataset_root, video_id, 'annot')\n            img_dir = join(self.dataset_root, video_id, 'imgs')\n            if not (os.path.isdir(annot_root) and os.path.isdir(img_dir)):\n                print(f'{annot_root} or {img_dir} not found. skip {video_id}!')\n                continue\n            annots = sorted(os.listdir(annot_root))\n            for annot in annots:\n                frame_num = int(annot.split('.')[0])\n                if video_id in self.broken_frames and \\\n                        frame_num in self.broken_frames[video_id]:\n                    print(f'skip broken frames: {frame_num} in {video_id}')\n                    continue\n\n                img_path = os.path.join(img_dir, f'{frame_num:06d}.png')\n                if not os.path.exists(img_path):\n                    print(f'{img_path} not found. skip!')\n                    continue\n\n                # Process image and add to JSON data\n                image_dict = self._process_image(img_path)\n                image_dict['id'] = image_id\n\n                # Construct annotation path\n                annot_path = os.path.join(annot_root, annot)\n                annotation = self._process_annotation(annot_path, image_id,\n                                                      anno_id)\n\n                # Process annotation and add to JSON data\n                self.json_data['images'].append(image_dict)\n                self.json_data['annotations'].append(annotation)\n\n                image_id += 1\n                anno_id += 1\n\n            print(f'Annotations from \"{annot_root}\" have been converted.')\n\n        self._save_json_data(json_save_name)\n\n    def _save_json_data(self, json_save_name):\n        json_save_path = os.path.join(self.dataset_root, json_save_name)\n        with open(json_save_path, 'w') as json_file:\n            json.dump(self.json_data, json_file, indent=4)\n\n\nif __name__ == '__main__':\n    convert300vw = Preprocess300VW(dataset_root='./tests/data/300vw')\n    convert300vw.convert_annotations()\n"
  },
  {
    "path": "tools/dataset_converters/300wlp2coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os\nimport os.path as osp\nimport shutil\nimport time\n\nimport cv2\nimport numpy as np\nfrom scipy.io import loadmat\n\n\n# Move all images to one folder\ndef move_img(img_path, save_img):\n    path_list = ['AFW', 'HELEN', 'IBUG', 'LFPW']\n    # 保存路径\n    if not os.path.isdir(save_img):\n        os.makedirs(save_img)\n\n    for people_name in path_list:\n        # 读取文件夹中图片\n        Image_dir = os.path.join(img_path, people_name)\n        img_list = os.listdir(Image_dir)\n        for img_name in img_list:\n            if 'jpg' in img_name:\n                old_img_path = Image_dir + '/' + img_name\n                shutil.move(old_img_path, save_img + '/' + img_name)\n\n\n# split 300w-lp data\ndef split_data(file_img,\n               train_path,\n               val_path,\n               test_path,\n               shuffle=True,\n               ratio1=0.8,\n               ratio2=0.1):\n    img_list = os.listdir(file_img)\n    if shuffle:\n        np.random.shuffle(img_list)\n\n    n_total = len(img_list)\n    offset_train = int(n_total * ratio1)\n    offset_val = int(n_total * ratio2) + offset_train\n    train_img = img_list[:offset_train]\n    val_img = img_list[offset_train:offset_val]\n    test_img = img_list[offset_val:]\n    for img in train_img:\n        shutil.move(file_img + '/' + img, train_path + '/' + img)\n    for img in val_img:\n        shutil.move(file_img + '/' + img, val_path + '/' + img)\n    for img in test_img:\n        shutil.move(file_img + '/' + img, test_path + '/' + img)\n\n\ndef default_dump(obj):\n    \"\"\"Convert numpy classes to JSON serializable objects.\"\"\"\n    if isinstance(obj, (np.integer, np.floating, np.bool_)):\n        return obj.item()\n    elif isinstance(obj, np.ndarray):\n        return obj.tolist()\n    else:\n        return obj\n\n\ndef convert_300WLP_to_coco(root_path, img_pathDir, out_file):\n    annotations = []\n    images = []\n    cnt = 0\n    if 'trainval' in img_pathDir:\n        img_dir_list = ['train', 'val']\n    else:\n        img_dir_list = [img_pathDir]\n\n    for tv in img_dir_list:\n\n        img_dir = osp.join(root_path, tv)\n        landmark_dir = os.path.join(root_path, '300W_LP', 'landmarks')\n        img_list = os.listdir(img_dir)\n\n        for idx, img_name in enumerate(img_list):\n            cnt += 1\n            img_path = osp.join(img_dir, img_name)\n            type_name = img_name.split('_')[0]\n            ann_name = img_name.split('.')[0] + '_pts.mat'\n            ann_path = osp.join(landmark_dir, type_name, ann_name)\n            data_info = loadmat(ann_path)\n\n            img = cv2.imread(img_path)\n\n            keypoints = data_info['pts_2d']\n            keypoints_all = []\n            for i in range(keypoints.shape[0]):\n                x, y = keypoints[i][0], keypoints[i][1]\n                keypoints_all.append([x, y, 2])\n            keypoints = np.array(keypoints_all)\n\n            x1, y1, _ = np.amin(keypoints, axis=0)\n            x2, y2, _ = np.amax(keypoints, axis=0)\n            w, h = x2 - x1, y2 - y1\n            bbox = [x1, y1, w, h]\n\n            image = {}\n            image['id'] = cnt\n            image['file_name'] = img_name\n            image['height'] = img.shape[0]\n            image['width'] = img.shape[1]\n            images.append(image)\n\n            ann = {}\n            ann['keypoints'] = keypoints.reshape(-1).tolist()\n            ann['image_id'] = cnt\n            ann['id'] = cnt\n            ann['num_keypoints'] = len(keypoints)\n            ann['bbox'] = bbox\n            ann['iscrowd'] = 0\n            ann['area'] = int(ann['bbox'][2] * ann['bbox'][3])\n            ann['category_id'] = 1\n\n            annotations.append(ann)\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info']['description'] = 'LaPa Generated by MMPose Team'\n    cocotype['info']['version'] = 1.0\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n    cocotype['categories'] = [{\n        'supercategory': 'person',\n        'id': 1,\n        'name': 'face',\n        'keypoints': [],\n        'skeleton': []\n    }]\n\n    json.dump(\n        cocotype,\n        open(out_file, 'w'),\n        ensure_ascii=False,\n        default=default_dump)\n    print(f'done {out_file}')\n\n\nif __name__ == '__main__':\n    # 1.Move all images to one folder\n    # 2.split 300W-LP data\n    # 3.convert json\n    img_path = './300W-LP/300W-LP'\n    save_img = './300W-LP/images'\n    move_img(img_path, save_img)\n\n    file_img = './300W-LP/images'\n    train_path = './300W-LP/train'\n    val_path = './300W-LP/val'\n    test_path = './300W-LP/test'\n    split_data(save_img, train_path, val_path, test_path)\n\n    root_path = './300W-LP'\n    anno_path_json = osp.join(root_path, 'annotations')\n    if not osp.exists(anno_path_json):\n        os.makedirs(anno_path_json)\n    for tv in ['val', 'test', 'train']:\n        print(f'processing {tv}')\n        convert_300WLP_to_coco(\n            root_path, tv,\n            anno_path_json + '/' + f'face_landmarks_300wlp_{tv}.json')\n"
  },
  {
    "path": "tools/dataset_converters/h36m_to_coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport os.path as osp\nfrom functools import wraps\n\nimport mmengine\nimport numpy as np\nfrom PIL import Image\n\nfrom mmpose.utils import SimpleCamera\n\n\ndef _keypoint_camera_to_world(keypoints,\n                              camera_params,\n                              image_name=None,\n                              dataset='Body3DH36MDataset'):\n    \"\"\"Project 3D keypoints from the camera space to the world space.\n\n    Args:\n        keypoints (np.ndarray): 3D keypoints in shape [..., 3]\n        camera_params (dict): Parameters for all cameras.\n        image_name (str): The image name to specify the camera.\n        dataset (str): The dataset type, e.g., Body3DH36MDataset.\n    \"\"\"\n    cam_key = None\n    if dataset == 'Body3DH36MDataset':\n        subj, rest = osp.basename(image_name).split('_', 1)\n        _, rest = rest.split('.', 1)\n        camera, rest = rest.split('_', 1)\n        cam_key = (subj, camera)\n    else:\n        raise NotImplementedError\n\n    camera = SimpleCamera(camera_params[cam_key])\n    keypoints_world = keypoints.copy()\n    keypoints_world[..., :3] = camera.camera_to_world(keypoints[..., :3])\n\n    return keypoints_world\n\n\ndef _get_bbox_xywh(center, scale, w=200, h=200):\n    w = w * scale\n    h = h * scale\n    x = center[0] - w / 2\n    y = center[1] - h / 2\n    return [x, y, w, h]\n\n\ndef mmcv_track_func(func):\n\n    @wraps(func)\n    def wrapped_func(args):\n        return func(*args)\n\n    return wrapped_func\n\n\n@mmcv_track_func\ndef _get_img_info(img_idx, img_name, img_root):\n    try:\n        im = Image.open(osp.join(img_root, img_name))\n        w, h = im.size\n    except:  # noqa: E722\n        return None\n\n    img = {\n        'file_name': img_name,\n        'height': h,\n        'width': w,\n        'id': img_idx + 1,\n    }\n    return img\n\n\n@mmcv_track_func\ndef _get_ann(idx, kpt_2d, kpt_3d, center, scale, imgname, camera_params):\n    bbox = _get_bbox_xywh(center, scale)\n    kpt_3d = _keypoint_camera_to_world(kpt_3d, camera_params, imgname)\n\n    ann = {\n        'id': idx + 1,\n        'category_id': 1,\n        'image_id': idx + 1,\n        'iscrowd': 0,\n        'bbox': bbox,\n        'area': bbox[2] * bbox[3],\n        'num_keypoints': 17,\n        'keypoints': kpt_2d.reshape(-1).tolist(),\n        'keypoints_3d': kpt_3d.reshape(-1).tolist()\n    }\n\n    return ann\n\n\ndef main():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        '--ann-file', type=str, default='tests/data/h36m/test_h36m_body3d.npz')\n    parser.add_argument(\n        '--camera-param-file', type=str, default='tests/data/h36m/cameras.pkl')\n    parser.add_argument('--img-root', type=str, default='tests/data/h36m')\n    parser.add_argument(\n        '--out-file', type=str, default='tests/data/h36m/h36m_coco.json')\n    parser.add_argument('--full-img-name', action='store_true')\n\n    args = parser.parse_args()\n\n    h36m_data = np.load(args.ann_file)\n    h36m_camera_params = mmengine.load(args.camera_param_file)\n    h36m_coco = {}\n\n    # categories\n    h36m_cats = [{\n        'supercategory':\n        'person',\n        'id':\n        1,\n        'name':\n        'person',\n        'keypoints': [\n            'root (pelvis)', 'left_hip', 'left_knee', 'left_foot', 'right_hip',\n            'right_knee', 'right_foot', 'spine', 'thorax', 'neck_base', 'head',\n            'left_shoulder', 'left_elbow', 'left_wrist', 'right_shoulder',\n            'right_elbow', 'right_wrist'\n        ],\n        'skeleton': [[0, 1], [1, 2], [2, 3], [0, 4], [4, 5], [5, 6], [0, 7],\n                     [7, 8], [8, 9], [9, 10], [8, 11], [11, 12], [12, 13],\n                     [8, 14], [14, 15], [15, 16]],\n    }]\n\n    # images\n    imgnames = h36m_data['imgname']\n    if not args.full_img_name:\n        imgnames = [osp.basename(fn) for fn in imgnames]\n    tasks = [(idx, fn, args.img_root) for idx, fn in enumerate(imgnames)]\n\n    h36m_imgs = mmengine.track_parallel_progress(\n        _get_img_info, tasks, nproc=12)\n\n    # annotations\n    kpts_2d = h36m_data['part']\n    kpts_3d = h36m_data['S']\n    centers = h36m_data['center']\n    scales = h36m_data['scale']\n    tasks = [(idx, ) + args + (h36m_camera_params, )\n             for idx, args in enumerate(\n                 zip(kpts_2d, kpts_3d, centers, scales, imgnames))]\n\n    h36m_anns = mmengine.track_parallel_progress(_get_ann, tasks, nproc=12)\n\n    # remove invalid data\n    h36m_imgs = [img for img in h36m_imgs if img is not None]\n    h36m_img_ids = set([img['id'] for img in h36m_imgs])\n    h36m_anns = [ann for ann in h36m_anns if ann['image_id'] in h36m_img_ids]\n\n    h36m_coco = {\n        'categories': h36m_cats,\n        'images': h36m_imgs,\n        'annotations': h36m_anns,\n    }\n\n    mmengine.dump(h36m_coco, args.out_file)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/dataset_converters/labelstudio2coco.py",
    "content": "# -----------------------------------------------------------------------------\n# Based on https://github.com/heartexlabs/label-studio-converter\n# Original license: Copyright (c) Heartex, under the Apache 2.0 License.\n# -----------------------------------------------------------------------------\n\nimport argparse\nimport io\nimport json\nimport logging\nimport pathlib\nimport xml.etree.ElementTree as ET\nfrom datetime import datetime\n\nimport numpy as np\n\nlogger = logging.getLogger(__name__)\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='Convert Label Studio JSON file to COCO format JSON File')\n    parser.add_argument('config', help='Labeling Interface xml code file path')\n    parser.add_argument('input', help='Label Studio format JSON file path')\n    parser.add_argument('output', help='The output COCO format JSON file path')\n    args = parser.parse_args()\n    return args\n\n\nclass LSConverter:\n\n    def __init__(self, config: str):\n        \"\"\"Convert the Label Studio Format JSON file to COCO format JSON file\n        which is needed by mmpose.\n\n           The annotations in label studio must follow the order:\n           keypoint 1, keypoint 2... keypoint n, rect of the instance,\n           polygon of the instance,\n           then annotations of the next instance.\n           Where the order of rect and polygon can be switched,\n           the bbox and area of the instance will be calculated with\n           the data behind.\n\n           Only annotating one of rect and polygon is also acceptable.\n        Args:\n            config (str): The annotations config xml file.\n                The xml content is from Project Setting ->\n                Label Interface -> Code.\n                Example:\n                ```\n                <View>\n                <KeyPointLabels name=\"kp-1\" toName=\"img-1\">\n                    <Label value=\"person\" background=\"#D4380D\"/>\n                </KeyPointLabels>\n                <PolygonLabels name=\"polygonlabel\" toName=\"img-1\">\n                    <Label value=\"person\" background=\"#0DA39E\"/>\n                </PolygonLabels>\n                <RectangleLabels name=\"label\" toName=\"img-1\">\n                    <Label value=\"person\" background=\"#DDA0EE\"/>\n                </RectangleLabels>\n                <Image name=\"img-1\" value=\"$img\"/>\n                </View>\n                ```\n        \"\"\"\n        # get label info from config file\n        tree = ET.parse(config)\n        root = tree.getroot()\n        labels = root.findall('.//KeyPointLabels/Label')\n        label_values = [label.get('value') for label in labels]\n\n        self.categories = list()\n        self.category_name_to_id = dict()\n        for i, value in enumerate(label_values):\n            # category id start with 1\n            self.categories.append({'id': i + 1, 'name': value})\n            self.category_name_to_id[value] = i + 1\n\n    def convert_to_coco(self, input_json: str, output_json: str):\n        \"\"\"Convert `input_json` to COCO format and save in `output_json`.\n\n        Args:\n            input_json (str): The path of Label Studio format JSON file.\n            output_json (str): The path of the output COCO JSON file.\n        \"\"\"\n\n        def add_image(images, width, height, image_id, image_path):\n            images.append({\n                'width': width,\n                'height': height,\n                'id': image_id,\n                'file_name': image_path,\n            })\n            return images\n\n        output_path = pathlib.Path(output_json)\n        output_path.parent.mkdir(parents=True, exist_ok=True)\n\n        images = list()\n        annotations = list()\n\n        with open(input_json, 'r') as f:\n            ann_list = json.load(f)\n\n        for item_idx, item in enumerate(ann_list):\n            # each image is an item\n            image_name = item['file_upload']\n            image_id = len(images)\n            width, height = None, None\n\n            # skip tasks without annotations\n            if not item['annotations']:\n                logger.warning('No annotations found for item #' +\n                               str(item_idx))\n                continue\n\n            kp_num = 0\n            for i, label in enumerate(item['annotations'][0]['result']):\n                category_name = None\n\n                # valid label\n                for key in [\n                        'rectanglelabels', 'polygonlabels', 'labels',\n                        'keypointlabels'\n                ]:\n                    if key == label['type'] and len(label['value'][key]) > 0:\n                        category_name = label['value'][key][0]\n                        break\n\n                if category_name is None:\n                    logger.warning('Unknown label type or labels are empty')\n                    continue\n\n                if not height or not width:\n                    if 'original_width' not in label or \\\n                            'original_height' not in label:\n                        logger.debug(\n                            f'original_width or original_height not found'\n                            f'in {image_name}')\n                        continue\n\n                    # get height and width info from annotations\n                    width, height = label['original_width'], label[\n                        'original_height']\n                    images = add_image(images, width, height, image_id,\n                                       image_name)\n\n                category_id = self.category_name_to_id[category_name]\n\n                annotation_id = len(annotations)\n\n                if 'rectanglelabels' == label['type'] or 'labels' == label[\n                        'type']:\n\n                    x = label['value']['x']\n                    y = label['value']['y']\n                    w = label['value']['width']\n                    h = label['value']['height']\n\n                    x = x * label['original_width'] / 100\n                    y = y * label['original_height'] / 100\n                    w = w * label['original_width'] / 100\n                    h = h * label['original_height'] / 100\n\n                    # rect annotation should be later than keypoints\n                    annotations[-1]['bbox'] = [x, y, w, h]\n                    annotations[-1]['area'] = w * h\n                    annotations[-1]['num_keypoints'] = kp_num\n\n                elif 'polygonlabels' == label['type']:\n                    points_abs = [(x / 100 * width, y / 100 * height)\n                                  for x, y in label['value']['points']]\n                    x, y = zip(*points_abs)\n\n                    x1, y1, x2, y2 = min(x), min(y), max(x), max(y)\n\n                    # calculate bbox and area from polygon's points\n                    # which may be different with rect annotation\n                    bbox = [x1, y1, x2 - x1, y2 - y1]\n                    area = float(0.5 * np.abs(\n                        np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))))\n\n                    # polygon label should be later than keypoints\n                    annotations[-1]['segmentation'] = [[\n                        coord for point in points_abs for coord in point\n                    ]]\n                    annotations[-1]['bbox'] = bbox\n                    annotations[-1]['area'] = area\n                    annotations[-1]['num_keypoints'] = kp_num\n\n                elif 'keypointlabels' == label['type']:\n                    x = label['value']['x'] * label['original_width'] / 100\n                    y = label['value']['y'] * label['original_height'] / 100\n\n                    # there is no method to annotate visible in Label Studio\n                    # so the keypoints' visible code will be 2 except (0,0)\n                    if x == y == 0:\n                        current_kp = [x, y, 0]\n                        kp_num_change = 0\n                    else:\n                        current_kp = [x, y, 2]\n                        kp_num_change = 1\n\n                    # create new annotation in coco\n                    # when the keypoint is the first point of an instance\n                    if i == 0 or item['annotations'][0]['result'][\n                            i - 1]['type'] != 'keypointlabels':\n                        annotations.append({\n                            'id': annotation_id,\n                            'image_id': image_id,\n                            'category_id': category_id,\n                            'keypoints': current_kp,\n                            'ignore': 0,\n                            'iscrowd': 0,\n                        })\n                        kp_num = kp_num_change\n                    else:\n                        annotations[-1]['keypoints'].extend(current_kp)\n                        kp_num += kp_num_change\n\n        with io.open(output_json, mode='w', encoding='utf8') as fout:\n            json.dump(\n                {\n                    'images': images,\n                    'categories': self.categories,\n                    'annotations': annotations,\n                    'info': {\n                        'year': datetime.now().year,\n                        'version': '1.0',\n                        'description': '',\n                        'contributor': 'Label Studio',\n                        'url': '',\n                        'date_created': str(datetime.now()),\n                    },\n                },\n                fout,\n                indent=2,\n            )\n\n\ndef main():\n    args = parse_args()\n    config = args.config\n    input_json = args.input\n    output_json = args.output\n    converter = LSConverter(config)\n    converter.convert_to_coco(input_json, output_json)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/dataset_converters/lapa2coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os\nimport os.path as osp\nimport time\n\nimport cv2\nimport mmengine\nimport numpy as np\n\n\ndef default_dump(obj):\n    \"\"\"Convert numpy classes to JSON serializable objects.\"\"\"\n    if isinstance(obj, (np.integer, np.floating, np.bool_)):\n        return obj.item()\n    elif isinstance(obj, np.ndarray):\n        return obj.tolist()\n    else:\n        return obj\n\n\ndef convert_labpa_to_coco(ann_dir, out_file):\n    annotations = []\n    images = []\n    cnt = 0\n\n    if 'trainval' in ann_dir:\n        ann_dir_list = ['train', 'val']\n    else:\n        ann_dir_list = [ann_dir]\n\n    for tv in ann_dir_list:\n        ann_dir = 'data/LaPa/' + tv\n        landmark_dir = osp.join(ann_dir, 'landmarks')\n        ann_list = os.listdir(landmark_dir)\n\n        img_dir = osp.join(ann_dir, 'images')\n\n        for idx, ann_file in enumerate(mmengine.track_iter_progress(ann_list)):\n            cnt += 1\n            ann_path = osp.join(landmark_dir, ann_file)\n            file_name = ann_file[:-4] + '.jpg'\n            img_path = osp.join(img_dir, file_name)\n            data_info = open(ann_path).readlines()\n\n            img = cv2.imread(img_path)\n\n            keypoints = []\n            for line in data_info[1:]:\n                x, y = line.strip().split(' ')\n                x, y = float(x), float(y)\n                keypoints.append([x, y, 2])\n            keypoints = np.array(keypoints)\n\n            x1, y1, _ = np.amin(keypoints, axis=0)\n            x2, y2, _ = np.amax(keypoints, axis=0)\n            w, h = x2 - x1, y2 - y1\n            bbox = [x1, y1, w, h]\n\n            image = {}\n            image['id'] = cnt\n            image['file_name'] = f'{tv}/images/{file_name}'\n            image['height'] = img.shape[0]\n            image['width'] = img.shape[1]\n            images.append(image)\n\n            ann = {}\n            ann['keypoints'] = keypoints.reshape(-1).tolist()\n            ann['image_id'] = cnt\n            ann['id'] = cnt\n            ann['num_keypoints'] = len(keypoints)\n            ann['bbox'] = bbox\n            ann['iscrowd'] = 0\n            ann['area'] = int(ann['bbox'][2] * ann['bbox'][3])\n            ann['category_id'] = 1\n\n            annotations.append(ann)\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info']['description'] = 'LaPa Generated by MMPose Team'\n    cocotype['info']['version'] = 1.0\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n    cocotype['categories'] = [{\n        'supercategory': 'person',\n        'id': 1,\n        'name': 'face',\n        'keypoints': [],\n        'skeleton': []\n    }]\n\n    json.dump(\n        cocotype,\n        open(out_file, 'w'),\n        ensure_ascii=False,\n        default=default_dump)\n    print(f'done {out_file}')\n\n\nif __name__ == '__main__':\n    if not osp.exists('data/LaPa/annotations'):\n        os.makedirs('data/LaPa/annotations')\n    for tv in ['val', 'test', 'train', 'trainval']:\n        print(f'processing {tv}')\n        convert_labpa_to_coco(tv, f'data/LaPa/annotations/lapa_{tv}.json')\n"
  },
  {
    "path": "tools/dataset_converters/mat2json.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport json\nimport time\n\nfrom scipy.io import loadmat\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='Converting the predicted .mat file to .json file.')\n    parser.add_argument('pred_mat_file', help='input prediction mat file.')\n    parser.add_argument(\n        'gt_json_file',\n        help='input ground-truth json file to get the image name. '\n        'Default: \"data/mpii/mpii_val.json\" ')\n    parser.add_argument('output_json_file', help='output converted json file.')\n    args = parser.parse_args()\n    return args\n\n\ndef save_json(list_file, path):\n    with open(path, 'w') as f:\n        json.dump(list_file, f, indent=4)\n    return 0\n\n\ndef convert_mat(pred_mat_file, gt_json_file, output_json_file):\n    res = loadmat(pred_mat_file)\n    preds = res['preds']\n    N = preds.shape[0]\n\n    with open(gt_json_file) as anno_file:\n        anno = json.load(anno_file)\n\n    assert len(anno) == N\n\n    instance = {}\n\n    for pred, ann in zip(preds, anno):\n        ann.pop('joints_vis')\n        ann['joints'] = pred.tolist()\n\n    instance['annotations'] = anno\n    instance['info'] = {}\n    instance['info']['description'] = 'Converted MPII prediction.'\n    instance['info']['year'] = time.strftime('%Y', time.localtime())\n    instance['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    save_json(instance, output_json_file)\n\n\ndef main():\n    args = parse_args()\n    convert_mat(args.pred_mat_file, args.gt_json_file, args.output_json_file)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/dataset_converters/parse_animalpose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os\nimport re\nimport time\nimport warnings\n\nimport cv2\nimport numpy as np\nimport xmltodict\nfrom xtcocotools.coco import COCO\n\nnp.random.seed(0)\n\n\ndef list_all_files(root_dir, ext='.xml'):\n    \"\"\"List all files in the root directory and all its sub directories.\n\n    :param root_dir: root directory\n    :param ext: filename extension\n    :return: list of files\n    \"\"\"\n    files = []\n    file_list = os.listdir(root_dir)\n    for i in range(0, len(file_list)):\n        path = os.path.join(root_dir, file_list[i])\n        if os.path.isdir(path):\n            files.extend(list_all_files(path))\n        if os.path.isfile(path):\n            if path.lower().endswith(ext):\n                files.append(path)\n    return files\n\n\ndef get_anno_info():\n    keypoints_info = [\n        'L_Eye',\n        'R_Eye',\n        'L_EarBase',\n        'R_EarBase',\n        'Nose',\n        'Throat',\n        'TailBase',\n        'Withers',\n        'L_F_Elbow',\n        'R_F_Elbow',\n        'L_B_Elbow',\n        'R_B_Elbow',\n        'L_F_Knee',\n        'R_F_Knee',\n        'L_B_Knee',\n        'R_B_Knee',\n        'L_F_Paw',\n        'R_F_Paw',\n        'L_B_Paw',\n        'R_B_Paw',\n    ]\n    skeleton_info = [[1, 2], [1, 3], [2, 4], [1, 5], [2, 5], [5, 6], [6, 8],\n                     [7, 8], [6, 9], [9, 13], [13, 17], [6, 10], [10, 14],\n                     [14, 18], [7, 11], [11, 15], [15, 19], [7, 12], [12, 16],\n                     [16, 20]]\n    category_info = [{\n        'supercategory': 'animal',\n        'id': 1,\n        'name': 'animal',\n        'keypoints': keypoints_info,\n        'skeleton': skeleton_info\n    }]\n\n    return keypoints_info, skeleton_info, category_info\n\n\ndef xml2coco_trainval(file_list, img_root, save_path, start_ann_id=0):\n    \"\"\"Save annotations in coco-format.\n\n    :param file_list: list of data annotation files.\n    :param img_root: the root dir to load images.\n    :param save_path: the path to save transformed annotation file.\n    :param start_ann_id: the starting point to count the annotation id.\n    :param val_num: the number of annotated objects for validation.\n    \"\"\"\n    images = []\n    annotations = []\n    img_ids = []\n    ann_ids = []\n\n    ann_id = start_ann_id\n\n    name2id = {\n        'L_Eye': 0,\n        'R_Eye': 1,\n        'L_EarBase': 2,\n        'R_EarBase': 3,\n        'Nose': 4,\n        'Throat': 5,\n        'TailBase': 6,\n        'Withers': 7,\n        'L_F_Elbow': 8,\n        'R_F_Elbow': 9,\n        'L_B_Elbow': 10,\n        'R_B_Elbow': 11,\n        'L_F_Knee': 12,\n        'R_F_Knee': 13,\n        'L_B_Knee': 14,\n        'R_B_Knee': 15,\n        'L_F_Paw': 16,\n        'R_F_Paw': 17,\n        'L_B_Paw': 18,\n        'R_B_Paw': 19\n    }\n    for file in file_list:\n        data_anno = xmltodict.parse(open(file).read())['annotation']\n\n        img_id = int(data_anno['image'].split('_')[0] +\n                     data_anno['image'].split('_')[1])\n\n        if img_id not in img_ids:\n            image_name = 'VOC2012/JPEGImages/' + data_anno['image'] + '.jpg'\n            img = cv2.imread(os.path.join(img_root, image_name))\n\n            image = {}\n            image['id'] = img_id\n            image['file_name'] = image_name\n            image['height'] = img.shape[0]\n            image['width'] = img.shape[1]\n\n            images.append(image)\n            img_ids.append(img_id)\n        else:\n            pass\n\n        keypoint_anno = data_anno['keypoints']['keypoint']\n        assert len(keypoint_anno) == 20\n\n        keypoints = np.zeros([20, 3], dtype=np.float32)\n\n        for kpt_anno in keypoint_anno:\n            keypoint_name = kpt_anno['@name']\n            keypoint_id = name2id[keypoint_name]\n\n            visibility = int(kpt_anno['@visible'])\n\n            if visibility == 0:\n                continue\n            else:\n                keypoints[keypoint_id, 0] = float(kpt_anno['@x'])\n                keypoints[keypoint_id, 1] = float(kpt_anno['@y'])\n                keypoints[keypoint_id, 2] = 2\n\n        anno = {}\n        anno['keypoints'] = keypoints.reshape(-1).tolist()\n        anno['image_id'] = img_id\n        anno['id'] = ann_id\n        anno['num_keypoints'] = int(sum(keypoints[:, 2] > 0))\n\n        visible_bounds = data_anno['visible_bounds']\n        anno['bbox'] = [\n            float(visible_bounds['@xmin']),\n            float(visible_bounds['@ymin']),\n            float(visible_bounds['@width']),\n            float(visible_bounds['@height'])\n        ]\n        anno['iscrowd'] = 0\n        anno['area'] = float(anno['bbox'][2] * anno['bbox'][3])\n        anno['category_id'] = 1\n\n        annotations.append(anno)\n        ann_ids.append(ann_id)\n        ann_id += 1\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info'][\n        'description'] = 'AnimalPose dataset Generated by MMPose Team'\n    cocotype['info']['version'] = '1.0'\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n\n    keypoints_info, skeleton_info, category_info = get_anno_info()\n\n    cocotype['categories'] = category_info\n\n    os.makedirs(os.path.dirname(save_path), exist_ok=True)\n    json.dump(cocotype, open(save_path, 'w'), indent=4)\n    print('number of images:', len(img_ids))\n    print('number of annotations:', len(ann_ids))\n    print(f'done {save_path}')\n\n\ndef xml2coco_test(file_list, img_root, save_path, start_ann_id=0):\n    \"\"\"Save annotations in coco-format.\n\n    :param file_list: list of data annotation files.\n    :param img_root: the root dir to load images.\n    :param save_path: the path to save transformed annotation file.\n    :param start_ann_id: the starting point to count the annotation id.\n    \"\"\"\n    images = []\n    annotations = []\n    img_ids = []\n    ann_ids = []\n\n    ann_id = start_ann_id\n\n    name2id = {\n        'L_eye': 0,\n        'R_eye': 1,\n        'L_ear': 2,\n        'R_ear': 3,\n        'Nose': 4,\n        'Throat': 5,\n        'Tail': 6,\n        'withers': 7,\n        'L_F_elbow': 8,\n        'R_F_elbow': 9,\n        'L_B_elbow': 10,\n        'R_B_elbow': 11,\n        'L_F_knee': 12,\n        'R_F_knee': 13,\n        'L_B_knee': 14,\n        'R_B_knee': 15,\n        'L_F_paw': 16,\n        'R_F_paw': 17,\n        'L_B_paw': 18,\n        'R_B_paw': 19\n    }\n\n    cat2id = {'cat': 1, 'cow': 2, 'dog': 3, 'horse': 4, 'sheep': 5}\n\n    for file in file_list:\n        data_anno = xmltodict.parse(open(file).read())['annotation']\n\n        category_id = cat2id[data_anno['category']]\n\n        img_id = category_id * 1000 + int(\n            re.findall(r'\\d+', data_anno['image'])[0])\n\n        assert img_id not in img_ids\n\n        # prepare images\n        image_name = os.path.join('animalpose_image_part2',\n                                  data_anno['category'], data_anno['image'])\n        img = cv2.imread(os.path.join(img_root, image_name))\n\n        image = {}\n        image['id'] = img_id\n        image['file_name'] = image_name\n        image['height'] = img.shape[0]\n        image['width'] = img.shape[1]\n\n        images.append(image)\n        img_ids.append(img_id)\n\n        # prepare annotations\n        keypoint_anno = data_anno['keypoints']['keypoint']\n        keypoints = np.zeros([20, 3], dtype=np.float32)\n\n        for kpt_anno in keypoint_anno:\n            keypoint_name = kpt_anno['@name']\n            keypoint_id = name2id[keypoint_name]\n\n            visibility = int(kpt_anno['@visible'])\n\n            if visibility == 0:\n                continue\n            else:\n                keypoints[keypoint_id, 0] = float(kpt_anno['@x'])\n                keypoints[keypoint_id, 1] = float(kpt_anno['@y'])\n                keypoints[keypoint_id, 2] = 2\n\n        anno = {}\n        anno['keypoints'] = keypoints.reshape(-1).tolist()\n        anno['image_id'] = img_id\n        anno['id'] = ann_id\n        anno['num_keypoints'] = int(sum(keypoints[:, 2] > 0))\n\n        visible_bounds = data_anno['visible_bounds']\n        anno['bbox'] = [\n            float(visible_bounds['@xmin']),\n            float(visible_bounds['@xmax']\n                  ),  # typo in original xml: should be 'ymin'\n            float(visible_bounds['@width']),\n            float(visible_bounds['@height'])\n        ]\n        anno['iscrowd'] = 0\n        anno['area'] = float(anno['bbox'][2] * anno['bbox'][3])\n        anno['category_id'] = 1\n\n        annotations.append(anno)\n        ann_ids.append(ann_id)\n        ann_id += 1\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info'][\n        'description'] = 'AnimalPose dataset Generated by MMPose Team'\n    cocotype['info']['version'] = '1.0'\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n\n    keypoints_info, skeleton_info, category_info = get_anno_info()\n\n    cocotype['categories'] = category_info\n\n    os.makedirs(os.path.dirname(save_path), exist_ok=True)\n    json.dump(cocotype, open(save_path, 'w'), indent=4)\n    print('=========================================================')\n    print('number of images:', len(img_ids))\n    print('number of annotations:', len(ann_ids))\n    print(f'done {save_path}')\n\n\ndef split_train_val(work_dir, trainval_file, train_file, val_file,\n                    val_ann_num):\n    \"\"\"Split train-val json file into training and validation files.\n\n    :param work_dir: path to load train-val json file, and save split files.\n    :param trainval_file: The input json file combining both train and val.\n    :param trainval_file: The output json file for training.\n    :param trainval_file: The output json file for validation.\n    :param val_ann_num: the number of validation annotations.\n    \"\"\"\n\n    coco = COCO(os.path.join(work_dir, trainval_file))\n\n    img_list = list(coco.imgs.keys())\n    np.random.shuffle(img_list)\n\n    count = 0\n\n    images_train = []\n    images_val = []\n    annotations_train = []\n    annotations_val = []\n\n    for img_id in img_list:\n        ann_ids = coco.getAnnIds(img_id)\n\n        if count + len(ann_ids) <= val_ann_num:\n            # for validation\n            count += len(ann_ids)\n            images_val.append(coco.imgs[img_id])\n            for ann_id in ann_ids:\n                annotations_val.append(coco.anns[ann_id])\n\n        else:\n            images_train.append(coco.imgs[img_id])\n            for ann_id in ann_ids:\n                annotations_train.append(coco.anns[ann_id])\n\n    if count == val_ann_num:\n        print(f'We have found {count} annotations for validation.')\n    else:\n        warnings.warn(\n            f'We only found {count} annotations, instead of {val_ann_num}.')\n\n    cocotype_train = {}\n    cocotype_val = {}\n\n    keypoints_info, skeleton_info, category_info = get_anno_info()\n\n    cocotype_train['info'] = {}\n    cocotype_train['info'][\n        'description'] = 'AnimalPose dataset Generated by MMPose Team'\n    cocotype_train['info']['version'] = '1.0'\n    cocotype_train['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype_train['info']['date_created'] = time.strftime(\n        '%Y/%m/%d', time.localtime())\n    cocotype_train['images'] = images_train\n    cocotype_train['annotations'] = annotations_train\n    cocotype_train['categories'] = category_info\n\n    json.dump(\n        cocotype_train,\n        open(os.path.join(work_dir, train_file), 'w'),\n        indent=4)\n    print('=========================================================')\n    print('number of images:', len(images_train))\n    print('number of annotations:', len(annotations_train))\n    print(f'done {train_file}')\n\n    cocotype_val['info'] = {}\n    cocotype_val['info'][\n        'description'] = 'AnimalPose dataset Generated by MMPose Team'\n    cocotype_val['info']['version'] = '1.0'\n    cocotype_val['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype_val['info']['date_created'] = time.strftime(\n        '%Y/%m/%d', time.localtime())\n    cocotype_val['images'] = images_val\n    cocotype_val['annotations'] = annotations_val\n    cocotype_val['categories'] = category_info\n\n    json.dump(\n        cocotype_val, open(os.path.join(work_dir, val_file), 'w'), indent=4)\n    print('=========================================================')\n    print('number of images:', len(images_val))\n    print('number of annotations:', len(annotations_val))\n    print(f'done {val_file}')\n\n\ndataset_dir = 'data/animalpose/'\n\n# We choose the images from PascalVOC for train + val\n# In total, train+val: 3608 images, 5117 annotations\nxml2coco_trainval(\n    list_all_files(os.path.join(dataset_dir, 'PASCAL2011_animal_annotation')),\n    dataset_dir,\n    os.path.join(dataset_dir, 'annotations', 'animalpose_trainval.json'),\n    start_ann_id=1000000)\n\n# train: 2798 images, 4000 annotations\n# val: 810 images, 1117 annotations\nsplit_train_val(\n    os.path.join(dataset_dir, 'annotations'),\n    'animalpose_trainval.json',\n    'animalpose_train.json',\n    'animalpose_val.json',\n    val_ann_num=1117)\n\n# We choose the remaining 1000 images for test\n# 1000 images, 1000 annotations\nxml2coco_test(\n    list_all_files(os.path.join(dataset_dir, 'animalpose_anno2')),\n    dataset_dir,\n    os.path.join(dataset_dir, 'annotations', 'animalpose_test.json'),\n    start_ann_id=0)\n"
  },
  {
    "path": "tools/dataset_converters/parse_cofw_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os\nimport time\n\nimport cv2\nimport h5py\nimport numpy as np\n\nmat_files = ['COFW_train_color.mat', 'COFW_test_color.mat']\ndataset_dir = 'data/cofw/'\n\nimage_root = os.path.join(dataset_dir, 'images/')\nannotation_root = os.path.join(dataset_dir, 'annotations/')\n\nos.makedirs(image_root, exist_ok=True)\nos.makedirs(annotation_root, exist_ok=True)\n\ncnt = 0\nfor mat_file in mat_files:\n    mat = h5py.File(os.path.join(dataset_dir, mat_file), 'r')\n\n    if 'train' in mat_file:\n        imgs = mat['IsTr']\n        pts = mat['phisTr']\n        bboxes = mat['bboxesTr']\n        is_train = True\n        json_file = 'cofw_train.json'\n    else:\n        imgs = mat['IsT']\n        pts = mat['phisT']\n        bboxes = mat['bboxesT']\n        is_train = False\n        json_file = 'cofw_test.json'\n\n    images = []\n    annotations = []\n\n    num = pts.shape[1]\n    for idx in range(0, num):\n        cnt += 1\n        img = np.array(mat[imgs[0, idx]]).transpose()\n        keypoints = pts[:, idx].reshape(3, -1).transpose()\n        # 2 for valid and 1 for occlusion\n        keypoints[:, 2] = 2 - keypoints[:, 2]\n        # matlab 1-index to python 0-index\n        keypoints[:, :2] -= 1\n        bbox = bboxes[:, idx]\n\n        # check nonnegativity\n        bbox[bbox < 0] = 0\n        keypoints[keypoints < 0] = 0\n\n        image = {}\n        image['id'] = cnt\n        image['file_name'] = f'{str(cnt).zfill(6)}.jpg'\n        image['height'] = img.shape[0]\n        image['width'] = img.shape[1]\n        cv2.imwrite(\n            os.path.join(image_root, image['file_name']),\n            cv2.cvtColor(img, cv2.COLOR_RGB2BGR))\n        images.append(image)\n\n        anno = {}\n        anno['keypoints'] = keypoints.reshape(-1).tolist()\n        anno['image_id'] = cnt\n        anno['id'] = cnt\n        anno['num_keypoints'] = len(keypoints)  # all keypoints are labelled\n        anno['bbox'] = bbox.tolist()\n        anno['iscrowd'] = 0\n        anno['area'] = anno['bbox'][2] * anno['bbox'][3]\n        anno['category_id'] = 1\n\n        annotations.append(anno)\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info']['description'] = 'COFW Generated by MMPose Team'\n    cocotype['info']['version'] = '1.0'\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n    cocotype['categories'] = [{\n        'supercategory': 'person',\n        'id': 1,\n        'name': 'face',\n        'keypoints': [],\n        'skeleton': []\n    }]\n\n    ann_path = os.path.join(annotation_root, json_file)\n    json.dump(cocotype, open(ann_path, 'w'))\n    print(f'done {ann_path}')\n"
  },
  {
    "path": "tools/dataset_converters/parse_deepposekit_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os\nimport time\n\nimport cv2\nimport h5py\nimport numpy as np\n\nnp.random.seed(0)\n\n\ndef save_coco_anno(keypoints_all,\n                   annotated_all,\n                   imgs_all,\n                   keypoints_info,\n                   skeleton_info,\n                   dataset,\n                   img_root,\n                   save_path,\n                   start_img_id=0,\n                   start_ann_id=0):\n    \"\"\"Save annotations in coco-format.\n\n    :param keypoints_all: keypoint annotations.\n    :param annotated_all: images annotated or not.\n    :param imgs_all: the array of images.\n    :param keypoints_info: information about keypoint name.\n    :param skeleton_info: information about skeleton connection.\n    :param dataset: information about dataset name.\n    :param img_root: the path to save images.\n    :param save_path: the path to save transformed annotation file.\n    :param start_img_id: the starting point to count the image id.\n    :param start_ann_id: the starting point to count the annotation id.\n    \"\"\"\n    images = []\n    annotations = []\n\n    img_id = start_img_id\n    ann_id = start_ann_id\n\n    num_annotations, keypoints_num, _ = keypoints_all.shape\n\n    for i in range(num_annotations):\n        img = imgs_all[i]\n        keypoints = np.concatenate(\n            [keypoints_all[i], annotated_all[i][:, None] * 2], axis=1)\n\n        min_x, min_y = np.min(keypoints[keypoints[:, 2] > 0, :2], axis=0)\n        max_x, max_y = np.max(keypoints[keypoints[:, 2] > 0, :2], axis=0)\n\n        anno = {}\n        anno['keypoints'] = keypoints.reshape(-1).tolist()\n        anno['image_id'] = img_id\n        anno['id'] = ann_id\n        anno['num_keypoints'] = int(sum(keypoints[:, 2] > 0))\n        anno['bbox'] = [\n            float(min_x),\n            float(min_y),\n            float(max_x - min_x + 1),\n            float(max_y - min_y + 1)\n        ]\n        anno['iscrowd'] = 0\n        anno['area'] = anno['bbox'][2] * anno['bbox'][3]\n        anno['category_id'] = 1\n\n        annotations.append(anno)\n        ann_id += 1\n\n        image = {}\n        image['id'] = img_id\n        image['file_name'] = f'{img_id}.jpg'\n        image['height'] = img.shape[0]\n        image['width'] = img.shape[1]\n\n        images.append(image)\n        img_id += 1\n\n        cv2.imwrite(os.path.join(img_root, image['file_name']), img)\n\n    skeleton = np.concatenate(\n        [np.arange(keypoints_num)[:, None], skeleton_info[:, 0][:, None]],\n        axis=1) + 1\n    skeleton = skeleton[skeleton.min(axis=1) > 0]\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info'][\n        'description'] = 'DeepPoseKit-Data Generated by MMPose Team'\n    cocotype['info']['version'] = '1.0'\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n    cocotype['categories'] = [{\n        'supercategory': 'animal',\n        'id': 1,\n        'name': dataset,\n        'keypoints': keypoints_info,\n        'skeleton': skeleton.tolist()\n    }]\n\n    os.makedirs(os.path.dirname(save_path), exist_ok=True)\n    json.dump(cocotype, open(save_path, 'w'), indent=4)\n    print('number of images:', img_id)\n    print('number of annotations:', ann_id)\n    print(f'done {save_path}')\n\n\nfor dataset in ['fly', 'locust', 'zebra']:\n    keypoints_info = []\n    if dataset == 'fly':\n        keypoints_info = [\n            'head', 'eyeL', 'eyeR', 'neck', 'thorax', 'abdomen', 'forelegR1',\n            'forelegR2', 'forelegR3', 'forelegR4', 'midlegR1', 'midlegR2',\n            'midlegR3', 'midlegR4', 'hindlegR1', 'hindlegR2', 'hindlegR3',\n            'hindlegR4', 'forelegL1', 'forelegL2', 'forelegL3', 'forelegL4',\n            'midlegL1', 'midlegL2', 'midlegL3', 'midlegL4', 'hindlegL1',\n            'hindlegL2', 'hindlegL3', 'hindlegL4', 'wingL', 'wingR'\n        ]\n    elif dataset == 'locust':\n        keypoints_info = [\n            'head', 'neck', 'thorax', 'abdomen1', 'abdomen2', 'anttipL',\n            'antbaseL', 'eyeL', 'forelegL1', 'forelegL2', 'forelegL3',\n            'forelegL4', 'midlegL1', 'midlegL2', 'midlegL3', 'midlegL4',\n            'hindlegL1', 'hindlegL2', 'hindlegL3', 'hindlegL4', 'anttipR',\n            'antbaseR', 'eyeR', 'forelegR1', 'forelegR2', 'forelegR3',\n            'forelegR4', 'midlegR1', 'midlegR2', 'midlegR3', 'midlegR4',\n            'hindlegR1', 'hindlegR2', 'hindlegR3', 'hindlegR4'\n        ]\n    elif dataset == 'zebra':\n        keypoints_info = [\n            'snout', 'head', 'neck', 'forelegL1', 'forelegR1', 'hindlegL1',\n            'hindlegR1', 'tailbase', 'tailtip'\n        ]\n    else:\n        NotImplementedError()\n\n    dataset_dir = f'data/DeepPoseKit-Data/datasets/{dataset}'\n\n    with h5py.File(\n            os.path.join(dataset_dir, 'annotation_data_release.h5'), 'r') as f:\n        # List all groups\n        annotations = np.array(f['annotations'])\n        annotated = np.array(f['annotated'])\n        images = np.array(f['images'])\n        skeleton_info = np.array(f['skeleton'])\n\n        annotation_num, kpt_num, _ = annotations.shape\n\n        data_list = np.arange(0, annotation_num)\n        np.random.shuffle(data_list)\n\n        val_data_num = annotation_num // 10\n        train_data_num = annotation_num - val_data_num\n\n        train_list = data_list[0:train_data_num]\n        val_list = data_list[train_data_num:]\n\n        img_root = os.path.join(dataset_dir, 'images')\n        os.makedirs(img_root, exist_ok=True)\n\n        save_coco_anno(\n            annotations[train_list], annotated[train_list], images[train_list],\n            keypoints_info, skeleton_info, dataset, img_root,\n            os.path.join(dataset_dir, 'annotations', f'{dataset}_train.json'))\n        save_coco_anno(\n            annotations[val_list],\n            annotated[val_list],\n            images[val_list],\n            keypoints_info,\n            skeleton_info,\n            dataset,\n            img_root,\n            os.path.join(dataset_dir, 'annotations', f'{dataset}_test.json'),\n            start_img_id=train_data_num,\n            start_ann_id=train_data_num)\n"
  },
  {
    "path": "tools/dataset_converters/parse_macaquepose_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport csv\nimport json\nimport os\nimport time\n\nimport cv2\nimport numpy as np\n\nnp.random.seed(0)\n\n\ndef get_poly_area(x, y):\n    \"\"\"Calculate area of polygon given (x,y) coordinates (Shoelace formula)\n\n    :param x: np.ndarray(N, )\n    :param y: np.ndarray(N, )\n    :return: area\n    \"\"\"\n    return float(0.5 *\n                 np.abs(np.dot(x, np.roll(y, 1)) - np.dot(y, np.roll(x, 1))))\n\n\ndef get_seg_area(segmentations):\n    area = 0\n    for segmentation in segmentations:\n        area += get_poly_area(segmentation[:, 0], segmentation[:, 1])\n    return area\n\n\ndef save_coco_anno(data_annotation,\n                   img_root,\n                   save_path,\n                   start_img_id=0,\n                   start_ann_id=0,\n                   kpt_num=17):\n    \"\"\"Save annotations in coco-format.\n\n    :param data_annotation: list of data annotation.\n    :param img_root: the root dir to load images.\n    :param save_path: the path to save transformed annotation file.\n    :param start_img_id: the starting point to count the image id.\n    :param start_ann_id: the starting point to count the annotation id.\n    :param kpt_num: the number of keypoint.\n    \"\"\"\n    images = []\n    annotations = []\n\n    img_id = start_img_id\n    ann_id = start_ann_id\n\n    for i in range(0, len(data_annotation)):\n        data_anno = data_annotation[i]\n        image_name = data_anno[0]\n\n        img = cv2.imread(os.path.join(img_root, image_name))\n\n        kp_string = data_anno[1]\n        kps = json.loads(kp_string)\n\n        seg_string = data_anno[2]\n        segs = json.loads(seg_string)\n\n        for kp, seg in zip(kps, segs):\n            keypoints = np.zeros([kpt_num, 3])\n            for ind, p in enumerate(kp):\n                if p['position'] is None:\n                    continue\n                else:\n                    keypoints[ind, 0] = p['position'][0]\n                    keypoints[ind, 1] = p['position'][1]\n                    keypoints[ind, 2] = 2\n\n            segmentations = []\n\n            max_x = -1\n            max_y = -1\n            min_x = 999999\n            min_y = 999999\n            for segm in seg:\n                if len(segm['segment']) == 0:\n                    continue\n\n                segmentation = np.array(segm['segment'])\n                segmentations.append(segmentation)\n\n                _max_x, _max_y = segmentation.max(0)\n                _min_x, _min_y = segmentation.min(0)\n\n                max_x = max(max_x, _max_x)\n                max_y = max(max_y, _max_y)\n                min_x = min(min_x, _min_x)\n                min_y = min(min_y, _min_y)\n\n            anno = {}\n            anno['keypoints'] = keypoints.reshape(-1).tolist()\n            anno['image_id'] = img_id\n            anno['id'] = ann_id\n            anno['num_keypoints'] = int(sum(keypoints[:, 2] > 0))\n            anno['bbox'] = [\n                float(min_x),\n                float(min_y),\n                float(max_x - min_x + 1),\n                float(max_y - min_y + 1)\n            ]\n            anno['iscrowd'] = 0\n            anno['area'] = get_seg_area(segmentations)\n            anno['category_id'] = 1\n            anno['segmentation'] = [\n                seg.reshape(-1).tolist() for seg in segmentations\n            ]\n\n            annotations.append(anno)\n            ann_id += 1\n\n        image = {}\n        image['id'] = img_id\n        image['file_name'] = image_name\n        image['height'] = img.shape[0]\n        image['width'] = img.shape[1]\n\n        images.append(image)\n        img_id += 1\n\n    cocotype = {}\n\n    cocotype['info'] = {}\n    cocotype['info']['description'] = 'MacaquePose Generated by MMPose Team'\n    cocotype['info']['version'] = '1.0'\n    cocotype['info']['year'] = time.strftime('%Y', time.localtime())\n    cocotype['info']['date_created'] = time.strftime('%Y/%m/%d',\n                                                     time.localtime())\n\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n    cocotype['categories'] = [{\n        'supercategory':\n        'animal',\n        'id':\n        1,\n        'name':\n        'macaque',\n        'keypoints': [\n            'nose', 'left_eye', 'right_eye', 'left_ear', 'right_ear',\n            'left_shoulder', 'right_shoulder', 'left_elbow', 'right_elbow',\n            'left_wrist', 'right_wrist', 'left_hip', 'right_hip', 'left_knee',\n            'right_knee', 'left_ankle', 'right_ankle'\n        ],\n        'skeleton': [[16, 14], [14, 12], [17, 15], [15, 13], [12, 13], [6, 12],\n                     [7, 13], [6, 7], [6, 8], [7, 9], [8, 10], [9, 11], [2, 3],\n                     [1, 2], [1, 3], [2, 4], [3, 5], [4, 6], [5, 7]]\n    }]\n\n    os.makedirs(os.path.dirname(save_path), exist_ok=True)\n    json.dump(cocotype, open(save_path, 'w'), indent=4)\n    print('number of images:', img_id)\n    print('number of annotations:', ann_id)\n    print(f'done {save_path}')\n\n\ndataset_dir = '/data/macaque/'\nwith open(os.path.join(dataset_dir, 'annotations.csv'), 'r') as fp:\n    data_annotation_all = list(csv.reader(fp, delimiter=','))[1:]\n\nnp.random.shuffle(data_annotation_all)\n\ndata_annotation_train = data_annotation_all[0:12500]\ndata_annotation_val = data_annotation_all[12500:]\n\nimg_root = os.path.join(dataset_dir, 'images')\nsave_coco_anno(\n    data_annotation_train,\n    img_root,\n    os.path.join(dataset_dir, 'annotations', 'macaque_train.json'),\n    kpt_num=17)\nsave_coco_anno(\n    data_annotation_val,\n    img_root,\n    os.path.join(dataset_dir, 'annotations', 'macaque_test.json'),\n    start_img_id=12500,\n    start_ann_id=15672,\n    kpt_num=17)\n"
  },
  {
    "path": "tools/dataset_converters/preprocess_h36m.py",
    "content": "# -----------------------------------------------------------------------------\n# Adapted from https://github.com/anibali/h36m-fetch\n# Original license: Copyright (c) Aiden Nibali, under the Apache License.\n# -----------------------------------------------------------------------------\n\nimport argparse\nimport os\nimport pickle\nimport tarfile\nimport xml.etree.ElementTree as ET\nfrom os.path import join\n\nimport cv2\nimport numpy as np\nfrom spacepy import pycdf\n\n\nclass PreprocessH36m:\n    \"\"\"Preprocess Human3.6M dataset.\n\n    Args:\n        metadata (str): Path to metadata.xml.\n        original_dir (str): Directory of the original dataset with all files\n            compressed. Specifically, .tgz files belonging to subject 1\n            should be placed under the subdirectory 's1'.\n        extracted_dir (str): Directory of the extracted files. If not given, it\n            will be placed under the same parent directory as original_dir.\n        processed_der (str): Directory of the processed files. If not given, it\n            will be placed under the same parent directory as original_dir.\n        sample_rate (int): Downsample FPS to `1 / sample_rate`. Default: 5.\n    \"\"\"\n\n    def __init__(self,\n                 metadata,\n                 original_dir,\n                 extracted_dir=None,\n                 processed_dir=None,\n                 sample_rate=5):\n        self.metadata = metadata\n        self.original_dir = original_dir\n        self.sample_rate = sample_rate\n\n        if extracted_dir is None:\n            self.extracted_dir = join(\n                os.path.dirname(os.path.abspath(self.original_dir)),\n                'extracted')\n        else:\n            self.extracted_dir = extracted_dir\n\n        if processed_dir is None:\n            self.processed_dir = join(\n                os.path.dirname(os.path.abspath(self.original_dir)),\n                'processed')\n        else:\n            self.processed_dir = processed_dir\n\n        self.subjects = []\n        self.sequence_mappings = {}\n        self.action_names = {}\n        self.camera_ids = []\n        self._load_metadata()\n\n        self.subjects_annot = ['S1', 'S5', 'S6', 'S7', 'S8', 'S9', 'S11']\n        self.subjects_splits = {\n            'train': ['S1', 'S5', 'S6', 'S7', 'S8'],\n            'test': ['S9', 'S11']\n        }\n        self.extract_files = ['Videos', 'D2_Positions', 'D3_Positions_mono']\n        self.movable_joints = [\n            0, 1, 2, 3, 6, 7, 8, 12, 13, 14, 15, 17, 18, 19, 25, 26, 27\n        ]\n        self.scale_factor = 1.2\n        self.image_sizes = {\n            '54138969': {\n                'width': 1000,\n                'height': 1002\n            },\n            '55011271': {\n                'width': 1000,\n                'height': 1000\n            },\n            '58860488': {\n                'width': 1000,\n                'height': 1000\n            },\n            '60457274': {\n                'width': 1000,\n                'height': 1002\n            }\n        }\n\n    def extract_tgz(self):\n        \"\"\"Extract files from self.extrct_files.\"\"\"\n        os.makedirs(self.extracted_dir, exist_ok=True)\n        for subject in self.subjects_annot:\n            cur_dir = join(self.original_dir, subject.lower())\n            for file in self.extract_files:\n                filename = join(cur_dir, file + '.tgz')\n                print(f'Extracting {filename} ...')\n                with tarfile.open(filename) as tar:\n                    tar.extractall(self.extracted_dir)\n        print('Extraction done.\\n')\n\n    def generate_cameras_file(self):\n        \"\"\"Generate cameras.pkl which contains camera parameters for 11\n        subjects each with 4 cameras.\"\"\"\n        cameras = {}\n        for subject in range(1, 12):\n            for camera in range(4):\n                key = (f'S{subject}', self.camera_ids[camera])\n                cameras[key] = self._get_camera_params(camera, subject)\n\n        out_file = join(self.processed_dir, 'annotation_body3d', 'cameras.pkl')\n        with open(out_file, 'wb') as fout:\n            pickle.dump(cameras, fout)\n        print(f'Camera parameters have been written to \"{out_file}\".\\n')\n\n    def generate_annotations(self):\n        \"\"\"Generate annotations for training and testing data.\"\"\"\n        output_dir = join(self.processed_dir, 'annotation_body3d',\n                          f'fps{50 // self.sample_rate}')\n        os.makedirs(output_dir, exist_ok=True)\n\n        for data_split in ('train', 'test'):\n            imgnames_all = []\n            centers_all = []\n            scales_all = []\n            kps2d_all = []\n            kps3d_all = []\n            for subject in self.subjects_splits[data_split]:\n                for action, subaction in self.sequence_mappings[subject].keys(\n                ):\n                    if action == '1':\n                        # exclude action \"_ALL\"\n                        continue\n                    for camera in self.camera_ids:\n                        imgnames, centers, scales, kps2d, kps3d\\\n                         = self._load_annotations(\n                            subject, action, subaction, camera)\n                        imgnames_all.append(imgnames)\n                        centers_all.append(centers)\n                        scales_all.append(scales)\n                        kps2d_all.append(kps2d)\n                        kps3d_all.append(kps3d)\n\n            imgnames_all = np.concatenate(imgnames_all)\n            centers_all = np.concatenate(centers_all)\n            scales_all = np.concatenate(scales_all)\n            kps2d_all = np.concatenate(kps2d_all)\n            kps3d_all = np.concatenate(kps3d_all)\n\n            out_file = join(output_dir, f'h36m_{data_split}.npz')\n            np.savez(\n                out_file,\n                imgname=imgnames_all,\n                center=centers_all,\n                scale=scales_all,\n                part=kps2d_all,\n                S=kps3d_all)\n\n            print(\n                f'All annotations of {data_split}ing data have been written to'\n                f' \"{out_file}\". {len(imgnames_all)} samples in total.\\n')\n\n            if data_split == 'train':\n                kps_3d_all = kps3d_all[..., :3]  # remove visibility\n                mean_3d, std_3d = self._get_pose_stats(kps_3d_all)\n\n                kps_2d_all = kps2d_all[..., :2]  # remove visibility\n                mean_2d, std_2d = self._get_pose_stats(kps_2d_all)\n\n                # centered around root\n                # the root keypoint is 0-index\n                kps_3d_rel = kps_3d_all[..., 1:, :] - kps_3d_all[..., :1, :]\n                mean_3d_rel, std_3d_rel = self._get_pose_stats(kps_3d_rel)\n\n                kps_2d_rel = kps_2d_all[..., 1:, :] - kps_2d_all[..., :1, :]\n                mean_2d_rel, std_2d_rel = self._get_pose_stats(kps_2d_rel)\n\n                stats = {\n                    'joint3d_stats': {\n                        'mean': mean_3d,\n                        'std': std_3d\n                    },\n                    'joint2d_stats': {\n                        'mean': mean_2d,\n                        'std': std_2d\n                    },\n                    'joint3d_rel_stats': {\n                        'mean': mean_3d_rel,\n                        'std': std_3d_rel\n                    },\n                    'joint2d_rel_stats': {\n                        'mean': mean_2d_rel,\n                        'std': std_2d_rel\n                    }\n                }\n                for name, stat_dict in stats.items():\n                    out_file = join(output_dir, f'{name}.pkl')\n                    with open(out_file, 'wb') as f:\n                        pickle.dump(stat_dict, f)\n                    print(f'Create statistic data file: {out_file}')\n\n    @staticmethod\n    def _get_pose_stats(kps):\n        \"\"\"Get statistic information `mean` and `std` of pose data.\n\n        Args:\n            kps (ndarray): keypoints in shape [..., K, D] where K and C is\n                the keypoint category number and dimension.\n        Returns:\n            mean (ndarray): [K, D]\n        \"\"\"\n        assert kps.ndim > 2\n        K, D = kps.shape[-2:]\n        kps = kps.reshape(-1, K, D)\n        mean = kps.mean(axis=0)\n        std = kps.std(axis=0)\n        return mean, std\n\n    def _load_metadata(self):\n        \"\"\"Load meta data from metadata.xml.\"\"\"\n\n        assert os.path.exists(self.metadata)\n\n        tree = ET.parse(self.metadata)\n        root = tree.getroot()\n\n        for i, tr in enumerate(root.find('mapping')):\n            if i == 0:\n                _, _, *self.subjects = [td.text for td in tr]\n                self.sequence_mappings \\\n                    = {subject: {} for subject in self.subjects}\n            elif i < 33:\n                action_id, subaction_id, *prefixes = [td.text for td in tr]\n                for subject, prefix in zip(self.subjects, prefixes):\n                    self.sequence_mappings[subject][(action_id, subaction_id)]\\\n                        = prefix\n\n        for i, elem in enumerate(root.find('actionnames')):\n            action_id = str(i + 1)\n            self.action_names[action_id] = elem.text\n\n        self.camera_ids \\\n            = [elem.text for elem in root.find('dbcameras/index2id')]\n\n        w0 = root.find('w0')\n        self.cameras_raw = [float(num) for num in w0.text[1:-1].split()]\n\n    def _get_base_filename(self, subject, action, subaction, camera):\n        \"\"\"Get base filename given subject, action, subaction and camera.\"\"\"\n        return f'{self.sequence_mappings[subject][(action, subaction)]}' + \\\n            f'.{camera}'\n\n    def _get_camera_params(self, camera, subject):\n        \"\"\"Get camera parameters given camera id and subject id.\"\"\"\n        metadata_slice = np.zeros(15)\n        start = 6 * (camera * 11 + (subject - 1))\n\n        metadata_slice[:6] = self.cameras_raw[start:start + 6]\n        metadata_slice[6:] = self.cameras_raw[265 + camera * 9 - 1:265 +\n                                              (camera + 1) * 9 - 1]\n\n        # extrinsics\n        x, y, z = -metadata_slice[0], metadata_slice[1], -metadata_slice[2]\n\n        R_x = np.array([[1, 0, 0], [0, np.cos(x), np.sin(x)],\n                        [0, -np.sin(x), np.cos(x)]])\n        R_y = np.array([[np.cos(y), 0, np.sin(y)], [0, 1, 0],\n                        [-np.sin(y), 0, np.cos(y)]])\n        R_z = np.array([[np.cos(z), np.sin(z), 0], [-np.sin(z),\n                                                    np.cos(z), 0], [0, 0, 1]])\n        R = (R_x @ R_y @ R_z).T\n        T = metadata_slice[3:6].reshape(-1, 1)\n        # convert unit from millimeter to meter\n        T *= 0.001\n\n        # intrinsics\n        c = metadata_slice[8:10, None]\n        f = metadata_slice[6:8, None]\n\n        # distortion\n        k = metadata_slice[10:13, None]\n        p = metadata_slice[13:15, None]\n\n        return {\n            'R': R,\n            'T': T,\n            'c': c,\n            'f': f,\n            'k': k,\n            'p': p,\n            'w': self.image_sizes[self.camera_ids[camera]]['width'],\n            'h': self.image_sizes[self.camera_ids[camera]]['height'],\n            'name': f'camera{camera + 1}',\n            'id': self.camera_ids[camera]\n        }\n\n    def _load_annotations(self, subject, action, subaction, camera):\n        \"\"\"Load annotations for a sequence.\"\"\"\n        subj_dir = join(self.extracted_dir, subject)\n        basename = self._get_base_filename(subject, action, subaction, camera)\n\n        # load 2D keypoints\n        with pycdf.CDF(\n                join(subj_dir, 'MyPoseFeatures', 'D2_Positions',\n                     basename + '.cdf')) as cdf:\n            kps_2d = np.array(cdf['Pose'])\n\n        num_frames = kps_2d.shape[1]\n        kps_2d = kps_2d.reshape((num_frames, 32, 2))[::self.sample_rate,\n                                                     self.movable_joints]\n        kps_2d = np.concatenate([kps_2d, np.ones((len(kps_2d), 17, 1))],\n                                axis=2)\n\n        # load 3D keypoints\n        with pycdf.CDF(\n                join(subj_dir, 'MyPoseFeatures', 'D3_Positions_mono',\n                     basename + '.cdf')) as cdf:\n            kps_3d = np.array(cdf['Pose'])\n\n        kps_3d = kps_3d.reshape(\n            (num_frames, 32, 3))[::self.sample_rate,\n                                 self.movable_joints] / 1000.\n        kps_3d = np.concatenate([kps_3d, np.ones((len(kps_3d), 17, 1))],\n                                axis=2)\n\n        # calculate bounding boxes\n        bboxes = np.stack([\n            np.min(kps_2d[:, :, 0], axis=1),\n            np.min(kps_2d[:, :, 1], axis=1),\n            np.max(kps_2d[:, :, 0], axis=1),\n            np.max(kps_2d[:, :, 1], axis=1)\n        ],\n                          axis=1)\n        centers = np.stack([(bboxes[:, 0] + bboxes[:, 2]) / 2,\n                            (bboxes[:, 1] + bboxes[:, 3]) / 2],\n                           axis=1)\n        scales = self.scale_factor * np.max(\n            bboxes[:, 2:] - bboxes[:, :2], axis=1) / 200\n\n        # extract frames and save imgnames\n        imgnames = []\n        video_path = join(subj_dir, 'Videos', basename + '.mp4')\n        sub_base = subject + '_' + basename.replace(' ', '_')\n        img_dir = join(self.processed_dir, 'images', subject, sub_base)\n        os.makedirs(img_dir, exist_ok=True)\n        prefix = join(subject, sub_base, sub_base)\n\n        cap = cv2.VideoCapture(video_path)\n        i = 0\n        while True:\n            success, img = cap.read()\n            if not success:\n                break\n            if i % self.sample_rate == 0:\n                imgname = f'{prefix}_{i + 1:06d}.jpg'\n                imgnames.append(imgname)\n                dest_path = join(self.processed_dir, 'images', imgname)\n                if not os.path.exists(dest_path):\n                    cv2.imwrite(dest_path, img)\n                if len(imgnames) == len(centers):\n                    break\n            i += 1\n        cap.release()\n        imgnames = np.array(imgnames)\n\n        print(f'Annoatations for sequence \"{subject} {basename}\" are loaded. '\n              f'{len(imgnames)} samples in total.')\n\n        return imgnames, centers, scales, kps_2d, kps_3d\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser()\n    parser.add_argument(\n        '--metadata', type=str, required=True, help='Path to metadata.xml')\n    parser.add_argument(\n        '--original',\n        type=str,\n        required=True,\n        help='Directory of the original dataset with all files compressed. '\n        'Specifically, .tgz files belonging to subject 1 should be placed '\n        'under the subdirectory \\\"s1\\\".')\n    parser.add_argument(\n        '--extracted',\n        type=str,\n        default=None,\n        help='Directory of the extracted files. If not given, it will be '\n        'placed under the same parent directory as original_dir.')\n    parser.add_argument(\n        '--processed',\n        type=str,\n        default=None,\n        help='Directory of the processed files. If not given, it will be '\n        'placed under the same parent directory as original_dir.')\n    parser.add_argument(\n        '--sample-rate',\n        type=int,\n        default=5,\n        help='Downsample FPS to `1 / sample_rate`. Default: 5.')\n    args = parser.parse_args()\n    return args\n\n\nif __name__ == '__main__':\n    args = parse_args()\n\n    h36m = PreprocessH36m(\n        metadata=args.metadata,\n        original_dir=args.original,\n        extracted_dir=args.extracted,\n        processed_dir=args.processed,\n        sample_rate=args.sample_rate)\n    h36m.extract_tgz()\n    h36m.generate_cameras_file()\n    h36m.generate_annotations()\n"
  },
  {
    "path": "tools/dataset_converters/preprocess_mpi_inf_3dhp.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport os\nimport pickle\nimport shutil\nfrom os.path import join\n\nimport cv2\nimport h5py\nimport mmcv\nimport numpy as np\nfrom scipy.io import loadmat\n\ntrain_subjects = [i for i in range(1, 9)]\ntest_subjects = [i for i in range(1, 7)]\ntrain_seqs = [1, 2]\ntrain_cams = [0, 1, 2, 4, 5, 6, 7, 8]\ntrain_frame_nums = {\n    (1, 1): 6416,\n    (1, 2): 12430,\n    (2, 1): 6502,\n    (2, 2): 6081,\n    (3, 1): 12488,\n    (3, 2): 12283,\n    (4, 1): 6171,\n    (4, 2): 6675,\n    (5, 1): 12820,\n    (5, 2): 12312,\n    (6, 1): 6188,\n    (6, 2): 6145,\n    (7, 1): 6239,\n    (7, 2): 6320,\n    (8, 1): 6468,\n    (8, 2): 6054\n}\ntest_frame_nums = {1: 6151, 2: 6080, 3: 5838, 4: 6007, 5: 320, 6: 492}\ntrain_img_size = (2048, 2048)\nroot_index = 14\njoints_17 = [7, 5, 14, 15, 16, 9, 10, 11, 23, 24, 25, 18, 19, 20, 4, 3, 6]\n\n\ndef get_pose_stats(kps):\n    \"\"\"Get statistic information `mean` and `std` of pose data.\n\n    Args:\n        kps (ndarray): keypoints in shape [..., K, D] where K and D is\n            the keypoint category number and dimension.\n    Returns:\n        mean (ndarray): [K, D]\n    \"\"\"\n    assert kps.ndim > 2\n    K, D = kps.shape[-2:]\n    kps = kps.reshape(-1, K, D)\n    mean = kps.mean(axis=0)\n    std = kps.std(axis=0)\n    return mean, std\n\n\ndef get_annotations(joints_2d, joints_3d, scale_factor=1.2):\n    \"\"\"Get annotations, including centers, scales, joints_2d and joints_3d.\n\n    Args:\n        joints_2d: 2D joint coordinates in shape [N, K, 2], where N is the\n            frame number, K is the joint number.\n        joints_3d: 3D joint coordinates in shape [N, K, 3], where N is the\n            frame number, K is the joint number.\n        scale_factor: Scale factor of bounding box. Default: 1.2.\n    Returns:\n        centers (ndarray): [N, 2]\n        scales (ndarray): [N,]\n        joints_2d (ndarray): [N, K, 3]\n        joints_3d (ndarray): [N, K, 4]\n    \"\"\"\n    # calculate joint visibility\n    visibility = (joints_2d[:, :, 0] >= 0) * \\\n                 (joints_2d[:, :, 0] < train_img_size[0]) * \\\n                 (joints_2d[:, :, 1] >= 0) * \\\n                 (joints_2d[:, :, 1] < train_img_size[1])\n    visibility = np.array(visibility, dtype=np.float32)[:, :, None]\n    joints_2d = np.concatenate([joints_2d, visibility], axis=-1)\n    joints_3d = np.concatenate([joints_3d, visibility], axis=-1)\n\n    # calculate bounding boxes\n    bboxes = np.stack([\n        np.min(joints_2d[:, :, 0], axis=1),\n        np.min(joints_2d[:, :, 1], axis=1),\n        np.max(joints_2d[:, :, 0], axis=1),\n        np.max(joints_2d[:, :, 1], axis=1)\n    ],\n                      axis=1)\n    centers = np.stack([(bboxes[:, 0] + bboxes[:, 2]) / 2,\n                        (bboxes[:, 1] + bboxes[:, 3]) / 2],\n                       axis=1)\n    scales = scale_factor * np.max(bboxes[:, 2:] - bboxes[:, :2], axis=1) / 200\n\n    return centers, scales, joints_2d, joints_3d\n\n\ndef load_trainset(data_root, out_dir):\n    \"\"\"Load training data, create annotation file and camera file.\n    Args:\n        data_root: Directory of dataset, which is organized in the following\n            hierarchy:\n                data_root\n                |-- train\n                    |-- S1\n                        |-- Seq1\n                        |-- Seq2\n                    |-- S2\n                    |-- ...\n                |-- test\n                    |-- TS1\n                    |-- TS2\n                    |-- ...\n        out_dir: Directory to save annotation file.\n    \"\"\"\n    _imgnames = []\n    _centers = []\n    _scales = []\n    _joints_2d = []\n    _joints_3d = []\n    cameras = {}\n\n    img_dir = join(out_dir, 'images')\n    os.makedirs(img_dir, exist_ok=True)\n    annot_dir = join(out_dir, 'annotations')\n    os.makedirs(annot_dir, exist_ok=True)\n\n    for subj in train_subjects:\n        for seq in train_seqs:\n            seq_path = join(data_root, 'train', f'S{subj}', f'Seq{seq}')\n            num_frames = train_frame_nums[(subj, seq)]\n\n            # load camera parametres\n            camera_file = join(seq_path, 'camera.calibration')\n            with open(camera_file, 'r') as fin:\n                lines = fin.readlines()\n                for cam in train_cams:\n                    K = [float(s) for s in lines[cam * 7 + 5][11:-2].split()]\n                    f = np.array([[K[0]], [K[5]]])\n                    c = np.array([[K[2]], [K[6]]])\n                    RT = np.array(\n                        [float(s) for s in lines[cam * 7 + 6][11:-2].split()])\n                    RT = np.reshape(RT, (4, 4))\n                    R = RT[:3, :3]\n                    # convert unit from millimeter to meter\n                    T = RT[:3, 3:] * 0.001\n                    size = [int(s) for s in lines[cam * 7 + 3][14:].split()]\n                    w, h = size\n                    cam_param = dict(\n                        R=R, T=T, c=c, f=f, w=w, h=h, name=f'train_cam_{cam}')\n                    cameras[f'S{subj}_Seq{seq}_Cam{cam}'] = cam_param\n\n            # load annotations\n            annot_file = os.path.join(seq_path, 'annot.mat')\n            annot2 = loadmat(annot_file)['annot2']\n            annot3 = loadmat(annot_file)['annot3']\n            for cam in train_cams:\n                # load 2D and 3D annotations\n                joints_2d = np.reshape(annot2[cam][0][:num_frames],\n                                       (num_frames, 28, 2))[:, joints_17]\n                joints_3d = np.reshape(annot3[cam][0][:num_frames],\n                                       (num_frames, 28, 3))[:, joints_17]\n                joints_3d = joints_3d * 0.001\n                centers, scales, joints_2d, joints_3d = get_annotations(\n                    joints_2d, joints_3d)\n                _centers.append(centers)\n                _scales.append(scales)\n                _joints_2d.append(joints_2d)\n                _joints_3d.append(joints_3d)\n\n                # extract frames from video\n                video_path = join(seq_path, 'imageSequence',\n                                  f'video_{cam}.avi')\n                video = mmcv.VideoReader(video_path)\n                for i in mmcv.track_iter_progress(range(num_frames)):\n                    img = video.read()\n                    if img is None:\n                        break\n                    imgname = f'S{subj}_Seq{seq}_Cam{cam}_{i+1:06d}.jpg'\n                    _imgnames.append(imgname)\n                    cv2.imwrite(join(img_dir, imgname), img)\n\n    _imgnames = np.array(_imgnames)\n    _centers = np.concatenate(_centers)\n    _scales = np.concatenate(_scales)\n    _joints_2d = np.concatenate(_joints_2d)\n    _joints_3d = np.concatenate(_joints_3d)\n\n    out_file = join(annot_dir, 'mpi_inf_3dhp_train.npz')\n    np.savez(\n        out_file,\n        imgname=_imgnames,\n        center=_centers,\n        scale=_scales,\n        part=_joints_2d,\n        S=_joints_3d)\n    print(f'Create annotation file for trainset: {out_file}. '\n          f'{len(_imgnames)} samples in total.')\n\n    out_file = join(annot_dir, 'cameras_train.pkl')\n    with open(out_file, 'wb') as fout:\n        pickle.dump(cameras, fout)\n    print(f'Create camera file for trainset: {out_file}.')\n\n    # get `mean` and `std` of pose data\n    _joints_3d = _joints_3d[..., :3]  # remove visibility\n    mean_3d, std_3d = get_pose_stats(_joints_3d)\n\n    _joints_2d = _joints_2d[..., :2]  # remove visibility\n    mean_2d, std_2d = get_pose_stats(_joints_2d)\n\n    # centered around root\n    _joints_3d_rel = _joints_3d - _joints_3d[..., root_index:root_index + 1, :]\n    mean_3d_rel, std_3d_rel = get_pose_stats(_joints_3d_rel)\n    mean_3d_rel[root_index] = mean_3d[root_index]\n    std_3d_rel[root_index] = std_3d[root_index]\n\n    _joints_2d_rel = _joints_2d - _joints_2d[..., root_index:root_index + 1, :]\n    mean_2d_rel, std_2d_rel = get_pose_stats(_joints_2d_rel)\n    mean_2d_rel[root_index] = mean_2d[root_index]\n    std_2d_rel[root_index] = std_2d[root_index]\n\n    stats = {\n        'joint3d_stats': {\n            'mean': mean_3d,\n            'std': std_3d\n        },\n        'joint2d_stats': {\n            'mean': mean_2d,\n            'std': std_2d\n        },\n        'joint3d_rel_stats': {\n            'mean': mean_3d_rel,\n            'std': std_3d_rel\n        },\n        'joint2d_rel_stats': {\n            'mean': mean_2d_rel,\n            'std': std_2d_rel\n        }\n    }\n    for name, stat_dict in stats.items():\n        out_file = join(annot_dir, f'{name}.pkl')\n        with open(out_file, 'wb') as f:\n            pickle.dump(stat_dict, f)\n        print(f'Create statistic data file: {out_file}')\n\n\ndef load_testset(data_root, out_dir, valid_only=True):\n    \"\"\"Load testing data, create annotation file and camera file.\n\n    Args:\n        data_root: Directory of dataset.\n        out_dir: Directory to save annotation file.\n        valid_only: Only keep frames with valid_label == 1.\n    \"\"\"\n    _imgnames = []\n    _centers = []\n    _scales = []\n    _joints_2d = []\n    _joints_3d = []\n    cameras = {}\n\n    img_dir = join(out_dir, 'images')\n    os.makedirs(img_dir, exist_ok=True)\n    annot_dir = join(out_dir, 'annotations')\n    os.makedirs(annot_dir, exist_ok=True)\n\n    for subj in test_subjects:\n        subj_path = join(data_root, 'test', f'TS{subj}')\n        num_frames = test_frame_nums[subj]\n\n        # load annotations\n        annot_file = os.path.join(subj_path, 'annot_data.mat')\n        with h5py.File(annot_file, 'r') as fin:\n            annot2 = np.array(fin['annot2']).reshape((-1, 17, 2))\n            annot3 = np.array(fin['annot3']).reshape((-1, 17, 3))\n            valid = np.array(fin['valid_frame']).reshape(-1)\n\n        # manually estimate camera intrinsics\n        fx, cx = np.linalg.lstsq(\n            annot3[:, :, [0, 2]].reshape((-1, 2)),\n            (annot2[:, :, 0] * annot3[:, :, 2]).reshape(-1, 1),\n            rcond=None)[0].flatten()\n        fy, cy = np.linalg.lstsq(\n            annot3[:, :, [1, 2]].reshape((-1, 2)),\n            (annot2[:, :, 1] * annot3[:, :, 2]).reshape(-1, 1),\n            rcond=None)[0].flatten()\n        if subj <= 4:\n            w, h = 2048, 2048\n        else:\n            w, h = 1920, 1080\n        cameras[f'TS{subj}'] = dict(\n            c=np.array([[cx], [cy]]),\n            f=np.array([[fx], [fy]]),\n            w=w,\n            h=h,\n            name=f'test_cam_{subj}')\n\n        # get annotations\n        if valid_only:\n            valid_frames = np.nonzero(valid)[0]\n        else:\n            valid_frames = np.arange(num_frames)\n        joints_2d = annot2[valid_frames, :, :]\n        joints_3d = annot3[valid_frames, :, :] * 0.001\n\n        centers, scales, joints_2d, joints_3d = get_annotations(\n            joints_2d, joints_3d)\n        _centers.append(centers)\n        _scales.append(scales)\n        _joints_2d.append(joints_2d)\n        _joints_3d.append(joints_3d)\n\n        # copy and rename images\n        for i in valid_frames:\n            imgname = f'TS{subj}_{i+1:06d}.jpg'\n            shutil.copyfile(\n                join(subj_path, 'imageSequence', f'img_{i+1:06d}.jpg'),\n                join(img_dir, imgname))\n            _imgnames.append(imgname)\n\n    _imgnames = np.array(_imgnames)\n    _centers = np.concatenate(_centers)\n    _scales = np.concatenate(_scales)\n    _joints_2d = np.concatenate(_joints_2d)\n    _joints_3d = np.concatenate(_joints_3d)\n\n    if valid_only:\n        out_file = join(annot_dir, 'mpi_inf_3dhp_test_valid.npz')\n    else:\n        out_file = join(annot_dir, 'mpi_inf_3dhp_test_all.npz')\n    np.savez(\n        out_file,\n        imgname=_imgnames,\n        center=_centers,\n        scale=_scales,\n        part=_joints_2d,\n        S=_joints_3d)\n    print(f'Create annotation file for testset: {out_file}. '\n          f'{len(_imgnames)} samples in total.')\n\n    out_file = join(annot_dir, 'cameras_test.pkl')\n    with open(out_file, 'wb') as fout:\n        pickle.dump(cameras, fout)\n    print(f'Create camera file for testset: {out_file}.')\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('data_root', type=str, help='data root')\n    parser.add_argument(\n        'out_dir', type=str, help='directory to save annotation files.')\n    args = parser.parse_args()\n    data_root = args.data_root\n    out_dir = args.out_dir\n\n    load_trainset(data_root, out_dir)\n    load_testset(data_root, out_dir, valid_only=True)\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_300w.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___300w/raw/300w.tar.gz.00 -C $DOWNLOAD_DIR/\ntar -xvf $DOWNLOAD_DIR/300w/300w.tar.00 -C $DATA_ROOT/\nrm -rf $DOWNLOAD_DIR/300w $DOWNLOAD_DIR/OpenDataLab___300w\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_aic.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___AI_Challenger/raw/AI_Challenger.tar.gz -C $DATA_ROOT\nrm -rf $DOWNLOAD_DIR/OpenDataLab___AI_Challenger\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_ap10k.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___AP-10K/raw/AP-10K.tar.gz.00 -C $DOWNLOAD_DIR/\ntar -xvf $DOWNLOAD_DIR/AP-10K/AP-10K.tar.00 -C $DATA_ROOT/\nrm -rf $DOWNLOAD_DIR/AP-10K $DOWNLOAD_DIR/OpenDataLab___AP-10K\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_coco2017.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\nunzip $DOWNLOAD_DIR/OpenDataLab___COCO_2017/raw/Images/val2017.zip -d $DATA_ROOT\nunzip $DOWNLOAD_DIR/OpenDataLab___COCO_2017/raw/Images/train2017.zip -d $DATA_ROOT\nunzip $DOWNLOAD_DIR/OpenDataLab___COCO_2017/raw/Annotations/annotations_trainval2017.zip -d $DATA_ROOT\nrm -rf $DOWNLOAD_DIR/OpenDataLab___COCO_2017\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_crowdpose.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___CrowdPose/raw/CrowdPose.tar.gz -C $DATA_ROOT\nrm -rf $DOWNLOAD_DIR/OpenDataLab___CrowdPose\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_freihand.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___FreiHAND/raw/FreiHAND.tar.gz -C $DATA_ROOT\nrm -rf $DOWNLOAD_DIR/OpenDataLab___FreiHAND\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_hagrid.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ncat $DOWNLOAD_DIR/OpenDataLab___HaGRID/raw/*.tar.gz.*  | tar -xvz -C $DATA_ROOT/..\ntar -xvf $DATA_ROOT/HaGRID.tar -C $DATA_ROOT/..\nrm -rf $DOWNLOAD_DIR/OpenDataLab___HaGRID\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_halpe.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___Halpe/raw/Halpe.tar.gz.00 -C $DOWNLOAD_DIR/\ntar -xvf $DOWNLOAD_DIR/Halpe/Halpe.tar.00 -C $DATA_ROOT/\nrm -rf $DOWNLOAD_DIR/Halpe $DOWNLOAD_DIR/OpenDataLab___Halpe\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_lapa.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___LaPa/raw/LaPa.tar.gz -C $DATA_ROOT\nrm -rf $DOWNLOAD_DIR/OpenDataLab___LaPa\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_mpii.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___MPII_Human_Pose/raw/MPII_Human_Pose.tar.gz -C $DATA_ROOT\nrm -rf $DOWNLOAD_DIR/OpenDataLab___MPII_Human_Pose\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_onehand10k.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___OneHand10K/raw/OneHand10K.tar.gz.00 -C $DOWNLOAD_DIR/\ntar -xvf $DOWNLOAD_DIR/OneHand10K/OneHand10K.tar.00 -C $DATA_ROOT/\nrm -rf $DOWNLOAD_DIR/OneHand10K $DOWNLOAD_DIR/OpenDataLab___OneHand10K\n"
  },
  {
    "path": "tools/dataset_converters/scripts/preprocess_wflw.sh",
    "content": "#!/usr/bin/env bash\n\nDOWNLOAD_DIR=$1\nDATA_ROOT=$2\n\ntar -zxvf $DOWNLOAD_DIR/OpenDataLab___WFLW/raw/WFLW.tar.gz.00 -C $DOWNLOAD_DIR/\ntar -xvf $DOWNLOAD_DIR/WFLW/WFLW.tar.00 -C $DATA_ROOT/\nrm -rf $DOWNLOAD_DIR/WFLW $DOWNLOAD_DIR/OpenDataLab___WFLW\n"
  },
  {
    "path": "tools/dataset_converters/ubody_kpts_to_coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport os\nfrom copy import deepcopy\nfrom multiprocessing import Pool\n\nimport mmengine\nimport numpy as np\nfrom pycocotools.coco import COCO\n\n\ndef findAllFile(base):\n    file_path = []\n    for root, ds, fs in os.walk(base):\n        for f in fs:\n            fullname = os.path.join(root, f)\n            file_path.append(fullname)\n    return file_path\n\n\ndef convert(video_path: str):\n    video_name = video_path.split('/')[-1]\n    image_path = video_path.replace(video_name, video_name.split('.')[0])\n    image_path = image_path.replace('/videos/', '/images/')\n    os.makedirs(image_path, exist_ok=True)\n    print(\n        f'ffmpeg -i {video_path} -f image2 -r 30 -b:v 5626k {image_path}/%06d.png'  # noqa\n    )\n    os.system(\n        f'ffmpeg -i {video_path} -f image2 -r 30 -b:v 5626k {image_path}/%06d.png'  # noqa\n    )\n\n\ndef split_dataset(annotation_path: str, split_path: str):\n    folders = os.listdir(annotation_path)\n    splits = np.load(split_path)\n    train_annos = []\n    val_annos = []\n    train_imgs = []\n    val_imgs = []\n    t_id = 0\n    v_id = 0\n    categories = [{'supercategory': 'person', 'id': 1, 'name': 'person'}]\n\n    for scene in folders:\n        scene_train_anns = []\n        scene_val_anns = []\n        scene_train_imgs = []\n        scene_val_imgs = []\n        data = COCO(\n            os.path.join(annotation_path, scene, 'keypoint_annotation.json'))\n        print(f'Processing {scene}.........')\n        progress_bar = mmengine.ProgressBar(len(data.anns.keys()))\n        for aid in data.anns.keys():\n            ann = data.anns[aid]\n            img = data.loadImgs(ann['image_id'])[0]\n\n            if img['file_name'].startswith('/'):\n                file_name = img['file_name'][1:]  # [1:] means delete '/'\n            else:\n                file_name = img['file_name']\n            video_name = file_name.split('/')[-2]\n            if 'Trim' in video_name:\n                video_name = video_name.split('_Trim')[0]\n\n            img_path = os.path.join(\n                annotation_path.replace('annotations', 'images'), scene,\n                file_name)\n            if not os.path.exists(img_path):\n                progress_bar.update()\n                continue\n\n            img['file_name'] = os.path.join(scene, file_name)\n            ann_ = deepcopy(ann)\n            img_ = deepcopy(img)\n            if video_name in splits:\n                scene_val_anns.append(ann)\n                scene_val_imgs.append(img)\n                ann_['id'] = v_id\n                ann_['image_id'] = v_id\n                img_['id'] = v_id\n                val_annos.append(ann_)\n                val_imgs.append(img_)\n                v_id += 1\n            else:\n                scene_train_anns.append(ann)\n                scene_train_imgs.append(img)\n                ann_['id'] = t_id\n                ann_['image_id'] = t_id\n                img_['id'] = t_id\n                train_annos.append(ann_)\n                train_imgs.append(img_)\n                t_id += 1\n\n            progress_bar.update()\n\n        scene_train_data = dict(\n            images=scene_train_imgs,\n            annotations=scene_train_anns,\n            categories=categories)\n        scene_val_data = dict(\n            images=scene_val_imgs,\n            annotations=scene_val_anns,\n            categories=categories)\n\n        mmengine.dump(\n            scene_train_data,\n            os.path.join(annotation_path, scene, 'train_annotations.json'))\n        mmengine.dump(\n            scene_val_data,\n            os.path.join(annotation_path, scene, 'val_annotations.json'))\n\n    train_data = dict(\n        images=train_imgs, annotations=train_annos, categories=categories)\n    val_data = dict(\n        images=val_imgs, annotations=val_annos, categories=categories)\n\n    mmengine.dump(train_data,\n                  os.path.join(annotation_path, 'train_annotations.json'))\n    mmengine.dump(val_data,\n                  os.path.join(annotation_path, 'val_annotations.json'))\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--data-root', type=str, default='data/UBody')\n    args = parser.parse_args()\n    video_root = f'{args.data_root}/videos'\n    split_path = f'{args.data_root}/splits/intra_scene_test_list.npy'\n    annotation_path = f'{args.data_root}/annotations'\n\n    video_paths = findAllFile(video_root)\n    pool = Pool(processes=1)\n    pool.map(convert, video_paths)\n    pool.close()\n    pool.join()\n\n    split_dataset(annotation_path, split_path)\n"
  },
  {
    "path": "tools/dataset_converters/ubody_smplx_to_coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport json\nimport os\nimport os.path as osp\nfrom functools import partial\nfrom typing import Dict, List\n\nimport mmengine\nimport numpy as np\nimport smplx\nimport torch\nfrom pycocotools.coco import COCO\n\n\nclass SMPLX(object):\n\n    def __init__(self, human_model_path):\n        self.human_model_path = human_model_path\n        self.layer_args = {\n            'create_global_orient': False,\n            'create_body_pose': False,\n            'create_left_hand_pose': False,\n            'create_right_hand_pose': False,\n            'create_jaw_pose': False,\n            'create_leye_pose': False,\n            'create_reye_pose': False,\n            'create_betas': False,\n            'create_expression': False,\n            'create_transl': False,\n        }\n\n        self.neutral_model = smplx.create(\n            self.human_model_path,\n            'smplx',\n            gender='NEUTRAL',\n            use_pca=False,\n            use_face_contour=True,\n            **self.layer_args)\n        if torch.cuda.is_available():\n            self.neutral_model = self.neutral_model.to('cuda:0')\n\n        self.vertex_num = 10475\n        self.face = self.neutral_model.faces\n        self.shape_param_dim = 10\n        self.expr_code_dim = 10\n        # 22 (body joints) + 30 (hand joints) + 1 (face jaw joint)\n        self.orig_joint_num = 53\n\n        # yapf: disable\n        self.orig_joints_name = (\n            # 22 body joints\n            'Pelvis', 'L_Hip', 'R_Hip', 'Spine_1', 'L_Knee', 'R_Knee',\n            'Spine2', 'L_Ankle', 'R_Ankle', 'Spine_3', 'L_Foot', 'R_Foot',\n            'Neck', 'L_Collar', 'R_Collar', 'Head', 'L_Shoulder',\n            'R_Shoulder', 'L_Elbow', 'R_Elbow', 'L_Wrist', 'R_Wrist',\n            # left hand joints\n            'L_Index_1', 'L_Index_2', 'L_Index_3', 'L_Middle_1', 'L_Middle_2',\n            'L_Middle_3', 'L_Pinky_1', 'L_Pinky_2', 'L_Pinky_3', 'L_Ring_1',\n            'L_Ring_2', 'L_Ring_3', 'L_Thumb_1', 'L_Thumb_2', 'L_Thumb_3',\n            # right hand joints\n            'R_Index_1', 'R_Index_2', 'R_Index_3', 'R_Middle_1', 'R_Middle_2',\n            'R_Middle_3', 'R_Pinky_1', 'R_Pinky_2', 'R_Pinky_3', 'R_Ring_1',\n            'R_Ring_2', 'R_Ring_3', 'R_Thumb_1', 'R_Thumb_2', 'R_Thumb_3',\n            # 1 face jaw joint\n            'Jaw',\n        )\n        self.orig_flip_pairs = (\n            # body joints\n            (1, 2), (4, 5), (7, 8), (10, 11), (13, 14), (16, 17), (18, 19),\n            (20, 21),\n            # hand joints\n            (22, 37), (23, 38), (24, 39), (25, 40), (26, 41), (27, 42),\n            (28, 43), (29, 44), (30, 45), (31, 46), (32, 47), (33, 48),\n            (34, 49), (35, 50), (36, 51),\n        )\n        # yapf: enable\n        self.orig_root_joint_idx = self.orig_joints_name.index('Pelvis')\n        self.orig_joint_part = {\n            'body':\n            range(\n                self.orig_joints_name.index('Pelvis'),\n                self.orig_joints_name.index('R_Wrist') + 1),\n            'lhand':\n            range(\n                self.orig_joints_name.index('L_Index_1'),\n                self.orig_joints_name.index('L_Thumb_3') + 1),\n            'rhand':\n            range(\n                self.orig_joints_name.index('R_Index_1'),\n                self.orig_joints_name.index('R_Thumb_3') + 1),\n            'face':\n            range(\n                self.orig_joints_name.index('Jaw'),\n                self.orig_joints_name.index('Jaw') + 1)\n        }\n\n        # changed SMPLX joint set for the supervision\n        self.joint_num = (\n            137  # 25 (body joints) + 40 (hand joints) + 72 (face keypoints)\n        )\n        # yapf: disable\n        self.joints_name = (\n            # 25 body joints\n            'Pelvis', 'L_Hip', 'R_Hip', 'L_Knee', 'R_Knee', 'L_Ankle',\n            'R_Ankle', 'Neck', 'L_Shoulder', 'R_Shoulder', 'L_Elbow',\n            'R_Elbow', 'L_Wrist', 'R_Wrist', 'L_Big_toe', 'L_Small_toe',\n            'L_Heel', 'R_Big_toe', 'R_Small_toe', 'R_Heel', 'L_Ear', 'R_Ear',\n            'L_Eye', 'R_Eye', 'Nose',\n            # left hand joints\n            'L_Thumb_1', 'L_Thumb_2', 'L_Thumb_3', 'L_Thumb4', 'L_Index_1',\n            'L_Index_2', 'L_Index_3', 'L_Index_4', 'L_Middle_1', 'L_Middle_2',\n            'L_Middle_3', 'L_Middle_4', 'L_Ring_1', 'L_Ring_2', 'L_Ring_3',\n            'L_Ring_4', 'L_Pinky_1', 'L_Pinky_2', 'L_Pinky_3', 'L_Pinky_4',\n            # right hand joints\n            'R_Thumb_1', 'R_Thumb_2', 'R_Thumb_3', 'R_Thumb_4', 'R_Index_1',\n            'R_Index_2', 'R_Index_3', 'R_Index_4', 'R_Middle_1', 'R_Middle_2',\n            'R_Middle_3', 'R_Middle_4', 'R_Ring_1', 'R_Ring_2', 'R_Ring_3',\n            'R_Ring_4', 'R_Pinky_1', 'R_Pinky_2', 'R_Pinky_3', 'R_Pinky_4',\n            # 72 face keypoints\n            *[\n                f'Face_{i}' for i in range(1, 73)\n            ],\n        )\n\n        self.root_joint_idx = self.joints_name.index('Pelvis')\n        self.lwrist_idx = self.joints_name.index('L_Wrist')\n        self.rwrist_idx = self.joints_name.index('R_Wrist')\n        self.neck_idx = self.joints_name.index('Neck')\n        self.flip_pairs = (\n            # body joints\n            (1, 2), (3, 4), (5, 6), (8, 9), (10, 11), (12, 13), (14, 17),\n            (15, 18), (16, 19), (20, 21), (22, 23),\n            # hand joints\n            (25, 45), (26, 46), (27, 47), (28, 48), (29, 49), (30, 50),\n            (31, 51), (32, 52), (33, 53), (34, 54), (35, 55), (36, 56),\n            (37, 57), (38, 58), (39, 59), (40, 60), (41, 61), (42, 62),\n            (43, 63), (44, 64),\n            # face eyebrow\n            (67, 68), (69, 78), (70, 77), (71, 76), (72, 75), (73, 74),\n            # face below nose\n            (83, 87), (84, 86),\n            # face eyes\n            (88, 97), (89, 96), (90, 95), (91, 94), (92, 99), (93, 98),\n            # face mouse\n            (100, 106), (101, 105), (102, 104), (107, 111), (108, 110),\n            # face lip\n            (112, 116), (113, 115), (117, 119),\n            # face contours\n            (120, 136), (121, 135), (122, 134), (123, 133), (124, 132),\n            (125, 131), (126, 130), (127, 129)\n        )\n        self.joint_idx = (\n            0, 1, 2, 4, 5, 7, 8, 12, 16, 17, 18, 19, 20, 21, 60, 61, 62, 63,\n            64, 65, 59, 58, 57, 56, 55,  # body joints\n            37, 38, 39, 66, 25, 26, 27, 67, 28, 29, 30, 68, 34, 35, 36, 69, 31,\n            32, 33, 70,  # left hand joints\n            52, 53, 54, 71, 40, 41, 42, 72, 43, 44, 45, 73, 49, 50, 51, 74, 46,\n            47, 48, 75,  # right hand joints\n            22, 15,  # jaw, head\n            57, 56,  # eyeballs\n            76, 77, 78, 79, 80, 81, 82, 83, 84, 85,  # eyebrow\n            86, 87, 88, 89,  # nose\n            90, 91, 92, 93, 94,  # below nose\n            95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106,  # eyes\n            107,  # right mouth\n            108, 109, 110, 111, 112,  # upper mouth\n            113,  # left mouth\n            114, 115, 116, 117, 118,  # lower mouth\n            119,  # right lip\n            120, 121, 122,  # upper lip\n            123,  # left lip\n            124, 125, 126,  # lower lip\n            127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139,\n            140, 141, 142, 143,  # face contour\n        )\n        # yapf: enable\n\n        self.joint_part = {\n            'body':\n            range(\n                self.joints_name.index('Pelvis'),\n                self.joints_name.index('Nose') + 1),\n            'lhand':\n            range(\n                self.joints_name.index('L_Thumb_1'),\n                self.joints_name.index('L_Pinky_4') + 1),\n            'rhand':\n            range(\n                self.joints_name.index('R_Thumb_1'),\n                self.joints_name.index('R_Pinky_4') + 1),\n            'hand':\n            range(\n                self.joints_name.index('L_Thumb_1'),\n                self.joints_name.index('R_Pinky_4') + 1),\n            'face':\n            range(\n                self.joints_name.index('Face_1'),\n                self.joints_name.index('Face_72') + 1)\n        }\n\n\ndef read_annotation_file(annotation_file: str) -> List[Dict]:\n    with open(annotation_file, 'r') as f:\n        annotations = json.load(f)\n    return annotations\n\n\ndef cam2pixel(cam_coord, f, c):\n    x = cam_coord[:, 0] / cam_coord[:, 2] * f[0] + c[0]\n    y = cam_coord[:, 1] / cam_coord[:, 2] * f[1] + c[1]\n    z = cam_coord[:, 2]\n    return np.stack((x, y, z), 1)\n\n\ndef process_scene_anno(scene: str, annotation_root: str, splits: np.array,\n                       human_model_path: str):\n    annos = read_annotation_file(\n        osp.join(annotation_root, scene, 'smplx_annotation.json'))\n    keypoint_annos = COCO(\n        osp.join(annotation_root, scene, 'keypoint_annotation.json'))\n    human_model = SMPLX(human_model_path)\n\n    train_annos = []\n    val_annos = []\n    train_imgs = []\n    val_imgs = []\n\n    progress_bar = mmengine.ProgressBar(len(keypoint_annos.anns.keys()))\n    for aid in keypoint_annos.anns.keys():\n        ann = keypoint_annos.anns[aid]\n        img = keypoint_annos.loadImgs(ann['image_id'])[0]\n        if img['file_name'].startswith('/'):\n            file_name = img['file_name'][1:]\n        else:\n            file_name = img['file_name']\n\n        video_name = file_name.split('/')[-2]\n        if 'Trim' in video_name:\n            video_name = video_name.split('_Trim')[0]\n\n        img_path = os.path.join(\n            annotation_root.replace('annotations', 'images'), scene, file_name)\n        if not os.path.exists(img_path):\n            progress_bar.update()\n            continue\n        if str(aid) not in annos:\n            progress_bar.update()\n            continue\n\n        smplx_param = annos[str(aid)]\n        human_model_param = smplx_param['smplx_param']\n        cam_param = smplx_param['cam_param']\n        if 'lhand_valid' not in human_model_param:\n            human_model_param['lhand_valid'] = ann['lefthand_valid']\n            human_model_param['rhand_valid'] = ann['righthand_valid']\n            human_model_param['face_valid'] = ann['face_valid']\n\n        rotation_valid = np.ones((human_model.orig_joint_num),\n                                 dtype=np.float32)\n        coord_valid = np.ones((human_model.joint_num), dtype=np.float32)\n\n        root_pose = human_model_param['root_pose']\n        body_pose = human_model_param['body_pose']\n        shape = human_model_param['shape']\n        trans = human_model_param['trans']\n\n        if 'lhand_pose' in human_model_param and human_model_param.get(\n                'lhand_valid', False):\n            lhand_pose = human_model_param['lhand_pose']\n        else:\n            lhand_pose = np.zeros(\n                (3 * len(human_model.orig_joint_part['lhand'])),\n                dtype=np.float32)\n            rotation_valid[human_model.orig_joint_part['lhand']] = 0\n            coord_valid[human_model.orig_joint_part['lhand']] = 0\n\n        if 'rhand_pose' in human_model_param and human_model_param.get(\n                'rhand_valid', False):\n            rhand_pose = human_model_param['rhand_pose']\n        else:\n            rhand_pose = np.zeros(\n                (3 * len(human_model.orig_joint_part['rhand'])),\n                dtype=np.float32)\n            rotation_valid[human_model.orig_joint_part['rhand']] = 0\n            coord_valid[human_model.orig_joint_part['rhand']] = 0\n\n        if 'jaw_pose' in human_model_param and \\\n            'expr' in human_model_param and \\\n                human_model_param.get('face_valid', False):\n            jaw_pose = human_model_param['jaw_pose']\n            expr = human_model_param['expr']\n        else:\n            jaw_pose = np.zeros((3), dtype=np.float32)\n            expr = np.zeros((human_model.expr_code_dim), dtype=np.float32)\n            rotation_valid[human_model.orig_joint_part['face']] = 0\n            coord_valid[human_model.orig_joint_part['face']] = 0\n\n        # init human model inputs\n        device = torch.device(\n            'cuda:0') if torch.cuda.is_available() else torch.device('cpu')\n        root_pose = torch.FloatTensor(root_pose).to(device).view(1, 3)\n        body_pose = torch.FloatTensor(body_pose).to(device).view(-1, 3)\n        lhand_pose = torch.FloatTensor(lhand_pose).to(device).view(-1, 3)\n        rhand_pose = torch.FloatTensor(rhand_pose).to(device).view(-1, 3)\n        jaw_pose = torch.FloatTensor(jaw_pose).to(device).view(-1, 3)\n        shape = torch.FloatTensor(shape).to(device).view(1, -1)\n        expr = torch.FloatTensor(expr).to(device).view(1, -1)\n        trans = torch.FloatTensor(trans).to(device).view(1, -1)\n        zero_pose = torch.zeros((1, 3), dtype=torch.float32, device=device)\n\n        with torch.no_grad():\n            output = human_model.neutral_model(\n                betas=shape,\n                body_pose=body_pose.view(1, -1),\n                global_orient=root_pose,\n                transl=trans,\n                left_hand_pose=lhand_pose.view(1, -1),\n                right_hand_pose=rhand_pose.view(1, -1),\n                jaw_pose=jaw_pose.view(1, -1),\n                leye_pose=zero_pose,\n                reye_pose=zero_pose,\n                expression=expr)\n\n        joint_cam = output.joints[0].cpu().numpy()[human_model.joint_idx, :]\n        joint_img = cam2pixel(joint_cam, cam_param['focal'],\n                              cam_param['princpt'])\n\n        joint_cam = (joint_cam - joint_cam[human_model.root_joint_idx, None, :]\n                     )  # root-relative\n        joint_cam[human_model.joint_part['lhand'], :] = (\n            joint_cam[human_model.joint_part['lhand'], :] -\n            joint_cam[human_model.lwrist_idx, None, :]\n        )  # left hand root-relative\n        joint_cam[human_model.joint_part['rhand'], :] = (\n            joint_cam[human_model.joint_part['rhand'], :] -\n            joint_cam[human_model.rwrist_idx, None, :]\n        )  # right hand root-relative\n        joint_cam[human_model.joint_part['face'], :] = (\n            joint_cam[human_model.joint_part['face'], :] -\n            joint_cam[human_model.neck_idx, None, :])  # face root-relative\n\n        body_3d_size = 2\n        output_hm_shape = (16, 16, 12)\n        joint_img[human_model.joint_part['body'],\n                  2] = ((joint_cam[human_model.joint_part['body'], 2].copy() /\n                         (body_3d_size / 2) + 1) / 2.0 * output_hm_shape[0])\n        joint_img[human_model.joint_part['lhand'],\n                  2] = ((joint_cam[human_model.joint_part['lhand'], 2].copy() /\n                         (body_3d_size / 2) + 1) / 2.0 * output_hm_shape[0])\n        joint_img[human_model.joint_part['rhand'],\n                  2] = ((joint_cam[human_model.joint_part['rhand'], 2].copy() /\n                         (body_3d_size / 2) + 1) / 2.0 * output_hm_shape[0])\n        joint_img[human_model.joint_part['face'],\n                  2] = ((joint_cam[human_model.joint_part['face'], 2].copy() /\n                         (body_3d_size / 2) + 1) / 2.0 * output_hm_shape[0])\n\n        keypoints_2d = joint_img[:, :2].copy()\n        keypoints_3d = joint_img.copy()\n        keypoints_valid = coord_valid.reshape((-1, 1))\n\n        ann['keypoints'] = keypoints_2d.tolist()\n        ann['keypoints_3d'] = keypoints_3d.tolist()\n        ann['keypoints_valid'] = keypoints_valid.tolist()\n        ann['camera_param'] = cam_param\n        img['file_name'] = os.path.join(scene, file_name)\n        if video_name in splits:\n            val_annos.append(ann)\n            val_imgs.append(img)\n        else:\n            train_annos.append(ann)\n            train_imgs.append(img)\n        progress_bar.update()\n\n    categories = [{\n        'supercategory': 'person',\n        'id': 1,\n        'name': 'person',\n        'keypoints': human_model.joints_name,\n        'skeleton': human_model.flip_pairs\n    }]\n    train_data = {\n        'images': train_imgs,\n        'annotations': train_annos,\n        'categories': categories\n    }\n    val_data = {\n        'images': val_imgs,\n        'annotations': val_annos,\n        'categories': categories\n    }\n\n    mmengine.dump(\n        train_data,\n        osp.join(annotation_root, scene, 'train_3dkeypoint_annotation.json'))\n    mmengine.dump(\n        val_data,\n        osp.join(annotation_root, scene, 'val_3dkeypoint_annotation.json'))\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser()\n    parser.add_argument('--data-root', type=str, default='data/UBody')\n    parser.add_argument('--human-model-path', type=str, default='data/SMPLX')\n    parser.add_argument(\n        '--nproc', default=8, type=int, help='number of process')\n    args = parser.parse_args()\n\n    split_path = f'{args.data_root}/splits/intra_scene_test_list.npy'\n    annotation_path = f'{args.data_root}/annotations'\n\n    folders = os.listdir(annotation_path)\n    folders = [f for f in folders if osp.isdir(osp.join(annotation_path, f))]\n    human_model_path = args.human_model_path\n    splits = np.load(split_path)\n\n    if args.nproc > 1:\n        mmengine.track_parallel_progress(\n            partial(\n                process_scene_anno,\n                annotation_root=annotation_path,\n                splits=splits,\n                human_model_path=human_model_path), folders, args.nproc)\n    else:\n        mmengine.track_progress(\n            partial(\n                process_scene_anno,\n                annotation_root=annotation_path,\n                splits=splits,\n                human_model_path=human_model_path), folders)\n"
  },
  {
    "path": "tools/dataset_converters/wflw2coco.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport math\nimport os\nimport os.path as osp\n\nimport cv2\nimport numpy as np\n\n\ndef default_dump(obj):\n    \"\"\"Convert numpy classes to JSON serializable objects.\"\"\"\n    if isinstance(obj, (np.integer, np.floating, np.bool_)):\n        return obj.item()\n    elif isinstance(obj, np.ndarray):\n        return obj.tolist()\n    else:\n        return obj\n\n\ndef convert_wflw_to_coco(ann_file, out_file):\n    annotations = []\n    images = []\n    files = []\n    cnt = 0\n    image_cnt = 0\n\n    data_infos = open(ann_file).readlines()\n    data_infos = [x.strip().split() for x in data_infos]\n    for data in data_infos:\n        file_name = data[-1]\n        img_path = osp.join('data/wflw/WFLW_images', file_name)\n        img = cv2.imread(img_path)\n\n        keypoints = []\n\n        coordinates = [data[i:i + 2] for i in range(0, 196, 2)]\n\n        for coordinate in coordinates:\n            x, y = coordinate[0], coordinate[1]\n            x, y = float(x), float(y)\n            keypoints.append([x, y, 1])\n        keypoints = np.array(keypoints)\n\n        x1, y1, _ = np.amin(keypoints, axis=0)\n        x2, y2, _ = np.amax(keypoints, axis=0)\n        w, h = x2 - x1, y2 - y1\n        scale = math.ceil(max(w, h)) / 200\n        w_new = w / scale\n        h_new = h / scale\n        center = [(x1 + x2) / 2, (y1 + y2) / 2]\n        x1_new = center[0] - w_new / 2\n        y1_new = center[1] - h_new / 2\n        bbox = [x1_new, y1_new, w_new, h_new]\n\n        image = {}\n        # check if the image already exists\n        if file_name in files:\n            image = images[files.index(file_name)]\n        else:\n            image['id'] = image_cnt\n            image['file_name'] = f'{file_name}'\n            image['height'] = img.shape[0]\n            image['width'] = img.shape[1]\n            image_cnt = image_cnt + 1\n            files.append(file_name)\n            images.append(image)\n\n        ann = {}\n        ann['keypoints'] = keypoints.reshape(-1).tolist()\n        ann['image_id'] = image['id']\n        ann['id'] = cnt\n        ann['num_keypoints'] = len(keypoints)\n        ann['bbox'] = bbox\n        ann['is_crowd'] = 0\n        ann['area'] = w * h\n        ann['category_id'] = 1\n        ann['center'] = center\n        ann['scale'] = scale\n        annotations.append(ann)\n        cnt = cnt + 1\n\n    cocotype = {}\n    cocotype['images'] = images\n    cocotype['annotations'] = annotations\n    cocotype['categories'] = [{\n        'supercategory': 'person',\n        'id': 1,\n        'name': 'face',\n        'keypoints': [],\n        'skeleton': []\n    }]\n\n    json.dump(\n        cocotype,\n        open(out_file, 'w'),\n        ensure_ascii=False,\n        default=default_dump)\n    print(f'done {out_file}')\n\n\nif __name__ == '__main__':\n    if not osp.exists('data/wflw/annotations'):\n        os.makedirs('data/wflw/annotations')\n    root_folder = 'data/wflw'\n    ann_folder = f'{root_folder}/WFLW_annotations'\n    for root, dirs, files in os.walk(ann_folder):\n        for file in files:\n            if not file.endswith('txt'):\n                continue\n            print(f'Processing {file}')\n            sub_class = file.split('_')[-1].replace('.txt', '')\n            if sub_class != 'train' and sub_class != 'test':\n                out_file = f'face_landmarks_wflw_test_{sub_class}.json'\n            else:\n                out_file = f'face_landmarks_wflw_{sub_class}.json'\n            convert_wflw_to_coco(f'{root}/{file}',\n                                 f'{root_folder}/annotations/{out_file}')\n"
  },
  {
    "path": "tools/dist_test.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nCONFIG=$1\nCHECKPOINT=$2\nGPUS=$3\nNNODES=${NNODES:-1}\nNODE_RANK=${NODE_RANK:-0}\nPORT=${PORT:-29500}\nMASTER_ADDR=${MASTER_ADDR:-\"127.0.0.1\"}\n\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\npython -m torch.distributed.launch \\\n    --nnodes=$NNODES \\\n    --node_rank=$NODE_RANK \\\n    --master_addr=$MASTER_ADDR \\\n    --nproc_per_node=$GPUS \\\n    --master_port=$PORT \\\n    $(dirname \"$0\")/test.py \\\n    $CONFIG \\\n    $CHECKPOINT \\\n    --launcher pytorch \\\n    ${@:4}\n"
  },
  {
    "path": "tools/dist_train.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nCONFIG=$1\nGPUS=$2\nNNODES=${NNODES:-1}\nNODE_RANK=${NODE_RANK:-0}\nPORT=${PORT:-29500}\nMASTER_ADDR=${MASTER_ADDR:-\"127.0.0.1\"}\n\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\npython -m torch.distributed.launch \\\n    --nnodes=$NNODES \\\n    --node_rank=$NODE_RANK \\\n    --master_addr=$MASTER_ADDR \\\n    --nproc_per_node=$GPUS \\\n    --master_port=$PORT \\\n    $(dirname \"$0\")/train.py \\\n    $CONFIG \\\n    --launcher pytorch ${@:3}\n"
  },
  {
    "path": "tools/misc/browse_dataset.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport os\nimport os.path as osp\nfrom itertools import accumulate\n\nimport mmcv\nimport mmengine\nimport mmengine.fileio as fileio\nfrom mmengine import Config, DictAction\nfrom mmengine.registry import build_from_cfg, init_default_scope\nfrom mmengine.structures import InstanceData\n\nfrom mmpose.datasets import CombinedDataset\nfrom mmpose.registry import DATASETS, VISUALIZERS\nfrom mmpose.structures import PoseDataSample\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Browse a dataset')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument(\n        '--output-dir',\n        default=None,\n        type=str,\n        help='If there is no display interface, you can save it.')\n    parser.add_argument('--not-show', default=False, action='store_true')\n    parser.add_argument(\n        '--max-item-per-dataset',\n        default=50,\n        type=int,\n        help='Define the maximum item processed per dataset')\n    parser.add_argument(\n        '--phase',\n        default='train',\n        type=str,\n        choices=['train', 'test', 'val'],\n        help='phase of dataset to visualize, accept \"train\" \"test\" and \"val\".'\n        ' Defaults to \"train\".')\n    parser.add_argument(\n        '--show-interval',\n        type=float,\n        default=2,\n        help='the interval of show (s)')\n    parser.add_argument(\n        '--mode',\n        default='transformed',\n        type=str,\n        choices=['original', 'transformed'],\n        help='display mode; display original pictures or transformed '\n        'pictures. \"original\" means to show images load from disk'\n        '; \"transformed\" means to show images after transformed;'\n        'Defaults to \"transformed\".')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. If the value to '\n        'be overwritten is a list, it should be like key=\"[a,b]\" or key=a,b '\n        'It also allows nested list/tuple values, e.g. key=\"[(a,b),(c,d)]\" '\n        'Note that the quotation marks are necessary and that no white space '\n        'is allowed.')\n    args = parser.parse_args()\n    return args\n\n\ndef generate_dup_file_name(out_file):\n    \"\"\"Automatically rename out_file when duplicated file exists.\n\n    This case occurs when there is multiple instances on one image.\n    \"\"\"\n    if out_file and osp.exists(out_file):\n        img_name, postfix = osp.basename(out_file).rsplit('.', 1)\n        exist_files = tuple(\n            filter(lambda f: f.startswith(img_name),\n                   os.listdir(osp.dirname(out_file))))\n        if len(exist_files) > 0:\n            img_path = f'{img_name}({len(exist_files)}).{postfix}'\n            out_file = osp.join(osp.dirname(out_file), img_path)\n    return out_file\n\n\ndef main():\n    args = parse_args()\n    cfg = Config.fromfile(args.config)\n    if args.cfg_options is not None:\n        cfg.merge_from_dict(args.cfg_options)\n    backend_args = cfg.get('backend_args', dict(backend='local'))\n\n    # register all modules in mmpose into the registries\n    scope = cfg.get('default_scope', 'mmpose')\n    if scope is not None:\n        init_default_scope(scope)\n\n    if args.mode == 'original':\n        cfg[f'{args.phase}_dataloader'].dataset.pipeline = []\n    else:\n        # pack transformed keypoints for visualization\n        cfg[f'{args.phase}_dataloader'].dataset.pipeline[\n            -1].pack_transformed = True\n\n    dataset = build_from_cfg(cfg[f'{args.phase}_dataloader'].dataset, DATASETS)\n\n    visualizer = VISUALIZERS.build(cfg.visualizer)\n    visualizer.set_dataset_meta(dataset.metainfo)\n\n    if isinstance(dataset, CombinedDataset):\n\n        def generate_index_generator(dataset_starting_indexes: list,\n                                     max_item_datasets: int):\n            \"\"\"Generates indexes to traverse each dataset element in turn,\n            based on starting indexes and maximum items per dataset.\"\"\"\n            for relative_idx in range(max(max_item_datasets)):\n                for dataset_idx, dataset_starting_idx in enumerate(\n                        dataset_starting_indexes):\n                    if relative_idx >= max_item_datasets[dataset_idx]:\n                        continue\n                    yield dataset_starting_idx + relative_idx\n\n        # Generate starting indexes for each dataset\n        dataset_starting_indexes = list(accumulate([0] + dataset.lens[:-1]))\n        max_item_datasets = [\n            min(dataset_len, args.max_item_per_dataset)\n            for dataset_len in dataset.lens\n        ]\n\n        # Generate indexes using the generator\n        indexes = generate_index_generator(dataset_starting_indexes,\n                                           max_item_datasets)\n\n        total = sum(max_item_datasets)\n        multiple_datasets = True\n    else:\n        max_length = min(len(dataset), args.max_item_per_dataset)\n        indexes = iter(range(max_length))\n        total = max_length\n        multiple_datasets = False\n\n    progress_bar = mmengine.ProgressBar(total)\n\n    for idx in indexes:\n        item = dataset[idx]\n\n        if args.mode == 'original':\n            img_path = item['img_path']\n            img_bytes = fileio.get(img_path, backend_args=backend_args)\n            img = mmcv.imfrombytes(img_bytes, channel_order='bgr')\n            dataset_name = item.get('dataset_name', None)\n\n            # forge pseudo data_sample\n            gt_instances = InstanceData()\n            gt_instances.keypoints = item['keypoints']\n            if item['keypoints_visible'].ndim == 3:\n                gt_instances.keypoints_visible = item['keypoints_visible'][...,\n                                                                           0]\n            else:\n                gt_instances.keypoints_visible = item['keypoints_visible']\n            gt_instances.bboxes = item['bbox']\n            data_sample = PoseDataSample()\n            data_sample.gt_instances = gt_instances\n\n        else:\n            img = item['inputs'].permute(1, 2, 0).numpy()\n            data_sample = item['data_samples']\n            img_path = data_sample.img_path\n            dataset_name = data_sample.metainfo.get('dataset_name', None)\n\n        # save image with annotation\n        output_dir = osp.join(\n            args.output_dir, dataset_name\n        ) if multiple_datasets and dataset_name else args.output_dir\n        out_file = osp.join(\n            output_dir,\n            osp.basename(img_path)) if args.output_dir is not None else None\n        out_file = generate_dup_file_name(out_file)\n\n        img = mmcv.bgr2rgb(img)\n\n        visualizer.add_datasample(\n            osp.basename(img_path),\n            img,\n            data_sample,\n            draw_pred=False,\n            draw_bbox=(args.mode == 'original'),\n            draw_heatmap=True,\n            show=not args.not_show,\n            wait_time=args.show_interval,\n            out_file=out_file)\n\n        progress_bar.update()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/misc/generate_bbox_file.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport json\n\nimport numpy as np\nfrom mmengine import Config\n\nfrom mmpose.evaluation.functional import nms\nfrom mmpose.registry import DATASETS\nfrom mmpose.structures import bbox_xyxy2xywh\nfrom mmpose.utils import register_all_modules\n\ntry:\n    from mmdet.apis import DetInferencer\n    has_mmdet = True\nexcept ImportError:\n    print('Please install mmdet to use this script!')\n    has_mmdet = False\n\n\ndef main():\n\n    parser = argparse.ArgumentParser()\n    parser.add_argument('det_config')\n    parser.add_argument('det_weight')\n    parser.add_argument('output', type=str)\n    parser.add_argument(\n        '--pose-config',\n        default='configs/body_2d_keypoint/topdown_heatmap/'\n        'coco/td-hm_hrnet-w32_8xb64-210e_coco-256x192.py')\n    parser.add_argument('--score-thr', default=0.1)\n    parser.add_argument('--nms-thr', default=0.65)\n    args = parser.parse_args()\n\n    register_all_modules()\n\n    config = Config.fromfile(args.pose_config)\n    config.test_dataloader.dataset.data_mode = 'bottomup'\n    config.test_dataloader.dataset.bbox_file = None\n    test_set = DATASETS.build(config.test_dataloader.dataset)\n    print(f'number of images: {len(test_set)}')\n\n    detector = DetInferencer(args.det_config, args.det_weight)\n\n    new_bbox_files = []\n    for i in range(len(test_set)):\n        data = test_set.get_data_info(i)\n        image_id = data['img_id']\n        img_path = data['img_path']\n        result = detector(\n            img_path,\n            return_datasamples=True)['predictions'][0].pred_instances.numpy()\n        bboxes = np.concatenate((result.bboxes, result.scores[:, None]),\n                                axis=1)\n        bboxes = bboxes[bboxes[..., -1] > args.score_thr]\n        bboxes = bboxes[nms(bboxes, args.nms_thr)]\n        scores = bboxes[..., -1].tolist()\n        bboxes = bbox_xyxy2xywh(bboxes[..., :4]).tolist()\n\n        for bbox, score in zip(bboxes, scores):\n            new_bbox_files.append(\n                dict(category_id=1, image_id=image_id, score=score, bbox=bbox))\n\n    with open(args.output, 'w') as f:\n        json.dump(new_bbox_files, f, indent='')\n\n\nif __name__ == '__main__':\n    if has_mmdet:\n        main()\n"
  },
  {
    "path": "tools/misc/keypoints2coco_without_mmdet.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport json\nimport os\nfrom argparse import ArgumentParser\n\nfrom mmcv import track_iter_progress\nfrom PIL import Image\nfrom xtcocotools.coco import COCO\n\nfrom mmpose.apis import inference_top_down_pose_model, init_pose_model\n\n\ndef main():\n    \"\"\"Visualize the demo images.\n\n    pose_keypoints require the json_file containing boxes.\n    \"\"\"\n    parser = ArgumentParser()\n    parser.add_argument('pose_config', help='Config file for detection')\n    parser.add_argument('pose_checkpoint', help='Checkpoint file')\n    parser.add_argument('--img-root', type=str, default='', help='Image root')\n    parser.add_argument(\n        '--json-file',\n        type=str,\n        default='',\n        help='Json file containing image person bboxes in COCO format.')\n    parser.add_argument(\n        '--out-json-file',\n        type=str,\n        default='',\n        help='Output json contains pseudolabeled annotation')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        default=False,\n        help='whether to show img')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--kpt-thr', type=float, default=0.3, help='Keypoint score threshold')\n\n    args = parser.parse_args()\n\n    coco = COCO(args.json_file)\n    # build the pose model from a config file and a checkpoint file\n    pose_model = init_pose_model(\n        args.pose_config, args.pose_checkpoint, device=args.device.lower())\n\n    dataset = pose_model.cfg.data['test']['type']\n\n    img_keys = list(coco.imgs.keys())\n\n    # optional\n    return_heatmap = False\n\n    # e.g. use ('backbone', ) to return backbone feature\n    output_layer_names = None\n\n    categories = [{'id': 1, 'name': 'person'}]\n    img_anno_dict = {'images': [], 'annotations': [], 'categories': categories}\n\n    # process each image\n    ann_uniq_id = int(0)\n    for i in track_iter_progress(range(len(img_keys))):\n        # get bounding box annotations\n        image_id = img_keys[i]\n        image = coco.loadImgs(image_id)[0]\n        image_name = os.path.join(args.img_root, image['file_name'])\n\n        width, height = Image.open(image_name).size\n        ann_ids = coco.getAnnIds(image_id)\n\n        # make person bounding boxes\n        person_results = []\n        for ann_id in ann_ids:\n            person = {}\n            ann = coco.anns[ann_id]\n            # bbox format is 'xywh'\n            person['bbox'] = ann['bbox']\n            person_results.append(person)\n\n        pose_results, returned_outputs = inference_top_down_pose_model(\n            pose_model,\n            image_name,\n            person_results,\n            bbox_thr=None,\n            format='xywh',\n            dataset=dataset,\n            return_heatmap=return_heatmap,\n            outputs=output_layer_names)\n\n        # add output of model and bboxes to dict\n        for indx, i in enumerate(pose_results):\n            pose_results[indx]['keypoints'][\n                pose_results[indx]['keypoints'][:, 2] < args.kpt_thr, :3] = 0\n            pose_results[indx]['keypoints'][\n                pose_results[indx]['keypoints'][:, 2] >= args.kpt_thr, 2] = 2\n            x = int(pose_results[indx]['bbox'][0])\n            y = int(pose_results[indx]['bbox'][1])\n            w = int(pose_results[indx]['bbox'][2] -\n                    pose_results[indx]['bbox'][0])\n            h = int(pose_results[indx]['bbox'][3] -\n                    pose_results[indx]['bbox'][1])\n            bbox = [x, y, w, h]\n            area = round((w * h), 0)\n\n            images = {\n                'file_name': image_name.split('/')[-1],\n                'height': height,\n                'width': width,\n                'id': int(image_id)\n            }\n\n            annotations = {\n                'keypoints': [\n                    int(i) for i in pose_results[indx]['keypoints'].reshape(\n                        -1).tolist()\n                ],\n                'num_keypoints':\n                len(pose_results[indx]['keypoints']),\n                'area':\n                area,\n                'iscrowd':\n                0,\n                'image_id':\n                int(image_id),\n                'bbox':\n                bbox,\n                'category_id':\n                1,\n                'id':\n                ann_uniq_id,\n            }\n\n            img_anno_dict['annotations'].append(annotations)\n            ann_uniq_id += 1\n\n        img_anno_dict['images'].append(images)\n\n    # create json\n    with open(args.out_json_file, 'w') as outfile:\n        json.dump(img_anno_dict, outfile, indent=2)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/misc/pth_transfer.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nfrom collections import OrderedDict\n\nimport torch\n\n\ndef change_model(args):\n    dis_model = torch.load(args.dis_path, map_location='cpu')\n    all_name = []\n    if args.two_dis:\n        for name, v in dis_model['state_dict'].items():\n            if name.startswith('teacher.backbone'):\n                all_name.append((name[8:], v))\n            elif name.startswith('distill_losses.loss_mgd.down'):\n                all_name.append(('head.' + name[24:], v))\n            elif name.startswith('teacher.neck'):\n                all_name.append((name[8:], v))\n            elif name.startswith('student.head'):\n                all_name.append((name[8:], v))\n            else:\n                continue\n    else:\n        for name, v in dis_model['state_dict'].items():\n            if name.startswith('student.'):\n                all_name.append((name[8:], v))\n            else:\n                continue\n    state_dict = OrderedDict(all_name)\n    dis_model['state_dict'] = state_dict\n\n    save_keys = ['meta', 'state_dict']\n    ckpt_keys = list(dis_model.keys())\n    for k in ckpt_keys:\n        if k not in save_keys:\n            dis_model.pop(k, None)\n\n    torch.save(dis_model, args.output_path)\n\n\nif __name__ == '__main__':\n    parser = argparse.ArgumentParser(description='Transfer CKPT')\n    parser.add_argument('dis_path', help='dis_model path')\n    parser.add_argument('output_path', help='output path')\n    parser.add_argument(\n        '--two_dis', action='store_true', default=False, help='if two dis')\n    args = parser.parse_args()\n    change_model(args)\n"
  },
  {
    "path": "tools/misc/publish_model.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport subprocess\nfrom datetime import date\n\nimport torch\nfrom mmengine.logging import print_log\nfrom mmengine.utils import digit_version\nfrom mmengine.utils.dl_utils import TORCH_VERSION\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='Process a checkpoint to be published')\n    parser.add_argument('in_file', help='input checkpoint filename')\n    parser.add_argument('out_file', help='output checkpoint filename')\n    parser.add_argument(\n        '--save-keys',\n        nargs='+',\n        type=str,\n        default=['meta', 'state_dict'],\n        help='keys to save in published checkpoint (default: meta state_dict)')\n    args = parser.parse_args()\n    return args\n\n\ndef process_checkpoint(in_file, out_file, save_keys=['meta', 'state_dict']):\n    checkpoint = torch.load(in_file, map_location='cpu')\n\n    # only keep `meta` and `state_dict` for smaller file size\n    ckpt_keys = list(checkpoint.keys())\n    for k in ckpt_keys:\n        if k not in save_keys:\n            print_log(\n                f'Key `{k}` will be removed because it is not in '\n                f'save_keys. If you want to keep it, '\n                f'please set --save-keys.',\n                logger='current')\n            checkpoint.pop(k, None)\n\n    # if it is necessary to remove some sensitive data in checkpoint['meta'],\n    # add the code here.\n\n    if digit_version(TORCH_VERSION) >= digit_version('1.8.0'):\n        torch.save(checkpoint, out_file, _use_new_zipfile_serialization=False)\n    else:\n        torch.save(checkpoint, out_file)\n    sha = subprocess.check_output(['sha256sum', out_file]).decode()\n    if out_file.endswith('.pth'):\n        out_file_name = out_file[:-4]\n    else:\n        out_file_name = out_file\n\n    date_now = date.today().strftime('%Y%m%d')\n    final_file = out_file_name + f'-{sha[:8]}_{date_now}.pth'\n    subprocess.Popen(['mv', out_file, final_file])\n\n\ndef main():\n    args = parse_args()\n    process_checkpoint(args.in_file, args.out_file, args.save_keys)\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/slurm_test.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nset -x\n\nPARTITION=$1\nJOB_NAME=$2\nCONFIG=$3\nCHECKPOINT=$4\nGPUS=${GPUS:-8}\nGPUS_PER_NODE=${GPUS_PER_NODE:-8}\nCPUS_PER_TASK=${CPUS_PER_TASK:-5}\nSRUN_ARGS=${SRUN_ARGS:-\"\"}\n\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\nsrun -p ${PARTITION} \\\n    --job-name=${JOB_NAME} \\\n    --gres=gpu:${GPUS_PER_NODE} \\\n    --ntasks=${GPUS} \\\n    --ntasks-per-node=${GPUS_PER_NODE} \\\n    --cpus-per-task=${CPUS_PER_TASK} \\\n    --kill-on-bad-exit=1 \\\n    ${SRUN_ARGS} \\\n    python -u tools/test.py ${CONFIG} ${CHECKPOINT} --launcher=\"slurm\" ${@:5}\n"
  },
  {
    "path": "tools/slurm_train.sh",
    "content": "#!/usr/bin/env bash\n# Copyright (c) OpenMMLab. All rights reserved.\n\nset -x\n\nPARTITION=$1\nJOB_NAME=$2\nCONFIG=$3\nWORK_DIR=$4\nGPUS=${GPUS:-8}\nGPUS_PER_NODE=${GPUS_PER_NODE:-8}\nCPUS_PER_TASK=${CPUS_PER_TASK:-5}\nSRUN_ARGS=${SRUN_ARGS:-\"\"}\n\nPYTHONPATH=\"$(dirname $0)/..\":$PYTHONPATH \\\nsrun -p ${PARTITION} \\\n    --job-name=${JOB_NAME} \\\n    --gres=gpu:${GPUS_PER_NODE} \\\n    --ntasks=${GPUS} \\\n    --ntasks-per-node=${GPUS_PER_NODE} \\\n    --cpus-per-task=${CPUS_PER_TASK} \\\n    --kill-on-bad-exit=1 \\\n    ${SRUN_ARGS} \\\n    python -u tools/train.py ${CONFIG} --work-dir=${WORK_DIR} --launcher=\"slurm\" ${@:5}\n"
  },
  {
    "path": "tools/test.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport os\nimport os.path as osp\n\nimport mmengine\nfrom mmengine.config import Config, DictAction\nfrom mmengine.hooks import Hook\nfrom mmengine.runner import Runner\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(\n        description='MMPose test (and eval) model')\n    parser.add_argument('config', help='test config file path')\n    parser.add_argument('checkpoint', help='checkpoint file')\n    parser.add_argument(\n        '--work-dir', help='the directory to save evaluation results')\n    parser.add_argument('--out', help='the file to save metric results.')\n    parser.add_argument(\n        '--dump',\n        type=str,\n        help='dump predictions to a pickle file for offline evaluation')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        default={},\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. For example, '\n        \"'--cfg-options model.backbone.depth=18 model.backbone.with_cp=True'\")\n    parser.add_argument(\n        '--show-dir',\n        help='directory where the visualization images will be saved.')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        help='whether to display the prediction results in a window.')\n    parser.add_argument(\n        '--interval',\n        type=int,\n        default=1,\n        help='visualize per interval samples.')\n    parser.add_argument(\n        '--wait-time',\n        type=float,\n        default=1,\n        help='display time of every window. (second)')\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    # When using PyTorch version >= 2.0.0, the `torch.distributed.launch`\n    # will pass the `--local-rank` parameter to `tools/test.py` instead\n    # of `--local_rank`.\n    parser.add_argument('--local_rank', '--local-rank', type=int, default=0)\n    parser.add_argument(\n        '--badcase',\n        action='store_true',\n        help='whether analyze badcase in test')\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n    return args\n\n\ndef merge_args(cfg, args):\n    \"\"\"Merge CLI arguments to config.\"\"\"\n\n    cfg.launcher = args.launcher\n    cfg.load_from = args.checkpoint\n\n    # -------------------- work directory --------------------\n    # work_dir is determined in this priority: CLI > segment in file > filename\n    if args.work_dir is not None:\n        # update configs according to CLI args if args.work_dir is not None\n        cfg.work_dir = args.work_dir\n    elif cfg.get('work_dir', None) is None:\n        # use config filename as default work_dir if cfg.work_dir is None\n        cfg.work_dir = osp.join('./work_dirs',\n                                osp.splitext(osp.basename(args.config))[0])\n\n    # -------------------- visualization --------------------\n    if (args.show and not args.badcase) or (args.show_dir is not None):\n        assert 'visualization' in cfg.default_hooks, \\\n            'PoseVisualizationHook is not set in the ' \\\n            '`default_hooks` field of config. Please set ' \\\n            '`visualization=dict(type=\"PoseVisualizationHook\")`'\n\n        cfg.default_hooks.visualization.enable = True\n        cfg.default_hooks.visualization.show = False \\\n            if args.badcase else args.show\n        if args.show:\n            cfg.default_hooks.visualization.wait_time = args.wait_time\n        cfg.default_hooks.visualization.out_dir = args.show_dir\n        cfg.default_hooks.visualization.interval = args.interval\n\n    # -------------------- badcase analyze --------------------\n    if args.badcase:\n        assert 'badcase' in cfg.default_hooks, \\\n            'BadcaseAnalyzeHook is not set in the ' \\\n            '`default_hooks` field of config. Please set ' \\\n            '`badcase=dict(type=\"BadcaseAnalyzeHook\")`'\n\n        cfg.default_hooks.badcase.enable = True\n        cfg.default_hooks.badcase.show = args.show\n        if args.show:\n            cfg.default_hooks.badcase.wait_time = args.wait_time\n        cfg.default_hooks.badcase.interval = args.interval\n\n        metric_type = cfg.default_hooks.badcase.get('metric_type', 'loss')\n        if metric_type not in ['loss', 'accuracy']:\n            raise ValueError('Only support badcase metric type'\n                             \"in ['loss', 'accuracy']\")\n\n        if metric_type == 'loss':\n            if not cfg.default_hooks.badcase.get('metric'):\n                cfg.default_hooks.badcase.metric = cfg.model.head.loss\n        else:\n            if not cfg.default_hooks.badcase.get('metric'):\n                cfg.default_hooks.badcase.metric = cfg.test_evaluator\n\n    # -------------------- Dump predictions --------------------\n    if args.dump is not None:\n        assert args.dump.endswith(('.pkl', '.pickle')), \\\n            'The dump file must be a pkl file.'\n        dump_metric = dict(type='DumpResults', out_file_path=args.dump)\n        if isinstance(cfg.test_evaluator, (list, tuple)):\n            cfg.test_evaluator = [*cfg.test_evaluator, dump_metric]\n        else:\n            cfg.test_evaluator = [cfg.test_evaluator, dump_metric]\n\n    # -------------------- Other arguments --------------------\n    if args.cfg_options is not None:\n        cfg.merge_from_dict(args.cfg_options)\n\n    return cfg\n\n\ndef main():\n    args = parse_args()\n\n    # load config\n    cfg = Config.fromfile(args.config)\n    cfg = merge_args(cfg, args)\n\n    # build the runner from config\n    runner = Runner.from_cfg(cfg)\n\n    if args.out:\n\n        class SaveMetricHook(Hook):\n\n            def after_test_epoch(self, _, metrics=None):\n                if metrics is not None:\n                    mmengine.dump(metrics, args.out)\n\n        runner.register_hook(SaveMetricHook(), 'LOWEST')\n\n    # start testing\n    runner.test()\n\n\nif __name__ == '__main__':\n    main()\n"
  },
  {
    "path": "tools/torchserve/mmpose2torchserve.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os.path as osp\nimport warnings\nfrom argparse import ArgumentParser, Namespace\nfrom tempfile import TemporaryDirectory\n\nimport mmcv\nimport torch\nfrom mmengine.runner import CheckpointLoader\n\ntry:\n    from model_archiver.model_packaging import package_model\n    from model_archiver.model_packaging_utils import ModelExportUtils\nexcept ImportError:\n    package_model = None\n\n\ndef mmpose2torchserve(config_file: str,\n                      checkpoint_file: str,\n                      output_folder: str,\n                      model_name: str,\n                      model_version: str = '1.0',\n                      force: bool = False):\n    \"\"\"Converts MMPose model (config + checkpoint) to TorchServe `.mar`.\n\n    Args:\n        config_file:\n            In MMPose config format.\n            The contents vary for each task repository.\n        checkpoint_file:\n            In MMPose checkpoint format.\n            The contents vary for each task repository.\n        output_folder:\n            Folder where `{model_name}.mar` will be created.\n            The file created will be in TorchServe archive format.\n        model_name:\n            If not None, used for naming the `{model_name}.mar` file\n            that will be created under `output_folder`.\n            If None, `{Path(checkpoint_file).stem}` will be used.\n        model_version:\n            Model's version.\n        force:\n            If True, if there is an existing `{model_name}.mar`\n            file under `output_folder` it will be overwritten.\n    \"\"\"\n\n    mmcv.mkdir_or_exist(output_folder)\n\n    config = mmcv.Config.fromfile(config_file)\n\n    with TemporaryDirectory() as tmpdir:\n        model_file = osp.join(tmpdir, 'config.py')\n        config.dump(model_file)\n        handler_path = osp.join(osp.dirname(__file__), 'mmpose_handler.py')\n        model_name = model_name or osp.splitext(\n            osp.basename(checkpoint_file))[0]\n\n        # use mmcv CheckpointLoader if checkpoint is not from a local file\n        if not osp.isfile(checkpoint_file):\n            ckpt = CheckpointLoader.load_checkpoint(checkpoint_file)\n            checkpoint_file = osp.join(tmpdir, 'checkpoint.pth')\n            with open(checkpoint_file, 'wb') as f:\n                torch.save(ckpt, f)\n\n        args = Namespace(\n            **{\n                'model_file': model_file,\n                'serialized_file': checkpoint_file,\n                'handler': handler_path,\n                'model_name': model_name,\n                'version': model_version,\n                'export_path': output_folder,\n                'force': force,\n                'requirements_file': None,\n                'extra_files': None,\n                'runtime': 'python',\n                'archive_format': 'default'\n            })\n        manifest = ModelExportUtils.generate_manifest_json(args)\n        package_model(args, manifest)\n\n\ndef parse_args():\n    parser = ArgumentParser(\n        description='Convert MMPose models to TorchServe `.mar` format.')\n    parser.add_argument('config', type=str, help='config file path')\n    parser.add_argument('checkpoint', type=str, help='checkpoint file path')\n    parser.add_argument(\n        '--output-folder',\n        type=str,\n        required=True,\n        help='Folder where `{model_name}.mar` will be created.')\n    parser.add_argument(\n        '--model-name',\n        type=str,\n        default=None,\n        help='If not None, used for naming the `{model_name}.mar`'\n        'file that will be created under `output_folder`.'\n        'If None, `{Path(checkpoint_file).stem}` will be used.')\n    parser.add_argument(\n        '--model-version',\n        type=str,\n        default='1.0',\n        help='Number used for versioning.')\n    parser.add_argument(\n        '-f',\n        '--force',\n        action='store_true',\n        help='overwrite the existing `{model_name}.mar`')\n    args = parser.parse_args()\n\n    return args\n\n\nif __name__ == '__main__':\n    args = parse_args()\n\n    # Following strings of text style are from colorama package\n    bright_style, reset_style = '\\x1b[1m', '\\x1b[0m'\n    red_text, blue_text = '\\x1b[31m', '\\x1b[34m'\n    white_background = '\\x1b[107m'\n\n    msg = white_background + bright_style + red_text\n    msg += 'DeprecationWarning: This tool will be deprecated in future. '\n    msg += blue_text + 'Welcome to use the unified model deployment toolbox '\n    msg += 'MMDeploy: https://github.com/open-mmlab/mmdeploy'\n    msg += reset_style\n    warnings.warn(msg)\n\n    if package_model is None:\n        raise ImportError('`torch-model-archiver` is required.'\n                          'Try: pip install torch-model-archiver')\n\n    mmpose2torchserve(args.config, args.checkpoint, args.output_folder,\n                      args.model_name, args.model_version, args.force)\n"
  },
  {
    "path": "tools/torchserve/mmpose_handler.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport base64\nimport os\n\nimport mmcv\nimport torch\n\nfrom mmpose.apis import (inference_bottom_up_pose_model,\n                         inference_top_down_pose_model, init_pose_model)\nfrom mmpose.models.detectors import AssociativeEmbedding, TopDown\n\ntry:\n    from ts.torch_handler.base_handler import BaseHandler\nexcept ImportError:\n    raise ImportError('Please install torchserve.')\n\n\nclass MMPoseHandler(BaseHandler):\n\n    def initialize(self, context):\n        properties = context.system_properties\n        self.map_location = 'cuda' if torch.cuda.is_available() else 'cpu'\n        self.device = torch.device(self.map_location + ':' +\n                                   str(properties.get('gpu_id')) if torch.cuda.\n                                   is_available() else self.map_location)\n        self.manifest = context.manifest\n\n        model_dir = properties.get('model_dir')\n        serialized_file = self.manifest['model']['serializedFile']\n        checkpoint = os.path.join(model_dir, serialized_file)\n        self.config_file = os.path.join(model_dir, 'config.py')\n\n        self.model = init_pose_model(self.config_file, checkpoint, self.device)\n        self.initialized = True\n\n    def preprocess(self, data):\n        images = []\n\n        for row in data:\n            image = row.get('data') or row.get('body')\n            if isinstance(image, str):\n                image = base64.b64decode(image)\n            image = mmcv.imfrombytes(image)\n            images.append(image)\n\n        return images\n\n    def inference(self, data, *args, **kwargs):\n        if isinstance(self.model, TopDown):\n            results = self._inference_top_down_pose_model(data)\n        elif isinstance(self.model, (AssociativeEmbedding, )):\n            results = self._inference_bottom_up_pose_model(data)\n        else:\n            raise NotImplementedError(\n                f'Model type {type(self.model)} is not supported.')\n\n        return results\n\n    def _inference_top_down_pose_model(self, data):\n        results = []\n        for image in data:\n            # use dummy person bounding box\n            preds, _ = inference_top_down_pose_model(\n                self.model, image, person_results=None)\n            results.append(preds)\n        return results\n\n    def _inference_bottom_up_pose_model(self, data):\n        results = []\n        for image in data:\n            preds, _ = inference_bottom_up_pose_model(self.model, image)\n            results.append(preds)\n        return results\n\n    def postprocess(self, data):\n        output = [[{\n            'keypoints': pred['keypoints'].tolist()\n        } for pred in preds] for preds in data]\n\n        return output\n"
  },
  {
    "path": "tools/torchserve/test_torchserver.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport os\nimport os.path as osp\nimport warnings\nfrom argparse import ArgumentParser\n\nimport requests\n\nfrom mmpose.apis import (inference_bottom_up_pose_model,\n                         inference_top_down_pose_model, init_pose_model,\n                         vis_pose_result)\nfrom mmpose.models import AssociativeEmbedding, TopDown\n\n\ndef parse_args():\n    parser = ArgumentParser()\n    parser.add_argument('img', help='Image file')\n    parser.add_argument('config', help='Config file')\n    parser.add_argument('checkpoint', help='Checkpoint file')\n    parser.add_argument('model_name', help='The model name in the server')\n    parser.add_argument(\n        '--inference-addr',\n        default='127.0.0.1:8080',\n        help='Address and port of the inference server')\n    parser.add_argument(\n        '--device', default='cuda:0', help='Device used for inference')\n    parser.add_argument(\n        '--out-dir', default='vis_results', help='Visualization output path')\n    args = parser.parse_args()\n    return args\n\n\ndef main(args):\n    os.makedirs(args.out_dir, exist_ok=True)\n\n    # Inference single image by native apis.\n    model = init_pose_model(args.config, args.checkpoint, device=args.device)\n    if isinstance(model, TopDown):\n        pytorch_result, _ = inference_top_down_pose_model(\n            model, args.img, person_results=None)\n    elif isinstance(model, (AssociativeEmbedding, )):\n        pytorch_result, _ = inference_bottom_up_pose_model(model, args.img)\n    else:\n        raise NotImplementedError()\n\n    vis_pose_result(\n        model,\n        args.img,\n        pytorch_result,\n        out_file=osp.join(args.out_dir, 'pytorch_result.png'))\n\n    # Inference single image by torchserve engine.\n    url = 'http://' + args.inference_addr + '/predictions/' + args.model_name\n    with open(args.img, 'rb') as image:\n        response = requests.post(url, image)\n    server_result = response.json()\n\n    vis_pose_result(\n        model,\n        args.img,\n        server_result,\n        out_file=osp.join(args.out_dir, 'torchserve_result.png'))\n\n\nif __name__ == '__main__':\n    args = parse_args()\n    main(args)\n\n    # Following strings of text style are from colorama package\n    bright_style, reset_style = '\\x1b[1m', '\\x1b[0m'\n    red_text, blue_text = '\\x1b[31m', '\\x1b[34m'\n    white_background = '\\x1b[107m'\n\n    msg = white_background + bright_style + red_text\n    msg += 'DeprecationWarning: This tool will be deprecated in future. '\n    msg += blue_text + 'Welcome to use the unified model deployment toolbox '\n    msg += 'MMDeploy: https://github.com/open-mmlab/mmdeploy'\n    msg += reset_style\n    warnings.warn(msg)\n"
  },
  {
    "path": "tools/train.py",
    "content": "# Copyright (c) OpenMMLab. All rights reserved.\nimport argparse\nimport os\nimport os.path as osp\n\nfrom mmengine.config import Config, DictAction\nfrom mmengine.runner import Runner\n\n\ndef parse_args():\n    parser = argparse.ArgumentParser(description='Train a pose model')\n    parser.add_argument('config', help='train config file path')\n    parser.add_argument('--work-dir', help='the dir to save logs and models')\n    parser.add_argument(\n        '--resume',\n        nargs='?',\n        type=str,\n        const='auto',\n        help='If specify checkpint path, resume from it, while if not '\n        'specify, try to auto resume from the latest checkpoint '\n        'in the work directory.')\n    parser.add_argument(\n        '--amp',\n        action='store_true',\n        default=False,\n        help='enable automatic-mixed-precision training')\n    parser.add_argument(\n        '--no-validate',\n        action='store_true',\n        help='whether not to evaluate the checkpoint during training')\n    parser.add_argument(\n        '--auto-scale-lr',\n        action='store_true',\n        help='whether to auto scale the learning rate according to the '\n        'actual batch size and the original batch size.')\n    parser.add_argument(\n        '--show-dir',\n        help='directory where the visualization images will be saved.')\n    parser.add_argument(\n        '--show',\n        action='store_true',\n        help='whether to display the prediction results in a window.')\n    parser.add_argument(\n        '--interval',\n        type=int,\n        default=1,\n        help='visualize per interval samples.')\n    parser.add_argument(\n        '--wait-time',\n        type=float,\n        default=1,\n        help='display time of every window. (second)')\n    parser.add_argument(\n        '--cfg-options',\n        nargs='+',\n        action=DictAction,\n        help='override some settings in the used config, the key-value pair '\n        'in xxx=yyy format will be merged into config file. If the value to '\n        'be overwritten is a list, it should be like key=\"[a,b]\" or key=a,b '\n        'It also allows nested list/tuple values, e.g. key=\"[(a,b),(c,d)]\" '\n        'Note that the quotation marks are necessary and that no white space '\n        'is allowed.')\n    parser.add_argument(\n        '--launcher',\n        choices=['none', 'pytorch', 'slurm', 'mpi'],\n        default='none',\n        help='job launcher')\n    # When using PyTorch version >= 2.0.0, the `torch.distributed.launch`\n    # will pass the `--local-rank` parameter to `tools/train.py` instead\n    # of `--local_rank`.\n    parser.add_argument('--local_rank', '--local-rank', type=int, default=0)\n    args = parser.parse_args()\n    if 'LOCAL_RANK' not in os.environ:\n        os.environ['LOCAL_RANK'] = str(args.local_rank)\n\n    return args\n\n\ndef merge_args(cfg, args):\n    \"\"\"Merge CLI arguments to config.\"\"\"\n    if args.no_validate:\n        cfg.val_cfg = None\n        cfg.val_dataloader = None\n        cfg.val_evaluator = None\n\n    cfg.launcher = args.launcher\n\n    # work_dir is determined in this priority: CLI > segment in file > filename\n    if args.work_dir is not None:\n        # update configs according to CLI args if args.work_dir is not None\n        cfg.work_dir = args.work_dir\n    elif cfg.get('work_dir', None) is None:\n        # use config filename as default work_dir if cfg.work_dir is None\n        cfg.work_dir = osp.join('./work_dirs',\n                                osp.splitext(osp.basename(args.config))[0])\n\n    # enable automatic-mixed-precision training\n    if args.amp is True:\n        from mmengine.optim import AmpOptimWrapper, OptimWrapper\n        optim_wrapper = cfg.optim_wrapper.get('type', OptimWrapper)\n        assert optim_wrapper in (OptimWrapper, AmpOptimWrapper,\n                                 'OptimWrapper', 'AmpOptimWrapper'), \\\n            '`--amp` is not supported custom optimizer wrapper type ' \\\n            f'`{optim_wrapper}.'\n        cfg.optim_wrapper.type = 'AmpOptimWrapper'\n        cfg.optim_wrapper.setdefault('loss_scale', 'dynamic')\n\n    # resume training\n    if args.resume == 'auto':\n        cfg.resume = True\n        cfg.load_from = None\n    elif args.resume is not None:\n        cfg.resume = True\n        cfg.load_from = args.resume\n\n    # enable auto scale learning rate\n    if args.auto_scale_lr:\n        cfg.auto_scale_lr.enable = True\n\n    # visualization\n    if args.show or (args.show_dir is not None):\n        assert 'visualization' in cfg.default_hooks, \\\n            'PoseVisualizationHook is not set in the ' \\\n            '`default_hooks` field of config. Please set ' \\\n            '`visualization=dict(type=\"PoseVisualizationHook\")`'\n\n        cfg.default_hooks.visualization.enable = True\n        cfg.default_hooks.visualization.show = args.show\n        if args.show:\n            cfg.default_hooks.visualization.wait_time = args.wait_time\n        cfg.default_hooks.visualization.out_dir = args.show_dir\n        cfg.default_hooks.visualization.interval = args.interval\n\n    if args.cfg_options is not None:\n        cfg.merge_from_dict(args.cfg_options)\n\n    return cfg\n\n\ndef main():\n    args = parse_args()\n\n    # load config\n    cfg = Config.fromfile(args.config)\n\n    # merge CLI arguments to config\n    cfg = merge_args(cfg, args)\n\n    # set preprocess configs to model\n    if 'preprocess_cfg' in cfg:\n        cfg.model.setdefault('data_preprocessor',\n                             cfg.get('preprocess_cfg', {}))\n\n    # build the runner from config\n    runner = Runner.from_cfg(cfg)\n\n    # start training\n    runner.train()\n\n\nif __name__ == '__main__':\n    main()\n"
  }
]